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

发布于 2024-11-24 13:16:30 字数 568 浏览 1 评论 0原文

我有这个简单的欧拉积分器。为了找到精确的碰撞时间,它也应该处理负 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;
}

非常感谢!

马丁

I have this simple euler integrator. For finding precise collision times it should handle negative dt's as well (I divide the frame time and simulate back when I detect a collision).

For some reason

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

gives different results than:

someBody.update(1.0);

It might be because I use euler instead of RK4 or verlet?

Here's the code for the integrator:

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

Thanks a lot!

Maarten

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不忘初心 2024-12-01 13:16:30

原因是数学。让我们关注 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

您应该简单地速度 += 加速度 * dt;

The reason is math. Let's focus on velocity variable:

If you call:

someBody.update(1.0)

you'll get:

velocity += acceleration * 1

But if you call:

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

you will get:

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

(which gives velocity += acceleration * 1.18)

You should have simply velocity += acceleration * dt;

你是暖光i 2024-12-01 13:16:30

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

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

Suspect floating point error accumulation in Body::update.
Example: 1 + 2 + 3 + 4 = 10 but 1.0 + 2.0 + 3.0 + 4.0 = something else.

The easiest fix is to round the results after each major computation step.

末が日狂欢 2024-12-01 13:16:30

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

我对每一帧使用固定的时间步长。该函数用于对部分帧进行模拟。所以我现在完全忽略加速。这样,帧内的所有内容都是线性发生的,并且加速度仅在帧之间添加。

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

尽管我认为这些错误加起来不会如此显着。在大约 50 帧内,弹跳对象从其全高度 (100) 降至大约一半高度。大约 200 帧后,它仍然在地板上。当我不在框架内调用多个更新时,一切都很好。

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

Thanks, the acceleration was indeed wrong.

I use a fixed timestep for each frame. This function is to run the simulation for partial frames. So I ignore the accaleraion completely now. This way everything within a frame happens linearly and the acceleration is only added in between frames.

The problem persists though. I think it might be the floating point errors as poited out by Magicianeer.

Although I think these errors would not add up so dramatically. In around 50 frames a bouncing object goes from it's full height (100) to about half that height. In around 200 frames it's still on the floor. When I don't call multiple the updates within the frame it's all fine.

I'll try keeping the position at the end of the frame and putting it back after doing the partial frame simulations. That way the errors won't add up over multiple frames.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文