Beispiel #1
0
 /// <summary>
 /// Creates a MatrixD that scales along the x-axis, y-axis, and y-axis.
 /// </summary>
 /// <param name="x">Scaling factor that is applied along the x-axis.</param>
 /// <param name="y">Scaling factor that is applied along the y-axis.</param>
 /// <param name="z">Scaling factor that is applied along the z-axis.</param>
 /// <param name="result">When the method completes, contains the created scaling MatrixD.</param>
 public static void Scaling(double x, double y, double z, out MatrixD result)
 {
     result = MatrixD.Identity;
     result.M11 = x;
     result.M22 = y;
     result.M33 = z;
 }
Beispiel #2
0
 /// <summary>
 /// Determines the quotient of two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to divide.</param>
 /// <param name="right">The second MatrixD to divide.</param>
 /// <returns>The quotient of the two matrices.</returns>
 public static MatrixD Divide(MatrixD left, MatrixD right)
 {
     MatrixD result;
     Divide(ref left, ref right, out result);
     return result;
 }
Beispiel #3
0
 /// <summary>
 /// Performs the exponential operation on a MatrixD.
 /// </summary>
 /// <param name="value">The MatrixD to perform the operation on.</param>
 /// <param name="exponent">The exponent to raise the MatrixD to.</param>
 /// <returns>The exponential MatrixD.</returns>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="exponent"/> is negative.</exception>
 public static MatrixD Exponent(MatrixD value, int exponent)
 {
     MatrixD result;
     Exponent(ref value, exponent, out result);
     return result;
 }
Beispiel #4
0
 /// <summary>
 /// Creates a 3D affine transformation MatrixD.
 /// </summary>
 /// <param name="scaling">Scaling factor.</param>
 /// <param name="rotationCenter">The center of the rotation.</param>
 /// <param name="rotation">The rotation of the transformation.</param>
 /// <param name="translation">The translation factor of the transformation.</param>
 /// <param name="result">When the method completes, contains the created affine transformation MatrixD.</param>
 public static void AffineTransformation(double scaling, ref Vector3D rotationCenter, ref Quaternion rotation, ref Vector3D translation, out MatrixD result)
 {
     result = Scaling(scaling) * Translation(-rotationCenter) * RotationQuaternion(rotation) *
         Translation(rotationCenter) * Translation(translation);
 }
Beispiel #5
0
        /// <summary>
        /// Scales a MatrixD by the given value.
        /// </summary>
        /// <param name="left">The MatrixD to scale.</param>
        /// <param name="right">The amount by which to scale.</param>
        /// <param name="result">When the method completes, contains the scaled MatrixD.</param>
        public static void Divide(ref MatrixD left, double right, out MatrixD result)
        {
            double inv = 1.0f / right;

            result.M11 = left.M11 * inv;
            result.M12 = left.M12 * inv;
            result.M13 = left.M13 * inv;
            result.M14 = left.M14 * inv;
            result.M21 = left.M21 * inv;
            result.M22 = left.M22 * inv;
            result.M23 = left.M23 * inv;
            result.M24 = left.M24 * inv;
            result.M31 = left.M31 * inv;
            result.M32 = left.M32 * inv;
            result.M33 = left.M33 * inv;
            result.M34 = left.M34 * inv;
            result.M41 = left.M41 * inv;
            result.M42 = left.M42 * inv;
            result.M43 = left.M43 * inv;
            result.M44 = left.M44 * inv;
        }
