【问题标题】:How to handle multiple simultaneous elastic collisions?如何处理多个同时发生的弹性碰撞?
【发布时间】:2013-05-08 06:33:44
【问题描述】:

我通过使用the basic equations on wikipedia 碰撞成对的二维凸对象(无旋转)来计算结果。但是,当存在依赖关系时,例如两个对象同时撞击另一个对象:

例如这里,对象 1 和 2 同时击中 3,成对方法失败。根据我计算碰撞的顺序(首先是 1-3 或首先是 2-3),我会得到不同的结果。通过碰撞重复迭代仍然会产生顺序相关的结果。

我已经设置好了,所以我可以弄清楚哪些对象相互接触,所以我的代码会在计算其中一个对象时知道对象 3 正在与另一个对象发生碰撞(所以 1-3碰撞将知道 2-3 碰撞,反之亦然)。我也会知道哪些边/角与什么接触。

任何解决方案都需要稳健...例如,如果设置变得更复杂,如以下 2 个示例:

流程需要能够处理这种情况,甚至更糟。任何可能的同时接触/冲突链。我将拥有描述它们的所有数据,所以我“只”需要知道如何解决这些系统的一般情况。我目前没有对旋转做任何事情,这简化了事情。

它似乎需要将对象组合在一起,但由非正交边(参见最后一个六边形示例)引起的干扰似乎会使该方法失败。

我看到之前有人问过a similar question,但从未检查过给出的答案(死胡同?)。我也不确定冲击传播将如何解决我的第一个示例,因为 C 在第一次碰撞后正在远离……那么传播什么冲击?编辑:好的,我现在看到同时碰撞和冲击传播是两个不同的想法,这就是为什么它看起来没有用。

【问题讨论】:

  • 您链接到的问题实际上有一个答案,这可能就是您要寻找的。​​span>
  • @AlexSzatmary 我不确定这种方法如何适用于我的第一个示例。一旦发生第一次碰撞,C 就会离开……在处理第二次碰撞时不会传播冲击。

标签: algorithm language-agnostic physics game-physics physics-engine


【解决方案1】:

这种dynamic simulation of multi-contact physics 会产生linear complementarity problem。有算法可以解决this kind of problem;数学与用于线性规划问题的数学有关。

解决此类问题的需求比您想象的要普遍。任何一种模糊逼真的模拟(即重力、地面和非弹性碰撞)很快就会以物体相互靠在一起而告终;准确而稳健地处理从空间动态碰撞到滑动和滚动物体,再到“块堆叠”配置的过渡,在技术上可能具有挑战性。

我建议寻找books or other resources 的主题。您实际需要哪些技术取决于您的特定应用程序,但您也许可以找到一些有用的库。

【讨论】:

    【解决方案2】:

    根据我计算碰撞的顺序(先 1-3 或先 2-3),我会得到不同的结果。

    没错。这是由于碰撞的物理原理。考虑这个简单的例子,使用你的第一个图:

    m_1 = m_2 = m_3
    u_1 = u_2
    u_3 = 0
    x_1 = x_2 + d
    

    1 和 2 之间的唯一区别是 1 更接近 3 d。 1 先打 3,停止,v_3 变成 u_1(u 是初始速度,v 是最终速度)。因为 u_2 和新的 v_3 相同,所以对象 2 和 3 都将以恒定的速度向右移动,它们之间的距离 d 是恒定的;他们永远不会碰。如果 1 和 2 交换,即如果 x_2 = x_1 + d,则 2 碰到 3 并停止,并且 1 在 3 之后被 d 跟踪。

    碰撞的顺序很重要,将同时发生的碰撞视为两个连续的瞬时碰撞会产生冲突的结果,具体取决于处理碰撞的顺序。

    真正同时发生的碰撞通常是一种病态的情况(在数学上),并且对于游戏甚至许多科学模型来说可能没有必要正确解决。

    如果正确解决多个弹性碰撞确实很重要,则可以计算出该数学,但您需要添加额外的假设。两个物体的弹性碰撞由动量守恒给出:

    m_1 u_1 + m_2 u_2 = m_1 v_1 + m_2 v_2
    

    和能量守恒:

    (1/2) * m_1 u_1^2 + (1/2) * m_2 u_2^2 = (1/2) * m_1 v_1^2 + (1/2) * m_2 v_2^2
    

    给定物体的初始速度,可以找到两个物体碰撞后的速度。如果你想修改这些方程来解释第三个对象,

    m_1 u_1 + m_2 u_2 + m_3 u_3 = m_1 v_1 + m_2 v_2 + m_3 v_3
    (1/2) * m_1 u_1^2 + (1/2) * m_2 u_2^2 + (1/2) * m_3 u_3^2 = (1/2) * m_1 v_1^2 + (1/2) * m_2 v_2^2 + (1/2) * m_3 u_3^2
    

    必须引入第三个独立方程。一个简单的约束可能是物体 1 和 2 的动量转移应该与它们的质量成正比:

    m_1^2 (v_1 - u_1) = m_2^2 (v_2 - u_2)
    

    这对于图 1 中描述的情况会很好:直观地说,我希望 1 和 2 具有相同的最终速度,而这个约束会给你这个。请注意,这个方程没有明确的物理基础,在其他情况下可能会产生奇怪的结果。试验一下,看看什么是正确的。

    您在 Wikipedia 上提到的方程式(标准的、非常有用的教科书方程式)假设两个对象之间存在瞬时动量转移。这对于现实生活中的任何事情都不是真的。当一个台球撞到另一个时,球的变形非常轻微,这种变形需要时间;这个时间在毫秒或更短的范围内,通常可以忽略不计。

    【讨论】:

    • 这一切都非常真实,但我的模拟比现实简单得多。时间有离散的步骤,物体是刚性的。因此,虽然真正同时发生的病例可能是病态的,但不幸的是,我不得不处理它,因为在我的模拟中这是不可避免的可能性。而且我需要以一种确定性的方式来处理它,否则不同客户端之间会出现不同步......无论如何,处理这个问题的假设是什么?
    • user173342,您是想模拟真实发生的事情,还是仅仅模拟一些似是而非的事情(例如游戏)?非常不一样。现实生活中的模拟会根据配置(物体之间的距离和速度)调整步长。虽然您的程序可能是确定性的并且总是产生相同的输出,但在现实生活中,当您在台球中进行开场休息时会发生什么情况并非如此。如果您希望它产生似是而非的、真实的结果,您可能不得不引入现实生活中发生的随机噪声。使它成为一个真实的模拟是很困难的。仅仅看似合理更容易。
    【解决方案3】:

    逐个进行单独的碰撞,但始终使用每个对象的初始速度。完成后,将每个对象的速度变化相加。

    (v1_1,v3_1) = collide(u1,u3,m1,m3)
    (v2_2,v3_2) = collide(u2,u3,m2,m3)
    v1 = u1 + (v1_1 - u1) = v1_1
    v2 = u2 + (v2_2 - u2) = u2_2
    v3 = u3 + (v3_1 - u3) + (v3_2 - u3) = v3_1 + v3_2 - u3
    

    这样,它不会是顺序敏感的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 2012-11-29
      相关资源
      最近更新 更多