Reading — step 1 of 5
Read
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
- Compute the contact normal
n(unit vector) and the tangentt(perpendicular ton). - Project the relative velocity onto
t:v_t = (v_b - v_a) . t. - Compute the desired tangent impulse that would stop sliding entirely:
j_t_desired = -v_t / (1/m_a + 1/m_b) - Clamp it to the Coulomb cone:
cap = mu * |j_n| j_t = clamp(j_t_desired, -cap, +cap) - Apply
j_t * tto 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…