Beispiel #6
0
        /// <summary>
        /// Decomposes a MatrixD into an orthonormalized MatrixD Q and a right triangular MatrixD R.
        /// </summary>
        /// <param name="Q">When the method completes, contains the orthonormalized MatrixD of the decomposition.</param>
        /// <param name="R">When the method completes, contains the right triangular MatrixD of the decomposition.</param>
        public void DecomposeQR(out MatrixD Q, out MatrixD R)
        {
            MatrixD temp = this;
            temp.Transpose();
            Orthonormalize(ref temp, out Q);
            Q.Transpose();

            R = new MatrixD();
            R.M11 = Vector4D.Dot(Q.Column1, Column1);
            R.M12 = Vector4D.Dot(Q.Column1, Column2);
            R.M13 = Vector4D.Dot(Q.Column1, Column3);
            R.M14 = Vector4D.Dot(Q.Column1, Column4);

            R.M22 = Vector4D.Dot(Q.Column2, Column2);
            R.M23 = Vector4D.Dot(Q.Column2, Column3);
            R.M24 = Vector4D.Dot(Q.Column2, Column4);

            R.M33 = Vector4D.Dot(Q.Column3, Column3);
            R.M34 = Vector4D.Dot(Q.Column3, Column4);

            R.M44 = Vector4D.Dot(Q.Column4, Column4);
        }
Beispiel #7
0
 /// <summary>
 /// Determines the sum of two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to add.</param>
 /// <param name="right">The second MatrixD to add.</param>
 /// <param name="result">When the method completes, contains the sum of the two matrices.</param>
 public static void Add(ref MatrixD left, ref MatrixD right, out MatrixD result)
 {
     result.M11 = left.M11 + right.M11;
     result.M12 = left.M12 + right.M12;
     result.M13 = left.M13 + right.M13;
     result.M14 = left.M14 + right.M14;
     result.M21 = left.M21 + right.M21;
     result.M22 = left.M22 + right.M22;
     result.M23 = left.M23 + right.M23;
     result.M24 = left.M24 + right.M24;
     result.M31 = left.M31 + right.M31;
     result.M32 = left.M32 + right.M32;
     result.M33 = left.M33 + right.M33;
     result.M34 = left.M34 + right.M34;
     result.M41 = left.M41 + right.M41;
     result.M42 = left.M42 + right.M42;
     result.M43 = left.M43 + right.M43;
     result.M44 = left.M44 + right.M44;
 }
Beispiel #8
0
 /// <summary>
 /// Determines the difference between two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to subtract.</param>
 /// <param name="right">The second MatrixD to subtract.</param>
 /// <param name="result">When the method completes, contains the difference between the two matrices.</param>
 public static void Subtract(ref MatrixD left, ref MatrixD right, out MatrixD result)
 {
     result.M11 = left.M11 - right.M11;
     result.M12 = left.M12 - right.M12;
     result.M13 = left.M13 - right.M13;
     result.M14 = left.M14 - right.M14;
     result.M21 = left.M21 - right.M21;
     result.M22 = left.M22 - right.M22;
     result.M23 = left.M23 - right.M23;
     result.M24 = left.M24 - right.M24;
     result.M31 = left.M31 - right.M31;
     result.M32 = left.M32 - right.M32;
     result.M33 = left.M33 - right.M33;
     result.M34 = left.M34 - right.M34;
     result.M41 = left.M41 - right.M41;
     result.M42 = left.M42 - right.M42;
     result.M43 = left.M43 - right.M43;
     result.M44 = left.M44 - right.M44;
 }
Beispiel #9
0
 /// <summary>
 /// Determines the difference between two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to subtract.</param>
 /// <param name="right">The second MatrixD to subtract.</param>
 /// <returns>The difference between the two matrices.</returns>
 public static MatrixD Subtract(MatrixD left, MatrixD right)
 {
     MatrixD result;
     Subtract(ref left, ref right, out result);
     return result;
 }
Beispiel #10
0
 /// <summary>
 /// Performs a cubic interpolation between two matrices.
 /// </summary>
 /// <param name="start">Start MatrixD.</param>
 /// <param name="end">End MatrixD.</param>
 /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
 /// <param name="result">When the method completes, contains the cubic interpolation of the two matrices.</param>
 public static void SmoothStep(ref MatrixD start, ref MatrixD end, double amount, out MatrixD result)
 {
     amount = MathUtilD.SmoothStep(amount);
     Lerp(ref start, ref end, amount, out result);
 }
