两个普通六面体之间的碰撞检测

时间:2010-09-05 23:44:13

标签: c++ c algorithm collision-detection

我有2个六面体。唯一的保证是它们每个都有8个vertex3f(带有x,y和z分量的顶点)。鉴于此,我怎样才能知道这些是否发生碰撞?

3 个答案:

答案 0 :(得分:5)

在我试图回答问题并删除我的帖子后,我删除了你的上一个问题后,我犹豫不决。请不要再这样做了。无论如何:

不一定是最佳的,但显然是正确的,基于constructive solid geometry

  1. 将两个实体分别表示为6个半空间的交集。请注意,这取决于凸性而不是其他任何东西,并且延伸到具有更多边的实体。半空间的首选表示是选择每个表面上的一个点(例如,一个顶点)和指向该表面的向外指向单位法线向量。
  2. 通过将所有12个半空间视为新固体的定义半空间来交叉两个实体。 (此步骤纯粹是概念性的,可能不涉及任何实际代码。)
  3. 计算新实体的曲面/边缘表示,并检查它是否为非空。这样做的一种方法是首先用12个半空间中的每一个填充表面/边缘表示,其中边缘在2个实体的边界之外,然后将其边缘与剩余的11个半空间中的每一个相交。 / LI>

    听起来有点像工作,但没有什么复杂的。只有点积,交叉积(获得初始表示)和投影。

答案 1 :(得分:3)

我似乎太愚蠢了。

考虑一下。如果实体1的任何边缘与实体2的任何面相交,则会发生碰撞。这并不是很全面,因为有一种情况完全包含在另一种中,你可以通过确定其中一种是否包含在另一种中来进行测试。


检查边缘面交叉是这样的。

  1. 将边缘定义为从一个顶点运行到另一个顶点的向量。记下边缘的长度L
  2. 通过顶点,法线,平面内基础以及该基础中剩余顶点的位置定义平面线段。
  3. Find the intersection of the line and the plane。在通常的公式中,您将能够获得沿着线的长度,以及在您选择的基础上的交叉点的平面内坐标
  4. 交点必须以长度[0,L]为单位,并且必须位于平面中的图形内。最后一部分有点难,但有a well known general solution
  5. 这会奏效。为了口才,我更喜欢R..'s solution。如果你需要速度......好吧,你只需要尝试它们就可以看到。

答案 2 :(得分:1)

假设您的六面体之一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)),则六面体不可能发生碰撞。对yz坐标重复此操作。定性地说,这就像在x轴上观察每个六面体的阴影一样。如果它们不重叠,则多面体不会发生碰撞。

如果任何间隔重叠,则必须继续进行更精确的碰撞检测。这将更加棘手。明显的蛮力方法是检查一个边缘的任何一个边缘是否与另一个面相交,但我想你可以做得更好。

检查边缘是否与面相交的蛮力方法......首先,您会找到边缘定义的线与面定义的平面的交点(例如,请参阅wikipedia) 。然后你必须检查那个点是否实际上在边缘和面部。边缘很简单 - 只需看看坐标是否位于定义边缘的两个顶点的坐标之间。面部比较棘手,特别是不能保证凸起。在一般情况下,您只需要看到它所在的每个边缘定义的半平面的哪一侧。如果它在所有人的内半平面上,它就在脸部内部。遗憾的是,我现在没有时间打字,但我打赌谷歌搜索可以帮助你。但当然,这都是蛮力,可能有更好的方法。 (而且dmckee指出了一个不能处理的特殊情况)