2

这是我为 Lua 中的 LOVE2D 引擎制作的一个小库,它使用分离轴定理来解决碰撞问题。

当我的 SAT 程序开始运行时,我非常高兴,并开始使用大量多边形对其进行测试。它在大多数情况下都有效,并且也为它们提供了正确的最小平移向量。奇怪的是——如果两个形状都有锐角,那么这些角度会导致程序失败,当形状不接触时返回碰撞,或者更不寻常的是,它会给出一个奇怪的最小平移向量。我检查了返回法线的函数——因为我觉得这是我可能失败的第一点,但它似乎工作正常。

这是处理我的碰撞的主要功能。

function findIntersection(shape1, shape2)
--Get axes to test.
--MTV means 'minimum translation vector' ie. the shortest vector of intersection
local axes1 = {}
local axes2 = {}
local overlap = false
local MTV = {direction = 0, magnitude = 99999}

for i, vert in pairs(shape1.hitbox) do
    nrm = getNormal(shape1.hitbox, i)
    table.insert(axes1, nrm)
end
for i, vert in pairs(shape2.hitbox)do
    nrm = getNormal(shape2.hitbox, i)
    table.insert(axes2, nrm)
end

--print(#axes1 .. '    ' .. #axes2)

--now that we have the axes, we have to project along each of them
for i, axis in pairs(axes1) do
    test1 = hitboxProj(shape1, vectorToCoord(axis.direction, axis.magnitude))
    test2 = hitboxProj(shape2, vectorToCoord(axis.direction, axis.magnitude))
    if test2.max > test1.min or test1.max > test2.min then
        if test2.max - test1.min < MTV.magnitude then
            MTV.direction = axes1[i].direction
            MTV.magnitude = test2.max - test1.min
        end
    else
        return false
    end
end

--now that we have the axes, we have to project along each of them
for i, axis in pairs(axes2) do
    test1 = hitboxProj(shape1, vectorToCoord(axis.direction, axis.magnitude))
    test2 = hitboxProj(shape2, vectorToCoord(axis.direction, axis.magnitude))
    if test2.max > test1.min or test1.max > test2.min then
        if test2.max - test1.min < MTV.magnitude then
            MTV.direction = axes2[i].direction
            MTV.magnitude = test2.max - test1.min
        end
    else
        return false
    end
end

return {MTV}
end

我的项目文件在 github https://github.com/ToffeeGoat/ToffeeCollision

4

1 回答 1

0

这是一个好的开始,您的代码相当清晰。有些事情可以改进,特别是我看到你所有的功能都是全局的。对于初学者,您希望将所有功能存储在“模块”中以避免污染 _G 空间。您可以将本地人用于其他所有事情。请注意,编写x == 0这种检查仅适用于整数并且在涉及浮点数学时可能会失败的东西并不可靠。我建议为库中的每个函数编写一个简单的测试脚本。

此外,return {x = xCoord, y = yCoord}当您可以使用 Lua 返回多个值时,编写起来效率不高return xCoord, yCoord。创建大量中间表会给垃圾收集器带来压力。您的某些代码需要像“getDirection”函数一样进行修改。我的意思是这类事情已经有众所周知的技术。查看我的教程以获取示例:https ://2dengine.com/?p=vectors#Angle_between_two_vectors

里面有一些愚蠢的东西,比如function sq(x) return x*x end。你知道你可以用 Lua 写 x^2 吗? addDeg可以用模运算符代替: newAng = (角度 + 加法)%360 另请注意,使用度数绝对没有任何好处 - 我建议只使用弧度。您已经在使用以弧度表示的 math.pi。无论哪种方式,您都必须选择弧度或度数并坚持其中一个。不要在代码中同时使用这两个单位。

我不想过多吹毛求疵,因为您的代码还不错,您只需要习惯一些最佳实践即可。这是我的另一个教程: https ://2dengine.com/?p=intersections

于 2020-09-01T07:22:08.320 回答