Numerical Integration for Animation
A physics engine — cloth, hair, ragdolls, a fountain of sparks, a planet on a string — is at heart a
machine that solves Newton's second law over and over, sixty times a second. You know
the acceleration (force over mass), and you want the position; getting from one to the other means
integrating an ordinary differential equation forward in time. But you never solve it
exactly. You take a discrete step of size \Delta t — one frame —
and guess the next state from the current one. Which guess you use is one of the most
consequential lines in your whole engine.
The wrong integrator makes a swinging pendulum gain energy until it whirls over the top; the
right one, costing not a single extra multiply, keeps it swinging forever. This page is a tour of the
handful of integrators every animation programmer should know —
explicit Euler, semi-implicit (symplectic) Euler,
Verlet, RK4 and implicit Euler — and the
stability vs accuracy vs cost trade-off that decides between them.
The problem, stated cleanly
A particle has position x, velocity v = \dot x,
and an acceleration a = f(x, v)/m set by the forces on it. The exact motion
obeys the second-order ODE \ddot x = a, which we split into two first-order
equations — the state is the pair (x, v):
\dot x = v, \qquad \dot v = a(x, v).
An integrator is a rule that turns the state at frame n,
(x_n, v_n), into the state at frame n+1 one
timestep \Delta t later. Every scheme below is a different such rule. Our
running test case is the unit spring: a mass on a spring with
a = -x (Hooke's law with all constants set to 1). Its exact solution is a
pure oscillation x(t) = \cos t that never changes amplitude — the
perfect stress test, because any energy an integrator invents or destroys shows up immediately as a
growing or shrinking swing.
Explicit (forward) Euler — the naive one
The simplest possible guess: assume velocity and acceleration are constant across the frame, and step
both forward using the values you have now.
x_{n+1} = x_n + v_n\,\Delta t, \qquad v_{n+1} = v_n + a_n\,\Delta t.
One line each, no solve, blazingly cheap. It is also, for oscillating systems, quietly disastrous.
Because both updates use the old state, explicit Euler systematically overshoots on the
outward swing and never fully pays it back — it injects energy every step. A
frictionless orbit spirals outward; an undamped spring's amplitude grows frame by
frame until the simulation blows up. It is also only conditionally stable: even the
amplitude aside, if \Delta t is too large relative to the stiffness, the
error doubles every step and you get an instant explosion.
Semi-implicit (symplectic) Euler — the games default
Now change one thing: update the velocity first, then use that
brand-new velocity to update the position.
v_{n+1} = v_n + a_n\,\Delta t, \qquad x_{n+1} = x_n + v_{n+1}\,\Delta t.
That is the entire difference — the order of the two lines, and which v
feeds the position update. The cost is identical to explicit Euler. But this scheme is
symplectic: it does not conserve energy exactly, but it conserves a nearby "shadow"
energy, so the error oscillates within a bounded band instead of drifting off to infinity. An
undamped spring stays bouncing at (very nearly) constant amplitude forever; an orbit stays an orbit.
This is why semi-implicit Euler is the default integrator in essentially every real-time game
engine — you get stability for free, just by reordering two assignments.
- Explicit (forward) Euler: both updates use the old state
(x{+}{=}v\,\Delta t, then v{+}{=}a\,\Delta t).
Cheap, first-order, energy-gaining and only conditionally stable — oscillators explode.
- Semi-implicit (symplectic) Euler: update
v first, then step x with the
new v. Same cost, first-order, but symplectic —
bounded energy error, stable for oscillators. The games default.
See it blow up: explicit vs semi-implicit
Below, all three curves integrate the same unit spring (a=-x,
x_0=1, v_0=0). The faint curve is the exact
answer \cos t. The other two are explicit Euler and
semi-implicit Euler stepped with the timestep \Delta t you
choose. Drag the slider up: the semi-implicit curve keeps hugging a bounded band, but the explicit
curve's amplitude grows every swing — and as \Delta t gets
large it runs away off the top of the chart. Same forces, same start, one reordered line.
Notice that shrinking \Delta t slows explicit Euler's blow-up but
never cures it — the energy gain per step shrinks but stays positive, so given enough time it always
wins. Semi-implicit doesn't have the disease to begin with.
Worked example: five steps of the unit spring
Let's hand-crank both schemes on a = -x starting at
x_0 = 1, v_0 = 0, with a deliberately coarse
\Delta t = 0.5. The true amplitude is fixed at 1.
Explicit Euler (x_{n+1}=x_n+v_n\Delta t, then
v_{n+1}=v_n-x_n\Delta t):
| step | x | v | energy ½(x²+v²) |
| 0 | 1.000 | 0.000 | 0.500 |
| 1 | 1.000 | −0.500 | 0.625 |
| 2 | 0.750 | −1.000 | 0.781 |
| 3 | 0.250 | −1.375 | 0.977 |
| 4 | −0.438 | −1.500 | 1.221 |
The energy climbs every single step — 0.500 \to 0.625 \to 0.781 \to \dots —
and it will keep climbing until the spring flies apart. Now the semi-implicit version
(v_{n+1}=v_n-x_n\Delta t first, then
x_{n+1}=x_n+v_{n+1}\Delta t):
| step | v (updated first) | x | energy ½(x²+v²) |
| 0 | 0.000 | 1.000 | 0.500 |
| 1 | −0.500 | 0.750 | 0.406 |
| 2 | −0.875 | 0.313 | 0.432 |
| 3 | −1.031 | −0.203 | 0.552 |
| 4 | −0.930 | −0.668 | 0.655 |
The energy wobbles around — 0.5 \to 0.41 \to 0.43 \to 0.55\dots — but it
oscillates rather than marching monotonically upward. Over thousands of steps the explicit
column diverges to infinity while the semi-implicit column stays trapped in a band around the true
value. That bounded wobble is the symplectic property doing its job. (The band is this wide only
because \Delta t=0.5 is huge; at a realistic
\Delta t=1/60 it's imperceptible.)
Verlet — the constraint-solver's friend
Position Verlet drops explicit velocity entirely and remembers the
previous two positions. From a Taylor expansion of x(t\pm\Delta t)
the odd terms cancel, leaving:
x_{n+1} = 2x_n - x_{n-1} + a_n\,\Delta t^2.
Velocity is implied by the gap between successive positions (v \approx (x_n -
x_{n-1})/\Delta t) rather than tracked as its own variable. Verlet is
time-reversible and symplectic, so it's stable like semi-implicit Euler, and it has a
killer feature for animation: because the state is the positions, you can enforce
constraints by simply moving the points — clamp a cloth vertex, snap a rope
segment back to its rest length — and the "velocity" corrects itself automatically next frame. This is
the engine behind position-based dynamics and the famous
cloth
and rope simulations that made Verlet legendary in games.
RK4 — accuracy, at a price
Fourth-order Runge–Kutta evaluates the acceleration four times per step — at
the start, twice at the midpoint, and at the end — and blends the four slopes with weights
\tfrac16(k_1 + 2k_2 + 2k_3 + k_4). The payoff is 4th-order
accuracy: halve \Delta t and the error drops by a factor of
2^4 = 16, versus just 2 for either Euler. For
trajectories where you need the path to be quantitatively right — a ballistic missile, an
orbital-mechanics demo, a scientific visualisation — RK4 is the workhorse.
But it costs four force evaluations per step (often the most expensive part of the
loop), it is not symplectic (a plain RK4 orbit slowly loses energy), and — crucially — being
high-order buys you accuracy, not stability. Against a stiff system (very
strong springs, like taut cloth) RK4 still needs a tiny \Delta t or it too
explodes. Accuracy and stability are different axes; RK4 only helps the first.
Implicit (backward) Euler — unconditionally stable, but sluggish
Flip explicit Euler around: evaluate the forces at the new, unknown state instead of the old
one.
v_{n+1} = v_n + a(x_{n+1})\,\Delta t, \qquad x_{n+1} = x_n + v_{n+1}\,\Delta t.
Since the right-hand side mentions the unknown x_{n+1}, you can't just read
it off — you must solve a (linear) system each frame. In exchange you get
unconditional stability: no matter how large \Delta t or
how stiff the springs, it will never blow up. That's why it's the classic choice for
stiff cloth (the Baraff–Witkin cloth solver), where explicit methods would demand
absurdly tiny timesteps.
The catch is the mirror image of explicit Euler: implicit Euler is numerically damped.
Where forward Euler invents energy, backward Euler destroys it — an undamped spring
slowly decays to rest, motion looks sluggish and over-smoothed, and lively bounces go dead.
You trade explosions for molasses. (Symplectic integrators sit in the sweet middle: neither gaining
nor bleeding energy.)
The trade-off, in one table
| Integrator | Cost / step | Order | Energy behaviour | Best for |
| Explicit (forward) Euler | 1 eval | 1st | Gains → explodes | almost nothing (teaching) |
| Semi-implicit (symplectic) Euler | 1 eval | 1st | Bounded (symplectic) | real-time games default |
| Verlet | 1 eval | 2nd | Bounded (symplectic) | constraints, cloth, rope (PBD) |
| RK4 | 4 evals | 4th | Slow drift | accurate trajectories |
| Implicit (backward) Euler | 1 eval + solve | 1st | Damped (loses energy) | stiff cloth (won't explode) |
There is no free lunch: stability, accuracy and cost pull against each other. The
real-time animator's usual answer — cheap, stable, good-enough-accurate — is semi-implicit
Euler or Verlet. You escalate to RK4 when the path must be accurate, and to implicit
Euler when the system is so stiff that nothing explicit survives.
The most common beginner bug in a homemade physics toy: you write the textbook update
x \mathrel{+}= v\,\Delta t; \; v \mathrel{+}= a\,\Delta t, launch a planet
into a circular orbit, and watch it spiral outward and fly off — or you hang a mass
on a spring and its bouncing gets wider and wider until it detonates. Nothing is wrong with
your forces; it's the integrator. Explicit Euler adds a sliver of energy every frame, and for an
oscillator that sliver compounds without bound. The fix costs nothing: update the velocity
first, then use the new velocity to update the position (semi-implicit Euler). One reordered
line and the orbit stays round, the spring stays bounded. If you're reaching for a smaller
\Delta t to "fix" a growing oscillation, stop — you're treating a symptom of
the wrong scheme.
Because accuracy is not the thing real-time animation is short of — stability and
budget are. RK4 costs four force evaluations per step, and in a scene with thousands of
interacting particles that quadruples the single most expensive part of your frame. Worse, RK4 buys
accuracy, not stability: point it at a stiff spring and it explodes just like the Eulers do,
only four times more slowly. And it isn't symplectic, so over a long shot an RK4 orbit visibly loses
energy and decays. For a game running at 60 Hz you don't need the trajectory correct to eight
decimals — you need it to not blow up and to look alive while costing one evaluation.
That's exactly what the cheap symplectic methods deliver, which is why the fancy integrator loses to
the humble one.