【问题标题】:Continuous collision detection between two moving tetrahedra两个移动四面体之间的连续碰撞检测
【发布时间】:2009-07-11 01:31:06
【问题描述】:

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

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

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

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

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

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

并会输出以下内容:

  • 是否有碰撞
  • 碰撞发生多长时间后
  • 碰撞发生在空间的哪个点

提前感谢您的帮助。

【问题讨论】:

  • +1 只是因为标题太酷了——如果你在尝试,你就不可能做得更好!-)。 (抱歉,我在 3D 计算几何方面没有足够的专业知识来实际提供帮助)。
  • 是的,这是一个很酷的标题。我不记得足够的数学来解决这个问题,但我相信你会想要解决一个微分参数方程,建模当前位置 (x,y,z) = (f(t),g(t),h(t )) 对于每个对象。您可以通过首先根据每个对象的最小球体确定它们是否足够接近以使其成为碰撞来优化它。如果它们不是,它们就不会发生碰撞。如果是,那么您可以进行复杂的计算。
  • 在这里操作。我可能会使用其他技术来过滤哪些对象对实际上需要进行碰撞测试(有些人称之为broadphase)。如果没有人提出任何真正的方程或更好的方法,我将把所有东西放在一个距离方程中(关于时间)并编写一个算法来试图找到它的解决方案。老实说,我真的不想这样做,尤其是如果它已经完成的话。

标签: physics collision-detection


【解决方案1】:

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

连续碰撞检测将首先计算每个三角形在无限时间内追踪的体积。对于以恒定速度移动且不旋转的三角形,这个体积可能看起来像一个三棱柱。然后 CCD 会检查体积之间的碰撞,最后追溯三角形是否以及在什么时间实际共享相同的空间。

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

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

第二种补充方法可能会尝试通过将每个三角形分解成小的、几乎棱柱形的子体积来逼近每个三角形所描绘的实际体积。它将以两个时间增量获取三角形位置,并添加通过在这些时刻跟踪三角形顶点生成的曲面。这是一个近似值,因为它连接的是一条直线而不是一条实际的曲线。为了避免严重错误的近似值,每个连续时刻之间的持续时间需要足够短,以使三角形只完成一小部分旋转。持续时间可以从角速度推导出来。

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

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

【讨论】:

  • 在这里操作。感谢您的贡献。我更多的是考虑一种精确的解决问题的方法。如果我想要一些近似的东西,我会简单地使用具有非常小的时间步长的离散碰撞检测。如果我不关心时间,我会使用类似二分法的方法来找到碰撞前的精确点,直到小数点。
  • 我会做两个球体碰撞,因为在 3D 中,圆柱体/圆柱体碰撞速度非常快(它基本上只是检查空间中两条线之间的最小距离)。所以首先你看看圆柱体是否碰撞,然后你看看球体是否碰撞(同时在那个碰撞体积中)。然后在离散时间进行三角形检查。角速度破坏了您在那个阶段通常拥有的大多数快捷方式。
【解决方案2】:

我花了很多时间想知道像这样的几何问题,而且似乎准确的解决方案,尽管它们的陈述很简单,但太复杂而无法实用,即使对于类似的 2D 情况也是如此。

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

【讨论】:

  • 在这里操作。 (听起来不是很刻薄,但是)如果“世界其他地方都对这些感到满意,那你为什么不呢?”这种逻辑适用于大多数日常创新,我们仍然会使用蜡烛和马车。
【解决方案3】:

如果您试图碰撞非旋转四面体,我建议获取 Minkowski 和并执行射线检查,但这不适用于旋转。

我能想到的最好办法是使用它们的边界球执行扫球碰撞,给你一定范围的时间来检查使用二分法或你有什么。

【讨论】:

    【解决方案4】:

    以下是封闭式数学方法的概要。这其中的每个元素都将很容易单独表达,如果可以写出来,它们的最终组合将是一个封闭形式的表达:

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

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

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

    将这些步骤分层会产生非常难看的方程,但通过计算求解它们并不难(尽管四面体的旋转需要确保不会陷入局部最小值)。另一种选择可能是将其插入 Mathematica 之类的东西来为您启动。 (并非所有问题都有简单的答案。)

    【讨论】:

      【解决方案5】:

      抱歉,我不是数学爱好者,也不知道正确的术语是什么。希望我的拙劣用词不要掩饰我的意思太多。

      选择任意时间步长。

      计算每个形状在垂直于时间步长上移动的轴的二维范围内。

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

      一种精度越来越高的二分搜索,以发现发生有限交点的点。

      【讨论】:

      • 在这里操作。感谢您的贡献。考虑做同样的事情,这是我上面在 cmets 中提到的类似二分法的方法 - 尽管我相信必须有一种实际的数学方法可以直接找到确切的答案。现在我正在玩 2D 的公式,希望我能找到一个准确而快速的方法。
      【解决方案6】:

      您的问题可以转化为线性规划问题并准确求解。

      首先,假设(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)
      

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

      【讨论】:

      • 除非您根本不处理轮换,这是 OP 明确要求的。
      • q 点可以是 p 点的旋转版本。中间是线性插值旋转。这可以说比其他建议的“离散化和数值求解”解决方案要好得多。
      【解决方案7】:

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

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

      注意:如果您走偏斜系统的路线,请注意距离问题。你必须在正确的八分圆!这种方法有利于向量和四元数,而重心坐标有利于矩阵。所以选择你的系统最有效地使用。

      【讨论】:

        猜你喜欢
        • 2019-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        • 1970-01-01
        • 2019-08-06
        • 1970-01-01
        相关资源
        最近更新 更多