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

  1. Retrieve Bodies Recursively: Matter.Composite.allBodies(composite) traverses the given composite and any child composites, returning a flat array of all contained Body objects.
  2. Handle Empty Containers: If the composite contains no bodies, the function safely returns a zero-sized boundary.
  3. Compare Coordinates: Each Body in Matter.js maintains a bounds property containing min and max vectors ({ x, y }). Iterating through the array finds the lowest min values and highest max values across all elements.
  4. 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.x
    • height = bounds.max.y - bounds.min.y

This calculation should be executed after Matter.Engine.update() whenever current, physics-accurate bounds are required.