两个移动四面体之间的连续碰撞检测

时间:2009-07-11 01:31:06

标签: physics collision-detection

我的问题很简单。我有两个四面体,每个都有当前位置,空间线速度,角速度和质心(实际上是旋转中心)。

有了这些数据,我试图找到一个(快速)算法,该算法将精确地确定(1)它们是否会在某个时间点发生碰撞,如果是这种情况,(2)在它们碰撞了多少时间之后(3)碰撞点。

大多数人会通过三角形 - 三角形碰撞检测来解决这个问题,但这会浪费一些CPU循环来进行冗余操作,例如在检查不同三角形时检查一个四面体的相同边缘与另一个四面体的相同边缘。这只意味着我会稍微优化一下。无需担心。

问题是我不知道任何公共CCD(连续碰撞检测)三角形 - 三角形算法,它会考虑自转。

因此,我需要一个输入以下数据的算法:

  • 三个三角形的顶点数据
  • 位置和旋转中心/质量
  • 线速度和角速度

并输出以下内容:

  • 是否有碰撞
  • 发生碰撞的时间
  • 在空间中发生碰撞的那一点

提前感谢您的帮助。

7 个答案:

答案 0 :(得分:6)

常用的离散碰撞检测将在连续的离散时间点检查每个形状的三角形是否发生碰撞。虽然直接计算,但由于在测试的离散点之间发生碰撞,它可能会错过快速移动的物体撞击另一个物体。

连续碰撞检测首先计算每个三角形在无限时间内描绘的体积。对于以恒定速度移动且没有旋转的三角形,该体积看起来像三棱柱。然后,CCD将检查卷之间的碰撞,最后追溯三角形实际上共享相同空间的时间。

当引入角速度时,每个三角形描绘的体积不再像棱镜那样。它可能看起来更像螺丝的形状,如DNA链,或者通过在任意轴周围旋转三角形同时线性拖动它可能获得的其他一些非平凡的形状。计算这种体积的形状并非易事。

一种方法可能首先计算包含整个四面体的球体,当它以给定的角速度矢量旋转时,如果它没有线性移动。您可以为每个顶点计算旋转圆,并从中导出球体。给定一个球体,我们现在可以将挤出的CCD体积近似为具有球体半径的圆柱体,并沿线性速度矢量前进。找到这些圆柱体的碰撞使我们得到一个区域的第一个近似值来搜索碰撞。

第二种补充方法可能会尝试将每个三角形所追踪的实际体积近似分解为几乎棱柱形的小体积。它将以两个时间增量取三角形位置,并添加通过在那些时刻跟踪三角形顶点而生成的曲面。它是近似值,因为它连接直线而不是实际曲线。对于避免粗差的近似,每个连续矩之间的持续时间需要足够短,使得三角形仅完成旋转的一小部分。持续时间可以从角速度得出。

第二种方法创造了更多的多边形!您可以使用第一种方法来限制搜索量,然后使用第二种方法来获得更高的精度。

如果你正在为游戏引擎解决这个问题,你可能会发现上面的精度足够了(我仍然会对计算成本感到不寒而栗)。相反,如果您正在撰写CAD程序或撰写论文,您可能会发现它不太令人满意。在后一种情况下,您可能希望改进第二种方法,可能是通过对转动的移动三角形所占据的体积进行更好的几何描述 - 当限制为小转弯角时。

答案 1 :(得分:1)

我花了很多时间来思考像这样的几何问题,看起来准确的解决方案,尽管它们的简单陈述,实际上太复杂了,即使对于类似的2D情况也是如此。

但直观地说,当你考虑线性平移速度和线性角速度时,我看到这样的解决方案确实存在。不要以为你会在网上或任何一本书中找到答案,因为我们在这里讨论的是特殊但复杂的案例。无论如何,迭代解决方案可能就是你想要的 - 世界其他地方对这些解决方案感到满意,那你为什么不应该这样做?

答案 2 :(得分:1)

如果你试图碰撞非旋转的四面体,我建议你拿一个Minkowski总和并进行射线检查,但这不适用于旋转。

我能想到的最好的就是使用它们的边界球进行扫掠球体碰撞,给你一系列的时间来检查使用二分或者你有什么。

答案 3 :(得分:1)

以下是封闭式数学方法的概述。这个元素的每个元素都很容易单独表达,如果有人能写出来,这些元素的最终组合将是一个封闭的表达式:

