Penetration Resolution (push out)
Penetration Resolution (push-out)¶
function resolveAabbPenetration(a, b):
overlapX = min(a.right, b.right) - max(a.left, b.left)
overlapY = min(a.bottom, b.bottom) - max(a.top, b.top)
if overlapX < overlapY:
// push apart along X, whichever direction is shorter
if a.centerX < b.centerX:
a.x -= overlapX / 2
b.x += overlapX / 2
else:
a.x += overlapX / 2
b.x -= overlapX / 2
else:
if a.centerY < b.centerY:
a.y -= overlapY / 2
b.y += overlapY / 2
else:
a.y += overlapY / 2
b.y -= overlapY / 2
Penetration resolution computes how much two boxes overlap on each axis, then separates them along the axis with the smaller overlap — this is the "path of least resistance" out of the collision, and avoids objects being flung out at odd angles. Splitting the correction 50/50 between both objects keeps things symmetric (skip this and push only the dynamic object if the other is static/immovable).