分离轴定理和Python

时间:2011-05-16 04:59:06

标签: python math physics pygame

这就是我目前正在做的事情:

创建垂直于2个矩形的4个边的4轴。由于它们是矩形,因此我不需要为每条边生成轴(法线)。

然后我绕过我的4轴。

所以对于每个轴: 我将矩形的每个角投影到轴上。 有两个包含这些投影的列表(数组)。每个矩形一个。 然后我得到每个投影和轴的点积。这将返回标量值 可用于确定最小值和最大值

现在2个列表包含标量而不是向量。我对列表进行排序,以便我可以轻松选择最小值和最大值。如果方框B的最小值=方框A的最大值或方框B的最大值<=方框A的最小值,则该轴上没有碰撞,并且对象之间没有碰撞。

此时函数结束,循环中断。

如果所有轴都没有满足这些条件,那么我们就会发生碰撞

我希望这是正确的做法。

python代码本身可以在http://pastebin.com/vNFP3mAb

找到

此外: http://www.gamedev.net/page/reference/index.html/_/reference/programming/game-programming/collision-detection/2d-rotated-rectangle-collision-r2604

我遇到的问题是上面的代码不起作用。即使没有碰撞,它也始终检测到碰撞。我输入的内容正是代码所做的。如果我遗漏任何步骤或者只是不了解SAT如何运作,请告诉我。

2 个答案:

答案 0 :(得分:5)

一般情况下,有必要执行问题中列出的步骤,以确定矩形是否“碰撞”(相交),注意OP确实可以打破(结束非交叉)找到分离轴。

在为早期出口提供机会的意义上,有几种简单的“优化”方法。这些的实际价值取决于被检查的矩形的分布,但两者都很容易纳入现有的框架中。

(1)边界圆检查

证明非交叉的一种快速方法是通过显示两个矩形的边界圆不相交。矩形的边界圆共享其中心,即任一对角线的中点,并且其直径等于任一对角线的长度。如果两个圆心之间的距离超过两个圆的半径之和,则圆不相交。因此矩形也不能相交。如果目的是找到分离轴,我们还没有完成。但是,如果我们只想知道矩形是否“碰撞”,则可以提前退出。

(2)另一个矩形的顶点

一个矩形的顶点在与另一个矩形的边缘平行的轴上的投影提供了足够的信息来检测该顶点何时在另一个矩形内。当后一个矩形已经平移并且未旋转到原点(边缘平行于普通轴)时,这种检查特别容易。如果发生一个矩形的顶点在另一个矩形的内部,则矩形明显相交。当然,这是交叉的充分条件,而不是必要条件。但是它允许早期退出并得到交叉点的结论(当然没有找到分离轴,因为没有交叉点。)

答案 1 :(得分:3)

我发现有两件事是错的。首先,投影应该只是顶点与轴的点积。你正在做的事情太复杂了。其次,你获得轴的方式是不正确的。你写道:

Axis1 = [  -(A_TR[0] - A_TL[0]),
             A_TR[1] - A_TL[1] ]

应该在哪里阅读:

Axis1 = [  -(A_TR[1] - A_TL[1]),
             A_TR[0] - A_TL[0] ]

区别在于坐标确实为你提供了一个向量,但为了获得垂直,你需要交换x和y值并否定其中一个。

希望有所帮助。

编辑发现了另一个错误

在此代码中:

if not ( B_Scalars[0] <= A_Scalars[3] or B_Scalars[3] >= A_Scalars[0] ):
            #no overlap so no collision
            return 0

那应该是:

if not ( B_Scalars[3] <= A_Scalars[0] or A_Scalars[3] <= B_Scalars[0] ):

Sort为您提供增加值的列表。所以[1,2,3,4]和[10,11,12,13]不重叠,因为后者的最小值大于前者的最大值。第二个比较是交换输入集的时间。