Beispiel #11
0
 /// <summary>
 /// Performs a cubic interpolation between two matrices.
 /// </summary>
 /// <param name="start">Start MatrixD.</param>
 /// <param name="end">End MatrixD.</param>
 /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
 /// <returns>The cubic interpolation of the two matrices.</returns>
 public static MatrixD SmoothStep(MatrixD start, MatrixD end, double amount)
 {
     MatrixD result;
     SmoothStep(ref start, ref end, amount, out result);
     return result;
 }
Beispiel #12
0
        /// <summary>
        /// Creates a skew/shear MatrixD by means of a translation vector, a rotation vector, and a rotation angle.
        /// shearing is performed in the direction of translation vector, where translation vector and rotation vector define the shearing plane.
        /// The effect is such that the skewed rotation vector has the specified angle with rotation itself.
        /// </summary>
        /// <param name="angle">The rotation angle.</param>
        /// <param name="rotationVec">The rotation vector</param>
        /// <param name="transVec">The translation vector</param>
        /// <param name="MatrixD">Contains the created skew/shear MatrixD. </param>
        public static void Skew(double angle, ref Vector3D rotationVec, ref Vector3D transVec, out MatrixD MatrixD)
        {
            //http://elckerlyc.ewi.utwente.nl/browser/Elckerlyc/Hmi/HmiMath/src/hmi/math/Mat3f.java
            double MINIMAL_SKEW_ANGLE = 0.000001f;

            Vector3D e0 = rotationVec;
            Vector3D e1 = Vector3D.Normalize(transVec);

            double rv1;
            Vector3D.Dot(ref rotationVec, ref  e1, out rv1);
            e0 += rv1 * e1;
            double rv0;
            Vector3D.Dot(ref rotationVec, ref e0, out rv0);
            double cosa = (double)System.Math.Cos(angle);
            double sina = (double)System.Math.Sin(angle);
            double rr0 = rv0 * cosa - rv1 * sina;
            double rr1 = rv0 * sina + rv1 * cosa;

            if (rr0 < MINIMAL_SKEW_ANGLE)
                throw new ArgumentException("illegal skew angle");

            double d = (rr1 / rr0) - (rv1 / rv0);

            MatrixD = MatrixD.Identity;
            MatrixD.M11 = d * e1[0] * e0[0] + 1.0f;
            MatrixD.M12 = d * e1[0] * e0[1];
            MatrixD.M13 = d * e1[0] * e0[2];
            MatrixD.M21 = d * e1[1] * e0[0];
            MatrixD.M22 = d * e1[1] * e0[1] + 1.0f;
            MatrixD.M23 = d * e1[1] * e0[2];
            MatrixD.M31 = d * e1[2] * e0[0];
            MatrixD.M32 = d * e1[2] * e0[1];
            MatrixD.M33 = d * e1[2] * e0[2] + 1.0f;
        }
Beispiel #13
0
        /// <summary>
        /// Creates a MatrixD that flattens geometry into a shadow.
        /// </summary>
        /// <param name="light">The light direction. If the W component is 0, the light is directional light; if the
        /// W component is 1, the light is a point light.</param>
        /// <param name="plane">The plane onto which to project the geometry as a shadow. This parameter is assumed to be normalized.</param>
        /// <param name="result">When the method completes, contains the shadow MatrixD.</param>
        public static void Shadow(ref Vector4D light, ref Plane plane, out MatrixD result)
        {
            double dot = (plane.Normal.X * light.X) + (plane.Normal.Y * light.Y) + (plane.Normal.Z * light.Z) + (plane.D * light.W);
            double x = -plane.Normal.X;
            double y = -plane.Normal.Y;
            double z = -plane.Normal.Z;
            double d = -plane.D;

            result.M11 = (x * light.X) + dot;
            result.M21 = y * light.X;
            result.M31 = z * light.X;
            result.M41 = d * light.X;
            result.M12 = x * light.Y;
            result.M22 = (y * light.Y) + dot;
            result.M32 = z * light.Y;
            result.M42 = d * light.Y;
            result.M13 = x * light.Z;
            result.M23 = y * light.Z;
            result.M33 = (z * light.Z) + dot;
            result.M43 = d * light.Z;
            result.M14 = x * light.W;
            result.M24 = y * light.W;
            result.M34 = z * light.W;
            result.M44 = (d * light.W) + dot;
        }
