如何测试两个移动的2d定向边框的碰撞?

时间:2009-04-19 01:53:31

标签: collision-detection

OBB具有位置(x,y),速度(x,y)和方向(矩阵)。鉴于定期更新,OBB必须相互冲突,返回被认为成功的移动部分。

我查看了GPWiki上的Polygon测试 - http://gpwiki.org/index.php/Polygon_Collision - 但它没有考虑移动对象或完全在OBB中的对象。

“实时碰撞检测”一书涵盖了第4章:边界体积中的3D OBB,但3维测试方法明显比2D更复杂。

5 个答案:

答案 0 :(得分:4)

为了测试2个定向边界框之间的碰撞检测,我使用分离轴定理(SAT)。事实上,SAT可用于任何2个凸形之间的碰撞检测。这种技术理解起来并不复杂,并且具有合理的性能。 该定理可以很容易地扩展到3D。

编辑:

算法尝试确定是否可以在两个对象之间拟合平面。如果存在这样的平面,则该对象被分开,并且不能相交。

要确定对象是否分开,只需将对象投影到平面的normal上,然后比较间隔并查看它们是否重叠。

因此,显然有无数个平面可以放在两个分开的对象之间。但事实证明,你只需要测试一些飞机。

可以证明,对于盒子,要测试的分离平面是法线等于两个盒子的轴的平面。因此,对于2个盒子,您只需要测试4个分离平面。在4个平面中,一旦找到分隔框的分离平面,那么您就知道框不能相交,并且您返回无碰撞标记。

如果4个平面无法分开方框,那么方框必须是交叉的,并且你有碰撞。

答案 1 :(得分:2)

另一个建议(涵盖遏制,我认为更便宜):

检查#1的4个顶点中的任何一个是否在#2内,然后检查#2的4个顶点中的任何一个是否在#1内。以下是我建议如何做到这一点:

假设您正在检查的#1的顶点是v,而#2的4个顶点是v1 ... v4。 按#2的方向反转所有5个顶点。 (通过方向矩阵M反向旋转矢量u,乘以M转置:M ^ T u,假设在你的常规方向中通过左乘法工作。) 生成的第二个框,称为#2',现在是轴对齐的 - 您可以立即检查v'是否包含在其中。

如果你发现#2内的任何#1 - 顶点 - 停止,你就有了交集。否则 - 继续。

可以立即想到一些优化(也许你可以在每个盒子中存储未旋转的顶点副本?如果大小是固定的,也许你可以比较它们以立即消除一个可能的包含,并节省3个潜在的测试? )但除非你将它应用于成对的箱子对,否则这个测试应该足够便宜。

关于动作,你可以在那里得到你想要的深度 - 查找“连续碰撞”,并亲眼看看。 (我特别记得Stephane Redon的一些不错的作品)。我完全相信没有任何游戏可以做任何这些花哨的东西:如果你确实移动得非常快,你可以细分你的时间步长并对每个位置/方向子迭代进行碰撞检查。

(编辑:)有另外一个关于它的讨论right here,有很好的参考资料。

答案 2 :(得分:1)

如果你有两个带有任意方向的边界框(即矩形)(我假设这意味着一些“旋转”),那么我会做以下事情:

  • 从初始位置开始(我假设边界框不相交),根据速度向前平移每个方框(但是随着时间的推移,你正在应用移动)。
  • 找到每个已翻译的边界框的角的坐标。这4个坐标定义了构成边界框边缘的4个线段的端点。
  • 对于边界框#1,测试其每个线段与边界框#2的4个线段之间的交叉点。您可以使用标准公式计算两条线的交点,例如here所述。
  • 如果有一个交叉路口,请使用交叉点的坐标和您应用的已知转换来计算成功移动的部分。
  • 为每次更新重复上述步骤。

编辑:粗略的伪代码(包含评论中讨论的内容)如下所示:

...test for intersections between the OBB edges...
if any intersections are found{
    ...run code for when OBBs are partially overlapping...
}else{
    P = line segment whose endpoints are the OBB centers;
    ...test for intersections between P and OBB edges...
    if P intersects edges of both OBBs{
        ...run code for when OBBs are not touching...
    }else{
        ...run code for when one OBB is completely inside the other...
    }
}

答案 3 :(得分:0)

你说2d,但也提到3d更复杂。对于碰撞检测,您基本上想要测试两个形状是否相互交叉。在2D中,使用边界框,这些是rectangles。您需要使用算法来查看矩形是否相交,还要检查一个是否完全包含在另一个中(简单算法的3个测试)。对于3d,这些是立方体。一样。查看这个matrix对象 - 对象交叉点,找到你想要的那些。检查对象本身的交集,并且一个完全包含在另一个中。

此过程不仅可以扩展到边界框,还可以扩展到凸起的边界外壳,多边形或完整的三维对象中的边界或实际对象本身。最终结果是,随着物体在空间和时间上的进展,它们的表面是否发生碰撞或它们是否在彼此内部。如果您的粒度太粗糙,并且在您正在建模的情况下,它们应该发生碰撞,但它们最终会相互移动,您应该进行额外的光线束缚的交叉点测试,以查看是否有一个中心的加权点。对象与另一个的边界相交。

答案 4 :(得分:0)

您可能应该实现四叉树(请参阅wikipedia)以跟踪飞机上的所有对象。遗憾的是,我从未实现过一次碰撞检测,但似乎其他people已经能够使用四叉树为您创建类似的场景。