Step 1 of 5 · Reading · ~4 min
Read
Collision Response
Collision Response
The narrow phase told you that two bodies touch, along which normal, and how deep. Response turns that into motion: bodies must stop approaching (and maybe bounce), and the overlap that already exists must be removed. After this lesson your program will compute the new velocities of two colliding bodies and the positions that push them out of each other.
Impulse: a change of velocity in one instant
An impulse J is a force acting for an instant. It changes a body's velocity by J / m immediately, with no integration. At a contact the only direction that matters for bouncing is the contact normal n (unit length, pointing from A to B), so the impulse is j * n for a single number j that we solve for.
Equal and opposite: A receives -j * n and B receives +j * n. Total momentum is therefore unchanged.
Where j comes from
Measure the approach speed along the normal, the relative velocity of B with respect to A:
vn = (vB - vA) . n
vn < 0 means the bodies are closing, vn > 0 means they are already moving apart. The coefficient of restitution e says how much of the approach speed comes back as separation speed: after the collision vn' = -e * vn. With e = 1 the bounce is perfect, with e = 0 the bodies stay together along the normal.
Apply the impulse to each body's velocity and require that result. Using inverse mass w = 1 / m the solution is:
j = -(1 + e) * vn / (wA + wB)
vA' = vA - j * wA * n
vB' = vB + j * wB * n
Using w instead of m has a bonus: a wall or floor is simply w = 0. It then receives no velocity change, and the formula needs no special case for it. If both bodies have w = 0 there is nothing to solve, and j is 0.
Two rules before you apply it:
- If
vn > 0the bodies are separating. Do nothing (j = 0). Applying the formula would pull them back together. - Only the normal component changes. The part of the velocity along the surface is untouched (friction is a separate lesson).
Worked trace: A has mass 2 and velocity (6, 0), B has mass 3 and velocity (0, 0), n = (1, 0), e = 0.5.
vn = 0 - 6 = -6 wA = 0.5 wB = 1/3
j = 1.5 * 6 / (0.5 + 1/3) = 10.8
vA' = 6 - 10.8 * 0.5 = 0.6 vB' = 0 + 10.8 / 3 = 3.6
Check: the separation speed is 3.6 - 0.6 = 3 = e * 6, and the momentum is 2*0.6 + 3*3.6 = 12, the same as before (2 * 6).
Positional correction
Impulses edit velocities. The overlap that has already happened is still there, and under constant load (a stack of boxes under gravity) it keeps growing, so boxes sink into each other. After the velocities are fixed, move the bodies apart along the normal, in proportion to inverse mass so a heavy body moves less:
c = max(depth - slop, 0) / (wA + wB) * percent
A moves by -c * wA * n B moves by +c * wB * n
Two knobs keep it calm:
- slop (for example 0.01): overlap smaller than this is tolerated, so resting bodies do not jitter between touching and not touching.
- percent (for example 0.2 to 0.8): fix only a fraction of the overlap each step, so a deep penetration unwinds over several steps instead of snapping apart.
Worked trace: depth 0.21, slop 0.01, percent 0.5, equal masses (w = 1 each): c = 0.2 / 2 * 0.5 = 0.05. Each body moves 0.05 along the normal, in total 0.1.
Common mistakes
- Using
vA - vBforvn, which flips the sign test and the direction of the impulse. - Forgetting the
1 +in front ofe: the bodies then only stop approaching, with no bounce. - Dividing by mass instead of multiplying by inverse mass, and crashing on a static body.
- Resolving a separating pair, which glues bodies together as they move away.
- Correcting the full depth at once, or splitting it 50/50 regardless of mass.
Your exercise
The starter parses the commands and prints the results; you write impulse and correct. The most likely mistake is the sign of the relative velocity.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…