Beispiel #14
0
 /// <summary>
 /// Creates a MatrixD that uniformly scales along all three axis.
 /// </summary>
 /// <param name="scale">The uniform scale that is applied along all axis.</param>
 /// <param name="result">When the method completes, contains the created scaling MatrixD.</param>
 public static void Scaling(double scale, out MatrixD result)
 {
     result = MatrixD.Identity;
     result.M11 = result.M22 = result.M33 = scale;
 }
Beispiel #15
0
 /// <summary>
 /// Brings the MatrixD into upper triangular form using elementary row operations.
 /// </summary>
 /// <param name="value">The MatrixD to put into upper triangular form.</param>
 /// <returns>The upper triangular MatrixD.</returns>
 /// <remarks>
 /// If the MatrixD is not invertible (i.e. its determinant is zero) than the result of this
 /// method may produce Single.Nan and Single.Inf values. When the MatrixD represents a system
 /// of linear equations, than this often means that either no solution exists or an infinite
 /// number of solutions exist.
 /// </remarks>
 public static MatrixD UpperTriangularForm(MatrixD value)
 {
     MatrixD result;
     UpperTriangularForm(ref value, out result);
     return result;
 }
Beispiel #16
0
        /// <summary>
        /// Creates a transformation MatrixD.
        /// </summary>
        /// <param name="scalingCenter">Center point of the scaling operation.</param>
        /// <param name="scalingRotation">Scaling rotation amount.</param>
        /// <param name="scaling">Scaling factor.</param>
        /// <param name="rotationCenter">The center of the rotation.</param>
        /// <param name="rotation">The rotation of the transformation.</param>
        /// <param name="translation">The translation factor of the transformation.</param>
        /// <param name="result">When the method completes, contains the created transformation MatrixD.</param>
        public static void Transformation(ref Vector3D scalingCenter, ref Quaternion scalingRotation, ref Vector3D scaling, ref Vector3D rotationCenter, ref Quaternion rotation, ref Vector3D translation, out MatrixD result)
        {
            MatrixD sr = RotationQuaternion(scalingRotation);

            result = Translation(-scalingCenter) * Transpose(sr) * Scaling(scaling) * sr * Translation(scalingCenter) * Translation(-rotationCenter) *
                RotationQuaternion(rotation) * Translation(rotationCenter) * Translation(translation);
        }
Beispiel #17
0
        /// <summary>
        /// Decomposes a MatrixD into a lower triangular MatrixD L and an orthonormalized MatrixD Q.
        /// </summary>
        /// <param name="L">When the method completes, contains the lower triangular MatrixD of the decomposition.</param>
        /// <param name="Q">When the method completes, contains the orthonormalized MatrixD of the decomposition.</param>
        public void DecomposeLQ(out MatrixD L, out MatrixD Q)
        {
            Orthonormalize(ref this, out Q);

            L = new MatrixD();
            L.M11 = Vector4D.Dot(Q.Row1, Row1);

            L.M21 = Vector4D.Dot(Q.Row1, Row2);
            L.M22 = Vector4D.Dot(Q.Row2, Row2);

            L.M31 = Vector4D.Dot(Q.Row1, Row3);
            L.M32 = Vector4D.Dot(Q.Row2, Row3);
            L.M33 = Vector4D.Dot(Q.Row3, Row3);

            L.M41 = Vector4D.Dot(Q.Row1, Row4);
            L.M42 = Vector4D.Dot(Q.Row2, Row4);
            L.M43 = Vector4D.Dot(Q.Row3, Row4);
            L.M44 = Vector4D.Dot(Q.Row4, Row4);
        }
