Forces, Springs and Hooke's Law

A keyframed F-curve tells an object exactly where to be at every instant. A physics-driven object is told nothing of the sort — instead you tell it what forces push on it, and it works out its own motion. That single change of mindset — from scripting positions to summing forces — is the engine behind everything that reacts in a modern film or game: a cape that swings, hair that trails, cloth that settles, a camera that eases after its target, a jelly that wobbles. And astonishingly, almost all of it is built from one humble primitive: the damped spring.

This page builds motion the physical way. We accumulate forces into a net force, turn it into acceleration with a = F/m, and then meet the spring — Hooke's law with a dash of damping — as the workhorse from which cloth, hair, soft constraints and buttery UI follows are all assembled. Along the way we meet the villain of real-time physics: a stiff spring that explodes unless you tiptoe through time.

Accumulating forces

Newton's second law says the net force on a particle sets its acceleration. In an animation loop you don't get one tidy force — you get a pile of them, and your job each frame is to add them up. A particle starts each step with a zero force accumulator, and every influence in the scene throws its contribution in:

Sum them into \mathbf{F} = \sum_i \mathbf{F}_i, then \mathbf{a} = \frac{\mathbf{F}}{m}.

Once you have \mathbf{a}, an integrator advances velocity and position over the timestep \Delta t — that's the subject of numerical integration. The elegance is that forces compose: to add wind, you don't rewrite the solver, you just drop another vector into the accumulator. That is why the same tiny loop can drive a single bouncing pebble or a hundred thousand cloth particles.

The spring: Hooke's law

Connect two particles with an ideal spring of rest length L and stiffness k. When the spring is stretched or squashed away from L, it pulls (or pushes) the ends back toward that comfortable length, and — this is Hooke's great observation — the force grows linearly with how far you deform it.

Let \mathbf{x} be the vector from one end to the other, \lvert\mathbf{x}\rvert its current length, and \hat{\mathbf{x}} = \mathbf{x}/\lvert\mathbf{x}\rvert the unit direction along it. The spring force on the far end is

\mathbf{F}_{\text{spring}} = -k\,\bigl(\lvert\mathbf{x}\rvert - L\bigr)\,\hat{\mathbf{x}}.

Read it piece by piece: \lvert\mathbf{x}\rvert - L is the extension (positive when stretched, negative when compressed); \hat{\mathbf{x}} points along the spring; the leading minus sign makes the force restoring — a stretched spring pulls inward, a squashed spring pushes outward. Double the stretch and you double the force. That linearity is what makes springs so predictable and so easy to network together.

Only within limits. Hooke's law is a first-order approximation — the leading term of the restoring force for small deformations. Stretch a metal spring too far and it yields; squash real cloth and the fibres jam and the force shoots up nonlinearly. Animators exploit both: for gentle, well-behaved motion the linear law is perfect and fast, but a cloth solver often adds a stiff nonlinear term near full stretch so fabric refuses to pass through itself. The linear spring is the honest, useful lie you start from.

Adding damping so it settles

A pure Hooke spring is a perpetual-motion machine: give it energy and it oscillates forever, trading stretch for speed and back, never settling. Real springs lose energy to friction, and so must ours — otherwise your cloth quivers eternally and your camera never stops ringing. We add a damping force that opposes the rate at which the spring is changing length. With \mathbf{v}_{\text{rel}} the relative velocity of the two ends, only the component along the spring stretches it, so we damp exactly that:

\mathbf{F}_{\text{damp}} = -c\,\bigl(\mathbf{v}_{\text{rel}}\cdot\hat{\mathbf{x}}\bigr)\,\hat{\mathbf{x}}.

Here c is the damping coefficient. Projecting onto \hat{\mathbf{x}} matters: it damps stretching without secretly braking a particle that is merely swinging sideways, which would sap energy the spring never stored. The total spring-plus-damper force is the sum of the two, and it always drains the oscillation toward rest.

The spring–mass equation and its four moods

Collapse the problem to one dimension — a mass on a spring, measuring x as displacement from the rest length — and Newton's law m\ddot{x} = \sum F becomes the most famous ODE in engineering:

