Initializing 3D Canvas...

Centroid And Moments

2 min read1 page

Knowing the volume of an object isn't enough for physics simulations; we also need to know exactly where that volume is located. The Centroid is the mathematical center of an object's geometry.

Area vs Volume Centroids:

1. Area Centroid: Treats the object as a hollow, infinitely thin shell. The center balances the surface area. 2. Volume Centroid (Center of Mass): Treats the object as a completely solid, uniform material. The center balances the 3D volume. 3. For complex, non-symmetrical shapes, these two points will be in different locations!
python
1# Center of Mass vs Area Centroid
2def calculate_properties(mesh):
3 """Why solid density matters."""
4
5 # Area Centroid assumes the mesh is a hollow shell (like an empty balloon)
6 # The "weight" is purely on the surface.
7 area_centroid = calculate_area_centroid(mesh)
8
9 # Volume Centroid (Center of Mass) assumes the mesh is solid all the way through
10 # (like a block of cheese).
11 volume_centroid = calculate_volume_centroid(mesh)
12
13 return area_centroid, volume_centroid
Distribution (Hollow/Solid)
0.00
2 min read1 page

To find the Area Centroid of a complex mesh, we break the problem down to individual triangles. First, we find the centroid of each triangle (which is simply the average of its 3 vertices).

Weighted Average:

1. Find the center of every triangle. 2. Calculate the surface area of every triangle. 3. A large triangle has more "pull" on the final center than a tiny triangle. We multiply each center point by its area to create a Weighted Sum. 4. Finally, divide by the total surface area.
python
1# Calculating Area Centroid
2def get_area_centroid(mesh):
3 """Calculates the geometric center of the surface."""
4
5 total_area = 0.0
6 weighted_centroid_sum = Vector3(0,0,0)
7
8 for face in mesh.faces:
9 v0, v1, v2 = get_vertices(mesh, face)
10
11 # 1. Calculate the center point of this specific triangle
12 tri_center = (v0 + v1 + v2) / 3.0
13
14 # 2. Calculate the area of this triangle
15 tri_area = calculate_triangle_area(v0, v1, v2)
16
17 # 3. Multiply the center by the area (Weighted Sum)
18 weighted_centroid_sum += (tri_center * tri_area)
19 total_area += tri_area
20
21 # 4. Divide the total weighted sum by the total area
22 final_centroid = weighted_centroid_sum / total_area
23
24 return final_centroid
Algorithm Step
0.00
2 min read1 page

To find the true 3D Center of Mass (Volume Centroid), we use the exact same strategy as the Area Centroid, but we use Volume instead of Area. We start by projecting every triangle to the Origin to form Tetrahedrons.

Tetrahedron Center:

1. A Tetrahedron has 4 vertices: v0, v1, v2 and the Origin (0,0,0). 2. The geometric center of a tetrahedron is the average of its 4 vertices. 3. Because one vertex is (0,0,0), the formula simplifies to (v0 + v1 + v2) / 4.
python
1# Tetrahedron Centroid
2def get_tetrahedron_centroid(v0, v1, v2):
3 """Calculates the center of mass of a tetrahedron originating at (0,0,0)."""
4
5 # A tetrahedron has 4 vertices: The origin (0,0,0) and the 3 triangle vertices.
6 # The centroid of a tetrahedron is simply the average of its 4 vertices.
7
8 # Since the origin is (0,0,0), we just add v0+v1+v2 and divide by 4.
9 centroid = (v0 + v1 + v2) / 4.0
10
11 return centroid
Show (Tetrahedron/Centroid)
0.00
3 min read1 page

Just like with Area, we take the Weighted Average of every Tetrahedron. The elegant part of this algorithm is that because the Tetrahedron Volumes are Signed (+ or -), the Negative tetrahedrons automatically subtract their "weight" from the empty space, leaving us with the exact Center of Mass of the solid object.

Signed Weighting:

1. Calculate the Signed Volume and Centroid of every Tetrahedron. 2. Multiply the Centroid by the Signed Volume. 3. Sum all these weighted vectors. 4. Divide by the total Volume.
python
1# Calculating Volume Centroid
2def get_volume_centroid(mesh):
3 """Calculates the Center of Mass of a solid mesh."""
4
5 total_volume = 0.0
6 weighted_centroid_sum = Vector3(0,0,0)
7
8 for face in mesh.faces:
9 v0, v1, v2 = get_vertices(mesh, face)
10
11 # 1. Calculate Signed Tetrahedron Volume
12 tet_vol = calculate_signed_volume(v0, v1, v2)
13
14 # 2. Calculate Tetrahedron Centroid
15 tet_center = (v0 + v1 + v2) / 4.0
16
17 # 3. Add to the Weighted Sum
18 # Note: tet_vol can be negative! This perfectly subtracts
19 # the center-of-mass contribution of the empty space.
20 weighted_centroid_sum += (tet_center * tet_vol)
21 total_volume += tet_vol
22
23 # 4. Divide sum by total volume
24 final_centroid = weighted_centroid_sum / total_volume
25
26 return final_centroid
Integration (Box/Tetrahedrons/Center of Mass)
0.00
3 min read1 page

