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);

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.