Пример #1
0
        /// <summary>
        /// Converts an orthonormal matrix to axis angle representation.
        /// </summary>
        /// <param name="axis">Axis around which the rotation is performed.</param>
        /// <param name="angle">Amount of rotation.</param>
        public void ToAxisAngle(out Vector3 axis, out Degree angle)
        {
            float  trace   = m00 + m11 + m22;
            float  cos     = 0.5f * (trace - 1.0f);
            Radian radians = MathEx.Acos(cos);  // In [0, PI]

            angle = radians.Degrees;

            if (radians > 0.0f)
            {
                if (radians < MathEx.Pi)
                {
                    axis.x = m21 - m12;
                    axis.y = m02 - m20;
                    axis.z = m10 - m01;

                    axis.Normalize();
                }
                else
                {
                    // Angle is PI
                    float halfInverse;
                    if (m00 >= m11)
                    {
                        // r00 >= r11
                        if (m00 >= m22)
                        {
                            // r00 is maximum diagonal term
                            axis.x      = 0.5f * MathEx.Sqrt(m00 - m11 - m22 + 1.0f);
                            halfInverse = 0.5f / axis.x;
                            axis.y      = halfInverse * m01;
                            axis.z      = halfInverse * m02;
                        }
                        else
                        {
                            // r22 is maximum diagonal term
                            axis.z      = 0.5f * MathEx.Sqrt(m22 - m00 - m11 + 1.0f);
                            halfInverse = 0.5f / axis.z;
                            axis.x      = halfInverse * m02;
                            axis.y      = halfInverse * m12;
                        }
                    }
                    else
                    {
                        // r11 > r00
                        if (m11 >= m22)
                        {
                            // r11 is maximum diagonal term
                            axis.y      = 0.5f * MathEx.Sqrt(m11 - m00 - m22 + 1.0f);
                            halfInverse = 0.5f / axis.y;
                            axis.x      = halfInverse * m01;
                            axis.z      = halfInverse * m12;
                        }
                        else
                        {
                            // r22 is maximum diagonal term
                            axis.z      = 0.5f * MathEx.Sqrt(m22 - m00 - m11 + 1.0f);
                            halfInverse = 0.5f / axis.z;
                            axis.x      = halfInverse * m02;
                            axis.y      = halfInverse * m12;
                        }
                    }
                }
            }
            else
            {
                // The angle is 0 and the matrix is the identity.  Any axis will
                // work, so just use the x-axis.
                axis.x = 1.0f;
                axis.y = 0.0f;
                axis.z = 0.0f;
            }
        }
Пример #2
0
 /// <summary>
 /// Calculates the magnitude of the provided vector.
 /// </summary>
 /// <param name="v">Vector to calculate the magnitude for.</param>
 /// <returns>Magnitude of the vector.</returns>
 public static float Magnitude(Vector2 v)
 {
     return(MathEx.Sqrt(v.x * v.x + v.y * v.y));
 }