m\,\ddot{x} = -k\,x - c\,\dot{x}.

Its character is governed entirely by the damping ratio \zeta = \dfrac{c}{2\sqrt{km}}, comparing the actual damping to the special value that just barely kills oscillation. Four moods:

The critical value falls out of setting \zeta = 1: c_{\text{crit}} = 2\sqrt{km}. Below it you get wobble; above it you get molasses; right at it you get the crispest settle physics allows. Play with the slider below to feel all four.

Watching it settle

Below is the trajectory of a mass released from a unit stretch at rest (m=k=1, so \omega_0 = 1). Slide the damping ratio \zeta and watch the bold curve change mood. The faint line is the undamped reference (\zeta=0, a cosine that never dies); the dashed curve is critical damping (\zeta=1). Notice how any \zeta < 1 dips below the axis — that dip is the overshoot — while \zeta \ge 1 glides home without ever crossing zero.

For a smooth camera or UI "follow", \zeta = 1 is almost always what you want: chase a target with a critically-damped spring and the object slides after it and stops dead on arrival — no jelly wobble, no lag-then-snap. Tuning that one number is the difference between a camera that feels alive and one that feels seasick.

Worked example: release from a stretch, damp it just right

A 2\,\text{kg} mass hangs on a spring of stiffness k = 200\,\text{N/m}. We pull it 0.1\,\text{m} below its rest length and release it from rest. We want it to return as fast as possible without overshooting — critical damping. What forces act, and what c do we pick?

1. The forces. Measuring x from the rest length (gravity's constant pull just shifts where "rest" is, so it drops out of the deviation), the spring pulls with -kx = -200x and the damper with -c\dot{x}. The equation of motion is 2\ddot{x} = -200x - c\dot{x}.

2. Critical damping. Set \zeta = 1: c_{\text{crit}} = 2\sqrt{km} = 2\sqrt{200 \cdot 2} = 2\sqrt{400} = 40\ \text{N·s/m}.

3. The settle. The natural frequency is \omega_0 = \sqrt{k/m} = \sqrt{100} = 10\,\text{rad/s}. At critical damping the motion is x(t) = x_0\,e^{-\omega_0 t}\,(1 + \omega_0 t) = 0.1\,e^{-10t}(1 + 10t). It eases straight back toward zero, never crossing the axis, and is practically home within a few multiples of the time constant 1/\omega_0 = 0.1\,\text{s} — about a third of a second. Nudge c below 40 and it would overshoot and wobble; push it above and it would crawl. Forty is the crisp answer.

Springs everywhere

Once you trust the damped spring, you stop building special-case animation systems and start wiring springs together:

Each of these is the same force law, replicated and connected. Learn the one primitive and you have learned a large slice of production animation.

Stiffness, and why hard springs bite

Turn k up and the spring gets stiff: it snaps back violently, oscillating at a high frequency \omega_0 = \sqrt{k/m}. That speed is exactly the problem for a solver. An explicit integrator estimates the future from the current force, which is only trustworthy while the force barely changes over one step. A stiff spring's force swings wildly within a single frame, so unless \Delta t is tiny — roughly \Delta t \lesssim 2/\omega_0 for stability — the estimate overshoots, then over-corrects harder, and the numbers blow up to infinity. This is a stiff ODE: the physics is fine, the method can't keep up.

The cures all trade against each other: shrink \Delta t (accurate but slow), substep (run several small physics steps per rendered frame), soften the spring (lower k, if the look allows), or switch to a method built for stiffness — an implicit integrator (solves for the next force, stable at any step) or a position-based scheme (satisfies constraints directly rather than through forces). Which to reach for is the whole story of numerical integration.

Two classic ways a spring rig goes wrong, and their fixes:

Because frequency is \omega_0 = \sqrt{k/m} — mass sits in the denominator. Quadruple the mass and the oscillation slows by half (the period doubles). This is why animators cheat weight with springs: to make an object read as heavy, you don't redraw it, you lower its natural frequency — a slower, lazier wobble — and add a touch more damping so it settles ponderously. A light, twitchy prop gets a high k/m and a fast, nervous ring. The same spring math, retuned, becomes a performance dial for weight.