简单的欧拉物理,奇怪的行为

时间:2011-07-17 21:36:08

标签: c++ integration physics

我有这个简单的euler集成商。为了找到精确的碰撞时间,它也应该处理负dt(我在检测到碰撞时划分帧时间并模拟回来)。

出于某种原因

someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);

给出的结果不同于:

someBody.update(1.0);

可能是因为我使用的是euler而不是RK4或verlet?

以下是集成商的代码:

void Body::update(double dt)
{
    if (dt > 0) velocity += acceleration * (dt*dt);
    else velocity -= acceleration * (dt*dt);
    pos += velocity * dt;
    rotation += angularVelocity * dt;
}

非常感谢!

马腾

3 个答案:

答案 0 :(得分:3)

原因是数学。让我们关注velocity变量:

如果你打电话:

someBody.update(1.0)

你会得到:

velocity += acceleration * 1

但如果你打电话:

someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);

你会得到:

velocity += acceleration * (1 - 0.3^2 - 0.32^2 + 0.6^2)

(提供velocity += acceleration * 1.18

你应该只有velocity += acceleration * dt;

答案 1 :(得分:0)

怀疑Body :: update中的浮点错误累积。 示例:1 + 2 + 3 + 4 = 10但1.0 + 2.0 + 3.0 + 4.0 =其他。

最简单的解决方法是在每个主要计算步骤后对结果进行舍入。

答案 2 :(得分:0)

谢谢,加速确实是错误的。

我为每个帧使用固定的时间步长。此功能用于运行部分帧的模拟。所以我现在完全忽略了这种说法。这样,帧内的所有内容都会线性发生,加速度仅在帧之间添加。

问题仍然存在。我认为这可能是Magicianeer推出的浮点错误。

虽然我认为这些错误不会如此大幅增加。在大约50帧中,弹跳物体从其全高(100)到大约一半高度。在大约200帧,它仍然在地板上。当我没有在框架内调用多个更新时,一切都很好。

我会尝试将位置保持在帧的末尾,并在进行部分帧模拟后将其放回。这样,错误就不会在多个帧上累加。