Step 1 of 5 · Reading · ~4 min
Read
Collision Response
Coulomb Friction
The collision response from earlier stops bodies from sinking into each other, but it leaves them perfectly slippery: a box on a ramp would slide forever. Friction is the second impulse at a contact, acting along the surface instead of across it. After this lesson your program will compute that impulse, limit it the way real surfaces do, and apply it to both bodies.
Two directions at one contact
At a contact with unit normal n (pointing from A to B) the relative velocity of B with respect to A splits into two parts:
- along the normal,
vn = rv . n, handled by the collision impulsejn; - along the surface, along the tangent
t, which isnrotated a quarter turn counter-clockwise:t = (-ny, nx). The sliding speed isvt = rv . t, and it can be positive or negative.
Friction works on vt only. Treat the two directions as separate impulses: first the normal one, then friction.
What the impulse would have to be
To stop all sliding at once you need an impulse along t that cancels vt. For two bodies with inverse masses wA and wB the impulse that brings the relative tangent speed to zero is:
jt_want = -vt / (wA + wB)
This is the same mass-weighted formula as the normal impulse, with restitution 0. If it were always applied, friction would be infinite: any two surfaces that touch even lightly would stick as if welded.
The Coulomb limit
Real friction can only push back so hard, and how hard depends on how hard the surfaces are pressed together. Coulomb's law: the friction impulse is at most mu times the normal impulse,
|jt| <= mu * jn
so the allowed range is [-cap, +cap] with cap = mu * jn. Clamp the wanted value into it:
- If
|jt_want| <= cap, friction is strong enough to stop the sliding completely. The contact sticks (static friction) and the relative tangent speed becomes 0. - If
|jt_want| > cap, friction can only slow the slide. The contact slides (kinetic friction) and the impulse is exactly+capor-cap, with the sign ofjt_want: friction always opposes the motion.
jn >= 0 because contacts only push. With jn = 0 (the bodies barely touch, or are separating) the cap is zero and nothing grips.
The coefficient of a pair
Each material has its own mu. For a pair, Box2D, Bullet and PhysX use the geometric mean, mu = sqrt(muA * muB). If either surface is frictionless (0) the contact is frictionless, which is what an artist who painted a surface as ice expects. An average would let the other surface grip anyway.
Applying it
The impulse acts along t, opposite on the two bodies, weighted by inverse mass like any impulse:
vA = vA - jt * wA * t
vB = vB + jt * wB * t
Worked trace: a crate (mass 2, B) lands on a static floor (A, inverse mass 0), n = (0, 1), so t = (-1, 0). After the normal impulse its velocity is (3, 0). Then vt = -3 and jt_want = 3 / 0.5 = 6. Both surfaces have mu = 0.5, and the normal impulse was jn = 4, so cap = 2. 6 > 2: it slides, jt = +2, and the crate's velocity becomes (3, 0) + 2 * 0.5 * (-1, 0) = (2, 0). Its sliding speed fell from 3 to 2 but not to 0.
Common mistakes
- Using friction
mu * massinstead ofmu * jn; a heavy body does not grip more on a slope. - Clamping to
[0, cap]instead of[-cap, +cap]. The sign of friction depends on which way the body slides. - Averaging the two coefficients; use the geometric mean.
- Dividing by zero when both bodies are static, or when there is no tangential speed to remove.
- Applying friction before the normal impulse, so it uses a stale
jn.
Your exercise
The starter parses each contact and prints the result. You write friction. The most likely mistake is the sign of the clamp.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…