Exemple #1
0
    /// <summary>
    /// Calculates the inertia of the shape relative to the center of mass.
    /// </summary>
    /// <param name="shape"></param>
    /// <param name="centerOfMass"></param>
    /// <param name="inertia">Returns the inertia relative to the center of mass, not to the origin</param>
    /// <returns></returns>
    #region  public static FP CalculateMassInertia(ShapeData shape, out JVector centerOfMass, out JMatrix inertia)
    public static FP CalculateMassInertia(ShapeData shape, out TSVector centerOfMass,
                                          out TSMatrix inertia)
    {
        FP mass = FP.Zero;

        centerOfMass = TSVector.zero; inertia = TSMatrix.Zero;

        if (shape is Multishape)
        {
            throw new ArgumentException("Can't calculate inertia of multishapes.", "shape");
        }

        // build a triangle hull around the shape
        List <TSVector> hullTriangles = new List <TSVector>();

        shape.MakeHull(ref hullTriangles, 3);

        // create inertia of tetrahedron with vertices at
        // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
        FP       a = FP.One / (60 * FP.One), b = FP.One / (120 * FP.One);
        TSMatrix C = new TSMatrix(a, b, b, b, a, b, b, b, a);

        for (int i = 0; i < hullTriangles.Count; i += 3)
        {
            TSVector column0 = hullTriangles[i + 0];
            TSVector column1 = hullTriangles[i + 1];
            TSVector column2 = hullTriangles[i + 2];

            TSMatrix A = new TSMatrix(column0.x, column1.x, column2.x,
                                      column0.y, column1.y, column2.y,
                                      column0.z, column1.z, column2.z);

            FP detA = A.Determinant();

            // now transform this canonical tetrahedron to the target tetrahedron
            // inertia by a linear transformation A
            TSMatrix tetrahedronInertia = TSMatrix.Multiply(A * C * TSMatrix.Transpose(A), detA);

            TSVector tetrahedronCOM  = (FP.One / (4 * FP.One)) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
            FP       tetrahedronMass = (FP.One / (6 * FP.One)) * detA;

            inertia      += tetrahedronInertia;
            centerOfMass += tetrahedronMass * tetrahedronCOM;
            mass         += tetrahedronMass;
        }

        inertia      = TSMatrix.Multiply(TSMatrix.Identity, inertia.Trace()) - inertia;
        centerOfMass = centerOfMass * (FP.One / mass);

        FP x = centerOfMass.x;
        FP y = centerOfMass.y;
        FP z = centerOfMass.z;

        // now translate the inertia by the center of mass
        TSMatrix t = new TSMatrix(
            -mass * (y * y + z * z), mass * x * y, mass * x * z,
            mass * y * x, -mass * (z * z + x * x), mass * y * z,
            mass * z * x, mass * z * y, -mass * (x * x + y * y));

        TSMatrix.Add(ref inertia, ref t, out inertia);

        return(mass);
    }