How Does Planck.js Calculate Polygon Center of Mass?

Planck.js—a 2D physics engine rewritten from Box2D in JavaScript—calculates the center of mass for irregular, rigid polygon shapes using geometric decomposition and a weighted average of individual triangular masses. Because rigid body simulations require an accurate center of mass to compute rotational inertia, forces, and torques, the engine cannot rely on a simple bounding box average. Instead, it breaks down any complex, convex polygon into a series of triangles, calculates the center of mass (centroid) for each triangle, and computes a weighted average based on the area of those triangles to find the true center of mass.

Geometric Decomposition into Triangles

An irregular polygon’s center of mass cannot be determined by a single standard formula. Planck.js solves this by treating the polygon as a collection of adjacent triangles sharing a common origin point, usually the first vertex (\(v_0\)) or the global origin \((0,0)\).

For a polygon with \(n\) vertices, the engine iterates through the vertices to form \(n-2\) triangles. For each triangle formed by the origin and two adjacent vertices, two main properties are calculated:

The Mathematical Weighted Average

Once the individual centroids and areas are established, Planck.js uses a weighted average formula to combine them. Assuming uniform density across the shape, area is directly proportional to mass.

The coordinates for the overall center of mass (\(C\)) are calculated using the following equations:

\[C_x = \frac{\sum (Area_i \cdot Centroid_{ix})}{\sum Area_i}\]

\[C_y = \frac{\sum (Area_i \cdot Centroid_{iy})}{\sum Area_i}\]

In this calculation, \(\sum Area_i\) represents the total area of the polygon. If a polygon’s vertices are wound in a specific direction (clockwise versus counter-clockwise), the cross product handles the signed area automatically, ensuring the math balances out correctly even for complex convex shapes.

Code Execution in Planck.js

During the initialization of a PolygonShape in Planck.js, the engine automatically triggers an internal method to compute these mass properties. This method loops through the vertex array, performs the vector cross products, accumulates the total area, and updates the shape’s local centroid property.

When this shape is attached to a Body object, the body reads this local centroid and shifts its internal coordinate system so that the body’s local origin \((0,0)\) aligns perfectly with this calculated center of mass. This alignment ensures that when forces are applied to the body, it rotates naturally around its true physical center.