gpt4 book ai didi

java - 二维物理模拟中的物体重叠 (Java)

转载 作者:行者123 更新时间:2023-11-29 03:50:25 24 4
gpt4 key购买 nike

我用 Java 编写了一个程序,其中的圆圈可以相互反弹并相互吸引。

在大多数情况下(屏幕上的几个圆圈),没有明显的错误。当屏幕上出现大量圆圈时,问题开始出现。有时,如果太拥挤,圆圈会重叠。就好像所有其他圆圈的重量都在挤压这些圆圈,导致它们重叠。当然,这个程序并不知道一个圆有多重,所以它不是很强大。最有可能的是,处理解决冲突的逻辑无法处理拥挤的情况。

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

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

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

这仍然没有解决问题。如果圆圈被包围,并且与它的相邻圆圈之一重叠,则其位置会发生变化,因此它们不会重叠,但这个新位置可能会导致它与另一个圆圈重叠。同样的问题。

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

更多信息:

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

最佳答案

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

不幸的是,没有简单的方法来解决这个问题 - 这几乎意味着从头开始重写整个碰撞检测和解决代码。您必须计算出第一次碰撞的确切时间,仅更新那么远的所有内容,解决碰撞(进行速度更新)然后计算出下一次碰撞的确切时间,然后重复...

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

解决您的问题的廉价“解决方案”是减少更新的时间间隔 - 例如不要以 33 毫秒步长(~30fps)更新物理,尝试以 16 毫秒步长(~60fps)更新。这不会阻止问题的发生,但会大大降低它发生的可能性。将时间步长减半也会使处理器用于物理更新的时间加倍!

如果您使用廉价修复,最适合您的时间步长将取决于碰撞发生的频率 - 更多的碰撞意味着更小的时间步长。碰撞发生的频率基本上取决于圆圈移动的速度和它们的人口密度(给定区域有多少被圆圈填充)。

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

更新会是这样的:

  1. 开始更新框架。假设我们要更新时间 tF
  2. 对于每一对圆圈,计算出您预计碰撞发生的时间(忽略所有其他圆圈)。我们称这次为 tC
  3. 找到tC 的最小值。假设这是圆 AB 之间的碰撞,我们称该碰撞为 cAB
  4. 如果 tC <= tF,将所有圆圈更新到时间 tC。否则,转到第 6 步。
  5. 解决冲突 cAB。回到第 2 步!
  6. 将所有圆圈更新为时间tF

如您所想,这可能会变得相当复杂。对于非圆形物体(尤其是当你包含角动量等东西时),第 2 步可能非常棘手(并且在计算上很昂贵),尽管你可以在这里做很多技巧来加速它。也基本上不可能知道您将在第 2 步和第 5 步之间循环多少次。

就像我说的,做好物理模拟很困难。实时进行更难!

关于java - 二维物理模拟中的物体重叠 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9031633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com