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:
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}");
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)andSolidCylinder(axis along Y, from its mass, radius and half height) give the tensor of a solid about its own center, axes along the shape.InertiaFis 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,ShiftToCenterandRotateare there for doing it by hand.InertiaD.PrincipalAxes(tensor)diagonalizes it:Momentsare the principal moments in ascending order,Rotationthe axes as a matrix andOrientationthe 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.