- Home /
Constant force motion: s = s0 + v0 * t + a0 * t * t. Why?
I have a rigid body with with an absolute constant force (100, 0, 0). I am trying to predict the next position of the rigid body. The mass is equal to 1 so the constant force and the acceleration are the same.
According to Wikipedia the end displacement s should be
s = s0 + v0 * t + a0 * t * t / 2;
where s0, v0 and a0 are the initial displacement, velocity and acceleration. And t is the time interval (Time.fixedDeltaTime in Unity).
For some reason the correct displacement formula in Unity is
s = s0 + v0 * t + a0 * t * t;
I am trying to figure out why. I've tested this using a simple script with a FixedUpdate() method which logs the current position to the console.
Vector2 s0 = transform.position;
Vector2 v0 = rigidbody.velocity;
Vector2 a0 = constantForce.force;
float dt = Time.fixedDeltaTime;
Vector2 dsV = dt * v0;
Vector2 dsA = 1.0f * dt * dt * a0;
Vector2 s1 = s0 + dsV + dsA;
Debug.Log("DSIP X: " + s0.x + " + " + dsV.x + " + " + dsA.x + " = " + s1.x + " @ " + Time.time);
Answer by Owen-Reynolds · Jun 02, 2013 at 04:18 PM
Wikipedia is giving you the calculus equation, which assumes an infinite small time step (the basic principle of calculus.)
In any step-based physics system, you have to decide whether to add force at the start or the end of the time step. One moves you a little too fast, the other a little too slow. If you tested over many frames, you'd see that Unity is probably just a tiny bit over the correct value. If you could run Unity at 1000, 10000 ... frames/sec, you'd see it getting closer and closer to the real value (again, definition of calculus.)
It's the same as the rectangle method of calculating area under a curve (at the start of any calculus text.) Each rectangle either goes up to the lowest part of the curve, or the highest, which will under/over estimate the area. As the rectangles get thinner (which is like more time steps,) they both squeeze to the real value.
That's right: position should be calculated in Unity with the wiki's equation, but doing this each frame may produce weird errors due to the discrete nature of physics emulation. Try to calculate the position 100 frames ahead, for instance (100 * t) and compare to the actual position after 100 frames: you will see that they're very close.
I didn't realize Unity applies the forces at the beginning. I'll keep that in $$anonymous$$d from now on.