Matter.js High vs Low Density Body Interactions
This article explores the physical and computational effects of pairing high-density and low-density rigid bodies within the Matter.js 2D physics engine. It breaks down how density dictates mass calculations, examines the resulting momentum transfer and collision dynamics, highlights common numerical instabilities such as tunneling and constraint jitter, and outlines practical methods to maintain simulation stability.
Mass Derivation in Matter.js
In Matter.js, a body's mass is not set in isolation by default; it is calculated automatically using the formula:
\[\text{mass} = \text{density} \times \text{area}\]
The default density for all bodies is 0.001. When you
dramatically raise the density of one body while lowering or maintaining
the default density of another, you create an extreme mass ratio. Even
if two shapes share identical geometry and dimensions, a high-density
body will possess significantly higher inertia than a low-density
body.
Collision Dynamics and Momentum Transfer
When a high-density body collides with a low-density body, the interaction is governed by the conservation of linear momentum:
\[m_1 v_{1i} + m_2 v_{2i} = m_1 v_{1f} + m_2 v_{2f}\]
Because the high-density body possesses vastly more mass (\(m_1 \gg m_2\)):
- Velocity Imbalance: The high-density body barely registers the collision, continuing along its trajectory with virtually uninterrupted velocity. Conversely, the low-density body absorbs nearly all relative velocity change, resulting in sudden, violent acceleration.
- Exaggerated Restitution: Even moderate restitution (bounciness) settings can cause the lighter body to rebound at extreme speeds when struck by the heavier body.
- Unbalanced Pushing Forces: Low-density bodies cannot effectively push, block, or deflect high-density bodies. Instead, a moving high-density body acts almost like an immovable kinematic object relative to the lighter body.
Engine Instabilities and Artifacts
Extreme mass disparities are notoriously difficult for discrete, iterative physics solvers like Matter.js to resolve. Combining high- and low-density bodies introduces several distinct simulation problems:
1. Tunneling (Passing Through Geometry)
When a high-density body imparts massive velocity to a low-density body in a single step, the lighter body can move further in one frame than its own thickness. This causes the object to skip collision checks entirely on the next frame, tunneling through walls, floors, or other objects.
2. Constraint Jitter and Explosions
Attaching a high-density body to a low-density body via a
Constraint (spring or rigid link) destabilizes the
iterative solver. The solver attempts to reconcile the positions of both
bodies simultaneously. Because correcting the position of the heavy body
requires massive force, the light body is overcorrected, resulting in
violent vibration, stretching, or the simulation "exploding."
3. Stacking Collapse
If a high-density body is placed on top of a low-density body resting on static ground, the lighter body will often sink into the floor or be compressed through boundaries. The iterative impulse resolution algorithm prioritizes resting contacts equally, leading to penetration errors under extreme weight loads.
Best Practices for Managing Density Disparities
To maintain stable simulations when working with varied densities in Matter.js, implement the following adjustments:
- Clamp Mass Ratios: Keep mass ratios between interacting bodies within a manageable threshold (ideally no greater than 1:10 or 1:20). Avoid pairing bodies with mass ratios exceeding 1:100.
- Increase Solver Iterations: Increase
engine.positionIterationsandengine.velocityIterations(default is 6 and 4, respectively). Raising these values to 10–15 helps resolve stiff contacts and reduces constraint instability. - Substep the Engine: Instead of taking large frame
steps, update the engine multiple times per frame with a smaller delta
time (
Engine.update(engine, 1000 / 60 / substeps)). This directly counteracts tunneling caused by sudden high-speed impulses. - Apply Velocity Clamps: Manually restrict the
maximum linear velocity (
body.velocity) of low-density bodies inside anafterUpdateorbeforeUpdateevent listener to prevent them from accelerating beyond the simulation's collision threshold.