我不太确定这是否回答了你的问题,或者它是否更冗长的评论。如果我在这里完全脱离基地,请告诉我。
所以假设A和B是某种类型Point,并且你调用 , 的方法Point,resolve(Point that)它被定义为
dist = Math.abs(this.x - that.x)
diff = (dist - r) / dist
moveBy = 0.5 * diff * dist
this.x = this.x + moveBy
that.x = that.x - moveBy
我不太确定我是否正确理解了您,但您是说您正在为 A 和 B 调用此方法,即 A.resolve(B)and B.resolve(A)?别。moveBy在两个调用中是相同的,但是用不同this的that符号应用它,所以它会抵消。这就是说顺序很重要。请注意,只需调用A.resolve(B) 即可。
是的,我想涵盖所有基础,但我认为您实际上并没有按照我上面的建议进行操作。相反,也许您所拥有的是以下内容resolve(Point that),
dist = Math.abs(this.x - that.x)
diff = (dist - r) / dist
this.moveBy = 0.5 * diff * dist
并且只是稍后在另一个函数中才实际应用this.x += this.moveBy. 这几乎没问题。不过,不完全是。原因很简单:Math.abs。让我们看一下谐波运动方程。这是粒子A和B之间键的能量:
E=k2(∥rA−rB∥−r0)2
使用牛顿运动方程,
mAr¨A=−∂E∂rA=−k(∥rA−rB∥−r0)rA−rB∥rA−rB∥
这与上面的代码相比如何?代码不保留方向性(因为代码中的绝对值),因此所有力都指向一个特定方向(正,轴)。xy
如果有更多的粒子,方程并不会变得更复杂:左边我们有和以前一样的东西,右边有更多的力项。这就是说,在您最有可能使用的欧拉积分方案中,您可以首先计算所有力,然后根据这些力计算所有速度,然后根据这些力计算所有位移。计算一个粒子的力应该完全独立于其他粒子的计算(好吧,独立是一个糟糕的选择,因为一半的力是相同的,但根据牛顿第三定律,方向相反,但是在并行计算的意义上,它们不会相互影响)。