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 Centroid: The geometric center of a triangle is the average of its three vertices.
- The Area (Weight): The area of each triangle is computed using the cross product of its edge vectors, which acts as the “weight” for that specific section of the shape.
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.