如何修复物理引擎中“弹出”或抖动的对象?


11

我有一个简单的物理引擎,可以通过直接校正重叠物体的位置(现在仅是圆形)来解决碰撞,而不仅仅是更改速度或施加脉冲。仅在影响已解决后或在集成过程中才更改速度。

我遇到的问题是,在对象堆中,顶部对象在堆底部的对象上施加了过多的压力(隐式存在,算法中没有压力建模),这导致它们被推过地板,等等

我想通过按其y坐标对对象进行排序来解决此问题,因此可以从下至上解决冲突。但是现在,引擎显示了实际上应该处于静止状态的对象的奇怪弹出行为(请参阅gif)

在此处输入图片说明

不只是提供源代码,这可能是什么?


5
总而言之,这类似于以迭代方式求解线性方程组(或非线性系统,具体取决于您的约束/条件/等)。无论哪种情况,您都会看到这些伪像,因为从数字上看它们是正确的东西:会聚过程的中间状态。避免这种情况非常困难,并且可能意味着很多讨厌的骇客(无论如何,这发生在现实生活中,在分子水平上,这就是您所拥有的最能与现实生活中的事物相似的地方了:))。研究box2d以查看其基于脉冲动力的解决方案可能是一件好事。
teodron

@TravisG您如何解决问题?在尝试实现一个非常简单的物理引擎时,我正在寻找类似的问题。
cheesus

1
@cheeesus自从我从事此工作已经有一段时间了,但是我相信我只是使用了更多的迭代而花费了更少的时间。
TravisG 2013年

Answers:


5

我发现使用位置校正时的一种解决方案是进行几次迭代,并随着每次迭代改变强度。

doPhysics();

int num_iterations = 5;
for(int iteration=0; iteration<num_iterations; ++iteration)
{
    float strength = float(iteration+1)/num_iterations;
    correctPositions(strength);
}

因此,第一个迭代的强度为1 / num_iterations,而最后一个迭代的强度为1。这使得我的仿真比使用固定强度的相同数量的迭代更平滑,更稳定。


2
好的解决方案,但是为什么行得通呢?
古斯塔沃·麦克尼尔

5

您的问题在于您的身体没有“静止”状态。任何物理系统都具有一定量的能量,包括动能,热能等等。实际上,固形物会发生轻微变形,并将一些动能转化为热量,尽管很难测量。还要指出的是,实际上不存在完全固态的物体。甚至像金刚石这样的致密材料,在原子之间也有空间,从而使原子结构有弯曲的空间并吸收了动能。

为了使这一点相关,静止的物体处于唯一起作用的状态为“法向力”的状态,也就是说,阻止物体彼此漂浮的力。法向力的大小与物体的密度以及它们相互穿透的距离成正比。

物理引擎将此值称为“ slope”。

诀窍是:根据两个物体的相对速度,计算坡度,校正物体的位置,并施加法向力。在更新物体本身的过程中,计算每个物体的动能。如果它低于最小值,则使身体进入睡眠状态,直到对其施加足够大的力为止。(通常是最小值的两倍)。


0

为什么不向它们添加“粘性”表面并使它们逐渐粘在静止位置,当另一个物体撞击它时,它会将一些能量转移到其中,从而使其移动,但粘性表面将使其失去一些能量并停止运转处于静止位置。gif看起来没有摩擦。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.