1)四面体中每个点的运动方程在它自己的坐标系中相当简单。质心(CM)的运动将沿着直线平滑移动,并且角点将围绕穿过CM的轴旋转,这里假设为z轴,因此每个角点的等式(参数化为时间,t) p = v t + x + r(sin(wt + s) i + cos(wt + s) j ),其中 v 是质心的矢量速度; r是投影到x-y平面上的半径; i j k 是x,y和z单位向量;和 x 和s说明t = 0时的起始位置和旋转阶段。

2)请注意,每个对象都有自己的坐标系来轻松表示动作,但要比较它们,您需要将每个对象旋转到一个公共坐标系,也可以是屏幕的坐标系。 (请注意,不同的坐标系在空间中是固定的,不与四面体一起移动。)因此,确定旋转矩阵并将它们应用于每个轨迹(每个四面体的点和CM)

3)现在,您在同一坐标系内有每个轨迹的方程式,您需要找到交叉点的时间。这可以通过测试从四面体的点到CM的任何线段是否与另一个的三角形的任何三角形相交来找到。这也有一个封闭形式的表达式,可以找到here

分层这些步骤会产生非常丑陋的方程,但计算上解决它们并不困难(尽管四面体的旋转你需要确保不会陷入局部最小值)。另一种选择可能是将它插入像Mathematica这样的东西来为你做曲柄。 (并非所有问题都有简单的答案。)

答案 4 :(得分:0)

对不起,我不是数学家,也不知道正确的术语是什么。希望我糟糕的条款不要过多地隐藏我的意思。

选择一些任意时间步。

计算每个形状的边界,在两个维度上垂直于它为时间步长移动的轴。

对于时间步长:   如果任何两个物体的那些边界的轴相交,则半步并开始递归。

一种越来越精确的二元搜索,以发现有限交叉点发生的点。

答案 5 :(得分:0)

您的问题可以转化为线性编程问题并完全解决。

首先,假设(p0,p1,p2,p3)是时间t0的顶点,(q0,q1,q2,q3)是第一个四面体的时间t1的顶点,然后是4d的时空,他们填写以下4d封闭量

V = { (r,t) | (r,t) = a0 (p0,t0) + … + a3 (p3,t0) + b0 (q0,t1) + … + b3 (q3,t1) }

这里a0 ... a3和b0 ... b3参数在区间[0,1]中并且总和为1:

a0+a1+a2+a3+b0+b1+b2+b3=1

第二个四面体同样是一个凸多边形(在上面的所有部分加一个'来定义V',即移动四面体的4d体积。

现在两个凸多边形的交点是一个凸多边形。第一次发生这种情况将满足以下线性编程问题:

如果(p0,p1,p2,p3)移动到(q0,q1,q2,q3) 和(p0',p1',p2',p3')移动到(q0',q1',q2',q3') 然后第一次交叉发生在点/时间(r,t):

最小化t0 *(a0 + a1 + a2 + a3)+ t1 *(b0 + b1 + b2 + b3)受

的影响
0 <= ak <=1, 0<=bk <=1, 0 <= ak’ <=1, 0<=bk’ <=1, k=0..4
a0*(p0,t0) + … + a3*(p3,t0) + b0*(q0,t1) + … + b3*(q3,t1) 
  = a0’*(p0’,t0) + … + a3’*(p3’,t0) + b0’*(q0’,t1) + … + b3’*(q3’,t1)

最后一个实际上是4个方程,每个方程对应一个(r,t)。 这是16个值ak,bk,ak'和bk'的总共20个线性约束。 如果有解决方案,那么

(r,t)= a0*(p0,t0) + … + a3*(p3,t0) + b0*(q0,t1) + … + b3*(q3,t1)

是第一个交叉点。否则它们不相交。

答案 6 :(得分:0)

过去想过这个但却失去了兴趣......解决问题的最佳方法就是抽象出一个对象。 制作一个坐标系,其中第一个四面体是中心(重心坐标或以一个点为原点的倾斜系统),并通过使另一个四面体围绕中心旋转来抽象出旋转。如果您设置旋转时间,这应该为您提供参数方程。 将质心的运动添加到第一个和它的旋转,你有一组相对于第一个(距离)运动的方程。 求解距离等于零的t。

显然,使用这种方法,您添加的效果越多(如风阻),方程式越混乱,但它仍然可能是最简单的(几乎所有其他碰撞技术都使用这种抽象方法)。最大的问题是,如果添加任何具有反馈而没有解析解的效果,则整个方程变得无法解决。

注意:如果你走偏斜系统的路线,请注意距离的陷阱。你必须在正确的八分圆!然而,这种方法有利于向量和四元数,而重对有线则有利于矩阵。因此,选择您的系统最有效使用的那个。