Пример #3
0
        /// <summary>
        /// Decomposes the matrix into a set of values.
        /// </summary>
        /// <param name="matQ">Columns form orthonormal bases. If your matrix is affine and doesn't use non-uniform scaling
        /// this matrix will be the rotation part of the matrix.
        /// </param>
        /// <param name="vecD">If the matrix is affine these will be scaling factors of the matrix.</param>
        /// <param name="vecU">If the matrix is affine these will be shear factors of the matrix.</param>
        public void QDUDecomposition(out Matrix3 matQ, out Vector3 vecD, out Vector3 vecU)
        {
            matQ = new Matrix3();
            vecD = new Vector3();
            vecU = new Vector3();

            // Build orthogonal matrix Q
            float invLength = MathEx.InvSqrt(m00 * m00 + m10 * m10 + m20 * m20);

            matQ.m00 = m00 * invLength;
            matQ.m10 = m10 * invLength;
            matQ.m20 = m20 * invLength;

            float dot = matQ.m00 * m01 + matQ.m10 * m11 + matQ.m20 * m21;

            matQ.m01 = m01 - dot * matQ.m00;
            matQ.m11 = m11 - dot * matQ.m10;
            matQ.m21 = m21 - dot * matQ.m20;

            invLength = MathEx.InvSqrt(matQ.m01 * matQ.m01 + matQ.m11 * matQ.m11 + matQ.m21 * matQ.m21);
            matQ.m01 *= invLength;
            matQ.m11 *= invLength;
            matQ.m21 *= invLength;

            dot      = matQ.m00 * m02 + matQ.m10 * m12 + matQ.m20 * m22;
            matQ.m02 = m02 - dot * matQ.m00;
            matQ.m12 = m12 - dot * matQ.m10;
            matQ.m22 = m22 - dot * matQ.m20;

            dot       = matQ.m01 * m02 + matQ.m11 * m12 + matQ.m21 * m22;
            matQ.m02 -= dot * matQ.m01;
            matQ.m12 -= dot * matQ.m11;
            matQ.m22 -= dot * matQ.m21;

            invLength = MathEx.InvSqrt(matQ.m02 * matQ.m02 + matQ.m12 * matQ.m12 + matQ.m22 * matQ.m22);
            matQ.m02 *= invLength;
            matQ.m12 *= invLength;
            matQ.m22 *= invLength;

            // Guarantee that orthogonal matrix has determinant 1 (no reflections)
            float fDet = matQ.m00 * matQ.m11 * matQ.m22 + matQ.m01 * matQ.m12 * matQ.m20 +
                         matQ.m02 * matQ.m10 * matQ.m21 - matQ.m02 * matQ.m11 * matQ.m20 -
                         matQ.m01 * matQ.m10 * matQ.m22 - matQ.m00 * matQ.m12 * matQ.m21;

            if (fDet < 0.0f)
            {
                matQ.m00 = -matQ.m00;
                matQ.m01 = -matQ.m01;
                matQ.m02 = -matQ.m02;
                matQ.m10 = -matQ.m10;
                matQ.m11 = -matQ.m11;
                matQ.m12 = -matQ.m12;
                matQ.m20 = -matQ.m20;
                matQ.m21 = -matQ.m21;
                matQ.m21 = -matQ.m22;
            }

            // Build "right" matrix R
            Matrix3 matRight = new Matrix3();

            matRight.m00 = matQ.m00 * m00 + matQ.m10 * m10 + matQ.m20 * m20;
            matRight.m01 = matQ.m00 * m01 + matQ.m10 * m11 + matQ.m20 * m21;
            matRight.m11 = matQ.m01 * m01 + matQ.m11 * m11 + matQ.m21 * m21;
            matRight.m02 = matQ.m00 * m02 + matQ.m10 * m12 + matQ.m20 * m22;
            matRight.m12 = matQ.m01 * m02 + matQ.m11 * m12 + matQ.m21 * m22;
            matRight.m22 = matQ.m02 * m02 + matQ.m12 * m12 + matQ.m22 * m22;

            // The scaling component
            vecD[0] = matRight.m00;
            vecD[1] = matRight.m11;
            vecD[2] = matRight.m22;

            // The shear component
            float invD0 = 1.0f / vecD[0];

            vecU[0] = matRight.m01 * invD0;
            vecU[1] = matRight.m02 * invD0;
            vecU[2] = matRight.m12 / vecD[1];
        }
Пример #4
0
        /// <summary>
        /// Calculates the distance between two points.
        /// </summary>
        /// <param name="a">First two dimensional point.</param>
        /// <param name="b">Second two dimensional point.</param>
        /// <returns>Distance between the two points.</returns>
        public static float Distance(Vector2 a, Vector2 b)
        {
            Vector2 vector2 = new Vector2(a.x - b.x, a.y - b.y);

            return(MathEx.Sqrt(vector2.x * vector2.x + vector2.y * vector2.y));
        }