Beispiel #18
0
 /// <summary>
 /// Creates a translation MatrixD using the specified offsets.
 /// </summary>
 /// <param name="value">The offset for all three coordinate planes.</param>
 /// <param name="result">When the method completes, contains the created translation MatrixD.</param>
 public static void Translation(ref Vector3D value, out MatrixD result)
 {
     Translation(value.X, value.Y, value.Z, out result);
 }
Beispiel #19
0
 /// <summary>
 /// Determines whether the specified <see cref="SharpDX.MatrixD"/> is equal to this instance.
 /// </summary>
 /// <param name="other">The <see cref="SharpDX.MatrixD"/> to compare with this instance.</param>
 /// <returns>
 /// <c>true</c> if the specified <see cref="SharpDX.MatrixD"/> is equal to this instance; otherwise, <c>false</c>.
 /// </returns>
 public bool Equals(MatrixD other)
 {
     return (MathUtilD.WithinEpsilon(other.M11, M11) &&
         MathUtilD.WithinEpsilon(other.M12, M12) &&
         MathUtilD.WithinEpsilon(other.M13, M13) &&
         MathUtilD.WithinEpsilon(other.M14, M14) &&
         MathUtilD.WithinEpsilon(other.M21, M21) &&
         MathUtilD.WithinEpsilon(other.M22, M22) &&
         MathUtilD.WithinEpsilon(other.M23, M23) &&
         MathUtilD.WithinEpsilon(other.M24, M24) &&
         MathUtilD.WithinEpsilon(other.M31, M31) &&
         MathUtilD.WithinEpsilon(other.M32, M32) &&
         MathUtilD.WithinEpsilon(other.M33, M33) &&
         MathUtilD.WithinEpsilon(other.M34, M34) &&
         MathUtilD.WithinEpsilon(other.M41, M41) &&
         MathUtilD.WithinEpsilon(other.M42, M42) &&
         MathUtilD.WithinEpsilon(other.M43, M43) &&
         MathUtilD.WithinEpsilon(other.M44, M44));
 }
Beispiel #20
0
 /// <summary>
 /// Creates a translation MatrixD using the specified offsets.
 /// </summary>
 /// <param name="x">X-coordinate offset.</param>
 /// <param name="y">Y-coordinate offset.</param>
 /// <param name="z">Z-coordinate offset.</param>
 /// <param name="result">When the method completes, contains the created translation MatrixD.</param>
 public static void Translation(double x, double y, double z, out MatrixD result)
 {
     result = MatrixD.Identity;
     result.M41 = x;
     result.M42 = y;
     result.M43 = z;
 }
Beispiel #21
0
 /// <summary>
 /// Determines the sum of two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to add.</param>
 /// <param name="right">The second MatrixD to add.</param>
 /// <returns>The sum of the two matrices.</returns>
 public static MatrixD Add(MatrixD left, MatrixD right)
 {
     MatrixD result;
     Add(ref left, ref right, out result);
     return result;
 }
Beispiel #22
0
        /// <summary>
        /// Calculates the transpose of the specified MatrixD.
        /// </summary>
        /// <param name="value">The MatrixD whose transpose is to be calculated.</param>
        /// <param name="result">When the method completes, contains the transpose of the specified MatrixD.</param>
        public static void Transpose(ref MatrixD value, out MatrixD result)
        {
            MatrixD temp = new MatrixD();
            temp.M11 = value.M11;
            temp.M12 = value.M21;
            temp.M13 = value.M31;
            temp.M14 = value.M41;
            temp.M21 = value.M12;
            temp.M22 = value.M22;
            temp.M23 = value.M32;
            temp.M24 = value.M42;
            temp.M31 = value.M13;
            temp.M32 = value.M23;
            temp.M33 = value.M33;
            temp.M34 = value.M43;
            temp.M41 = value.M14;
            temp.M42 = value.M24;
            temp.M43 = value.M34;
            temp.M44 = value.M44;

            result = temp;
        }
