我正在编写一个简单的物理系统以获得乐趣,而且我遇到了一个让我陷入困境的问题。
现在的基本算法是:
我有一个移动的身体朝着两个静止的,无质量的身体移动。
移动物体在一个步骤中被平移以与其中一个物体碰撞。
我的回答是找到我可以移动的最小距离,这样他们就不会再碰撞了。在这种情况下,这意味着直接向下移动动态体。但是,现在它正在与另一个盒子碰撞。
我用那个盒子重复同样的事情,试图移动动态盒子,使它不再碰撞,但是将它推回到第一个盒子里。这永远重复。我的算法存在根本缺陷吗?
答案 0 :(得分:3)
在检测到碰撞后,不要向下移动,而是朝着你来自的方向向后移动会更好。这样你就可以保证,如果我们假设初始状态没有碰撞,你最终必须最终处于没有碰撞的状态。
我们需要找出需要缩小(缩放)v
以使其适合对象交叉点的程度。缩小的v
将具有正确的幅度,因此如果我们向-v
方向向后移动那个幅度,那么我们将不再相交。
假设一个交集包含x_intersection
和y_intersection
组件。为了找出我们需要向后移动到不再相交的程度,我们需要缩放原始v = (v_x, v_y)
向量。如果x_intersection
是较小的交点,那么我们会将v
缩放x_intersection / v_x
并将我们的对象移回-v * x_intersection / v_x
。这意味着我们向后退-(x_intersection, x_intersection * v_y/v_x)
。如果y_intersection
是较小的交点,则我们将v
缩放y_intersection / v_y
,然后将对象向后移动-v * y_intersection / v_y = -(y_intersection * v_x/v_y, y_intersection)
。
所以我想说你的算法中的步骤可能是:
v
如果发生碰撞
对于所有碰撞对象,找到我们需要移回的v
的最小缩放比例。这种缩放可以计算为两个比率的最小值
given v = (v_x, v_y)
min_i = min(x_intersection / v_x, y_intersection / v_y)
查找所有对象的最小缩放比例。
min_o = min(min_i) for all i
通过以最小比例缩放负移动方向而获得的向量方向上移回对象。这是v2 = (min_o*-v)
,其中v2
是我们用来移回的矢量。
例如:首先选择w
:
然后选择u2
:
完成:
答案 1 :(得分:1)
一种可能针对您描述的问题(完全未经测试)的强大解决方案:
将您的对象移动一个完整的时间步dt
检查与其他对象的碰撞,这可能是多个对象
通过插值计算'影响时间',这是一个小于时间步长的实数。对碰撞的每个对象执行此操作,并选择最小的对象。这为您提供了第一次碰撞的时间t_col < dt
。
重做最后一步,但现在仅移动t_col
的对象,使其完全击中对象,然后开始翻转速度和其他与碰撞相关的物理。你现在可以在这里完成这个步骤,如果你是懒惰的(可能没问题,因为dt
应该很小),或者继续移动另一个dt - t_col
,看看你是否打了别的东西。
这不是我刚才发明的,但类似于Simulink用来模拟这种不连续问题的zero-cross detection。