How Matter.js Calculates Collision Penetration Depth

In Matter.js, collision penetration depth is calculated primarily using the Separating Axis Theorem (SAT) for convex polygons and geometric distance formulas for circles. The physics engine determines how deeply two intersecting bodies overlap by projecting their vertices onto potential separation axes, identifying the axis with the smallest overlap—known as the Minimum Translation Vector (MTV)—and recording that minimum overlap value as the penetration depth.

The Separating Axis Theorem (SAT) Pipeline

Matter.js relies on the Matter.SAT module for detecting collisions between rigid bodies. The algorithm follows a structured pipeline to determine whether an intersection exists and to quantify its severity.

1. Generating Projection Axes

For convex polygons, potential separation axes are defined by the surface normals of the shapes' edges.

2. Projecting Vertices onto Each Axis

For every candidate axis, Matter.js projects the vertices of both bodies onto that axis using the vector dot product:

\[\text{projection} = \mathbf{v} \cdot \mathbf{axis}\]

By evaluating all vertices for a body, the engine identifies the minimum and maximum scalar projection values:

3. Calculating the Overlap

Once the projections are mapped onto the 1D axis, the engine computes the overlap between the two intervals:

\[\text{overlap} = \min(max_A, max_B) - \max(min_A, min_B)\]

If any axis yields an overlap less than or equal to zero, a gap exists. By the Separating Axis Theorem, the shapes are not colliding, and the calculation halts immediately.

4. Determining Penetration Depth and the Normal

If every tested axis produces an overlap greater than zero, a collision has occurred. Matter.js tracks the overlap values across all evaluated axes and selects the smallest one:

This minimum value represents the shortest distance required to push the bodies apart to resolve the collision without introducing unnecessary displacement.

Circle-to-Circle and Circle-to-Polygon Handling

Because circles have an infinite number of edge normals, Matter.js handles them through specialized projection logic:

Resulting Collision Data

The calculated depth is assigned to the depth property of the resulting collision object, paired with collision.normal. The physics solver uses this depth value in subsequent steps to apply positional correction, preventing bodies from sinking into one another, and to calculate the corrective impulse required to simulate realistic physical restitution.