How Matter.js Grid Broad-Phase Algorithm Works

In 2D physics engines, collision detection is divided into broad-phase and narrow-phase stages to maintain performance. This article explains how the grid-based broad-phase collision detection algorithm functions in Matter.js, breaking down how it partitions 2D space, assigns object bounding boxes to uniform cells, removes duplicate pairs, and optimizes processing before passing potential collisions to the narrow-phase solver.

The Purpose of Broad-Phase Detection

Directly testing every body against every other body using narrow-phase algorithms (such as the Separating Axis Theorem) results in an \(O(N^2)\) time complexity, which rapidly degrades frame rates as object counts grow. The broad-phase algorithm acts as an early culling filter. Its sole responsibility is to quickly discard pairs of objects that are too far apart to possibly collide, forwarding only a small list of candidate pairs to the narrow-phase.

Spatial Partitioning via Uniform Grids

Matter.js implements broad-phase collision detection using a spatial hash grid (Matter.Grid). The 2D world coordinate space is mathematically sliced into a uniform matrix of rectangular cells, or "buckets."

Each cell has a predefined width and height. Instead of storing exact geometric boundaries, the grid only tracks the presence of bodies within these spatial regions.

Step-by-Step Execution of the Grid Algorithm

1. Bounding Box Calculation (AABB)

Before interacting with the grid, Matter.js calculates an Axis-Aligned Bounding Box (AABB) for every active physics body. An AABB is a non-rotated rectangle defined simply by minimum and maximum coordinates: (min.x, min.y) and (max.x, max.y).

2. Cell Key Mapping

Using the AABB coordinates and the configured cell dimensions, the algorithm determines which grid coordinates the body spans:

3. Bucket Insertion

Matter.js iterates through the computed column and row ranges. The body reference is placed into the corresponding grid cells. If a body is small, it might reside in a single cell; if it is large or overlaps a boundary, it is inserted into multiple adjacent cells.

4. Pair Generation and Deduplication

Once all bodies are mapped to their respective cells, the engine iterates through each occupied cell to generate collision pairs:

5. Transition to Narrow-Phase

Once the grid traversal completes, the resulting unique set of candidate pairs is handed off to the narrow-phase algorithm. The narrow-phase then performs exact vertex, edge, and SAT calculations on this drastically reduced subset.

Dynamic Grid Updates

At each engine update step (tick):

Strengths and Limitations