Beispiel #23
0
        /// <summary>
        /// Creates a spherical billboard that rotates around a specified object position.
        /// </summary>
        /// <param name="objectPosition">The position of the object around which the billboard will rotate.</param>
        /// <param name="cameraPosition">The position of the camera.</param>
        /// <param name="cameraUpVector">The up vector of the camera.</param>
        /// <param name="cameraForwardVector">The forward vector of the camera.</param>
        /// <param name="result">When the method completes, contains the created billboard MatrixD.</param>
        public static void Billboard(ref Vector3D objectPosition, ref Vector3D cameraPosition, ref Vector3D cameraUpVector, ref Vector3D cameraForwardVector, out MatrixD result)
        {
            Vector3D crossed;
            Vector3D final;
            Vector3D difference = objectPosition - cameraPosition;

            double lengthSq = difference.LengthSquared();
            if (MathUtilD.IsZero(lengthSq))
                difference = -cameraForwardVector;
            else
                difference *= (double)(1.0 / System.Math.Sqrt(lengthSq));

            Vector3D.Cross(ref cameraUpVector, ref difference, out crossed);
            crossed.Normalize();
            Vector3D.Cross(ref difference, ref crossed, out final);

            result.M11 = crossed.X;
            result.M12 = crossed.Y;
            result.M13 = crossed.Z;
            result.M14 = 0.0d;
            result.M21 = final.X;
            result.M22 = final.Y;
            result.M23 = final.Z;
            result.M24 = 0.0d;
            result.M31 = difference.X;
            result.M32 = difference.Y;
            result.M33 = difference.Z;
            result.M34 = 0.0d;
            result.M41 = objectPosition.X;
            result.M42 = objectPosition.Y;
            result.M43 = objectPosition.Z;
            result.M44 = 1.0d;
        }
Beispiel #24
0
 /// <summary>
 /// Calculates the transpose of the specified MatrixD.
 /// </summary>
 /// <param name="value">The MatrixD whose transpose is to be calculated.</param>
 /// <returns>The transpose of the specified MatrixD.</returns>
 public static MatrixD Transpose(MatrixD value)
 {
     MatrixD result;
     Transpose(ref value, out result);
     return result;
 }
Beispiel #25
0
 /// <summary>
 /// Determines the quotient of two matrices.
 /// </summary>
 /// <param name="left">The first MatrixD to divide.</param>
 /// <param name="right">The second MatrixD to divide.</param>
 /// <param name="result">When the method completes, contains the quotient of the two matrices.</param>
 public static void Divide(ref MatrixD left, ref MatrixD right, out MatrixD result)
 {
     result.M11 = left.M11 / right.M11;
     result.M12 = left.M12 / right.M12;
     result.M13 = left.M13 / right.M13;
     result.M14 = left.M14 / right.M14;
     result.M21 = left.M21 / right.M21;
     result.M22 = left.M22 / right.M22;
     result.M23 = left.M23 / right.M23;
     result.M24 = left.M24 / right.M24;
     result.M31 = left.M31 / right.M31;
     result.M32 = left.M32 / right.M32;
     result.M33 = left.M33 / right.M33;
     result.M34 = left.M34 / right.M34;
     result.M41 = left.M41 / right.M41;
     result.M42 = left.M42 / right.M42;
     result.M43 = left.M43 / right.M43;
     result.M44 = left.M44 / right.M44;
 }
