I decided to quit being lazy and show some kind of derivation of how the original Verlet method looks with a variable step size. Because it seems like this faulty adaptation by Dummer is more pervasive than I thought, which is saddening. I also noticed that, as the above answer points out, the correct version is now on wikipedia alongside the Dummer one, though it was added after my "suggested correct answer".
When I look at Verlet method, I see that it looks a lot like leapfrog, velocity Verlet, implicit Euler etc., which look like second-order versions of modified midpoint, and some of them may be identical. In each of these, to some degree they have a leapfrog idea where integration of acceleration (into velocity) and integration of constant velocity (into position) are each staggered so that they overlap by half. This brings things like time-reversibility and stability, which are more important for the 'realism' of a simulation than accuracy is. And the 'realism', the believability, is more important for video games. We don't care if something moves to a slightly different position than it's exact mass would have truly caused, so long as it looks and feels realistic. We're not calculating where to point our high-powered satellite telescopes to look at features on distant objects, or future celestial events. Here, stability and efficiency takes priority here over mathematical accuracy. So, it seems like leapfrog method is appropriate. When you adapt leapfrog for variable time step, it loses some of this advantage, and it loses some of it's appeal for game physics. Stormer-Verlet is like leapfrog, except it uses the average velocity of the previous step instead of a separately maintained velocity. You can adapt this Stormer-Verlet in the same way as leapfrog. To integrate velocity forward with a fixed acceleration, you use half the length of the previous step and half the length of the next step, because they are staggered. If the steps were fixed like true leapfrog, they would be the same length and so the two half lengths sum to one. I use h for step size, a/v/p for acceleration/velocity/position, and hl/pl for 'last' as in previous step. These aren't really equations, more like assignment operations.
Original leapfrog:
v = v + a*h
p = p + v*h
With variable time step:
v = v + a*hl/2 + a*h/2
p = p + v*h
Factor a/2
:
v = v + a*(hl + h)/2
p = p + v*h
Use previous position (p - pl)/hl
for initial velocity:
v = (p - pl)/hl + a*(hl + h)/2
p = p + v*h
Substitute, we don't need v
:
p = p + ( (p - pl)/hl + a*(hl + h)/2)*h
Distribute h
:
p = p + (p - pl)*h/hl + a*h*(h + hl)/2
The result is not as simple or fast as the original Stormer form of Verlet, 2p - pl + a*h^2
. I hope this makes some sense. You would omit the last step in actual code, no need to multiply h
twice.