If you push an object, the Center of Mass tells you how it accelerates. But if you spin an object, you need to know its Moments of Inertia. This describes how resistant the object is to rotation around different axes.

Rotational Resistance:

1. Translate the entire mesh so that the Center of Mass is exactly at (0,0,0). 2. For every tetrahedron, integrate the square of the distance from the axis of rotation. 3. Mass that is far away from the axis creates a high moment of inertia (hard to spin). 4. Mass close to the axis creates a low moment of inertia (easy to spin, like an ice skater pulling their arms in).
python
1# Calculating Moments of Inertia
2def get_inertia_tensor(mesh, center_of_mass):
3 """Calculates rotational resistance around the X, Y, and Z axes."""
4
5 Ixx = Iyy = Izz = 0.0
6
7 for face in mesh.faces:
8 v0, v1, v2 = get_vertices(mesh, face)
9
10 # Move vertices relative to the Center of Mass
11 v0 -= center_of_mass
12 v1 -= center_of_mass
13 v2 -= center_of_mass
14
15 # Calculate volume of this tetrahedron
16 vol = calculate_signed_volume(v0, v1, v2)
17
18 # Integrate (y^2 + z^2) for Ixx, (x^2 + z^2) for Iyy, etc.
19 # This requires expanding a complex polynomial over the tetrahedron domain
20 Ixx += integrate_tetrahedron_inertia(v0, v1, v2, vol, axis='X')
21 Iyy += integrate_tetrahedron_inertia(v0, v1, v2, vol, axis='Y')
22 Izz += integrate_tetrahedron_inertia(v0, v1, v2, vol, axis='Z')
23
24 return Matrix3x3(Ixx, 0, 0, 0, Iyy, 0, 0, 0, Izz)
Shape (Sphere/Cylinder/Bar)
0.00
2 min read1 page

Inertia calculated along the world X, Y, and Z axes isn't very useful if the object is rotated diagonally! To find the true, natural spinning axes of a shape, we must calculate its Principal Axes.

Eigenvalue Decomposition:

1. The Inertia Tensor forms a 3x3 symmetric matrix. 2. Through Linear Algebra, we extract its Eigenvectors. 3. These vectors form a new, custom XYZ coordinate system perfectly aligned to the object's mass distribution. 4. An object thrown through the air will naturally want to spin stably around its Major or Minor principal axes!
python
1# Finding Principal Axes (Eigenvectors)
2def get_principal_axes(inertia_tensor):
3 """Calculates the natural spinning axes of the object."""
4
5 # 1. The inertia tensor is a 3x3 Symmetric Matrix.
6 # 2. We calculate its Eigenvalues and Eigenvectors.
7 eigenvalues, eigenvectors = calculate_eigen(inertia_tensor)
8
9 # Eigenvalues = The Principal Moments of Inertia (scalars)
10 # Eigenvectors = The Principal Axes (3 orthogonal 3D vectors)
11
12 # Sort them by magnitude (Major, Mid, Minor axes)
13 sorted_axes = sort_by_eigenvalue(eigenvalues, eigenvectors)
14
15 return sorted_axes
Rotate Object
0.00
2 min read1 page

Knowing the Principal Axes allows engineers to predict how an object will tumble in zero gravity (or when thrown in the air). The Tennis Racket Theorem (Dzhanibekov Effect) proves that an object will spin stably around its Major and Minor inertia axes, but spinning it around its Intermediate axis is fundamentally chaotic and unstable.

Rotational Stability:

1. Minor Axis: (e.g. spinning a football in a spiral). Stable. 2. Major Axis: (e.g. spinning a football end-over-end). Stable. 3. Intermediate Axis: Unstable! The object will periodically flip itself upside down mid-spin.
python
1# Dzhanibekov Effect (Tennis Racket Theorem)
2def simulate_spin(inertia_tensor, initial_angular_velocity):
3 """Why spinning around the middle axis is unstable."""
4
5 # 1. Get the Principal Axes (Major, Mid, Minor)
6 axes = get_principal_axes(inertia_tensor)
7
8 # 2. Physics shows that rotating around the Major (highest inertia)
9 # and Minor (lowest inertia) axes is perfectly stable.
10
11 # 3. Rotating around the Intermediate (Mid) axis is mathematically unstable!
12 # A tiny perturbation will cause the object to flip 180 degrees back and forth.
13
14 return apply_rigid_body_dynamics(axes, initial_angular_velocity)
Spin Axis (Minor/Major/Mid)
0.00
Play Simulation
1.00