Matter.js Bounds for Rotating Rectangular Bodies
This article provides an overview of how the 2D physics engine Matter.js calculates and updates the bounding area of a rectangular body undergoing rotation. In Matter.js, a body's bounds do not rotate with its geometry; instead, the engine continuously recomputes an Axis-Aligned Bounding Box (AABB) that encapsulates the body's rotated vertices. Understanding this distinction clarifies how Matter.js optimizes broadphase collision detection while maintaining precise collision resolution during physics simulations.
Vertices vs. Bounding Boxes
In Matter.js, a rectangular body is physically defined by a
collection of four coordinate points called vertices. When
a rectangular body rotates, the engine updates its angle
property and applies a 2D rotation matrix to these vertices around the
body’s center of mass (body.position). As a result, the
vertices reflect the exact geometric orientation of the rectangle at any
given moment.
However, the body.bounds property does not represent the
rotated shape itself. Instead, body.bounds always
represents an Axis-Aligned Bounding Box (AABB). An AABB is a
non-rotatable rectangle whose edges remain strictly parallel to the
global X and Y coordinate axes.
How Bounds Are Calculated During Rotation
Whenever a body changes its position or angle, Matter.js recalculates
the bounds using internal methods (primarily via
Matter.Bounds.update). The engine determines the new bounds
through the following steps:
- Vertex Transformation: The four corners of the rectangle are translated and rotated to their absolute world coordinates.
- Min/Max Evaluation: The engine iterates over the
transformed vertices to locate the extreme coordinates:
min.x: The lowest X-coordinate among all vertices.max.x: The highest X-coordinate among all vertices.min.y: The lowest Y-coordinate among all vertices.max.y: The highest Y-coordinate among all vertices.
- Bounding Box Assignment: These minimum and maximum
values form the corners of
body.bounds:(min.x, min.y)and(max.x, max.y).
Because the bounding box must encompass all rotated corners while
remaining aligned to the screen axes, the width and height of
body.bounds dynamically change. For example, a rectangle
rotated by 45 degrees produces a significantly larger AABB than the same
rectangle standing upright at 0 degrees.
Role in the Collision Pipeline
Matter.js uses a two-phase collision detection system, and the dynamic AABB is essential to its performance:
- Broadphase Collision Detection: Before running
complex mathematical calculations, Matter.js checks whether the
body.boundsof two objects overlap. Testing overlap between axis-aligned boxes is computationally trivial (requiring simple comparisons of min and max values). If the bounds do not intersect, the engine discards the pair immediately. - Narrowphase Collision Detection: If the expanding
AABB overlaps with another body's bounds, Matter.js proceeds to
narrowphase detection. In this phase, the engine uses the Separating
Axis Theorem (SAT) on the actual rotated
vertices. SAT ensures that collisions, contact points, and penetration depths are accurately calculated based on the true rectangular geometry, preventing false collisions that might otherwise be caused by the enlarged AABB.