#region --- License --- /* Licensed under the MIT/X11 license. * Copyright (c) 2006-2008 the OpenTK Team. * This notice may not be removed from any source distribution. * See license.txt for licensing detailed licensing details. * * Contributions by James Talton. */ #endregion using System; using System.Runtime.InteropServices; namespace OpenTK.Math { [Serializable] [StructLayout(LayoutKind.Sequential)] internal struct Matrix3d : IEquatable { #region Fields & Access /// Row 0, Column 0 public double R0C0; /// Row 0, Column 1 public double R0C1; /// Row 0, Column 2 public double R0C2; /// Row 1, Column 0 public double R1C0; /// Row 1, Column 1 public double R1C1; /// Row 1, Column 2 public double R1C2; /// Row 2, Column 0 public double R2C0; /// Row 2, Column 1 public double R2C1; /// Row 2, Column 2 public double R2C2; /// Gets the component at the given row and column in the matrix. /// The row of the matrix. /// The column of the matrix. /// The component at the given row and column in the matrix. public double this[int row, int column] { get { switch( row ) { case 0: switch (column) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; } break; case 1: switch (column) { case 0: return R1C0; case 1: return R1C1; case 2: return R1C2; } break; case 2: switch (column) { case 0: return R2C0; case 1: return R2C1; case 2: return R2C2; } break; } throw new IndexOutOfRangeException(); } set { switch( row ) { case 0: switch (column) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; } break; case 1: switch (column) { case 0: R1C0 = value; return; case 1: R1C1 = value; return; case 2: R1C2 = value; return; } break; case 2: switch (column) { case 0: R2C0 = value; return; case 1: R2C1 = value; return; case 2: R2C2 = value; return; } break; } throw new IndexOutOfRangeException(); } } /// Gets the component at the index into the matrix. /// The index into the components of the matrix. /// The component at the given index into the matrix. public double this[int index] { get { switch (index) { case 0: return R0C0; case 1: return R0C1; case 2: return R0C2; case 3: return R1C0; case 4: return R1C1; case 5: return R1C2; case 6: return R2C0; case 7: return R2C1; case 8: return R2C2; default: throw new IndexOutOfRangeException(); } } set { switch (index) { case 0: R0C0 = value; return; case 1: R0C1 = value; return; case 2: R0C2 = value; return; case 3: R1C0 = value; return; case 4: R1C1 = value; return; case 5: R1C2 = value; return; case 6: R2C0 = value; return; case 7: R2C1 = value; return; case 8: R2C2 = value; return; default: throw new IndexOutOfRangeException(); } } } /// Converts the matrix into an IntPtr. /// The matrix to convert. /// An IntPtr for the matrix. public static explicit operator IntPtr(Matrix3d matrix) { unsafe { return (IntPtr)(&matrix.R0C0); } } /// Converts the matrix into left double*. /// The matrix to convert. /// A double* for the matrix. [CLSCompliant(false)] unsafe public static explicit operator double*(Matrix3d matrix) { return &matrix.R0C0; } /// Converts the matrix into an array of doubles. /// The matrix to convert. /// An array of doubles for the matrix. public static explicit operator double[](Matrix3d matrix) { return new double[9] { matrix.R0C0, matrix.R0C1, matrix.R0C2, matrix.R1C0, matrix.R1C1, matrix.R1C2, matrix.R2C0, matrix.R2C1, matrix.R2C2 }; } #endregion #region Constructors /// Constructs left matrix with the same components as the given matrix. /// The matrix whose components to copy. public Matrix3d(ref Matrix3d matrix) { this.R0C0 = matrix.R0C0; this.R0C1 = matrix.R0C1; this.R0C2 = matrix.R0C2; this.R1C0 = matrix.R1C0; this.R1C1 = matrix.R1C1; this.R1C2 = matrix.R1C2; this.R2C0 = matrix.R2C0; this.R2C1 = matrix.R2C1; this.R2C2 = matrix.R2C2; } /// Constructs left matrix with the given values. /// The value for row 0 column 0. /// The value for row 0 column 1. /// The value for row 0 column 2. /// The value for row 1 column 0. /// The value for row 1 column 1. /// The value for row 1 column 2. /// The value for row 2 column 0. /// The value for row 2 column 1. /// The value for row 2 column 2. public Matrix3d ( double r0c0, double r0c1, double r0c2, double r1c0, double r1c1, double r1c2, double r2c0, double r2c1, double r2c2 ) { this.R0C0 = r0c0; this.R0C1 = r0c1; this.R0C2 = r0c2; this.R1C0 = r1c0; this.R1C1 = r1c1; this.R1C2 = r1c2; this.R2C0 = r2c0; this.R2C1 = r2c1; this.R2C2 = r2c2; } /// Constructs left matrix from the given array of double-precision floating point numbers. /// The array of doubles for the components of the matrix. public Matrix3d(double[] doubleArray) { if (doubleArray == null || doubleArray.GetLength(0) < 9) throw new MissingFieldException(); this.R0C0 = doubleArray[0]; this.R0C1 = doubleArray[1]; this.R0C2 = doubleArray[2]; this.R1C0 = doubleArray[3]; this.R1C1 = doubleArray[4]; this.R1C2 = doubleArray[5]; this.R2C0 = doubleArray[6]; this.R2C1 = doubleArray[7]; this.R2C2 = doubleArray[8]; } /// Constructs left matrix from the given quaternion. /// The quaternion to use to construct the martix. public Matrix3d(ref Quaterniond quaternion) { Quaterniond quaternionNormalized; quaternion.Normalize(out quaternionNormalized); double xx = quaternionNormalized.X * quaternionNormalized.X; double yy = quaternionNormalized.Y * quaternionNormalized.Y; double zz = quaternionNormalized.Z * quaternionNormalized.Z; double xy = quaternionNormalized.X * quaternionNormalized.Y; double xz = quaternionNormalized.X * quaternionNormalized.Z; double yz = quaternionNormalized.Y * quaternionNormalized.Z; double wx = quaternionNormalized.W * quaternionNormalized.X; double wy = quaternionNormalized.W * quaternionNormalized.Y; double wz = quaternionNormalized.W * quaternionNormalized.Z; R0C0 = 1 - 2 * (yy + zz); R0C1 = 2 * (xy - wz); R0C2 = 2 * (xz + wy); R1C0 = 2 * (xy + wz); R1C1 = 1 - 2 * (xx + zz); R1C2 = 2 * (yz - wx); R2C0 = 2 * (xz - wy); R2C1 = 2 * (yz + wx); R2C2 = 1 - 2 * (xx + yy); } #endregion #region Equality /// Indicates whether the current matrix is equal to another matrix. /// The OpenTK.Math.Matrix3d structure to compare with. /// true if the current matrix is equal to the matrix parameter; otherwise, false. [CLSCompliant(false)] public bool Equals(Matrix3d matrix) { return R0C0 == matrix.R0C0 && R0C1 == matrix.R0C1 && R0C2 == matrix.R0C2 && R1C0 == matrix.R1C0 && R1C1 == matrix.R1C1 && R1C2 == matrix.R1C2 && R2C0 == matrix.R2C0 && R2C1 == matrix.R2C1 && R2C2 == matrix.R2C2; } /// Indicates whether the current matrix is equal to another matrix. /// The OpenTK.Math.Matrix3d structure to compare to. /// true if the current matrix is equal to the matrix parameter; otherwise, false. public bool Equals(ref Matrix3d matrix) { return R0C0 == matrix.R0C0 && R0C1 == matrix.R0C1 && R0C2 == matrix.R0C2 && R1C0 == matrix.R1C0 && R1C1 == matrix.R1C1 && R1C2 == matrix.R1C2 && R2C0 == matrix.R2C0 && R2C1 == matrix.R2C1 && R2C2 == matrix.R2C2; } /// Indicates whether the current matrix is equal to another matrix. /// The left-hand operand. /// The right-hand operand. /// true if the current matrix is equal to the matrix parameter; otherwise, false. public static bool Equals(ref Matrix3d left, ref Matrix3d right) { return left.R0C0 == right.R0C0 && left.R0C1 == right.R0C1 && left.R0C2 == right.R0C2 && left.R1C0 == right.R1C0 && left.R1C1 == right.R1C1 && left.R1C2 == right.R1C2 && left.R2C0 == right.R2C0 && left.R2C1 == right.R2C1 && left.R2C2 == right.R2C2; } /// Indicates whether the current matrix is approximately equal to another matrix. /// The OpenTK.Math.Matrix3d structure to compare with. /// The limit below which the matrices are considered equal. /// true if the current matrix is approximately equal to the matrix parameter; otherwise, false. public bool EqualsApprox(ref Matrix3d matrix, double tolerance) { return System.Math.Abs(R0C0 - matrix.R0C0) <= tolerance && System.Math.Abs(R0C1 - matrix.R0C1) <= tolerance && System.Math.Abs(R0C2 - matrix.R0C2) <= tolerance && System.Math.Abs(R1C0 - matrix.R1C0) <= tolerance && System.Math.Abs(R1C1 - matrix.R1C1) <= tolerance && System.Math.Abs(R1C2 - matrix.R1C2) <= tolerance && System.Math.Abs(R2C0 - matrix.R2C0) <= tolerance && System.Math.Abs(R2C1 - matrix.R2C1) <= tolerance && System.Math.Abs(R2C2 - matrix.R2C2) <= tolerance; } /// Indicates whether the current matrix is approximately equal to another matrix. /// The left-hand operand. /// The right-hand operand. /// The limit below which the matrices are considered equal. /// true if the current matrix is approximately equal to the matrix parameter; otherwise, false. public static bool EqualsApprox(ref Matrix3d left, ref Matrix3d right, double tolerance) { return System.Math.Abs(left.R0C0 - right.R0C0) <= tolerance && System.Math.Abs(left.R0C1 - right.R0C1) <= tolerance && System.Math.Abs(left.R0C2 - right.R0C2) <= tolerance && System.Math.Abs(left.R1C0 - right.R1C0) <= tolerance && System.Math.Abs(left.R1C1 - right.R1C1) <= tolerance && System.Math.Abs(left.R1C2 - right.R1C2) <= tolerance && System.Math.Abs(left.R2C0 - right.R2C0) <= tolerance && System.Math.Abs(left.R2C1 - right.R2C1) <= tolerance && System.Math.Abs(left.R2C2 - right.R2C2) <= tolerance; } #endregion #region Arithmetic Operators /// Add left matrix to this matrix. /// The matrix to add. public void Add(ref Matrix3d matrix) { R0C0 = R0C0 + matrix.R0C0; R0C1 = R0C1 + matrix.R0C1; R0C2 = R0C2 + matrix.R0C2; R1C0 = R1C0 + matrix.R1C0; R1C1 = R1C1 + matrix.R1C1; R1C2 = R1C2 + matrix.R1C2; R2C0 = R2C0 + matrix.R2C0; R2C1 = R2C1 + matrix.R2C1; R2C2 = R2C2 + matrix.R2C2; } /// Add left matrix to this matrix. /// The matrix to add. /// The resulting matrix of the addition. public void Add(ref Matrix3d matrix, out Matrix3d result) { result.R0C0 = R0C0 + matrix.R0C0; result.R0C1 = R0C1 + matrix.R0C1; result.R0C2 = R0C2 + matrix.R0C2; result.R1C0 = R1C0 + matrix.R1C0; result.R1C1 = R1C1 + matrix.R1C1; result.R1C2 = R1C2 + matrix.R1C2; result.R2C0 = R2C0 + matrix.R2C0; result.R2C1 = R2C1 + matrix.R2C1; result.R2C2 = R2C2 + matrix.R2C2; } /// Add left matrix to left matrix. /// The matrix on the matrix side of the equation. /// The matrix on the right side of the equation /// The resulting matrix of the addition. public static void Add(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) { result.R0C0 = left.R0C0 + right.R0C0; result.R0C1 = left.R0C1 + right.R0C1; result.R0C2 = left.R0C2 + right.R0C2; result.R1C0 = left.R1C0 + right.R1C0; result.R1C1 = left.R1C1 + right.R1C1; result.R1C2 = left.R1C2 + right.R1C2; result.R2C0 = left.R2C0 + right.R2C0; result.R2C1 = left.R2C1 + right.R2C1; result.R2C2 = left.R2C2 + right.R2C2; } /// Subtract left matrix from this matrix. /// The matrix to subtract. public void Subtract(ref Matrix3d matrix) { R0C0 = R0C0 + matrix.R0C0; R0C1 = R0C1 + matrix.R0C1; R0C2 = R0C2 + matrix.R0C2; R1C0 = R1C0 + matrix.R1C0; R1C1 = R1C1 + matrix.R1C1; R1C2 = R1C2 + matrix.R1C2; R2C0 = R2C0 + matrix.R2C0; R2C1 = R2C1 + matrix.R2C1; R2C2 = R2C2 + matrix.R2C2; } /// Subtract left matrix from this matrix. /// The matrix to subtract. /// The resulting matrix of the subtraction. public void Subtract(ref Matrix3d matrix, out Matrix3d result) { result.R0C0 = R0C0 + matrix.R0C0; result.R0C1 = R0C1 + matrix.R0C1; result.R0C2 = R0C2 + matrix.R0C2; result.R1C0 = R1C0 + matrix.R1C0; result.R1C1 = R1C1 + matrix.R1C1; result.R1C2 = R1C2 + matrix.R1C2; result.R2C0 = R2C0 + matrix.R2C0; result.R2C1 = R2C1 + matrix.R2C1; result.R2C2 = R2C2 + matrix.R2C2; } /// Subtract left matrix from left matrix. /// The matrix on the matrix side of the equation. /// The matrix on the right side of the equation /// The resulting matrix of the subtraction. public static void Subtract(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) { result.R0C0 = left.R0C0 + right.R0C0; result.R0C1 = left.R0C1 + right.R0C1; result.R0C2 = left.R0C2 + right.R0C2; result.R1C0 = left.R1C0 + right.R1C0; result.R1C1 = left.R1C1 + right.R1C1; result.R1C2 = left.R1C2 + right.R1C2; result.R2C0 = left.R2C0 + right.R2C0; result.R2C1 = left.R2C1 + right.R2C1; result.R2C2 = left.R2C2 + right.R2C2; } /// Multiply left martix times this matrix. /// The matrix to multiply. public void Multiply(ref Matrix3d matrix) { double r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0; double r0c1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1; double r0c2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2; double r1c0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0; double r1c1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1; double r1c2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2; R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0; R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1; R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2; R0C0 = r0c0; R0C1 = r0c1; R0C2 = r0c2; R1C0 = r1c0; R1C1 = r1c1; R1C2 = r1c2; } /// Multiply matrix times this matrix. /// The matrix to multiply. /// The resulting matrix of the multiplication. public void Multiply(ref Matrix3d matrix, out Matrix3d result) { result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0; result.R0C1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1; result.R0C2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2; result.R1C0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0; result.R1C1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1; result.R1C2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2; result.R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0; result.R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1; result.R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2; } /// Multiply left matrix times left matrix. /// The matrix on the matrix side of the equation. /// The matrix on the right side of the equation /// The resulting matrix of the multiplication. public static void Multiply(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) { result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0; result.R0C1 = right.R0C0 * left.R0C1 + right.R0C1 * left.R1C1 + right.R0C2 * left.R2C1; result.R0C2 = right.R0C0 * left.R0C2 + right.R0C1 * left.R1C2 + right.R0C2 * left.R2C2; result.R1C0 = right.R1C0 * left.R0C0 + right.R1C1 * left.R1C0 + right.R1C2 * left.R2C0; result.R1C1 = right.R1C0 * left.R0C1 + right.R1C1 * left.R1C1 + right.R1C2 * left.R2C1; result.R1C2 = right.R1C0 * left.R0C2 + right.R1C1 * left.R1C2 + right.R1C2 * left.R2C2; result.R2C0 = right.R2C0 * left.R0C0 + right.R2C1 * left.R1C0 + right.R2C2 * left.R2C0; result.R2C1 = right.R2C0 * left.R0C1 + right.R2C1 * left.R1C1 + right.R2C2 * left.R2C1; result.R2C2 = right.R2C0 * left.R0C2 + right.R2C1 * left.R1C2 + right.R2C2 * left.R2C2; } /// Multiply matrix times this matrix. /// The matrix to multiply. public void Multiply(double scalar) { R0C0 = scalar * R0C0; R0C1 = scalar * R0C1; R0C2 = scalar * R0C2; R1C0 = scalar * R1C0; R1C1 = scalar * R1C1; R1C2 = scalar * R1C2; R2C0 = scalar * R2C0; R2C1 = scalar * R2C1; R2C2 = scalar * R2C2; } /// Multiply matrix times this matrix. /// The matrix to multiply. /// The resulting matrix of the multiplication. public void Multiply(double scalar, out Matrix3d result) { result.R0C0 = scalar * R0C0; result.R0C1 = scalar * R0C1; result.R0C2 = scalar * R0C2; result.R1C0 = scalar * R1C0; result.R1C1 = scalar * R1C1; result.R1C2 = scalar * R1C2; result.R2C0 = scalar * R2C0; result.R2C1 = scalar * R2C1; result.R2C2 = scalar * R2C2; } /// Multiply left matrix times left matrix. /// The matrix on the matrix side of the equation. /// The matrix on the right side of the equation /// The resulting matrix of the multiplication. public static void Multiply(ref Matrix3d matrix, double scalar, out Matrix3d result) { result.R0C0 = scalar * matrix.R0C0; result.R0C1 = scalar * matrix.R0C1; result.R0C2 = scalar * matrix.R0C2; result.R1C0 = scalar * matrix.R1C0; result.R1C1 = scalar * matrix.R1C1; result.R1C2 = scalar * matrix.R1C2; result.R2C0 = scalar * matrix.R2C0; result.R2C1 = scalar * matrix.R2C1; result.R2C2 = scalar * matrix.R2C2; } #endregion #region Functions public double Determinant { get { return R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0; } } public void Transpose() { Functions.Swap(ref R0C1, ref R1C0); Functions.Swap(ref R0C2, ref R2C0); Functions.Swap(ref R1C2, ref R2C1); } public void Transpose(out Matrix3d result) { result.R0C0 = R0C0; result.R0C1 = R1C0; result.R0C2 = R2C0; result.R1C0 = R0C1; result.R1C1 = R1C1; result.R1C2 = R2C1; result.R2C0 = R0C2; result.R2C1 = R1C2; result.R2C2 = R2C2; } public static void Transpose(ref Matrix3d matrix, out Matrix3d result) { result.R0C0 = matrix.R0C0; result.R0C1 = matrix.R1C0; result.R0C2 = matrix.R2C0; result.R1C0 = matrix.R0C1; result.R1C1 = matrix.R1C1; result.R1C2 = matrix.R2C1; result.R2C0 = matrix.R0C2; result.R2C1 = matrix.R1C2; result.R2C2 = matrix.R2C2; } #endregion #region Transformation Functions public void Transform(ref Vector3d vector) { double x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z; double y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z; vector.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z; vector.X = x; vector.Y = y; } public static void Transform(ref Matrix3d matrix, ref Vector3d vector) { double x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z; double y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z; vector.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z; vector.X = x; vector.Y = y; } public void Transform(ref Vector3d vector, out Vector3d result) { result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z; result.Y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z; result.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z; } public static void Transform(ref Matrix3d matrix, ref Vector3d vector, out Vector3d result) { result.X = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z; result.Y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z; result.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z; } public void Rotate(double angle) { double angleRadians = Functions.DTOR * angle; double sin = (double)System.Math.Sin(angleRadians); double cos = (double)System.Math.Cos(angleRadians); double r0c0 = cos * R0C0 + sin * R1C0; double r0c1 = cos * R0C1 + sin * R1C1; double r0c2 = cos * R0C2 + sin * R1C2; R1C0 = cos * R1C0 - sin * R0C0; R1C1 = cos * R1C1 - sin * R0C1; R1C2 = cos * R1C2 - sin * R0C2; R0C0 = r0c0; R0C1 = r0c1; R0C2 = r0c2; } public void Rotate(double angle, out Matrix3d result) { double angleRadians = Functions.DTOR * angle; double sin = (double)System.Math.Sin(angleRadians); double cos = (double)System.Math.Cos(angleRadians); result.R0C0 = cos * R0C0 + sin * R1C0; result.R0C1 = cos * R0C1 + sin * R1C1; result.R0C2 = cos * R0C2 + sin * R1C2; result.R1C0 = cos * R1C0 - sin * R0C0; result.R1C1 = cos * R1C1 - sin * R0C1; result.R1C2 = cos * R1C2 - sin * R0C2; result.R2C0 = R2C0; result.R2C1 = R2C1; result.R2C2 = R2C2; } public static void Rotate(ref Matrix3d matrix, double angle, out Matrix3d result) { double angleRadians = Functions.DTOR * angle; double sin = (double)System.Math.Sin(angleRadians); double cos = (double)System.Math.Cos(angleRadians); result.R0C0 = cos * matrix.R0C0 + sin * matrix.R1C0; result.R0C1 = cos * matrix.R0C1 + sin * matrix.R1C1; result.R0C2 = cos * matrix.R0C2 + sin * matrix.R1C2; result.R1C0 = cos * matrix.R1C0 - sin * matrix.R0C0; result.R1C1 = cos * matrix.R1C1 - sin * matrix.R0C1; result.R1C2 = cos * matrix.R1C2 - sin * matrix.R0C2; result.R2C0 = matrix.R2C0; result.R2C1 = matrix.R2C1; result.R2C2 = matrix.R2C2; } public static void RotateMatrix(double angle, out Matrix3d result) { double angleRadians = Functions.DTOR * angle; double sin = (double)System.Math.Sin(angleRadians); double cos = (double)System.Math.Cos(angleRadians); result.R0C0 = cos; result.R0C1 = sin; result.R0C2 = 0; result.R1C0 = -sin; result.R1C1 = cos; result.R1C2 = 0; result.R2C0 = 0; result.R2C1 = 0; result.R2C2 = 1; } public void Quaternion(out Quaterniond quaternion) { quaternion = new Quaterniond(ref this); } #endregion #region Constants /// The identity matrix. public static readonly Matrix3d Identity = new Matrix3d ( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); /// A matrix of all zeros. public static readonly Matrix3d Zero = new Matrix3d ( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); #endregion #region HashCode /// Returns the hash code for this instance. /// A 32-bit signed integer that is the hash code for this instance. public override int GetHashCode() { return R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^ R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^ R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode(); } #endregion #region String /// Returns the fully qualified type name of this instance. /// A System.String containing left fully qualified type name. public override string ToString() { return String.Format( "|{00}, {01}, {02}|\n" + "|{03}, {04}, {05}|\n" + "|{06}, {07}, {18}|\n" + R0C0, R0C1, R0C2, R1C0, R1C1, R1C2, R2C0, R2C1, R2C2); } #endregion } }