[英]Bodies overlapping in 2D Physics simulation (Java)
我用Java编写了一个程序,各个圈子可以相互跳动并相互吸引。
在大多数情况下(屏幕上没有几个圆圈),没有明显的错误。 当屏幕上有大量圆圈时,该问题开始发生。 有时,如果过于拥挤,圆圈会重叠。 好像所有其他圆的重量都将圆压在一起,导致它们重叠。 当然,该程序对圆的重量一无所知,因此它并不是真正的粉碎。 最有可能的是,解决冲突的逻辑无法处理拥挤的情况。
圆存储在数组中,每个圆都使用for循环遍历数组,并将其与其他圆进行比较。 如果此圆的中心与另一个圆的中心之间的距离小于其半径之和,则这些圆会发生碰撞。 两个圆的速度使用碰撞方程进行更新。
我认为出现问题是因为如果一个圆被包围,它可能会在其后的圆中接收到更新的速度,而其后的圆也可能会在前一个圆中接收到更新的速度。 换句话说,即使两个圆圈已经接触,它们也会被告知彼此相向移动。 一旦它们以这种方式重叠,我不知道为什么他们不撤消它们的重叠。
我尝试通过找到重叠的距离,然后将它们彼此分开,来恢复它们是否重叠的感人场景。 每个都移动一半的重叠距离。 这不会改变圆的速度,只会改变其位置。
这仍然不能解决问题。 如果圆被包围,并且与相邻的一个圆重叠,则其位置将更改为不重叠,但是此新位置可能导致其与另一个圆重叠。 同样的问题。
如果没有重力将这些圆推到一起,它们最终将散开并解决其重叠的问题,但是重力阻止了这种情况的发生。
更多信息:
计算碰撞后的新速度时,不会考虑重力。
在这两种情况下,听起来您对导致问题的原因的预感都是正确的。
不幸的是,没有简单的方法可以解决此问题-这在很大程度上意味着从头开始重写整个碰撞检测和解决方案代码。 您必须计算出第一次碰撞的确切时间,仅更新到目前为止的所有内容,解决碰撞(进行速度更新),然后计算出下一次碰撞的确切时间,然后重复...
写一个好的物理引擎很困难,这有充分的理由说明市场上有很多关于这个主题的教科书!
解决您问题的廉价“解决方案”是缩短更新时间间隔-例如,不要以33ms的步长(〜30fps)更新物理,而是尝试以16ms的步长(〜60fps)更新物理。 这不会阻止该问题,但是会减少发生的可能性。 将时间减半可以使处理器花费在物理更新上的时间加倍!
如果使用廉价修复程序,则最适合您的时间步长将由发生冲突的频率决定-冲突次数越多,时间步长就越小。 发生碰撞的频率基本上取决于圆圈趋向于移动的速度及其人口密度(给定区域的多少由圆圈填充)。
更新:有关“正确”方法的更多信息。
更新将如下所示:
tF
。 tC
。 tC
的最小值。 假设这是针对圆A
和圆B
之间的碰撞,我们将其称为碰撞cAB
。 tC
<= tF
,则更新所有圆圈直到时间tC
。 否则,请转到步骤6。 cAB
。 返回步骤2! tF
。 如您所料,这可能变得非常复杂。 对于非圆形物体(尤其是一旦包含角动量等的物体时),第2步可能非常棘手(而且成本很高),尽管您可以在此处进行很多操作以加快速度。 基本上也不知道您将在步骤2和5之间循环多少次。
就像我说的那样,很难进行良好的物理模拟。 实时进行操作更加困难!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.