Beispiel #26
0
 /// <summary>
 /// Calculates the transpose of the specified MatrixD.
 /// </summary>
 /// <param name="value">The MatrixD whose transpose is to be calculated.</param>
 /// <param name="result">When the method completes, contains the transpose of the specified MatrixD.</param>
 public static void TransposeByRef(ref MatrixD value, ref MatrixD result)
 {
     result.M11 = value.M11;
     result.M12 = value.M21;
     result.M13 = value.M31;
     result.M14 = value.M41;
     result.M21 = value.M12;
     result.M22 = value.M22;
     result.M23 = value.M32;
     result.M24 = value.M42;
     result.M31 = value.M13;
     result.M32 = value.M23;
     result.M33 = value.M33;
     result.M34 = value.M43;
     result.M41 = value.M14;
     result.M42 = value.M24;
     result.M43 = value.M34;
     result.M44 = value.M44;
 }
Beispiel #27
0
        /// <summary>
        /// Performs the exponential operation on a MatrixD.
        /// </summary>
        /// <param name="value">The MatrixD to perform the operation on.</param>
        /// <param name="exponent">The exponent to raise the MatrixD to.</param>
        /// <param name="result">When the method completes, contains the exponential MatrixD.</param>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="exponent"/> is negative.</exception>
        public static void Exponent(ref MatrixD value, int exponent, out MatrixD result)
        {
            //Source: http://rosettacode.org
            //Reference: http://rosettacode.org/wiki/MatrixD-exponentiation_operator

            if (exponent < 0)
                throw new ArgumentOutOfRangeException("exponent", "The exponent can not be negative.");

            if (exponent == 0)
            {
                result = MatrixD.Identity;
                return;
            }

            if (exponent == 1)
            {
                result = value;
                return;
            }

            MatrixD identity = MatrixD.Identity;
            MatrixD temp = value;

            while (true)
            {
                if ((exponent & 1) != 0)
                    identity = identity * temp;

                exponent /= 2;

                if (exponent > 0)
                    temp *= temp;
                else
                    break;
            }

            result = identity;
        }
Beispiel #28
0
        /// <summary>
        /// Brings the MatrixD into upper triangular form using elementary row operations.
        /// </summary>
        /// <param name="value">The MatrixD to put into upper triangular form.</param>
        /// <param name="result">When the method completes, contains the upper triangular MatrixD.</param>
        /// <remarks>
        /// If the MatrixD is not invertible (i.e. its determinant is zero) than the result of this
        /// method may produce Single.Nan and Single.Inf values. When the MatrixD represents a system
        /// of linear equations, than this often means that either no solution exists or an infinite
        /// number of solutions exist.
        /// </remarks>
        public static void UpperTriangularForm(ref MatrixD value, out MatrixD result)
        {
            //Adapted from the row echelon code.
            result = value;
            int lead = 0;
            int rowcount = 4;
            int columncount = 4;

            for (int r = 0; r < rowcount; ++r)
            {
                if (columncount <= lead)
                    return;

                int i = r;

                while (MathUtilD.IsZero(result[i, lead]))
                {
                    i++;

                    if (i == rowcount)
                    {
                        i = r;
                        lead++;

                        if (lead == columncount)
                            return;
                    }
                }

                if (i != r)
                {
                    result.ExchangeRows(i, r);
                }

                double multiplier = 1d / result[r, lead];

                for (; i < rowcount; ++i)
                {
                    if (i != r)
                    {
                        result[i, 0] -= result[r, 0] * multiplier * result[i, lead];
                        result[i, 1] -= result[r, 1] * multiplier * result[i, lead];
                        result[i, 2] -= result[r, 2] * multiplier * result[i, lead];
                        result[i, 3] -= result[r, 3] * multiplier * result[i, lead];
                    }
                }

                lead++;
            }
        }
