两个一般六面体之间的碰撞检测
Posted
技术标签:
【中文标题】两个一般六面体之间的碰撞检测【英文标题】:Collision detection between two general hexahedrons 【发布时间】:2010-09-05 23:44:13 【问题描述】:我有 2 个六面体。唯一的保证是它们每个都有 8 个 vertex3f(具有 x、y 和 z 分量的顶点)。鉴于此,我怎样才能知道它们是否发生冲突?
【问题讨论】:
没有必要删除和重新发布。编辑将问题排在活动队列的顶部。 无论您的最终算法是什么,您仍然可以使用边界框快速丢弃许多可能的冲突。对于每个六面体,取每个分量的最大值和最小值。如果任何区间不重叠,则六面体不能相交。 我不确定我是否理解这一点,但听起来它可以工作。 我会详细回答。 【参考方案1】:在我试图回答时你删除了你的最后一个问题并让我失去了我的帖子后,我很犹豫要不要回答。请不要再这样做了。无论如何:
不一定是最优的,但显然是正确的,基于constructive solid geometry:
-
将两个实体分别表示为 6 个半空间的交集。请注意,这取决于凸度,但仅取决于其他方面,并扩展到具有更多边的实体。我首选的半空间表示是在每个曲面上选择一个点(例如,一个顶点)和指向该曲面的向外指向的单位法线向量。
通过将所有 12 个半空间视为新实体的定义半空间来使两个实体相交。 (此步骤纯粹是概念性的,可能不涉及任何实际代码。)
计算新实体的表面/边缘表示并检查它是否为非空。执行此操作的一种方法是首先为 12 个半空间中的每一个填充一个曲面/边缘表示,其中边缘在 2 个实体的边界之外,然后将其边缘与其余 11 个半空间中的每一个相交。
这听起来有点工作,但没有什么复杂的。只有点积、叉积(以获得初始表示)和投影。
【讨论】:
如果删除的事情再次发生在您身上,并且您确实想要恢复内容,您也许可以尝试引起 mod 的注意 - 任何拥有 10k+ 代表的人都可以看到已删除的问题和答案。我当然很乐意为此类事情提供帮助。【参考方案2】:看来我太笨了,不能放弃。
考虑一下。如果实体 1 的任何边与实体 2 的任何面相交,就会发生碰撞。这不是很全面,因为有些情况下一个完全包含在另一个中,您可以通过确定其中一个的中心是否包含在另一个中来测试。
检查边缘面相交的工作方式如下。
-
将边定义为从一个顶点开始运行到另一个顶点的向量。记下边的长度
L
。
通过顶点、法线、平面内基础以及该基础中剩余顶点的位置来定义平面段。
Find the intersection of the line and the plane。在通常的公式中,您将能够获得沿线的长度以及交点的平面内坐标在您选择的基础上。
交点必须与长度为[0,L]
一致,并且必须位于平面中的图形内。最后一部分有点难,但有a well known general solution。
这会奏效。对于口才,我更喜欢R..'s solution。如果您需要速度...好吧,您只需尝试一下即可。
【讨论】:
我明白,我只是不确定如何检查边缘是否与面部相交,老实说,我真正在做的是一个轴对齐的边界立方体与旋转的边界立方体相交,跨度> 【参考方案3】:假设你的一个六面体H1
有顶点(x_1, y_1, z_1), (x_2, y_2, z_2), ...
。求每个坐标中的最大值和最小值:x_min = min(x_1, x_2, ...)
、x_max = max(x_1, x_2,...)
,以此类推。对另一个六面体 H2
执行相同操作。
如果区间[x_min(H1), x_max(H1)]
和区间[x_min(H2), x_max(H2)]
不相交(即x_max(H1) < x_min(H2)
或x_max(H2) < x_min(H1)
),则六面体不可能发生碰撞。对 y
和 z
坐标重复此操作。定性地说,这就像在 x 轴上查看每个六面体的阴影。如果它们不重叠,多面体就不会发生碰撞。
如果任何间隔确实重叠,您将不得不继续进行更精确的碰撞检测。这将更加棘手。显而易见的蛮力方法是检查一个人的任何边缘是否与另一个人的任何面相交,但我想你可以做得比这更好。
检查边缘是否与面相交的蛮力方法...首先,您会找到边缘定义的线与面定义的平面的交点(例如,参见wikipedia)。然后你必须检查那个点是否真的在边缘和面上。边缘很容易 - 只需查看坐标是否在定义边缘的两个顶点的坐标之间。脸比较棘手,尤其是不能保证它是凸的。在一般情况下,您只需查看它所在的每条边定义的半平面的哪一侧。如果所有这些都在内侧半平面上,则它在面部内侧。不幸的是,我现在没有时间输入所有内容,但我敢打赌谷歌搜索可以帮助你。但当然,这都是蛮力的,可能还有更好的方法。 (并且 dmckee 指出了一个特殊情况,这不能处理)
【讨论】:
如何进行边缘相交测试? @Milo:因为他只描述边界框测试,所以这些是应该测试相交的一维范围。 IE。 [a,b] 是否与 [c,d] 相交。以上是关于两个一般六面体之间的碰撞检测的主要内容,如果未能解决你的问题,请参考以下文章