Recursive AI

Inertia tensors and principal axes

All onemath recipes

Build the mass properties of a body from parts with OneMath: solid shapes, a combined center of mass and inertia tensor, and its principal axes, with the same bits on every platform.

A body made of a 2 kg box and a 1 kg ball, offset from each other:

C#
using RecursiveAI.OneMath;
using RecursiveAI.OneMath.Physics;
 
// A body made of two parts: a 2 kg box and a 1 kg sphere offset along x.
var box = new MassPropertiesD(2, new Vector3D(0, 0, 0), InertiaD.SolidBox(2, new Vector3D(1, 0.5, 0.25)));
var ball = new MassPropertiesD(1, new Vector3D(1.5, 0.5, 0), InertiaD.SolidSphere(1, 0.4));
 
MassPropertiesD body = InertiaD.Combine([box, ball]);
Console.WriteLine($"mass {body.Mass}, center {body.Center}");
Console.WriteLine($"inertia about the center:\n{body.Inertia}");
 
PrincipalAxesD axes = InertiaD.PrincipalAxes(body.Inertia);
Console.WriteLine($"principal moments {axes.Moments}");
Console.WriteLine($"orientation {axes.Orientation}");
Text
mass 3, center (0.5, 0.16666666666666666, 0)
inertia about the center:
[0.43900000000000006, -0.5, 0; -0.5, 2.2723333333333335, 0; 0, 0, 2.564]
principal moments (0.3115029928215277, 2.399830340511806, 2.564)
orientation (0, 0, 0.12451268641694911, 0.9922180158217418)

The pieces

  • InertiaD.SolidBox(mass, halfExtents), SolidSphere(mass, radius) and SolidCylinder (axis along Y, from its mass, radius and half height) give the tensor of a solid about its own center, axes along the shape. InertiaF is the float form.
  • MassPropertiesD(mass, center, inertia) is one part; InertiaD.Combine(parts) returns the total mass, the center of mass and the tensor about that center (parallel-axis shifts included). ShiftToPoint, ShiftToCenter and Rotate are there for doing it by hand.
  • InertiaD.PrincipalAxes(tensor) diagonalizes it: Moments are the principal moments in ascending order, Rotation the axes as a matrix and Orientation the same as a quaternion, with a right-handed frame and fixed signs.

The decomposition is cyclic Jacobi with a written-down order of operations, so the principal frame comes out the same, bit for bit, on every platform. NaN, infinity, a negative mass or a non-symmetric tensor throw an exception naming the field. Details in inertia and eigen decomposition.