Beispiel #29
0
        /// <summary>
        /// Calculates the inverse of the specified MatrixD.
        /// </summary>
        /// <param name="value">The MatrixD whose inverse is to be calculated.</param>
        /// <param name="result">When the method completes, contains the inverse of the specified MatrixD.</param>
        public static void Invert(ref MatrixD value, out MatrixD result)
        {
            double b0 = (value.M31 * value.M42) - (value.M32 * value.M41);
            double b1 = (value.M31 * value.M43) - (value.M33 * value.M41);
            double b2 = (value.M34 * value.M41) - (value.M31 * value.M44);
            double b3 = (value.M32 * value.M43) - (value.M33 * value.M42);
            double b4 = (value.M34 * value.M42) - (value.M32 * value.M44);
            double b5 = (value.M33 * value.M44) - (value.M34 * value.M43);

            double d11 = value.M22 * b5 + value.M23 * b4 + value.M24 * b3;
            double d12 = value.M21 * b5 + value.M23 * b2 + value.M24 * b1;
            double d13 = value.M21 * -b4 + value.M22 * b2 + value.M24 * b0;
            double d14 = value.M21 * b3 + value.M22 * -b1 + value.M23 * b0;

            double det = value.M11 * d11 - value.M12 * d12 + value.M13 * d13 - value.M14 * d14;
            if (System.Math.Abs(det) == 0.0f)
            {
                result = MatrixD.Zero;
                return;
            }

            det = 1f / det;

            double a0 = (value.M11 * value.M22) - (value.M12 * value.M21);
            double a1 = (value.M11 * value.M23) - (value.M13 * value.M21);
            double a2 = (value.M14 * value.M21) - (value.M11 * value.M24);
            double a3 = (value.M12 * value.M23) - (value.M13 * value.M22);
            double a4 = (value.M14 * value.M22) - (value.M12 * value.M24);
            double a5 = (value.M13 * value.M24) - (value.M14 * value.M23);

            double d21 = value.M12 * b5 + value.M13 * b4 + value.M14 * b3;
            double d22 = value.M11 * b5 + value.M13 * b2 + value.M14 * b1;
            double d23 = value.M11 * -b4 + value.M12 * b2 + value.M14 * b0;
            double d24 = value.M11 * b3 + value.M12 * -b1 + value.M13 * b0;

            double d31 = value.M42 * a5 + value.M43 * a4 + value.M44 * a3;
            double d32 = value.M41 * a5 + value.M43 * a2 + value.M44 * a1;
            double d33 = value.M41 * -a4 + value.M42 * a2 + value.M44 * a0;
            double d34 = value.M41 * a3 + value.M42 * -a1 + value.M43 * a0;

            double d41 = value.M32 * a5 + value.M33 * a4 + value.M34 * a3;
            double d42 = value.M31 * a5 + value.M33 * a2 + value.M34 * a1;
            double d43 = value.M31 * -a4 + value.M32 * a2 + value.M34 * a0;
            double d44 = value.M31 * a3 + value.M32 * -a1 + value.M33 * a0;

            result.M11 = +d11 * det; result.M12 = -d21 * det; result.M13 = +d31 * det; result.M14 = -d41 * det;
            result.M21 = -d12 * det; result.M22 = +d22 * det; result.M23 = -d32 * det; result.M24 = +d42 * det;
            result.M31 = +d13 * det; result.M32 = -d23 * det; result.M33 = +d33 * det; result.M34 = -d43 * det;
            result.M41 = -d14 * det; result.M42 = +d24 * det; result.M43 = -d34 * det; result.M44 = +d44 * det;
        }
Beispiel #30
0
 /// <summary>
 /// Creates a MatrixD that scales along the x-axis, y-axis, and y-axis.
 /// </summary>
 /// <param name="scale">Scaling factor for all three axes.</param>
 /// <param name="result">When the method completes, contains the created scaling MatrixD.</param>
 public static void Scaling(ref Vector3D scale, out MatrixD result)
 {
     Scaling(scale.X, scale.Y, scale.Z, out result);
 }