Matter.js Center of Mass for Irregular Polygons

Calculating the center of mass—also known as the centroid—for an irregular polygon is essential when building realistic 2D physics simulations. In Matter.js, the physics engine automatically aligns a rigid body's position with its center of mass, but calculating this manually is often required for custom rendering, offset adjustments, or pre-processing shape data. This article explains how to utilize Matter.js helper methods, specifically within the Vertices module, to compute the center of mass of any arbitrary set of points quickly and accurately.

The Vertices.centre Method

Matter.js provides a built-in helper method, Matter.Vertices.centre(vertices), specifically designed to calculate the geometric center of mass of a polygon defined by an array of vertex coordinates.

To use this method, define the irregular polygon as an array of vector objects, with each object containing x and y coordinates:

const { Vertices } = Matter;

const irregularPolygon = [
  { x: 0, y: 0 },
  { x: 50, y: 20 },
  { x: 80, y: 80 },
  { x: 30, y: 100 },
  { x: -20, y: 60 }
];

const centerOfMass = Vertices.centre(irregularPolygon);
console.log(centerOfMass); // Returns { x, y }

The Vertices.centre() function evaluates the signed area and edge distribution of the polygon, returning a vector { x, y } that represents the true geometric center of mass.

Normalizing Vertices Around the Centroid

When working with physics bodies, it is common practice to center the vertex data around (0, 0) so that rotations behave predictably around the object's origin. You can pair Vertices.centre() with Vertices.translate() to zero-center an irregular shape:

const com = Vertices.centre(irregularPolygon);

// Shift vertices so that the center of mass is positioned at (0, 0)
Vertices.translate(irregularPolygon, { x: -com.x, y: -com.y });

Integration with Bodies.fromVertices

When creating a rigid body directly using Matter.Bodies.fromVertices(), Matter.js automatically invokes these calculations internally:

const { Bodies } = Matter;

const body = Bodies.fromVertices(xPosition, yPosition, [irregularPolygon]);

In this process, Matter.js calculates the center of mass and translates the vertices so the center of mass aligns exactly with the (xPosition, yPosition) world coordinates supplied to the constructor.

Important Considerations for Accurate Results

  1. Winding Order: Vertices should be ordered sequentially around the perimeter (typically clockwise). Unordered or self-intersecting point clouds will produce incorrect area calculations, leading to an invalid center of mass.
  2. Concave Geometry: For concave polygons, Vertices.centre() still calculates the correct centroid across the perimeter. However, if the shape is being converted into a physics body, ensure the poly-decomp.js library is installed and available globally, as Matter.js requires convex decomposition to simulate irregular concave shapes correctly.