繁体   English   中英

在2D物理模拟(Java)中重叠的实体

[英]Bodies overlapping in 2D Physics simulation (Java)

我用Java编写了一个程序,各个圈子可以相互跳动并相互吸引。

在大多数情况下(屏幕上没有几个圆圈),没有明显的错误。 当屏幕上有大量圆圈时,该问题开始发生。 有时,如果过于拥挤,圆圈会重叠。 好像所有其他圆的重量都将圆压在一起,导致它们重叠。 当然,该程序对圆的重量一无所知,因此它并不是真正的粉碎。 最有可能的是,解决冲突的逻辑无法处理拥挤的情况。

圆存储在数组中,每个圆都使用for循环遍历数组,并将其与其他圆进行比较。 如果此圆的中心与另一个圆的中心之间的距离小于其半径之和,则这些圆会发生碰撞。 两个圆的速度使用碰撞方程进行更新。

我认为出现问题是因为如果一个圆被包围,它可能会在其后的圆中接收到更新的速度,而其后的圆也可能会在前一个圆中接收到更新的速度。 换句话说,即使两个圆圈已经接触,它们也会被告知彼此相向移动。 一旦它们以这种方式重叠,我不知道为什么他们不撤消它们的重叠。

我尝试通过找到重叠的距离,然后将它们彼此分开,来恢复它们是否重叠的感人场景。 每个都移动一半的重叠距离。 这不会改变圆的速度,只会改变其位置。

这仍然不能解决问题。 如果圆被包围,并且与相邻的一个圆重叠,则其位置将更改为不重叠,但是此新位置可能导致其与另一个圆重叠。 同样的问题。

如果没有重力将这些圆推到一起,它们最终将散开并解决其重叠的问题,但是重力阻止了这种情况的发生。

更多信息:

计算碰撞后的新速度时,不会考虑重力。

在这两种情况下,听起来您对导致问题的原因的预感都是正确的。

不幸的是,没有简单的方法可以解决此问题-这在很大程度上意味着从头开始重写整个碰撞检测和解决方案代码。 您必须计算出第一次碰撞的确切时间,仅更新到目前为止的所有内容,解决碰撞(进行速度更新),然后计算出下一次碰撞的确切时间,然后重复...

写一个好的物理引擎很困难,这有充分的理由说明市场上有很多关于这个主题的教科书!

解决您问题的廉价“解决方案”是缩短更新时间间隔-例如,不要以33ms的步长(〜30fps)更新物理,而是尝试以16ms的步长(〜60fps)更新物理。 这不会阻止该问题,但是会减少发生的可能性。 将时间减半可以使处理器花费在物理更新上的时间加倍!

如果使用廉价修复程序,则最适合您的时间步长将由发生冲突的频率决定-冲突次数越多,时间步长就越小。 发生碰撞的频率基本上取决于圆圈趋向于移动的速度及其人口密度(给定区域的多少由圆圈填充)。

更新:有关“正确”方法的更多信息。

更新将如下所示:

  1. 开始更新框架。 假设我们要更新到时间tF
  2. 对于每对圆,请确定何时会发生碰撞(忽略所有其他圆)。 这次称为tC
  3. 找出tC的最小值。 假设这是针对圆A和圆B之间的碰撞,我们将其称为碰撞cAB
  4. 如果tC <= tF ,则更新所有圆圈直到时间tC 否则,请转到步骤6。
  5. 解决碰撞cAB 返回步骤2!
  6. 将所有圆圈更新为时间tF

如您所料,这可能变得非常复杂。 对于非圆形物体(尤其是一旦包含角动量等的物体时),第2步可能非常棘手(而且成本很高),尽管您可以在此处进行很多操作以加快速度。 基本上也不知道您将在步骤2和5之间循环多少次。

就像我说的那样,很难进行良好的物理模拟。 实时进行操作更加困难!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM