Skip to content
Coulomb Friction
step 1/5

Reading — step 1 of 5

Read

~1 min readCollision Response

Coulomb Friction in 2D Contacts

After computing the normal-impulse j_n from the impulse equation, every real rigid-body engine also applies a tangent impulse to model friction. The dry-friction model used by Box2D, Bullet, Chipmunk and friends is Coulomb's law:

|j_t|  <=  mu * |j_n|

Where mu is the friction coefficient (often the geometric mean of the two contacting bodies' friction values: mu = sqrt(mu_a * mu_b)).

Algorithm

  1. Compute the contact normal n (unit vector) and the tangent t (perpendicular to n).
  2. Project the relative velocity onto t: v_t = (v_b - v_a) . t.
  3. Compute the desired tangent impulse that would stop sliding entirely:
    j_t_desired = -v_t / (1/m_a + 1/m_b)
    
  4. Clamp it to the Coulomb cone:
    cap = mu * |j_n|
    j_t = clamp(j_t_desired, -cap, +cap)
    
  5. Apply j_t * t to both bodies (one positive, one negative).

When |j_t_desired| <= cap you have static friction: the surfaces don't slide (the impulse exactly cancels tangential motion). When |j_t_desired| > cap you've exceeded the cone and you saturate at cap: this is kinetic friction — the surfaces slip and only the capped impulse is applied.

Why a cone?

The set of admissible (j_n, j_t) pairs is the Coulomb cone in impulse space. Real surfaces resist sliding up to a limit proportional to the normal force; past that limit they slide and a constant kinetic force acts (Coulomb assumes mu_static = mu_kinetic for simplicity).

Static vs kinetic in real engines

Most engines use a single coefficient. Some (Bullet, PhysX) expose both. Distinguishing them perfectly requires detecting when relative tangential velocity crosses zero — surprisingly expensive and rarely worth it for games.

Exercise

Given a series of contacts, compute the clamped tangent impulse.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…