Пример #1
0
        public static double CalculateMassInertia(Shape shape, out JVector centerOfMass,
            out JMatrix inertia)
        {
            double mass = 0.0f;
            centerOfMass = JVector.Zero; inertia = JMatrix.Zero;

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

            // build a triangle hull around the shape
            List<JVector> hullTriangles = new List<JVector>();
            shape.MakeHull(ref hullTriangles, 3);

            // create inertia of tetrahedron with vertices at
            // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
            double a = 1.0f / 60.0f, b = 1.0f / 120.0f;
            JMatrix C = new JMatrix(a, b, b, b, a, b, b, b, a);

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

                JMatrix A = new JMatrix(column0.X, column1.X, column2.X,
                    column0.Y, column1.Y, column2.Y,
                    column0.Z, column1.Z, column2.Z);

                double detA = A.Determinant();

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

                JVector tetrahedronCOM = (1.0f / 4.0f) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
                double tetrahedronMass = (1.0f / 6.0f) * detA;

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

            inertia = JMatrix.Multiply(JMatrix.Identity, inertia.Trace()) - inertia;
            centerOfMass = centerOfMass * (1.0f / mass);

            double x = centerOfMass.X;
            double y = centerOfMass.Y;
            double z = centerOfMass.Z;

            // now translate the inertia by the center of mass
            JMatrix t = new JMatrix(
                -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));

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

            return mass;
        }
Пример #2
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 float CalculateMassInertia(Shape shape, out JVector centerOfMass, out JMatrix inertia)
        public static float CalculateMassInertia(Shape shape, out Vector3 centerOfMass,
                                                 out Matrix3x3 inertia)
        {
            float mass = 0.0f;

            centerOfMass = Vector3.zero; inertia = Matrix3x3.Zero;

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

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

            shape.MakeHull(ref hullTriangles, 3);

            // create inertia of tetrahedron with vertices at
            // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
            float     a = 1.0f / 60.0f, b = 1.0f / 120.0f;
            Matrix3x3 C = new Matrix3x3(a, b, b, b, a, b, b, b, a);

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

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

                float detA = A.Determinant();

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

                Vector3 tetrahedronCOM  = (1.0f / 4.0f) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
                float   tetrahedronMass = (1.0f / 6.0f) * detA;

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

            inertia      = Matrix3x3.Multiply(Matrix3x3.Identity, inertia.Trace()) - inertia;
            centerOfMass = centerOfMass * (1.0f / mass);

            float x = centerOfMass.x;
            float y = centerOfMass.y;
            float z = centerOfMass.z;

            // now translate the inertia by the center of mass
            Matrix3x3 t = new Matrix3x3(
                -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));

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

            return(mass);
        }
Пример #3
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 float CalculateMassInertia(Shape shape, out JVector centerOfMass, out JMatrix inertia)
        public static float CalculateMassInertia(Shape shape, out JVector centerOfMass,
                                                 out JMatrix inertia)
        {
            float mass = 0.0f;

            centerOfMass = JVector.Zero; inertia = JMatrix.Zero;

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

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

            shape.MakeHull(ref hullTriangles, 3);

            // create inertia of tetrahedron with vertices at
            // (0,0,0) (1,0,0) (0,1,0) (0,0,1)
            float   a = 1.0f / 60.0f, b = 1.0f / 120.0f;
            JMatrix C = new JMatrix(a, b, b, b, a, b, b, b, a);

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

                JMatrix A = new JMatrix(column0.X, column1.X, column2.X,
                                        column0.Y, column1.Y, column2.Y,
                                        column0.Z, column1.Z, column2.Z);

                float detA = A.Determinant();

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

                JVector tetrahedronCOM  = (1.0f / 4.0f) * (hullTriangles[i + 0] + hullTriangles[i + 1] + hullTriangles[i + 2]);
                float   tetrahedronMass = (1.0f / 6.0f) * detA;

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

            inertia      = JMatrix.Multiply(JMatrix.Identity, inertia.Trace()) - inertia;
            centerOfMass = centerOfMass * (1.0f / mass);

            float x = centerOfMass.X;
            float y = centerOfMass.Y;
            float z = centerOfMass.Z;

            // now translate the inertia by the center of mass
            JMatrix t = new JMatrix(
                -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));

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

            return(mass);
        }