Calculate Composite Bounding Box in Matter.js
This article explains how to determine the total axis-aligned
bounding box (AABB) for a Composite in the Matter.js
physics engine. While individual physics bodies have pre-calculated
bounds properties, composites act as containers and do not
track an aggregate boundary automatically. By retrieving all nested
bodies within the composite and calculating the extremes of their
individual bounds, you can reliably derive the total encompassing
bounding box.
Why Composites Lack Built-In Bounds
A Matter.js Composite can contain bodies, constraints,
and other nested composites. Because the positions of these child
objects are dynamic and can change on every engine update, Matter.js
does not maintain a cached, overall boundary for composites to conserve
computational performance. To find the total boundary, you must
aggregate the bounds of every individual body inside the
composite hierarchy.
Step-by-Step Implementation
To compute the total bounding box, retrieve all descendant bodies
using Matter.Composite.allBodies() and iterate through them
to find the minimum and maximum X and Y coordinates.
function getCompositeBounds(composite) {
const bodies = Matter.Composite.allBodies(composite);
if (bodies.length === 0) {
return {
min: { x: 0, y: 0 },
max: { x: 0, y: 0 }
};
}
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;
for (let i = 0; i < bodies.length; i++) {
const bounds = bodies[i].bounds;
if (bounds.min.x < minX) minX = bounds.min.x;
if (bounds.min.y < minY) minY = bounds.min.y;
if (bounds.max.x > maxX) maxX = bounds.max.x;
if (bounds.max.y > maxY) maxY = bounds.max.y;
}
return {
min: { x: minX, y: minY },
max: { x: maxX, y: maxY }
};
}How the Calculation Works
- Retrieve Bodies Recursively:
Matter.Composite.allBodies(composite)traverses the given composite and any child composites, returning a flat array of all containedBodyobjects. - Handle Empty Containers: If the composite contains no bodies, the function safely returns a zero-sized boundary.
- Compare Coordinates: Each
Bodyin Matter.js maintains aboundsproperty containingminandmaxvectors ({ x, y }). Iterating through the array finds the lowestminvalues and highestmaxvalues across all elements. - Derive Dimensions: With the returned
{ min, max }object, you can easily calculate the total width and height of the composite:width = bounds.max.x - bounds.min.xheight = bounds.max.y - bounds.min.y
This calculation should be executed after
Matter.Engine.update() whenever current, physics-accurate
bounds are required.