From the velocity to constant speed
Step 1 — the curve gives position; its derivative gives velocity. A
parametric curve P(t) is just a position that depends on the
parameter t. Its
derivative
with respect to t is the velocity vector — it
points along the curve (it is the tangent) and its length is how fast
position changes per unit of t:
P'(t) = \frac{dP}{dt}, \qquad \text{speed} = \big\lVert P'(t) \big\rVert.
Step 2 — the trap: equal steps in t are not equal
steps in distance. Take two equal little steps of size
\Delta t. The distance actually travelled in each is about
\lVert P'(t)\rVert\,\Delta t — and that speed
\lVert P'(t)\rVert varies along the curve. Where the
control points are far apart the curve covers a lot of ground per unit
t (fast); where they bunch up it covers little (slow). So a
constant-t animation
\big\lVert P'(t) \big\rVert \neq \text{constant}
speeds up and slows down all on its own. That's the lurch.
Step 3 — what we actually want: constant speed. A steady camera
should cover the same arc length per unit of time, i.e.
\lVert \tfrac{dP}{d\tau}\rVert should be constant in the animation
clock \tau. We can't move the curve's geometry; we have to change
how we sample it — drive position by distance travelled, not by the raw parameter.
Step 4 — measure distance: the arc length. The cumulative distance from the
start of the curve up to parameter t is the
arc length
s(t) = \int_0^{t} \big\lVert P'(u) \big\rVert \, du.
This s(t) rises quickly where the curve is fast and slowly where
it crawls — it is a faithful "odometer" along the path. Its total value
L = s(1) is the whole curve's length.
Step 5 — reparametrise by arc length: invert s(t).
To advance the object a fixed distance \Delta s each frame, we need
the parameter that corresponds to a given distance — the inverse function
t(s). Then sampling the curve at equal distances,
Q(s) = P\big(t(s)\big),
gives motion at unit speed in s:
\lVert Q'(s)\rVert = 1. Equal distance per step means
constant speed, exactly what we asked for. (Want a specific speed
v? Advance \Delta s = v\,\Delta\tau per
frame.)
Step 6 — make it practical: precompute a lookup table. The integral
s(t) rarely has a tidy closed form, and inverting it analytically
is worse. So games tabulate it: walk the curve in many small
t-steps, accumulate the little distances
\lVert P(t_{k+1})-P(t_k)\rVert into a table of
(t_k,\, s_k) pairs. To find t for a
wanted distance s, binary-search the table for the bracketing
entries and linearly interpolate between them. That arc-length lookup table
(built once, used every frame) is how real engines turn a lurching curve into a smooth,
constant-speed glide.
Let P(t) be a parametric curve traced as the parameter
t runs over [0,1].
-
The derivative P'(t)=\tfrac{dP}{dt} is the
velocity: it is the tangent to the curve and its length
\lVert P'(t)\rVert is the speed per unit
t.
-
Equal \Delta t ≠ equal distance: since
\lVert P'(t)\rVert varies along the curve, a
constant-t animation speeds up where points are far apart and
crawls where they are close — it lurches.
-
Arc-length reparametrisation gives constant speed: with the cumulative
length s(t)=\int_0^t \lVert P'(u)\rVert\,du, sampling
Q(s)=P(t(s)) at equal \Delta s
moves at unit speed, \lVert Q'(s)\rVert = 1.
-
In practice, precompute s(t) as a table and
invert it by binary search — the arc-length lookup table — once per
curve, then reuse it every frame.
Picture three waypoints, two close together on the left and one far off to the right. A
uniform spline spends one third of its t-budget on the short
left hop and the other two thirds racing across the long right stretch — but those
fractions are about the parameter, not the distance. Run a dot by
constant t and it dawdles through the cramped left bend, then
flings itself across the wide gap: a visible surge precisely where the curve is
longest per unit t.
The arc-length table rebalances the budget. It measures that the right stretch is, say,
four times longer, so it hands the dot four times as many distance-steps there — the dot
slows down across the gap and speeds up through the bend until the ground covered per
frame is the same everywhere. The geometry of the path never changes; only the
schedule along it does. That is the entire trick, and it is why "follow the spline
at constant speed" always means "follow the spline's arc-length reparametrisation".