UniversityExtendedPhysicsGravityProgramming

How do you code air resistance?

Add a drag term proportional to v² to a falling object and it reaches a terminal velocity. Code it in a few lines of JavaScript and check it against the exact solution.

How do you code air resistance?

Add one term to the acceleration: gravity pulls down at gg, and drag pushes back with kv2k v^2, where k=12CdρA/mk = \tfrac{1}{2}C_d\rho A/m. Step the speed forward with a=g−kv2a = g - kv^2 and the object speeds up, then levels off at the terminal velocity g/k\sqrt{g/k} — exactly what happens in a real fall.

Key fact
Because drag is quadratic, the closed-form solution is v(t)=vttanh⁡(gt/vt)v(t) = v_t\tanh(gt/v_t). That gives you an exact answer to test your simulation against.

This is the code companion to How free fall works, which derives the drag force and terminal velocity.

The whole simulation

javascript
const g = 9.81, rho = 1.225;   // m/s², kg/m³
const m = 80, CdA = 0.7;        // skydiver: mass (kg), drag coefficient × area (m²)

const k = (0.5 * rho * CdA) / m;      // drag acceleration per v²
const vTerminal = Math.sqrt(g / k);   // 42.8 m/s

// s.v = downward speed (m/s), s.y = distance fallen (m)
function step(s, dt) {
  const a = g - k * s.v * s.v;   // gravity minus quadratic drag
  s.v += a * dt;                 // update velocity first…
  s.y += s.v * dt;               // …then position with the new velocity
}

// Closed-form solution for quadratic drag, used as the test oracle
const exact = (t) => ({
  v: vTerminal * Math.tanh((g * t) / vTerminal),
  y: ((vTerminal * vTerminal) / g) * Math.log(Math.cosh((g * t) / vTerminal)),
});

const s = { v: 0, y: 0 };
for (let t = 0; t < 30; t += 0.01) step(s, 0.01);
console.log(s, exact(30));

Does it match the exact solution?

For this skydiver the terminal velocity is 42.842.8 m/s, reached to within 5% after 8.08.0 s and within 1% after 11.511.5 s. Compared with a drag-free fall (98.198.1 m/s after 1010 s), drag has already held the speed to 41.941.9 m/s. Distance fallen in 3030 s:

Time stepDistance fallen in 30 sError vs exact
0.1 s1157.6 m+0.3%
0.01 s1154.5 m+0.03%
0.001 s1154.2 m≈ 0
exact1154.2 m—
The terminal speed is forgiving
Even with a huge step of 2 s the speed still settles on 42.8 m/s, because the drag term pulls it back each step; the distance is what needs the small step.

Going to two dimensions with wind

In 2D, drag opposes the motion relative to the air. If the air moves with velocity w⃗\vec w, use v⃗rel=v⃗−w⃗\vec v_{rel} = \vec v - \vec w and apply a⃗drag=−k ∣v⃗rel∣ v⃗rel\vec a_{drag} = -k\,|\vec v_{rel}|\,\vec v_{rel} to both components. A tailwind then reduces drag on the ball; a headwind increases it. The Ball Gravity simulation keeps things simpler: wind is just a constant horizontal acceleration, with no drag.

Linear vs quadratic drag
Quadratic drag (∝v2\propto v^2) describes fast objects in air. For very slow motion through a viscous fluid, drag is linear (∝v\propto v), which has a different terminal velocity and a simple exponential approach. Pick the law that fits the regime.

Frequently asked questions

How do I calculate terminal velocity in code?

Compute k=12CdρA/mk = \tfrac12 C_d\rho A/m and take vt=g/kv_t = \sqrt{g/k}. It is where the gravity and drag accelerations cancel: g=kvt2g = k v_t^2.

Why does my falling object oscillate or blow up?

Almost always a step that is too large for the acceleration you are applying. Reduce the time step, or use a more accurate integrator such as RK4, and check the result against the analytic solution.

What values of Cd and area should I use?

A sphere is about Cd=0.47C_d = 0.47; a belly-down skydiver has CdAC_d A around 0.5–0.9 m². Real values depend on shape and speed, so treat them as inputs you tune to a known terminal velocity.

Do I need the mass?

Yes: drag is a force, so the acceleration it produces is force divided by mass. A denser object with the same shape has a smaller kk and a higher terminal velocity.

Keep exploring