Why Matter.js Requires Poly-Decomposition
Matter.js relies on collision detection algorithms that are mathematically optimized exclusively for convex polygons. When developers introduce complex, concave shapes with inward indentations or hollows, the engine cannot calculate physical collisions accurately without preprocessing. To resolve this limitation, Matter.js requires a poly-decomposition library to break complex concave geometries down into sets of simpler convex sub-polygons that its collision pipeline can handle.
The Mathematical Limitation: Convex vs. Concave
In 2D physics engines, polygons are classified as either convex or concave:
- Convex Polygons: Any straight line drawn between two points inside the shape remains entirely within the shape. None of the internal angles exceed 180 degrees.
- Concave Polygons: The shape contains "caves" or inward indentations where internal angles exceed 180 degrees. A straight line between two internal points can pass outside the shape's boundaries.
Matter.js uses the Separating Axis Theorem (SAT) for collision detection. SAT states that if two convex shapes are not penetrating each other, a line (axis) can be drawn between them onto which their projections do not overlap.
SAT relies entirely on the geometry of convex hulls. When SAT is applied directly to a concave shape, the algorithm creates a false "convex hull" over the indentations, effectively treating hollow or indented areas as solid mass. This causes objects to bounce off empty spaces where the indentations exist.
How Poly-Decomposition Solves the Problem
Poly-decomposition algorithms (such as Bayazit's algorithm or Hertel-Mehlhorn) analyze the vertices of a concave polygon, identify the reflex vertices (internal angles greater than 180 degrees), and draw internal dividing lines. This process dissects the single complex shape into a minimal set of non-overlapping convex parts.
When you pass concave coordinates or an SVG path to Matter.js
alongside an integrated poly-decomposition library (such as
poly-decomp), the engine performs the following steps:
- Decomposition: The external library receives the raw vertex array and calculates the convex sub-polygons.
- Compound Body Creation: Matter.js takes each
resulting convex polygon and groups them into a single
Compound Body. - Collision Resolution: Matter.js runs SAT across the individual convex components. Because each sub-part is convex, SAT functions correctly, allowing other bodies to enter the indentations of the overarching shape without false collisions.
Why Poly-Decomposition Is Not Built In
Matter.js leaves poly-decomposition to an external library primarily to keep the engine's core bundle size lightweight. Polygon decomposition algorithms are computationally intensive and mathematically complex, involving extensive geometric calculation.
Since many 2D physics simulations only require primitives (rectangles, circles) or strictly convex polygons, bundling a decomposition engine natively would add unnecessary overhead for users who do not require complex, arbitrary geometry. Keeping it as a pluggable dependency provides modular flexibility without bloating the core engine.