Skip to content

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).