简单的欧拉物理,奇怪的行为
我有这个简单的欧拉积分器。为了找到精确的碰撞时间,它也应该处理负 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
原因是数学。让我们关注
velocity
变量:如果您调用:
someBody.update(1.0)
,您将得到:
velocity += Acceleration * 1
但是如果你打电话:
你会得到:
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:
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;
怀疑 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.
谢谢,加速确实是错误的。
我对每一帧使用固定的时间步长。该函数用于对部分帧进行模拟。所以我现在完全忽略加速。这样,帧内的所有内容都是线性发生的,并且加速度仅在帧之间添加。
但问题仍然存在。我认为这可能是 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.