Programmers and physics

I’m sure it’s an age thing. Despite over 30 years of evidence to the contrary, I still think of programming as an adjunct to math and science, so I’m always shocked when I see things like this little writeup by Hannu Kankaanpää. It’s an explanation of how to write a program that tracks the motion of an object under the pull of gravity, and Hannu wrote it because he noticed that game programmers were often doing it wrong.

What’s shocking about it? Well, the equations Hannu presents have been around for about 300 years and are currently taught in high school physics classes. We’re not talking about a secret algorithm known only to ninja coders. That he felt the need to present them in tutorial fashion in 2004—and to present examples of how many (most?) programmers were using the wrong formulas—is an indictment of the sorry state of math and science knowledge among software “engineers” at the time. That it recently made it onto Pinboard’s Popular page, suggests that there’s been little improvement.

The article presents game programmers as a weird mix of sophistication and ignorance. Hannu refers to the common technique for calculating motion as Euler’s method. He must believe his audience knows that term, which implies a familiarity with numerical methods. And yet within the world of numerical analysis, Euler’s method is famous for two things:

  1. Its conceptual simplicity. It provides a gentle introduction to the numerical solution of differential equations.
  2. Its appalling accuracy. Initial value problems solved by Euler’s methods drift blithely away from the true solution.

I can only assume that programmers who use Euler’s method have never actually learned any numerical analysis, and have just been passing this crappy algorithm around without any understanding of how it works (and doesn’t work).

Even worse is the notion that a numerical solution is necessary, something that even Hannu falls prey to. The great thing about motion under gravity (or any constant acceleration) is that it has a perfectly simple analytical solution:

v=v0+gtv = v_0 + g t x=x0+v0t+12gt2x = x_0 + v_0 t + \frac{1}{2} g t^2

This works for any set of initial position and velocity, x0x_0 and v0v_0, and any time interval, tt, for as long as the only force acting on the object is gravity. You can use it as an incremental solution if you want,

vi+1=vi+gΔtv_{i+1} = v_i + g \, \Delta t xi+1=xi+viΔt+12g(Δt)2x_{i+1} = x_i + v_i \, \Delta t + \frac{1}{2} g (\Delta t)^2

although you run the risk of accumulating small roundoff errors if you do. You can also rearrange the order of operations to make the calculation more efficient. But whatever the form you express it in, the solution is simple, straightforward, and has been known since the Principia. Worth more than a passing glance if you want your game to work like real life.