How Matter.js solveVelocity Handles Resting Contacts

In Matter.js, the Matter.Resolver.solveVelocity function is responsible for adjusting the linear and angular velocities of colliding bodies to ensure realistic physical interactions. This article explores how the engine processes collision pairs, suppresses micro-bouncing on resting contacts, computes normal and frictional impulses, and applies those impulses to update both linear speed and rotational velocity across resting bodies.

The Role of solveVelocity in the Engine Pipeline

Matter.Resolver.solveVelocity executes during the collision resolution phase of the physics update loop. After collision detection identifies overlapping bodies and generates contact manifolds, solveVelocity iterates over these contact points to calculate and apply momentum transfers (impulses).

When bodies are at rest relative to one another—such as a box resting on a floor or stacked crates—the goal of solveVelocity is to eliminate relative normal velocity at the contact points and oppose relative tangential velocity (sliding) without causing instability or visual jitter.

1. Calculating Relative Contact Velocity

For each contact point between two bodies, Body A and Body B, the solver computes the total velocity at the exact point of contact. Because a rigid body's local point velocity depends on both its center-of-mass translation and its rotation, the velocity at contact offset vector \(r\) is:

\[v_{point} = v + \omega \times r\]

Where:

The relative velocity \(v_{rel}\) between the two bodies at the contact point is then:

\[v_{rel} = (v_B + \omega_B \times r_B) - (v_A + \omega_A \times r_A)\]

2. Restitution Thresholding for Resting Contacts

Restitution defines how bouncy a collision is. Under standard conditions, separating velocity equals approaching velocity multiplied by the restitution coefficient. However, if applied continuously to resting contacts, even minute velocities would cause objects to vibrate or bounce perpetually.

To manage resting contacts, Matter.js evaluates whether the approaching velocity along the contact normal falls below a minimum threshold. When relative normal velocity is sufficiently small, the engine overrides the restitution coefficient, treating it effectively as zero. This dampening stops restitution from generating artificial kinetic energy, allowing bodies to settle into equilibrium.

3. Resolving Normal and Tangential Impulses

Once relative velocity is determined, solveVelocity computes the corrective impulses required to satisfy physical constraints:

Normal Impulse (Penetration Prevention)

The solver projects \(v_{rel}\) onto the contact normal. It determines the scalar impulse magnitude \(J_n\) necessary to bring the relative normal speed to zero (or the restitution target). The impulse is scaled by the effective mass of the system, which accounts for both the inverse masses (\(1/m_A, 1/m_B\)) and the rotational inertias (\(1/I_A, 1/I_B\)) relative to the contact point:

\[m_{eff} = \frac{1}{\frac{1}{m_A} + \frac{1}{m_B} + \frac{(r_A \times n)^2}{I_A} + \frac{(r_B \times n)^2}{I_B}}\]

Tangential Impulse (Friction)

The solver projects \(v_{rel}\) onto the tangent vector perpendicular to the normal. It calculates a friction impulse \(J_t\) to halt lateral sliding. To satisfy Coulomb's law of friction, the tangential impulse is clamped so that \(|J_t| \le \mu J_n\), where \(\mu\) is the combined friction coefficient of the two surfaces. For resting contacts with low lateral forces, this clamping prevents sliding entirely (static friction).

4. Applying Impulses to Linear and Angular Speeds

Once the total impulse vector \(J = J_n n + J_t t\) is established, it is applied directly to alter the velocities of the participating bodies:

Linear Velocity Adjustment

Linear momentum changes inversely proportional to mass:

Angular Velocity Adjustment

The contact impulse generates a torque around the center of mass based on the cross product of the contact offset \(r\) and the impulse vector \(J\):

Because the cross product \(r \times J\) accounts for both the normal impulse (which resists rotational tipping) and the friction impulse (which induces or counters spin), both angular and linear speeds are adjusted simultaneously in a physically consistent manner.

Iteration and Convergence

In complex scenes with resting stacks or multiple simultaneous contacts, resolving one contact point may alter the velocities at an adjacent contact. Matter.js addresses this by running solveVelocity over multiple iterations, governed by the engine.velocityIterations configuration. Through repeated passes, velocity adjustments converge toward a balanced state where normal velocities approach zero and friction holds resting bodies stable.