我正在制作一个paperjs应用程序,你有圆圈,每个圆圈都可以自由移动。一些圆圈通过线条相互连接,这些线条会使圆圈更接近彼此 - 即线条模拟圆圈之间的弹性带。然而,圆圈不允许重叠,所以我想做出一些碰撞排斥。目前我已将此作为圈子之间的排斥力量实施。对于每个圆圈,我检查所有其他圆圈的位置,并且每个圆圈的速度矢量在与其相近的圆圈的相反方向上增加,与它与该圆圈的接近程度成比例。实际上就像velocityvector += -(vectorFromThereToHere / 10)
然而,这具有连接圆之间的吸引力和所有圆之间的排斥力之间的效果,最终会出现连续的来回抖动。
那么在圈子之间实施某种排斥的最佳方式是什么,这种排斥不会导致任何颤动,但只会允许圈子“#”。边缘相互接触,而不是靠得更近?实际上,我希望圆圈可以简单地相互碰撞,不允许彼此滑动,但是它们可以无摩擦地沿着彼此的外边缘滑动,以达到它们的动量带来的位置。
答案 0 :(得分:1)
您可以实施inelastic collision,然后执行定位步骤。我们的想法是在撞击法线方向上对物体施加冲动。
// vx: velocity vector of object x
// ux: velocity vector of object x after impact
// mx: mass of the object x (1 if all objects are the same size)
// n: normal of impact (i.e.: p1-p2 in the case of circles)
// I: the coefficient of the impulse
// Equation of an inelastic collision
u1 * n = u2 * n
// Equations of the velocities after the impact
u1 = v1 + I * n / m1
u2 = v2 - I * n / m2
// solved for I:
I = (v1 - v2) * n / ((n*n)*(1/m1 + 1/m2))
当你有I
时,你只需要应用速度变化。在应用脉冲之前,您还可以检查是否I > 0
,以防止形状粘在一起。让我们看看它是如何工作的,并且如果球在所有这些之后开始缓慢重叠,则添加位置迭代。
PS:您可以在一个时间范围内重复整个碰撞步骤,以便在对象涉及许多碰撞时获得更好的结果(因为它们被粘在一起形成一个大球)