mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-24 17:05:37 +00:00
2346 lines
101 KiB
C#
2346 lines
101 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace OpenTK.Math
|
|
{
|
|
[Serializable]
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct Matrix4d : IEquatable<Matrix4d>
|
|
{
|
|
#region Fields & Access
|
|
|
|
/// <summary>Row 0, Column 0</summary>
|
|
public double R0C0;
|
|
|
|
/// <summary>Row 0, Column 1</summary>
|
|
public double R0C1;
|
|
|
|
/// <summary>Row 0, Column 2</summary>
|
|
public double R0C2;
|
|
|
|
/// <summary>Row 0, Column 3</summary>
|
|
public double R0C3;
|
|
|
|
/// <summary>Row 1, Column 0</summary>
|
|
public double R1C0;
|
|
|
|
/// <summary>Row 1, Column 1</summary>
|
|
public double R1C1;
|
|
|
|
/// <summary>Row 1, Column 2</summary>
|
|
public double R1C2;
|
|
|
|
/// <summary>Row 1, Column 3</summary>
|
|
public double R1C3;
|
|
|
|
/// <summary>Row 2, Column 0</summary>
|
|
public double R2C0;
|
|
|
|
/// <summary>Row 2, Column 1</summary>
|
|
public double R2C1;
|
|
|
|
/// <summary>Row 2, Column 2</summary>
|
|
public double R2C2;
|
|
|
|
/// <summary>Row 2, Column 3</summary>
|
|
public double R2C3;
|
|
|
|
/// <summary>Row 3, Column 0</summary>
|
|
public double R3C0;
|
|
|
|
/// <summary>Row 3, Column 1</summary>
|
|
public double R3C1;
|
|
|
|
/// <summary>Row 3, Column 2</summary>
|
|
public double R3C2;
|
|
|
|
/// <summary>Row 3, Column 3</summary>
|
|
public double R3C3;
|
|
|
|
/// <summary>Gets the component at the given row and column in the matrix.</summary>
|
|
/// <param name="row">The row of the matrix.</param>
|
|
/// <param name="column">The column of the matrix.</param>
|
|
/// <returns>The component at the given row and column in the matrix.</returns>
|
|
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;
|
|
case 3: return R0C3;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (column)
|
|
{
|
|
case 0: return R1C0;
|
|
case 1: return R1C1;
|
|
case 2: return R1C2;
|
|
case 3: return R1C3;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (column)
|
|
{
|
|
case 0: return R2C0;
|
|
case 1: return R2C1;
|
|
case 2: return R2C2;
|
|
case 3: return R2C3;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
switch (column)
|
|
{
|
|
case 0: return R3C0;
|
|
case 1: return R3C1;
|
|
case 2: return R3C2;
|
|
case 3: return R3C3;
|
|
}
|
|
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;
|
|
case 3: R0C3 = value; return;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (column)
|
|
{
|
|
case 0: R1C0 = value; return;
|
|
case 1: R1C1 = value; return;
|
|
case 2: R1C2 = value; return;
|
|
case 3: R1C3 = value; return;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (column)
|
|
{
|
|
case 0: R2C0 = value; return;
|
|
case 1: R2C1 = value; return;
|
|
case 2: R2C2 = value; return;
|
|
case 3: R2C3 = value; return;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
switch (column)
|
|
{
|
|
case 0: R3C0 = value; return;
|
|
case 1: R3C1 = value; return;
|
|
case 2: R3C2 = value; return;
|
|
case 3: R3C3 = value; return;
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new IndexOutOfRangeException();
|
|
} }
|
|
|
|
/// <summary>Gets the component at the index into the matrix.</summary>
|
|
/// <param name="index">The index into the components of the matrix.</param>
|
|
/// <returns>The component at the given index into the matrix.</returns>
|
|
public double this[int index]
|
|
{
|
|
get
|
|
{
|
|
switch (index)
|
|
{
|
|
case 0: return R0C0;
|
|
case 1: return R0C1;
|
|
case 2: return R0C2;
|
|
case 3: return R0C3;
|
|
case 4: return R1C0;
|
|
case 5: return R1C1;
|
|
case 6: return R1C2;
|
|
case 7: return R1C3;
|
|
case 8: return R2C0;
|
|
case 9: return R2C1;
|
|
case 10: return R2C2;
|
|
case 11: return R2C3;
|
|
case 12: return R3C0;
|
|
case 13: return R3C1;
|
|
case 14: return R3C2;
|
|
case 15: return R3C3;
|
|
default: throw new IndexOutOfRangeException();
|
|
}
|
|
}
|
|
set
|
|
{
|
|
switch (index)
|
|
{
|
|
case 0: R0C0 = value; return;
|
|
case 1: R0C1 = value; return;
|
|
case 2: R0C2 = value; return;
|
|
case 3: R0C3 = value; return;
|
|
case 4: R1C0 = value; return;
|
|
case 5: R1C1 = value; return;
|
|
case 6: R1C2 = value; return;
|
|
case 7: R1C3 = value; return;
|
|
case 8: R2C0 = value; return;
|
|
case 9: R2C1 = value; return;
|
|
case 10: R2C2 = value; return;
|
|
case 11: R2C3 = value; return;
|
|
case 12: R3C0 = value; return;
|
|
case 13: R3C1 = value; return;
|
|
case 14: R3C2 = value; return;
|
|
case 15: R3C3 = value; return;
|
|
default: throw new IndexOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Converts the matrix into an IntPtr.</summary>
|
|
/// <param name="matrix">The matrix to convert.</param>
|
|
/// <returns>An IntPtr for the matrix.</returns>
|
|
public static explicit operator IntPtr(Matrix4d matrix)
|
|
{
|
|
unsafe
|
|
{
|
|
return (IntPtr)(&matrix.R0C0);
|
|
}
|
|
}
|
|
|
|
/// <summary>Converts the matrix into left double*.</summary>
|
|
/// <param name="matrix">The matrix to convert.</param>
|
|
/// <returns>A double* for the matrix.</returns>
|
|
[CLSCompliant(false)]
|
|
unsafe public static explicit operator double*(Matrix4d matrix)
|
|
{
|
|
return &matrix.R0C0;
|
|
}
|
|
|
|
/// <summary>Converts the matrix into an array of doubles.</summary>
|
|
/// <param name="matrix">The matrix to convert.</param>
|
|
/// <returns>An array of doubles for the matrix.</returns>
|
|
public static explicit operator double[](Matrix4d matrix)
|
|
{
|
|
return new double[16]
|
|
{
|
|
matrix.R0C0,
|
|
matrix.R0C1,
|
|
matrix.R0C2,
|
|
matrix.R0C3,
|
|
matrix.R1C0,
|
|
matrix.R1C1,
|
|
matrix.R1C2,
|
|
matrix.R1C3,
|
|
matrix.R2C0,
|
|
matrix.R2C1,
|
|
matrix.R2C2,
|
|
matrix.R2C3,
|
|
matrix.R3C0,
|
|
matrix.R3C1,
|
|
matrix.R3C2,
|
|
matrix.R3C3
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>Constructs left matrix with the same components as the given matrix.</summary>
|
|
/// <param name="vector">The matrix whose components to copy.</param>
|
|
public Matrix4d(ref Matrix4d matrix)
|
|
{
|
|
this.R0C0 = matrix.R0C0;
|
|
this.R0C1 = matrix.R0C1;
|
|
this.R0C2 = matrix.R0C2;
|
|
this.R0C3 = matrix.R0C3;
|
|
this.R1C0 = matrix.R1C0;
|
|
this.R1C1 = matrix.R1C1;
|
|
this.R1C2 = matrix.R1C2;
|
|
this.R1C3 = matrix.R1C3;
|
|
this.R2C0 = matrix.R2C0;
|
|
this.R2C1 = matrix.R2C1;
|
|
this.R2C2 = matrix.R2C2;
|
|
this.R2C3 = matrix.R2C3;
|
|
this.R3C0 = matrix.R3C0;
|
|
this.R3C1 = matrix.R3C1;
|
|
this.R3C2 = matrix.R3C2;
|
|
this.R3C3 = matrix.R3C3;
|
|
}
|
|
|
|
/// <summary>Constructs left matrix with the given values.</summary>
|
|
/// <param name="r0c0">The value for row 0 column 0.</param>
|
|
/// <param name="r0c1">The value for row 0 column 1.</param>
|
|
/// <param name="r0c2">The value for row 0 column 2.</param>
|
|
/// <param name="r0c3">The value for row 0 column 3.</param>
|
|
/// <param name="r1c0">The value for row 1 column 0.</param>
|
|
/// <param name="r1c1">The value for row 1 column 1.</param>
|
|
/// <param name="r1c2">The value for row 1 column 2.</param>
|
|
/// <param name="r1c3">The value for row 1 column 3.</param>
|
|
/// <param name="r2c0">The value for row 2 column 0.</param>
|
|
/// <param name="r2c1">The value for row 2 column 1.</param>
|
|
/// <param name="r2c2">The value for row 2 column 2.</param>
|
|
/// <param name="r2c3">The value for row 2 column 3.</param>
|
|
/// <param name="r3c0">The value for row 3 column 0.</param>
|
|
/// <param name="r3c1">The value for row 3 column 1.</param>
|
|
/// <param name="r3c2">The value for row 3 column 2.</param>
|
|
/// <param name="r3c3">The value for row 3 column 3.</param>
|
|
public Matrix4d
|
|
(
|
|
double r0c0,
|
|
double r0c1,
|
|
double r0c2,
|
|
double r0c3,
|
|
double r1c0,
|
|
double r1c1,
|
|
double r1c2,
|
|
double r1c3,
|
|
double r2c0,
|
|
double r2c1,
|
|
double r2c2,
|
|
double r2c3,
|
|
double r3c0,
|
|
double r3c1,
|
|
double r3c2,
|
|
double r3c3
|
|
)
|
|
{
|
|
this.R0C0 = r0c0;
|
|
this.R0C1 = r0c1;
|
|
this.R0C2 = r0c2;
|
|
this.R0C3 = r0c3;
|
|
this.R1C0 = r1c0;
|
|
this.R1C1 = r1c1;
|
|
this.R1C2 = r1c2;
|
|
this.R1C3 = r1c3;
|
|
this.R2C0 = r2c0;
|
|
this.R2C1 = r2c1;
|
|
this.R2C2 = r2c2;
|
|
this.R2C3 = r2c3;
|
|
this.R3C0 = r3c0;
|
|
this.R3C1 = r3c1;
|
|
this.R3C2 = r3c2;
|
|
this.R3C3 = r3c3;
|
|
}
|
|
|
|
/// <summary>Constructs left matrix from the given array of double-precision floating point numbers.</summary>
|
|
/// <param name="doubleArray">The array of doubles for the components of the matrix.</param>
|
|
public Matrix4d(double[] doubleArray)
|
|
{
|
|
if (doubleArray == null || doubleArray.GetLength(0) < 16) throw new MissingFieldException();
|
|
|
|
this.R0C0 = doubleArray[0];
|
|
this.R0C1 = doubleArray[1];
|
|
this.R0C2 = doubleArray[2];
|
|
this.R0C3 = doubleArray[3];
|
|
this.R1C0 = doubleArray[4];
|
|
this.R1C1 = doubleArray[5];
|
|
this.R1C2 = doubleArray[6];
|
|
this.R1C3 = doubleArray[7];
|
|
this.R2C0 = doubleArray[8];
|
|
this.R2C1 = doubleArray[9];
|
|
this.R2C2 = doubleArray[10];
|
|
this.R2C3 = doubleArray[11];
|
|
this.R3C0 = doubleArray[12];
|
|
this.R3C1 = doubleArray[13];
|
|
this.R3C2 = doubleArray[14];
|
|
this.R3C3 = doubleArray[15];
|
|
}
|
|
|
|
/// <summary>Constructs left matrix from the given quaternion.</summary>
|
|
/// <param name="quaternion">The quaternion to use to construct the martix.</param>
|
|
public Matrix4d(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);
|
|
R0C3 = 0;
|
|
|
|
R1C0 = 2 * (xy + wz);
|
|
R1C1 = 1 - 2 * (xx + zz);
|
|
R1C2 = 2 * (yz - wx);
|
|
R1C3 = 0;
|
|
|
|
R2C0 = 2 * (xz - wy);
|
|
R2C1 = 2 * (yz + wx);
|
|
R2C2 = 1 - 2 * (xx + yy);
|
|
R2C3 = 0;
|
|
|
|
R3C0 = 0;
|
|
R3C1 = 0;
|
|
R3C2 = 0;
|
|
R3C3 = 1;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Equality
|
|
|
|
/// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
|
|
/// <param name="matrix">An matrix to compare with this matrix.</param>
|
|
/// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
|
|
public bool Equals(Matrix4d matrix)
|
|
{
|
|
return
|
|
R0C0 == matrix.R0C0 &&
|
|
R0C1 == matrix.R0C1 &&
|
|
R0C2 == matrix.R0C2 &&
|
|
R0C3 == matrix.R0C3 &&
|
|
R1C0 == matrix.R1C0 &&
|
|
R1C1 == matrix.R1C1 &&
|
|
R1C2 == matrix.R1C2 &&
|
|
R1C3 == matrix.R1C3 &&
|
|
R2C0 == matrix.R2C0 &&
|
|
R2C1 == matrix.R2C1 &&
|
|
R2C2 == matrix.R2C2 &&
|
|
R2C3 == matrix.R2C3 &&
|
|
R3C0 == matrix.R3C0 &&
|
|
R3C1 == matrix.R3C1 &&
|
|
R3C2 == matrix.R3C2 &&
|
|
R3C3 == matrix.R3C3;
|
|
|
|
}
|
|
|
|
public bool Equals(ref Matrix4d matrix)
|
|
{
|
|
return
|
|
R0C0 == matrix.R0C0 &&
|
|
R0C1 == matrix.R0C1 &&
|
|
R0C2 == matrix.R0C2 &&
|
|
R0C3 == matrix.R0C3 &&
|
|
R1C0 == matrix.R1C0 &&
|
|
R1C1 == matrix.R1C1 &&
|
|
R1C2 == matrix.R1C2 &&
|
|
R1C3 == matrix.R1C3 &&
|
|
R2C0 == matrix.R2C0 &&
|
|
R2C1 == matrix.R2C1 &&
|
|
R2C2 == matrix.R2C2 &&
|
|
R2C3 == matrix.R2C3 &&
|
|
R3C0 == matrix.R3C0 &&
|
|
R3C1 == matrix.R3C1 &&
|
|
R3C2 == matrix.R3C2 &&
|
|
R3C3 == matrix.R3C3;
|
|
|
|
}
|
|
|
|
public static bool Equals(ref Matrix4d left, ref Matrix4d right)
|
|
{
|
|
return
|
|
left.R0C0 == right.R0C0 &&
|
|
left.R0C1 == right.R0C1 &&
|
|
left.R0C2 == right.R0C2 &&
|
|
left.R0C3 == right.R0C3 &&
|
|
left.R1C0 == right.R1C0 &&
|
|
left.R1C1 == right.R1C1 &&
|
|
left.R1C2 == right.R1C2 &&
|
|
left.R1C3 == right.R1C3 &&
|
|
left.R2C0 == right.R2C0 &&
|
|
left.R2C1 == right.R2C1 &&
|
|
left.R2C2 == right.R2C2 &&
|
|
left.R2C3 == right.R2C3 &&
|
|
left.R3C0 == right.R3C0 &&
|
|
left.R3C1 == right.R3C1 &&
|
|
left.R3C2 == right.R3C2 &&
|
|
left.R3C3 == right.R3C3;
|
|
}
|
|
|
|
public bool EqualsApprox(ref Matrix4d 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(R0C3 - matrix.R0C3) <= 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(R1C3 - matrix.R1C3) <= tolerance &&
|
|
System.Math.Abs(R2C0 - matrix.R2C0) <= tolerance &&
|
|
System.Math.Abs(R2C1 - matrix.R2C1) <= tolerance &&
|
|
System.Math.Abs(R2C2 - matrix.R2C2) <= tolerance &&
|
|
System.Math.Abs(R2C3 - matrix.R2C3) <= tolerance &&
|
|
System.Math.Abs(R3C0 - matrix.R3C0) <= tolerance &&
|
|
System.Math.Abs(R3C1 - matrix.R3C1) <= tolerance &&
|
|
System.Math.Abs(R3C2 - matrix.R3C2) <= tolerance &&
|
|
System.Math.Abs(R3C3 - matrix.R3C3) <= tolerance;
|
|
}
|
|
|
|
public static bool EqualsApprox(ref Matrix4d left, ref Matrix4d 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.R0C3 - right.R0C3) <= 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.R1C3 - right.R1C3) <= 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 &&
|
|
System.Math.Abs(left.R2C3 - right.R2C3) <= tolerance &&
|
|
System.Math.Abs(left.R3C0 - right.R3C0) <= tolerance &&
|
|
System.Math.Abs(left.R3C1 - right.R3C1) <= tolerance &&
|
|
System.Math.Abs(left.R3C2 - right.R3C2) <= tolerance &&
|
|
System.Math.Abs(left.R3C3 - right.R3C3) <= tolerance;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Arithmetic Operators
|
|
|
|
|
|
/// <summary>Add left matrix to this matrix.</summary>
|
|
/// <param name="matrix">The matrix to add.</param>
|
|
public void Add(ref Matrix4d matrix)
|
|
{
|
|
R0C0 = R0C0 + matrix.R0C0;
|
|
R0C1 = R0C1 + matrix.R0C1;
|
|
R0C2 = R0C2 + matrix.R0C2;
|
|
R0C3 = R0C3 + matrix.R0C3;
|
|
R1C0 = R1C0 + matrix.R1C0;
|
|
R1C1 = R1C1 + matrix.R1C1;
|
|
R1C2 = R1C2 + matrix.R1C2;
|
|
R1C3 = R1C3 + matrix.R1C3;
|
|
R2C0 = R2C0 + matrix.R2C0;
|
|
R2C1 = R2C1 + matrix.R2C1;
|
|
R2C2 = R2C2 + matrix.R2C2;
|
|
R2C3 = R2C3 + matrix.R2C3;
|
|
R3C0 = R3C0 + matrix.R3C0;
|
|
R3C1 = R3C1 + matrix.R3C1;
|
|
R3C2 = R3C2 + matrix.R3C2;
|
|
R3C3 = R3C3 + matrix.R3C3;
|
|
}
|
|
|
|
/// <summary>Add left matrix to this matrix.</summary>
|
|
/// <param name="matrix">The matrix to add.</param>
|
|
/// <param name="result">The resulting matrix of the addition.</param>
|
|
public void Add(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
result.R0C0 = R0C0 + matrix.R0C0;
|
|
result.R0C1 = R0C1 + matrix.R0C1;
|
|
result.R0C2 = R0C2 + matrix.R0C2;
|
|
result.R0C3 = R0C3 + matrix.R0C3;
|
|
result.R1C0 = R1C0 + matrix.R1C0;
|
|
result.R1C1 = R1C1 + matrix.R1C1;
|
|
result.R1C2 = R1C2 + matrix.R1C2;
|
|
result.R1C3 = R1C3 + matrix.R1C3;
|
|
result.R2C0 = R2C0 + matrix.R2C0;
|
|
result.R2C1 = R2C1 + matrix.R2C1;
|
|
result.R2C2 = R2C2 + matrix.R2C2;
|
|
result.R2C3 = R2C3 + matrix.R2C3;
|
|
result.R3C0 = R3C0 + matrix.R3C0;
|
|
result.R3C1 = R3C1 + matrix.R3C1;
|
|
result.R3C2 = R3C2 + matrix.R3C2;
|
|
result.R3C3 = R3C3 + matrix.R3C3;
|
|
}
|
|
|
|
/// <summary>Add left matrix to left matrix.</summary>
|
|
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
|
/// <param name="right">The matrix on the right side of the equation</param>
|
|
/// <param name="result">The resulting matrix of the addition.</param>
|
|
public static void Add(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
|
|
{
|
|
result.R0C0 = left.R0C0 + right.R0C0;
|
|
result.R0C1 = left.R0C1 + right.R0C1;
|
|
result.R0C2 = left.R0C2 + right.R0C2;
|
|
result.R0C3 = left.R0C3 + right.R0C3;
|
|
result.R1C0 = left.R1C0 + right.R1C0;
|
|
result.R1C1 = left.R1C1 + right.R1C1;
|
|
result.R1C2 = left.R1C2 + right.R1C2;
|
|
result.R1C3 = left.R1C3 + right.R1C3;
|
|
result.R2C0 = left.R2C0 + right.R2C0;
|
|
result.R2C1 = left.R2C1 + right.R2C1;
|
|
result.R2C2 = left.R2C2 + right.R2C2;
|
|
result.R2C3 = left.R2C3 + right.R2C3;
|
|
result.R3C0 = left.R3C0 + right.R3C0;
|
|
result.R3C1 = left.R3C1 + right.R3C1;
|
|
result.R3C2 = left.R3C2 + right.R3C2;
|
|
result.R3C3 = left.R3C3 + right.R3C3;
|
|
}
|
|
|
|
|
|
/// <summary>Subtract left matrix from this matrix.</summary>
|
|
/// <param name="matrix">The matrix to subtract.</param>
|
|
public void Subtract(ref Matrix4d matrix)
|
|
{
|
|
R0C0 = R0C0 + matrix.R0C0;
|
|
R0C1 = R0C1 + matrix.R0C1;
|
|
R0C2 = R0C2 + matrix.R0C2;
|
|
R0C3 = R0C3 + matrix.R0C3;
|
|
R1C0 = R1C0 + matrix.R1C0;
|
|
R1C1 = R1C1 + matrix.R1C1;
|
|
R1C2 = R1C2 + matrix.R1C2;
|
|
R1C3 = R1C3 + matrix.R1C3;
|
|
R2C0 = R2C0 + matrix.R2C0;
|
|
R2C1 = R2C1 + matrix.R2C1;
|
|
R2C2 = R2C2 + matrix.R2C2;
|
|
R2C3 = R2C3 + matrix.R2C3;
|
|
R3C0 = R3C0 + matrix.R3C0;
|
|
R3C1 = R3C1 + matrix.R3C1;
|
|
R3C2 = R3C2 + matrix.R3C2;
|
|
R3C3 = R3C3 + matrix.R3C3;
|
|
}
|
|
|
|
/// <summary>Subtract left matrix from this matrix.</summary>
|
|
/// <param name="matrix">The matrix to subtract.</param>
|
|
/// <param name="result">The resulting matrix of the subtraction.</param>
|
|
public void Subtract(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
result.R0C0 = R0C0 + matrix.R0C0;
|
|
result.R0C1 = R0C1 + matrix.R0C1;
|
|
result.R0C2 = R0C2 + matrix.R0C2;
|
|
result.R0C3 = R0C3 + matrix.R0C3;
|
|
result.R1C0 = R1C0 + matrix.R1C0;
|
|
result.R1C1 = R1C1 + matrix.R1C1;
|
|
result.R1C2 = R1C2 + matrix.R1C2;
|
|
result.R1C3 = R1C3 + matrix.R1C3;
|
|
result.R2C0 = R2C0 + matrix.R2C0;
|
|
result.R2C1 = R2C1 + matrix.R2C1;
|
|
result.R2C2 = R2C2 + matrix.R2C2;
|
|
result.R2C3 = R2C3 + matrix.R2C3;
|
|
result.R3C0 = R3C0 + matrix.R3C0;
|
|
result.R3C1 = R3C1 + matrix.R3C1;
|
|
result.R3C2 = R3C2 + matrix.R3C2;
|
|
result.R3C3 = R3C3 + matrix.R3C3;
|
|
}
|
|
|
|
/// <summary>Subtract left matrix from left matrix.</summary>
|
|
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
|
/// <param name="right">The matrix on the right side of the equation</param>
|
|
/// <param name="result">The resulting matrix of the subtraction.</param>
|
|
public static void Subtract(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
|
|
{
|
|
result.R0C0 = left.R0C0 + right.R0C0;
|
|
result.R0C1 = left.R0C1 + right.R0C1;
|
|
result.R0C2 = left.R0C2 + right.R0C2;
|
|
result.R0C3 = left.R0C3 + right.R0C3;
|
|
result.R1C0 = left.R1C0 + right.R1C0;
|
|
result.R1C1 = left.R1C1 + right.R1C1;
|
|
result.R1C2 = left.R1C2 + right.R1C2;
|
|
result.R1C3 = left.R1C3 + right.R1C3;
|
|
result.R2C0 = left.R2C0 + right.R2C0;
|
|
result.R2C1 = left.R2C1 + right.R2C1;
|
|
result.R2C2 = left.R2C2 + right.R2C2;
|
|
result.R2C3 = left.R2C3 + right.R2C3;
|
|
result.R3C0 = left.R3C0 + right.R3C0;
|
|
result.R3C1 = left.R3C1 + right.R3C1;
|
|
result.R3C2 = left.R3C2 + right.R3C2;
|
|
result.R3C3 = left.R3C3 + right.R3C3;
|
|
}
|
|
|
|
|
|
/// <summary>Multiply left martix times this matrix.</summary>
|
|
/// <param name="matrix">The matrix to multiply.</param>
|
|
public void Multiply(ref Matrix4d matrix)
|
|
{
|
|
double r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0 + matrix.R0C3 * R3C0;
|
|
double r0c1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1 + matrix.R0C3 * R3C1;
|
|
double r0c2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2 + matrix.R0C3 * R3C2;
|
|
double r0c3 = matrix.R0C0 * R0C3 + matrix.R0C1 * R1C3 + matrix.R0C2 * R2C3 + matrix.R0C3 * R3C3;
|
|
double r1c0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0 + matrix.R1C3 * R3C0;
|
|
double r1c1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1 + matrix.R1C3 * R3C1;
|
|
double r1c2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2 + matrix.R1C3 * R3C2;
|
|
double r1c3 = matrix.R1C0 * R0C3 + matrix.R1C1 * R1C3 + matrix.R1C2 * R2C3 + matrix.R1C3 * R3C3;
|
|
double r2c0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0 + matrix.R2C3 * R3C0;
|
|
double r2c1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1 + matrix.R2C3 * R3C1;
|
|
double r2c2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2 + matrix.R2C3 * R3C2;
|
|
double r2c3 = matrix.R2C0 * R0C3 + matrix.R2C1 * R1C3 + matrix.R2C2 * R2C3 + matrix.R2C3 * R3C3;
|
|
|
|
R3C0 = matrix.R3C0 * R0C0 + matrix.R3C1 * R1C0 + matrix.R3C2 * R2C0 + matrix.R3C3 * R3C0;
|
|
R3C1 = matrix.R3C0 * R0C1 + matrix.R3C1 * R1C1 + matrix.R3C2 * R2C1 + matrix.R3C3 * R3C1;
|
|
R3C2 = matrix.R3C0 * R0C2 + matrix.R3C1 * R1C2 + matrix.R3C2 * R2C2 + matrix.R3C3 * R3C2;
|
|
R3C3 = matrix.R3C0 * R0C3 + matrix.R3C1 * R1C3 + matrix.R3C2 * R2C3 + matrix.R3C3 * R3C3;
|
|
|
|
R0C0 = r0c0;
|
|
R0C1 = r0c1;
|
|
R0C2 = r0c2;
|
|
R0C3 = r0c3;
|
|
R1C0 = r1c0;
|
|
R1C1 = r1c1;
|
|
R1C2 = r1c2;
|
|
R1C3 = r1c3;
|
|
R2C0 = r2c0;
|
|
R2C1 = r2c1;
|
|
R2C2 = r2c2;
|
|
R2C3 = r2c3;
|
|
}
|
|
|
|
/// <summary>Multiply matrix times this matrix.</summary>
|
|
/// <param name="matrix">The matrix to multiply.</param>
|
|
/// <param name="result">The resulting matrix of the multiplication.</param>
|
|
public void Multiply(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0 + matrix.R0C3 * R3C0;
|
|
result.R0C1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1 + matrix.R0C3 * R3C1;
|
|
result.R0C2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2 + matrix.R0C3 * R3C2;
|
|
result.R0C3 = matrix.R0C0 * R0C3 + matrix.R0C1 * R1C3 + matrix.R0C2 * R2C3 + matrix.R0C3 * R3C3;
|
|
result.R1C0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0 + matrix.R1C3 * R3C0;
|
|
result.R1C1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1 + matrix.R1C3 * R3C1;
|
|
result.R1C2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2 + matrix.R1C3 * R3C2;
|
|
result.R1C3 = matrix.R1C0 * R0C3 + matrix.R1C1 * R1C3 + matrix.R1C2 * R2C3 + matrix.R1C3 * R3C3;
|
|
result.R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0 + matrix.R2C3 * R3C0;
|
|
result.R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1 + matrix.R2C3 * R3C1;
|
|
result.R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2 + matrix.R2C3 * R3C2;
|
|
result.R2C3 = matrix.R2C0 * R0C3 + matrix.R2C1 * R1C3 + matrix.R2C2 * R2C3 + matrix.R2C3 * R3C3;
|
|
result.R3C0 = matrix.R3C0 * R0C0 + matrix.R3C1 * R1C0 + matrix.R3C2 * R2C0 + matrix.R3C3 * R3C0;
|
|
result.R3C1 = matrix.R3C0 * R0C1 + matrix.R3C1 * R1C1 + matrix.R3C2 * R2C1 + matrix.R3C3 * R3C1;
|
|
result.R3C2 = matrix.R3C0 * R0C2 + matrix.R3C1 * R1C2 + matrix.R3C2 * R2C2 + matrix.R3C3 * R3C2;
|
|
result.R3C3 = matrix.R3C0 * R0C3 + matrix.R3C1 * R1C3 + matrix.R3C2 * R2C3 + matrix.R3C3 * R3C3;
|
|
|
|
}
|
|
|
|
/// <summary>Multiply left matrix times left matrix.</summary>
|
|
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
|
/// <param name="right">The matrix on the right side of the equation</param>
|
|
/// <param name="result">The resulting matrix of the multiplication.</param>
|
|
public static void Multiply(ref Matrix4d left, ref Matrix4d right, out Matrix4d result)
|
|
{
|
|
result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0 + right.R0C3 * left.R3C0;
|
|
result.R0C1 = right.R0C0 * left.R0C1 + right.R0C1 * left.R1C1 + right.R0C2 * left.R2C1 + right.R0C3 * left.R3C1;
|
|
result.R0C2 = right.R0C0 * left.R0C2 + right.R0C1 * left.R1C2 + right.R0C2 * left.R2C2 + right.R0C3 * left.R3C2;
|
|
result.R0C3 = right.R0C0 * left.R0C3 + right.R0C1 * left.R1C3 + right.R0C2 * left.R2C3 + right.R0C3 * left.R3C3;
|
|
result.R1C0 = right.R1C0 * left.R0C0 + right.R1C1 * left.R1C0 + right.R1C2 * left.R2C0 + right.R1C3 * left.R3C0;
|
|
result.R1C1 = right.R1C0 * left.R0C1 + right.R1C1 * left.R1C1 + right.R1C2 * left.R2C1 + right.R1C3 * left.R3C1;
|
|
result.R1C2 = right.R1C0 * left.R0C2 + right.R1C1 * left.R1C2 + right.R1C2 * left.R2C2 + right.R1C3 * left.R3C2;
|
|
result.R1C3 = right.R1C0 * left.R0C3 + right.R1C1 * left.R1C3 + right.R1C2 * left.R2C3 + right.R1C3 * left.R3C3;
|
|
result.R2C0 = right.R2C0 * left.R0C0 + right.R2C1 * left.R1C0 + right.R2C2 * left.R2C0 + right.R2C3 * left.R3C0;
|
|
result.R2C1 = right.R2C0 * left.R0C1 + right.R2C1 * left.R1C1 + right.R2C2 * left.R2C1 + right.R2C3 * left.R3C1;
|
|
result.R2C2 = right.R2C0 * left.R0C2 + right.R2C1 * left.R1C2 + right.R2C2 * left.R2C2 + right.R2C3 * left.R3C2;
|
|
result.R2C3 = right.R2C0 * left.R0C3 + right.R2C1 * left.R1C3 + right.R2C2 * left.R2C3 + right.R2C3 * left.R3C3;
|
|
result.R3C0 = right.R3C0 * left.R0C0 + right.R3C1 * left.R1C0 + right.R3C2 * left.R2C0 + right.R3C3 * left.R3C0;
|
|
result.R3C1 = right.R3C0 * left.R0C1 + right.R3C1 * left.R1C1 + right.R3C2 * left.R2C1 + right.R3C3 * left.R3C1;
|
|
result.R3C2 = right.R3C0 * left.R0C2 + right.R3C1 * left.R1C2 + right.R3C2 * left.R2C2 + right.R3C3 * left.R3C2;
|
|
result.R3C3 = right.R3C0 * left.R0C3 + right.R3C1 * left.R1C3 + right.R3C2 * left.R2C3 + right.R3C3 * left.R3C3;
|
|
}
|
|
|
|
|
|
/// <summary>Multiply matrix times this matrix.</summary>
|
|
/// <param name="matrix">The matrix to multiply.</param>
|
|
public void Multiply(double scalar)
|
|
{
|
|
R0C0 = scalar * R0C0;
|
|
R0C1 = scalar * R0C1;
|
|
R0C2 = scalar * R0C2;
|
|
R0C3 = scalar * R0C3;
|
|
R1C0 = scalar * R1C0;
|
|
R1C1 = scalar * R1C1;
|
|
R1C2 = scalar * R1C2;
|
|
R1C3 = scalar * R1C3;
|
|
R2C0 = scalar * R2C0;
|
|
R2C1 = scalar * R2C1;
|
|
R2C2 = scalar * R2C2;
|
|
R2C3 = scalar * R2C3;
|
|
R3C0 = scalar * R3C0;
|
|
R3C1 = scalar * R3C1;
|
|
R3C2 = scalar * R3C2;
|
|
R3C3 = scalar * R3C3;
|
|
}
|
|
|
|
/// <summary>Multiply matrix times this matrix.</summary>
|
|
/// <param name="matrix">The matrix to multiply.</param>
|
|
/// <param name="result">The resulting matrix of the multiplication.</param>
|
|
public void Multiply(double scalar, out Matrix4d result)
|
|
{
|
|
result.R0C0 = scalar * R0C0;
|
|
result.R0C1 = scalar * R0C1;
|
|
result.R0C2 = scalar * R0C2;
|
|
result.R0C3 = scalar * R0C3;
|
|
result.R1C0 = scalar * R1C0;
|
|
result.R1C1 = scalar * R1C1;
|
|
result.R1C2 = scalar * R1C2;
|
|
result.R1C3 = scalar * R1C3;
|
|
result.R2C0 = scalar * R2C0;
|
|
result.R2C1 = scalar * R2C1;
|
|
result.R2C2 = scalar * R2C2;
|
|
result.R2C3 = scalar * R2C3;
|
|
result.R3C0 = scalar * R3C0;
|
|
result.R3C1 = scalar * R3C1;
|
|
result.R3C2 = scalar * R3C2;
|
|
result.R3C3 = scalar * R3C3;
|
|
}
|
|
|
|
/// <summary>Multiply left matrix times left matrix.</summary>
|
|
/// <param name="matrix">The matrix on the matrix side of the equation.</param>
|
|
/// <param name="right">The matrix on the right side of the equation</param>
|
|
/// <param name="result">The resulting matrix of the multiplication.</param>
|
|
public static void Multiply(ref Matrix4d matrix, double scalar, out Matrix4d result)
|
|
{
|
|
result.R0C0 = scalar * matrix.R0C0;
|
|
result.R0C1 = scalar * matrix.R0C1;
|
|
result.R0C2 = scalar * matrix.R0C2;
|
|
result.R0C3 = scalar * matrix.R0C3;
|
|
result.R1C0 = scalar * matrix.R1C0;
|
|
result.R1C1 = scalar * matrix.R1C1;
|
|
result.R1C2 = scalar * matrix.R1C2;
|
|
result.R1C3 = scalar * matrix.R1C3;
|
|
result.R2C0 = scalar * matrix.R2C0;
|
|
result.R2C1 = scalar * matrix.R2C1;
|
|
result.R2C2 = scalar * matrix.R2C2;
|
|
result.R2C3 = scalar * matrix.R2C3;
|
|
result.R3C0 = scalar * matrix.R3C0;
|
|
result.R3C1 = scalar * matrix.R3C1;
|
|
result.R3C2 = scalar * matrix.R3C2;
|
|
result.R3C3 = scalar * matrix.R3C3;
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Functions
|
|
|
|
public double Cofacter(int row, int column)
|
|
{
|
|
switch (row)
|
|
{
|
|
case 0:
|
|
switch (column)
|
|
{
|
|
case 0: return +(R1C1 * R2C2 * R3C3 - R1C1 * R2C3 * R3C2 - R1C2 * R2C1 * R3C3 + R1C3 * R2C1 * R3C2 + R1C2 * R2C3 * R3C1 - R1C3 * R2C2 * R3C1);
|
|
case 1: return -(R1C0 * R2C2 * R3C3 - R1C0 * R2C3 * R3C2 - R1C2 * R2C0 * R3C3 + R1C3 * R2C0 * R3C2 + R1C2 * R2C3 * R3C0 - R1C3 * R2C2 * R3C0);
|
|
case 2: return +(R1C0 * R2C1 * R3C3 - R1C0 * R2C3 * R3C1 - R1C1 * R2C0 * R3C3 + R1C3 * R2C0 * R3C1 + R1C1 * R2C3 * R3C0 - R1C3 * R2C1 * R3C0);
|
|
case 3: return -(R1C0 * R2C1 * R3C2 - R1C0 * R2C2 * R3C1 - R1C1 * R2C0 * R3C2 + R1C2 * R2C0 * R3C1 + R1C1 * R2C2 * R3C0 - R1C2 * R2C1 * R3C0);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (column)
|
|
{
|
|
case 0: return -(R0C1 * R2C2 * R3C3 - R0C1 * R2C3 * R3C2 - R0C2 * R2C1 * R3C3 + R0C3 * R2C1 * R3C2 + R0C2 * R2C3 * R3C1 - R0C3 * R2C2 * R3C1);
|
|
case 1: return +(R0C0 * R2C2 * R3C3 - R0C0 * R2C3 * R3C2 - R0C2 * R2C0 * R3C3 + R0C3 * R2C0 * R3C2 + R0C2 * R2C3 * R3C0 - R0C3 * R2C2 * R3C0);
|
|
case 2: return -(R0C0 * R2C1 * R3C3 - R0C0 * R2C3 * R3C1 - R0C1 * R2C0 * R3C3 + R0C3 * R2C0 * R3C1 + R0C1 * R2C3 * R3C0 - R0C3 * R2C1 * R3C0);
|
|
case 3: return +(R0C0 * R2C1 * R3C2 - R0C0 * R2C2 * R3C1 - R0C1 * R2C0 * R3C2 + R0C2 * R2C0 * R3C1 + R0C1 * R2C2 * R3C0 - R0C2 * R2C1 * R3C0);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (column)
|
|
{
|
|
case 0: return +(R0C1 * R1C2 * R3C3 - R0C1 * R1C3 * R3C2 - R0C2 * R1C1 * R3C3 + R0C3 * R1C1 * R3C2 + R0C2 * R1C3 * R3C1 - R0C3 * R1C2 * R3C1);
|
|
case 1: return -(R0C0 * R1C2 * R3C3 - R0C0 * R1C3 * R3C2 - R0C2 * R1C0 * R3C3 + R0C3 * R1C0 * R3C2 + R0C2 * R1C3 * R3C0 - R0C3 * R1C2 * R3C0);
|
|
case 2: return +(R0C0 * R1C1 * R3C3 - R0C0 * R1C3 * R3C1 - R0C1 * R1C0 * R3C3 + R0C3 * R1C0 * R3C1 + R0C1 * R1C3 * R3C0 - R0C3 * R1C1 * R3C0);
|
|
case 3: return -(R0C0 * R1C1 * R3C2 - R0C0 * R1C2 * R3C1 - R0C1 * R1C0 * R3C2 + R0C2 * R1C0 * R3C1 + R0C1 * R1C2 * R3C0 - R0C2 * R1C1 * R3C0);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
switch (column)
|
|
{
|
|
case 0: return -(R0C1 * R1C2 * R2C3 - R0C1 * R1C3 * R2C2 - R0C2 * R1C1 * R2C3 + R0C3 * R1C1 * R2C2 + R0C2 * R1C3 * R2C1 - R0C3 * R1C2 * R2C1);
|
|
case 1: return +(R0C0 * R1C2 * R2C3 - R0C0 * R1C3 * R2C2 - R0C2 * R1C0 * R2C3 + R0C3 * R1C0 * R2C2 + R0C2 * R1C3 * R2C0 - R0C3 * R1C2 * R2C0);
|
|
case 2: return -(R0C0 * R1C1 * R2C3 - R0C0 * R1C3 * R2C1 - R0C1 * R1C0 * R2C3 + R0C3 * R1C0 * R2C1 + R0C1 * R1C3 * R2C0 - R0C3 * R1C1 * R2C0);
|
|
case 3: return +(R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0);
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new IndexOutOfRangeException();
|
|
}
|
|
|
|
public double Determinant
|
|
{
|
|
get
|
|
{
|
|
return
|
|
R2C3 * R3C2 * R0C1 * R1C0 - R2C2 * R3C3 * R0C1 * R1C0 - R2C3 * R3C1 * R0C2 * R1C0 + R2C1 * R3C3 * R0C2 * R1C0 +
|
|
R2C2 * R3C1 * R0C3 * R1C0 - R2C1 * R3C2 * R0C3 * R1C0 - R0C0 * R2C3 * R3C2 * R1C1 + R0C0 * R2C2 * R3C3 * R1C1 +
|
|
R2C3 * R3C0 * R0C2 * R1C1 - R2C2 * R3C0 * R0C3 * R1C1 + R0C0 * R2C3 * R3C1 * R1C2 - R0C0 * R2C1 * R3C3 * R1C2 -
|
|
R2C3 * R3C0 * R0C1 * R1C2 + R2C1 * R3C0 * R0C3 * R1C2 - R0C0 * R2C2 * R3C1 * R1C3 + R0C0 * R2C1 * R3C2 * R1C3 +
|
|
R2C2 * R3C0 * R0C1 * R1C3 - R2C1 * R3C0 * R0C2 * R1C3 - R3C3 * R0C2 * R1C1 * R2C0 + R3C2 * R0C3 * R1C1 * R2C0 +
|
|
R3C3 * R0C1 * R1C2 * R2C0 - R3C1 * R0C3 * R1C2 * R2C0 - R3C2 * R0C1 * R1C3 * R2C0 + R3C1 * R0C2 * R1C3 * R2C0;
|
|
}
|
|
}
|
|
|
|
public void Minor(int row, int column, out Matrix3d result)
|
|
{
|
|
switch (row)
|
|
{
|
|
case 0:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = R1C1;
|
|
result.R0C1 = R1C2;
|
|
result.R0C2 = R1C3;
|
|
result.R1C0 = R2C1;
|
|
result.R1C1 = R2C2;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C1;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = R1C0;
|
|
result.R0C1 = R1C2;
|
|
result.R0C2 = R1C3;
|
|
result.R1C0 = R2C0;
|
|
result.R1C1 = R2C2;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = R1C0;
|
|
result.R0C1 = R1C1;
|
|
result.R0C2 = R1C3;
|
|
result.R1C0 = R2C0;
|
|
result.R1C1 = R2C1;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C1;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 3:
|
|
result.R0C0 = R1C0;
|
|
result.R0C1 = R1C1;
|
|
result.R0C2 = R1C2;
|
|
result.R1C0 = R2C0;
|
|
result.R1C1 = R2C1;
|
|
result.R1C2 = R2C2;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C1;
|
|
result.R2C2 = R3C2;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = R0C1;
|
|
result.R0C1 = R0C2;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R2C1;
|
|
result.R1C1 = R2C2;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C1;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C2;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R2C0;
|
|
result.R1C1 = R2C2;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C1;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R2C0;
|
|
result.R1C1 = R2C1;
|
|
result.R1C2 = R2C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C1;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = R0C1;
|
|
result.R0C1 = R0C2;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R1C1;
|
|
result.R1C1 = R1C2;
|
|
result.R1C2 = R1C3;
|
|
result.R2C0 = R3C1;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C2;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R1C0;
|
|
result.R1C1 = R1C2;
|
|
result.R1C2 = R1C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C2;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C1;
|
|
result.R0C2 = R0C3;
|
|
result.R1C0 = R1C0;
|
|
result.R1C1 = R1C1;
|
|
result.R1C2 = R1C3;
|
|
result.R2C0 = R3C0;
|
|
result.R2C1 = R3C1;
|
|
result.R2C2 = R3C3;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
throw new IndexOutOfRangeException();
|
|
}
|
|
public static void Minor(ref Matrix4d matrix, int row, int column, out Matrix3d result)
|
|
{
|
|
switch (row)
|
|
{
|
|
case 0:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = matrix.R1C1;
|
|
result.R0C1 = matrix.R1C2;
|
|
result.R0C2 = matrix.R1C3;
|
|
result.R1C0 = matrix.R2C1;
|
|
result.R1C1 = matrix.R2C2;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C1;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = matrix.R1C0;
|
|
result.R0C1 = matrix.R1C2;
|
|
result.R0C2 = matrix.R1C3;
|
|
result.R1C0 = matrix.R2C0;
|
|
result.R1C1 = matrix.R2C2;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = matrix.R1C0;
|
|
result.R0C1 = matrix.R1C1;
|
|
result.R0C2 = matrix.R1C3;
|
|
result.R1C0 = matrix.R2C0;
|
|
result.R1C1 = matrix.R2C1;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C1;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = matrix.R0C1;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R2C1;
|
|
result.R1C1 = matrix.R2C2;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C1;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R2C0;
|
|
result.R1C1 = matrix.R2C2;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R2C0;
|
|
result.R1C1 = matrix.R2C1;
|
|
result.R1C2 = matrix.R2C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C1;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = matrix.R0C1;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C1;
|
|
result.R1C1 = matrix.R1C2;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R3C1;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C2;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C2;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C1;
|
|
result.R2C2 = matrix.R3C3;
|
|
return;
|
|
|
|
case 3:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C2;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C2;
|
|
result.R2C0 = matrix.R3C0;
|
|
result.R2C1 = matrix.R3C1;
|
|
result.R2C2 = matrix.R3C2;
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
switch (column)
|
|
{
|
|
case 0:
|
|
result.R0C0 = matrix.R0C1;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C1;
|
|
result.R1C1 = matrix.R1C2;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R2C1;
|
|
result.R2C1 = matrix.R2C2;
|
|
result.R2C2 = matrix.R2C3;
|
|
return;
|
|
|
|
case 1:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C2;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C2;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C2;
|
|
result.R2C2 = matrix.R2C3;
|
|
return;
|
|
|
|
case 2:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C3;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C1;
|
|
result.R2C2 = matrix.R2C3;
|
|
return;
|
|
|
|
case 3:
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C2;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C2;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C1;
|
|
result.R2C2 = matrix.R2C2;
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new IndexOutOfRangeException();
|
|
}
|
|
|
|
public void CofacterMatrix(out Matrix4d result)
|
|
{
|
|
result.R0C0 = Cofacter(0, 0);
|
|
result.R0C1 = Cofacter(0, 1);
|
|
result.R0C2 = Cofacter(0, 2);
|
|
result.R0C3 = Cofacter(0, 3);
|
|
result.R1C0 = Cofacter(1, 0);
|
|
result.R1C1 = Cofacter(1, 1);
|
|
result.R1C2 = Cofacter(1, 2);
|
|
result.R1C3 = Cofacter(1, 3);
|
|
result.R2C0 = Cofacter(2, 0);
|
|
result.R2C1 = Cofacter(2, 1);
|
|
result.R2C2 = Cofacter(2, 2);
|
|
result.R2C3 = Cofacter(2, 3);
|
|
result.R3C0 = Cofacter(3, 0);
|
|
result.R3C1 = Cofacter(3, 1);
|
|
result.R3C2 = Cofacter(3, 2);
|
|
result.R3C3 = Cofacter(3, 3);
|
|
}
|
|
public static void CofacterMatrix(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
result.R0C0 = matrix.Cofacter(0, 0);
|
|
result.R0C1 = matrix.Cofacter(0, 1);
|
|
result.R0C2 = matrix.Cofacter(0, 2);
|
|
result.R0C3 = matrix.Cofacter(0, 3);
|
|
result.R1C0 = matrix.Cofacter(1, 0);
|
|
result.R1C1 = matrix.Cofacter(1, 1);
|
|
result.R1C2 = matrix.Cofacter(1, 2);
|
|
result.R1C3 = matrix.Cofacter(1, 3);
|
|
result.R2C0 = matrix.Cofacter(2, 0);
|
|
result.R2C1 = matrix.Cofacter(2, 1);
|
|
result.R2C2 = matrix.Cofacter(2, 2);
|
|
result.R2C3 = matrix.Cofacter(2, 3);
|
|
result.R3C0 = matrix.Cofacter(3, 0);
|
|
result.R3C1 = matrix.Cofacter(3, 1);
|
|
result.R3C2 = matrix.Cofacter(3, 2);
|
|
result.R3C3 = matrix.Cofacter(3, 3);
|
|
}
|
|
|
|
public void Transpose()
|
|
{
|
|
Functions.Swap(ref R0C1, ref R1C0);
|
|
Functions.Swap(ref R0C2, ref R2C0);
|
|
Functions.Swap(ref R0C3, ref R3C0);
|
|
Functions.Swap(ref R1C2, ref R2C1);
|
|
Functions.Swap(ref R1C3, ref R3C1);
|
|
Functions.Swap(ref R2C3, ref R3C2);
|
|
}
|
|
public void Transpose(out Matrix4d result)
|
|
{
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R1C0;
|
|
result.R0C2 = R2C0;
|
|
result.R0C3 = R3C0;
|
|
result.R1C0 = R0C1;
|
|
result.R1C1 = R1C1;
|
|
result.R1C2 = R2C1;
|
|
result.R1C3 = R3C1;
|
|
result.R2C0 = R0C2;
|
|
result.R2C1 = R1C2;
|
|
result.R2C2 = R2C2;
|
|
result.R2C3 = R3C2;
|
|
result.R3C0 = R0C3;
|
|
result.R3C1 = R1C3;
|
|
result.R3C2 = R2C3;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void Transpose(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R1C0;
|
|
result.R0C2 = matrix.R2C0;
|
|
result.R0C3 = matrix.R3C0;
|
|
result.R1C0 = matrix.R0C1;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R2C1;
|
|
result.R1C3 = matrix.R3C1;
|
|
result.R2C0 = matrix.R0C2;
|
|
result.R2C1 = matrix.R1C2;
|
|
result.R2C2 = matrix.R2C2;
|
|
result.R2C3 = matrix.R3C2;
|
|
result.R3C0 = matrix.R0C3;
|
|
result.R3C1 = matrix.R1C3;
|
|
result.R3C2 = matrix.R2C3;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
|
|
public void Adjoint(out Matrix4d result)
|
|
{
|
|
CofacterMatrix(out result);
|
|
result.Transpose();
|
|
}
|
|
public static void Adjoint(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
matrix.CofacterMatrix(out result);
|
|
result.Transpose();
|
|
}
|
|
|
|
public void Inverse(out Matrix4d result)
|
|
{
|
|
CofacterMatrix(out result);
|
|
result.Transpose();
|
|
result.Multiply(1 / Determinant);
|
|
}
|
|
public static void Inverse(ref Matrix4d matrix, out Matrix4d result)
|
|
{
|
|
matrix.CofacterMatrix(out result);
|
|
result.Transpose();
|
|
result.Multiply(1 / result.Determinant);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Transformation Functions
|
|
|
|
public void Transform(ref Vector4d vector)
|
|
{
|
|
double x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z + R0C3 * vector.W;
|
|
double y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z + R1C3 * vector.W;
|
|
double z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z + R2C3 * vector.W;
|
|
vector.W = R3C0 * vector.X + R3C1 * vector.Y + R3C2 * vector.Z + R3C3 * vector.W;
|
|
vector.X = x;
|
|
vector.Y = y;
|
|
vector.Z = z;
|
|
}
|
|
public static void Transform(ref Matrix4d matrix, ref Vector4d vector)
|
|
{
|
|
double x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z + matrix.R0C3 * vector.W;
|
|
double y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z + matrix.R1C3 * vector.W;
|
|
double z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z + matrix.R2C3 * vector.W;
|
|
vector.W = matrix.R3C0 * vector.X + matrix.R3C1 * vector.Y + matrix.R3C2 * vector.Z + matrix.R3C3 * vector.W;
|
|
vector.X = x;
|
|
vector.Y = y;
|
|
vector.Z = z;
|
|
}
|
|
public void Transform(ref Vector4d vector, out Vector4d result)
|
|
{
|
|
result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z + R0C3 * vector.W;
|
|
result.Y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z + R1C3 * vector.W;
|
|
result.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z + R2C3 * vector.W;
|
|
result.W = R3C0 * vector.X + R3C1 * vector.Y + R3C2 * vector.Z + R3C3 * vector.W;
|
|
}
|
|
public static void Transform(ref Matrix4d matrix, ref Vector4d vector, out Vector4d result)
|
|
{
|
|
result.X = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z + matrix.R0C3 * vector.W;
|
|
result.Y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z + matrix.R1C3 * vector.W;
|
|
result.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z + matrix.R2C3 * vector.W;
|
|
result.W = matrix.R3C0 * vector.X + matrix.R3C1 * vector.Y + matrix.R3C2 * vector.Z + matrix.R3C3 * vector.W;
|
|
}
|
|
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 Matrix4d 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 Matrix4d 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 RotateX(double angle)
|
|
{
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
|
|
double r1c0 = cos * R1C0 + sin * R2C0;
|
|
double r1c1 = cos * R1C1 + sin * R2C1;
|
|
double r1c2 = cos * R1C2 + sin * R2C2;
|
|
double r1c3 = cos * R1C3 + sin * R2C3;
|
|
|
|
R2C0 = cos * R2C0 - sin * R1C0;
|
|
R2C1 = cos * R2C1 - sin * R1C1;
|
|
R2C2 = cos * R2C2 - sin * R1C2;
|
|
R2C3 = cos * R2C3 - sin * R1C3;
|
|
|
|
R1C0 = r1c0;
|
|
R1C1 = r1c1;
|
|
R1C2 = r1c2;
|
|
R1C3 = r1c3;
|
|
}
|
|
public void RotateX(double angle, out Matrix4d result)
|
|
{
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C1;
|
|
result.R0C2 = R0C2;
|
|
result.R0C3 = R0C3;
|
|
result.R1C0 = cos * R1C0 + sin * R2C0;
|
|
result.R1C1 = cos * R1C1 + sin * R2C1;
|
|
result.R1C2 = cos * R1C2 + sin * R2C2;
|
|
result.R1C3 = cos * R1C3 + sin * R2C3;
|
|
result.R2C0 = cos * R2C0 - sin * R1C0;
|
|
result.R2C1 = cos * R2C1 - sin * R1C1;
|
|
result.R2C2 = cos * R2C2 - sin * R1C2;
|
|
result.R2C3 = cos * R2C3 - sin * R1C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void RotateX(ref Matrix4d matrix, double angle, out Matrix4d result)
|
|
{
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C2;
|
|
result.R0C3 = matrix.R0C3;
|
|
result.R1C0 = cos * matrix.R1C0 + sin * matrix.R2C0;
|
|
result.R1C1 = cos * matrix.R1C1 + sin * matrix.R2C1;
|
|
result.R1C2 = cos * matrix.R1C2 + sin * matrix.R2C2;
|
|
result.R1C3 = cos * matrix.R1C3 + sin * matrix.R2C3;
|
|
result.R2C0 = cos * matrix.R2C0 - sin * matrix.R1C0;
|
|
result.R2C1 = cos * matrix.R2C1 - sin * matrix.R1C1;
|
|
result.R2C2 = cos * matrix.R2C2 - sin * matrix.R1C2;
|
|
result.R2C3 = cos * matrix.R2C3 - sin * matrix.R1C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void RotateXMatrix(double angle, out Matrix4d result)
|
|
{
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
|
|
result.R0C0 = 1;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = cos;
|
|
result.R1C2 = sin;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = -sin;
|
|
result.R2C2 = cos;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void RotateY(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 * R2C0;
|
|
double r0c1 = cos * R0C1 - sin * R2C1;
|
|
double r0c2 = cos * R0C2 - sin * R2C2;
|
|
double r0c3 = cos * R0C3 - sin * R2C3;
|
|
|
|
R2C0 = sin * R0C0 + cos * R2C0;
|
|
R2C1 = sin * R0C1 + cos * R2C1;
|
|
R2C2 = sin * R0C2 + cos * R2C2;
|
|
R2C3 = sin * R0C3 + cos * R2C3;
|
|
|
|
R0C0 = r0c0;
|
|
R0C1 = r0c1;
|
|
R0C2 = r0c2;
|
|
R0C3 = r0c3;
|
|
|
|
}
|
|
public void RotateY(double angle, out Matrix4d 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 * R2C0;
|
|
result.R0C1 = cos * R0C1 - sin * R2C1;
|
|
result.R0C2 = cos * R0C2 - sin * R2C2;
|
|
result.R0C3 = cos * R0C3 - sin * R2C3;
|
|
result.R1C0 = R1C0;
|
|
result.R1C1 = R1C1;
|
|
result.R1C2 = R1C2;
|
|
result.R1C3 = R1C3;
|
|
result.R2C0 = sin * R0C0 + cos * R2C0;
|
|
result.R2C1 = sin * R0C1 + cos * R2C1;
|
|
result.R2C2 = sin * R0C2 + cos * R2C2;
|
|
result.R2C3 = sin * R0C3 + cos * R2C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void RotateY(ref Matrix4d matrix, double angle, out Matrix4d 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.R2C0;
|
|
result.R0C1 = cos * matrix.R0C1 - sin * matrix.R2C1;
|
|
result.R0C2 = cos * matrix.R0C2 - sin * matrix.R2C2;
|
|
result.R0C3 = cos * matrix.R0C3 - sin * matrix.R2C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C2;
|
|
result.R1C3 = matrix.R1C3;
|
|
result.R2C0 = sin * matrix.R0C0 + cos * matrix.R2C0;
|
|
result.R2C1 = sin * matrix.R0C1 + cos * matrix.R2C1;
|
|
result.R2C2 = sin * matrix.R0C2 + cos * matrix.R2C2;
|
|
result.R2C3 = sin * matrix.R0C3 + cos * matrix.R2C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void RotateYMatrix(double angle, out Matrix4d 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 = 0;
|
|
result.R0C2 = -sin;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = 1;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = sin;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = cos;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void RotateZ(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;
|
|
double r0c3 = cos * R0C3 + sin * R1C3;
|
|
|
|
R1C0 = cos * R1C0 - sin * R0C0;
|
|
R1C1 = cos * R1C1 - sin * R0C1;
|
|
R1C2 = cos * R1C2 - sin * R0C2;
|
|
R1C3 = cos * R1C3 - sin * R0C3;
|
|
|
|
R0C0 = r0c0;
|
|
R0C1 = r0c1;
|
|
R0C2 = r0c2;
|
|
R0C3 = r0c3;
|
|
}
|
|
public void RotateZ(double angle, out Matrix4d 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.R0C3 = cos * R0C3 + sin * R1C3;
|
|
result.R1C0 = cos * R1C0 - sin * R0C0;
|
|
result.R1C1 = cos * R1C1 - sin * R0C1;
|
|
result.R1C2 = cos * R1C2 - sin * R0C2;
|
|
result.R1C3 = cos * R1C3 - sin * R0C3;
|
|
result.R2C0 = R2C0;
|
|
result.R2C1 = R2C1;
|
|
result.R2C2 = R2C2;
|
|
result.R2C3 = R2C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void RotateZ(ref Matrix4d matrix, double angle, out Matrix4d 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.R0C3 = cos * matrix.R0C3 + sin * matrix.R1C3;
|
|
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.R1C3 = cos * matrix.R1C3 - sin * matrix.R0C3;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C1;
|
|
result.R2C2 = matrix.R2C2;
|
|
result.R2C3 = matrix.R2C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void RotateZMatrix(double angle, out Matrix4d 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.R0C3 = 0;
|
|
result.R1C0 = -sin;
|
|
result.R1C1 = cos;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = 1;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void Rotate(ref Vector3d axis, double angle)
|
|
{
|
|
Vector3d axisNormalized;
|
|
axis.Normalize(out axisNormalized);
|
|
double x = axisNormalized.X;
|
|
double y = axisNormalized.Y;
|
|
double z = axisNormalized.Z;
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double oneMinusCos = 1 - cos;
|
|
double xOneMinusCos = x * oneMinusCos;
|
|
double yOneMinusCos = y * oneMinusCos;
|
|
double zOneMinusCos = z * oneMinusCos;
|
|
double xxOneMinusCos = x * xOneMinusCos;
|
|
double xyOneMinusCos = x * yOneMinusCos;
|
|
double xzOneMinusCos = x * zOneMinusCos;
|
|
double yyOneMinusCos = y * yOneMinusCos;
|
|
double yzOneMinusCos = y * zOneMinusCos;
|
|
double zzOneMinusCos = z * zOneMinusCos;
|
|
double xSin = x * sin;
|
|
double ySin = y * sin;
|
|
double zSin = z * sin;
|
|
|
|
double rotateR0C0 = xxOneMinusCos + cos;
|
|
double rotateR0C1 = xyOneMinusCos + zSin;
|
|
double rotateR0C2 = xzOneMinusCos - ySin;
|
|
double rotateR1C0 = xyOneMinusCos - zSin;
|
|
double rotateR1C1 = yyOneMinusCos + cos;
|
|
double rotateR1C2 = yzOneMinusCos + xSin;
|
|
double rotateR2C0 = xzOneMinusCos + ySin;
|
|
double rotateR2C1 = yzOneMinusCos - xSin;
|
|
double rotateR2C2 = zzOneMinusCos + cos;
|
|
|
|
double r0c0 = rotateR0C0 * R0C0 + rotateR0C1 * R1C0 + rotateR0C2 * R2C0;
|
|
double r0c1 = rotateR0C0 * R0C1 + rotateR0C1 * R1C1 + rotateR0C2 * R2C1;
|
|
double r0c2 = rotateR0C0 * R0C2 + rotateR0C1 * R1C2 + rotateR0C2 * R2C2;
|
|
double r0c3 = rotateR0C0 * R0C3 + rotateR0C1 * R1C3 + rotateR0C2 * R2C3;
|
|
|
|
double r1c0 = rotateR1C0 * R0C0 + rotateR1C1 * R1C0 + rotateR1C2 * R2C0;
|
|
double r1c1 = rotateR1C0 * R0C1 + rotateR1C1 * R1C1 + rotateR1C2 * R2C1;
|
|
double r1c2 = rotateR1C0 * R0C2 + rotateR1C1 * R1C2 + rotateR1C2 * R2C2;
|
|
double r1c3 = rotateR1C0 * R0C3 + rotateR1C1 * R1C3 + rotateR1C2 * R2C3;
|
|
|
|
R2C0 = rotateR2C0 * R0C0 + rotateR2C1 * R1C0 + rotateR2C2 * R2C0;
|
|
R2C1 = rotateR2C0 * R0C1 + rotateR2C1 * R1C1 + rotateR2C2 * R2C1;
|
|
R2C2 = rotateR2C0 * R0C2 + rotateR2C1 * R1C2 + rotateR2C2 * R2C2;
|
|
R2C3 = rotateR2C0 * R0C3 + rotateR2C1 * R1C3 + rotateR2C2 * R2C3;
|
|
|
|
R0C0 = r0c0;
|
|
R0C1 = r0c1;
|
|
R0C2 = r0c2;
|
|
R0C3 = r0c3;
|
|
|
|
R1C0 = r1c0;
|
|
R1C1 = r1c1;
|
|
R1C2 = r1c2;
|
|
R1C3 = r1c3;
|
|
}
|
|
public void Rotate(ref Vector3d axis, double angle, out Matrix4d result)
|
|
{
|
|
Vector3d axisNormalized;
|
|
axis.Normalize(out axisNormalized);
|
|
double x = axisNormalized.X;
|
|
double y = axisNormalized.Y;
|
|
double z = axisNormalized.Z;
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double oneMinusCos = 1 - cos;
|
|
double xOneMinusCos = x * oneMinusCos;
|
|
double yOneMinusCos = y * oneMinusCos;
|
|
double zOneMinusCos = z * oneMinusCos;
|
|
double xxOneMinusCos = x * xOneMinusCos;
|
|
double xyOneMinusCos = x * yOneMinusCos;
|
|
double xzOneMinusCos = x * zOneMinusCos;
|
|
double yyOneMinusCos = y * yOneMinusCos;
|
|
double yzOneMinusCos = y * zOneMinusCos;
|
|
double zzOneMinusCos = z * zOneMinusCos;
|
|
double xSin = x * sin;
|
|
double ySin = y * sin;
|
|
double zSin = z * sin;
|
|
|
|
double rotateR0C0 = xxOneMinusCos + cos;
|
|
double rotateR0C1 = xyOneMinusCos + zSin;
|
|
double rotateR0C2 = xzOneMinusCos - ySin;
|
|
double rotateR1C0 = xyOneMinusCos - zSin;
|
|
double rotateR1C1 = yyOneMinusCos + cos;
|
|
double rotateR1C2 = yzOneMinusCos + xSin;
|
|
double rotateR2C0 = xzOneMinusCos + ySin;
|
|
double rotateR2C1 = yzOneMinusCos - xSin;
|
|
double rotateR2C2 = zzOneMinusCos + cos;
|
|
|
|
result.R0C0 = rotateR0C0 * R0C0 + rotateR0C1 * R1C0 + rotateR0C2 * R2C0;
|
|
result.R0C1 = rotateR0C0 * R0C1 + rotateR0C1 * R1C1 + rotateR0C2 * R2C1;
|
|
result.R0C2 = rotateR0C0 * R0C2 + rotateR0C1 * R1C2 + rotateR0C2 * R2C2;
|
|
result.R0C3 = rotateR0C0 * R0C3 + rotateR0C1 * R1C3 + rotateR0C2 * R2C3;
|
|
result.R1C0 = rotateR1C0 * R0C0 + rotateR1C1 * R1C0 + rotateR1C2 * R2C0;
|
|
result.R1C1 = rotateR1C0 * R0C1 + rotateR1C1 * R1C1 + rotateR1C2 * R2C1;
|
|
result.R1C2 = rotateR1C0 * R0C2 + rotateR1C1 * R1C2 + rotateR1C2 * R2C2;
|
|
result.R1C3 = rotateR1C0 * R0C3 + rotateR1C1 * R1C3 + rotateR1C2 * R2C3;
|
|
result.R2C0 = rotateR2C0 * R0C0 + rotateR2C1 * R1C0 + rotateR2C2 * R2C0;
|
|
result.R2C1 = rotateR2C0 * R0C1 + rotateR2C1 * R1C1 + rotateR2C2 * R2C1;
|
|
result.R2C2 = rotateR2C0 * R0C2 + rotateR2C1 * R1C2 + rotateR2C2 * R2C2;
|
|
result.R2C3 = rotateR2C0 * R0C3 + rotateR2C1 * R1C3 + rotateR2C2 * R2C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void Rotate(ref Matrix4d matrix, ref Vector3d axis, double angle, out Matrix4d result)
|
|
{
|
|
Vector3d axisNormalized;
|
|
axis.Normalize(out axisNormalized);
|
|
double x = axisNormalized.X;
|
|
double y = axisNormalized.Y;
|
|
double z = axisNormalized.Z;
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double oneMinusCos = 1 - cos;
|
|
double xOneMinusCos = x * oneMinusCos;
|
|
double yOneMinusCos = y * oneMinusCos;
|
|
double zOneMinusCos = z * oneMinusCos;
|
|
double xxOneMinusCos = x * xOneMinusCos;
|
|
double xyOneMinusCos = x * yOneMinusCos;
|
|
double xzOneMinusCos = x * zOneMinusCos;
|
|
double yyOneMinusCos = y * yOneMinusCos;
|
|
double yzOneMinusCos = y * zOneMinusCos;
|
|
double zzOneMinusCos = z * zOneMinusCos;
|
|
double xSin = x * sin;
|
|
double ySin = y * sin;
|
|
double zSin = z * sin;
|
|
|
|
double rotateR0C0 = xxOneMinusCos + cos;
|
|
double rotateR0C1 = xyOneMinusCos + zSin;
|
|
double rotateR0C2 = xzOneMinusCos - ySin;
|
|
double rotateR1C0 = xyOneMinusCos - zSin;
|
|
double rotateR1C1 = yyOneMinusCos + cos;
|
|
double rotateR1C2 = yzOneMinusCos + xSin;
|
|
double rotateR2C0 = xzOneMinusCos + ySin;
|
|
double rotateR2C1 = yzOneMinusCos - xSin;
|
|
double rotateR2C2 = zzOneMinusCos + cos;
|
|
|
|
|
|
result.R0C0 = rotateR0C0 * matrix.R0C0 + rotateR0C1 * matrix.R1C0 + rotateR0C2 * matrix.R2C0;
|
|
result.R0C1 = rotateR0C0 * matrix.R0C1 + rotateR0C1 * matrix.R1C1 + rotateR0C2 * matrix.R2C1;
|
|
result.R0C2 = rotateR0C0 * matrix.R0C2 + rotateR0C1 * matrix.R1C2 + rotateR0C2 * matrix.R2C2;
|
|
result.R0C3 = rotateR0C0 * matrix.R0C3 + rotateR0C1 * matrix.R1C3 + rotateR0C2 * matrix.R2C3;
|
|
result.R1C0 = rotateR1C0 * matrix.R0C0 + rotateR1C1 * matrix.R1C0 + rotateR1C2 * matrix.R2C0;
|
|
result.R1C1 = rotateR1C0 * matrix.R0C1 + rotateR1C1 * matrix.R1C1 + rotateR1C2 * matrix.R2C1;
|
|
result.R1C2 = rotateR1C0 * matrix.R0C2 + rotateR1C1 * matrix.R1C2 + rotateR1C2 * matrix.R2C2;
|
|
result.R1C3 = rotateR1C0 * matrix.R0C3 + rotateR1C1 * matrix.R1C3 + rotateR1C2 * matrix.R2C3;
|
|
result.R2C0 = rotateR2C0 * matrix.R0C0 + rotateR2C1 * matrix.R1C0 + rotateR2C2 * matrix.R2C0;
|
|
result.R2C1 = rotateR2C0 * matrix.R0C1 + rotateR2C1 * matrix.R1C1 + rotateR2C2 * matrix.R2C1;
|
|
result.R2C2 = rotateR2C0 * matrix.R0C2 + rotateR2C1 * matrix.R1C2 + rotateR2C2 * matrix.R2C2;
|
|
result.R2C3 = rotateR2C0 * matrix.R0C3 + rotateR2C1 * matrix.R1C3 + rotateR2C2 * matrix.R2C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void RotateMatrix(ref Vector3d axis, double angle, out Matrix4d result)
|
|
{
|
|
Vector3d axisNormalized;
|
|
axis.Normalize(out axisNormalized);
|
|
double x = axisNormalized.X;
|
|
double y = axisNormalized.Y;
|
|
double z = axisNormalized.Z;
|
|
double angleRadians = Functions.DTOR * angle;
|
|
double cos = (double)System.Math.Cos(angleRadians);
|
|
double sin = (double)System.Math.Sin(angleRadians);
|
|
double oneMinusCos = 1 - cos;
|
|
double xOneMinusCos = x * oneMinusCos;
|
|
double yOneMinusCos = y * oneMinusCos;
|
|
double zOneMinusCos = z * oneMinusCos;
|
|
double xxOneMinusCos = x * xOneMinusCos;
|
|
double xyOneMinusCos = x * yOneMinusCos;
|
|
double xzOneMinusCos = x * zOneMinusCos;
|
|
double yyOneMinusCos = y * yOneMinusCos;
|
|
double yzOneMinusCos = y * zOneMinusCos;
|
|
double zzOneMinusCos = z * zOneMinusCos;
|
|
double xSin = x * sin;
|
|
double ySin = y * sin;
|
|
double zSin = z * sin;
|
|
|
|
result.R0C0 = xxOneMinusCos + cos;
|
|
result.R0C1 = xyOneMinusCos + zSin;
|
|
result.R0C2 = xzOneMinusCos - ySin;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = xyOneMinusCos - zSin;
|
|
result.R1C1 = yyOneMinusCos + cos;
|
|
result.R1C2 = yzOneMinusCos + xSin;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = xzOneMinusCos + ySin;
|
|
result.R2C1 = yzOneMinusCos - xSin;
|
|
result.R2C2 = zzOneMinusCos + cos;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void Translate(double x, double y, double z)
|
|
{
|
|
R3C0 = x * R0C0 + y * R1C0 + z * R2C0 + R3C0;
|
|
R3C1 = x * R0C1 + y * R1C1 + z * R2C1 + R3C1;
|
|
R3C2 = x * R0C2 + y * R1C2 + z * R2C2 + R3C2;
|
|
R3C3 = x * R0C3 + y * R1C3 + z * R2C3 + R3C3;
|
|
}
|
|
public void Translate(double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C1;
|
|
result.R0C2 = R0C2;
|
|
result.R0C3 = R0C3;
|
|
result.R1C0 = R1C0;
|
|
result.R1C1 = R1C1;
|
|
result.R1C2 = R1C2;
|
|
result.R1C3 = R1C3;
|
|
result.R2C0 = R2C0;
|
|
result.R2C1 = R2C1;
|
|
result.R2C2 = R2C2;
|
|
result.R2C3 = R2C3;
|
|
result.R3C0 = x * R0C0 + y * R1C0 + z * R2C0 + R3C0;
|
|
result.R3C1 = x * R0C1 + y * R1C1 + z * R2C1 + R3C1;
|
|
result.R3C2 = x * R0C2 + y * R1C2 + z * R2C2 + R3C2;
|
|
result.R3C3 = x * R0C3 + y * R1C3 + z * R2C3 + R3C3;
|
|
}
|
|
public static void Translate(ref Matrix4d matrix, double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C2;
|
|
result.R0C3 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C2;
|
|
result.R1C3 = matrix.R1C3;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C1;
|
|
result.R2C2 = matrix.R2C2;
|
|
result.R2C3 = matrix.R2C3;
|
|
result.R3C0 = x * matrix.R0C0 + y * matrix.R1C0 + z * matrix.R2C0 + matrix.R3C0;
|
|
result.R3C1 = x * matrix.R0C1 + y * matrix.R1C1 + z * matrix.R2C1 + matrix.R3C1;
|
|
result.R3C2 = x * matrix.R0C2 + y * matrix.R1C2 + z * matrix.R2C2 + matrix.R3C2;
|
|
result.R3C3 = x * matrix.R0C3 + y * matrix.R1C3 + z * matrix.R2C3 + matrix.R3C3;
|
|
}
|
|
public static void TranslateMatrix(double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = 1;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = 1;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = 1;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = x;
|
|
result.R3C1 = y;
|
|
result.R3C2 = z;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void Translate(ref Vector3d vector)
|
|
{
|
|
R3C0 = vector.X * R0C0 + vector.Y * R1C0 + vector.Z * R2C0 + R3C0;
|
|
R3C1 = vector.X * R0C1 + vector.Y * R1C1 + vector.Z * R2C1 + R3C1;
|
|
R3C2 = vector.X * R0C2 + vector.Y * R1C2 + vector.Z * R2C2 + R3C2;
|
|
R3C3 = vector.X * R0C3 + vector.Y * R1C3 + vector.Z * R2C3 + R3C3;
|
|
}
|
|
public void Translate(ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = R0C0;
|
|
result.R0C1 = R0C1;
|
|
result.R0C2 = R0C2;
|
|
result.R0C3 = R0C3;
|
|
result.R1C0 = R1C0;
|
|
result.R1C1 = R1C1;
|
|
result.R1C2 = R1C2;
|
|
result.R1C3 = R1C3;
|
|
result.R2C0 = R2C0;
|
|
result.R2C1 = R2C1;
|
|
result.R2C2 = R2C2;
|
|
result.R2C3 = R2C3;
|
|
result.R3C0 = vector.X * R0C0 + vector.Y * R1C0 + vector.Z * R2C0 + R3C0;
|
|
result.R3C1 = vector.X * R0C1 + vector.Y * R1C1 + vector.Z * R2C1 + R3C1;
|
|
result.R3C2 = vector.X * R0C2 + vector.Y * R1C2 + vector.Z * R2C2 + R3C2;
|
|
result.R3C3 = vector.X * R0C3 + vector.Y * R1C3 + vector.Z * R2C3 + R3C3;
|
|
}
|
|
public static void Translate(ref Matrix4d matrix, ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = matrix.R0C0;
|
|
result.R0C1 = matrix.R0C1;
|
|
result.R0C2 = matrix.R0C2;
|
|
result.R0C3 = matrix.R0C3;
|
|
result.R1C0 = matrix.R1C0;
|
|
result.R1C1 = matrix.R1C1;
|
|
result.R1C2 = matrix.R1C2;
|
|
result.R1C3 = matrix.R1C3;
|
|
result.R2C0 = matrix.R2C0;
|
|
result.R2C1 = matrix.R2C1;
|
|
result.R2C2 = matrix.R2C2;
|
|
result.R2C3 = matrix.R2C3;
|
|
result.R3C0 = vector.X * matrix.R0C0 + vector.Y * matrix.R1C0 + vector.Z * matrix.R2C0 + matrix.R3C0;
|
|
result.R3C1 = vector.X * matrix.R0C1 + vector.Y * matrix.R1C1 + vector.Z * matrix.R2C1 + matrix.R3C1;
|
|
result.R3C2 = vector.X * matrix.R0C2 + vector.Y * matrix.R1C2 + vector.Z * matrix.R2C2 + matrix.R3C2;
|
|
result.R3C3 = vector.X * matrix.R0C3 + vector.Y * matrix.R1C3 + vector.Z * matrix.R2C3 + matrix.R3C3;
|
|
}
|
|
public static void TranslateMatrix(ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = 1;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = 1;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = 1;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = vector.X;
|
|
result.R3C1 = vector.Y;
|
|
result.R3C2 = vector.Z;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void Scale(double x, double y, double z)
|
|
{
|
|
R0C0 = x * R0C0;
|
|
R0C1 = x * R0C1;
|
|
R0C2 = x * R0C2;
|
|
R0C3 = x * R0C3;
|
|
R1C0 = y * R1C0;
|
|
R1C1 = y * R1C1;
|
|
R1C2 = y * R1C2;
|
|
R1C3 = y * R1C3;
|
|
R2C0 = z * R2C0;
|
|
R2C1 = z * R2C1;
|
|
R2C2 = z * R2C2;
|
|
R2C3 = z * R2C3;
|
|
}
|
|
public void Scale(double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = x * R0C0;
|
|
result.R0C1 = x * R0C1;
|
|
result.R0C2 = x * R0C2;
|
|
result.R0C3 = x * R0C3;
|
|
result.R1C0 = y * R1C0;
|
|
result.R1C1 = y * R1C1;
|
|
result.R1C2 = y * R1C2;
|
|
result.R1C3 = y * R1C3;
|
|
result.R2C0 = z * R2C0;
|
|
result.R2C1 = z * R2C1;
|
|
result.R2C2 = z * R2C2;
|
|
result.R2C3 = z * R2C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void Scale(ref Matrix4d matrix, double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = x * matrix.R0C0;
|
|
result.R0C1 = x * matrix.R0C1;
|
|
result.R0C2 = x * matrix.R0C2;
|
|
result.R0C3 = x * matrix.R0C3;
|
|
result.R1C0 = y * matrix.R1C0;
|
|
result.R1C1 = y * matrix.R1C1;
|
|
result.R1C2 = y * matrix.R1C2;
|
|
result.R1C3 = y * matrix.R1C3;
|
|
result.R2C0 = z * matrix.R2C0;
|
|
result.R2C1 = z * matrix.R2C1;
|
|
result.R2C2 = z * matrix.R2C2;
|
|
result.R2C3 = z * matrix.R2C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void ScaleMatrix(double x, double y, double z, out Matrix4d result)
|
|
{
|
|
result.R0C0 = x;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = y;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = z;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
public void Scale(ref Vector3d vector)
|
|
{
|
|
R0C0 = vector.X * R0C0;
|
|
R0C1 = vector.X * R0C1;
|
|
R0C2 = vector.X * R0C2;
|
|
R0C3 = vector.X * R0C3;
|
|
R1C0 = vector.Y * R1C0;
|
|
R1C1 = vector.Y * R1C1;
|
|
R1C2 = vector.Y * R1C2;
|
|
R1C3 = vector.Y * R1C3;
|
|
R2C0 = vector.Z * R2C0;
|
|
R2C1 = vector.Z * R2C1;
|
|
R2C2 = vector.Z * R2C2;
|
|
R2C3 = vector.Z * R2C3;
|
|
}
|
|
public void Scale(ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = vector.X * R0C0;
|
|
result.R0C1 = vector.X * R0C1;
|
|
result.R0C2 = vector.X * R0C2;
|
|
result.R0C3 = vector.X * R0C3;
|
|
result.R1C0 = vector.Y * R1C0;
|
|
result.R1C1 = vector.Y * R1C1;
|
|
result.R1C2 = vector.Y * R1C2;
|
|
result.R1C3 = vector.Y * R1C3;
|
|
result.R2C0 = vector.Z * R2C0;
|
|
result.R2C1 = vector.Z * R2C1;
|
|
result.R2C2 = vector.Z * R2C2;
|
|
result.R2C3 = vector.Z * R2C3;
|
|
result.R3C0 = R3C0;
|
|
result.R3C1 = R3C1;
|
|
result.R3C2 = R3C2;
|
|
result.R3C3 = R3C3;
|
|
}
|
|
public static void Scale(ref Matrix4d matrix, ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = vector.X * matrix.R0C0;
|
|
result.R0C1 = vector.X * matrix.R0C1;
|
|
result.R0C2 = vector.X * matrix.R0C2;
|
|
result.R0C3 = vector.X * matrix.R0C3;
|
|
result.R1C0 = vector.Y * matrix.R1C0;
|
|
result.R1C1 = vector.Y * matrix.R1C1;
|
|
result.R1C2 = vector.Y * matrix.R1C2;
|
|
result.R1C3 = vector.Y * matrix.R1C3;
|
|
result.R2C0 = vector.Z * matrix.R2C0;
|
|
result.R2C1 = vector.Z * matrix.R2C1;
|
|
result.R2C2 = vector.Z * matrix.R2C2;
|
|
result.R2C3 = vector.Z * matrix.R2C3;
|
|
result.R3C0 = matrix.R3C0;
|
|
result.R3C1 = matrix.R3C1;
|
|
result.R3C2 = matrix.R3C2;
|
|
result.R3C3 = matrix.R3C3;
|
|
}
|
|
public static void ScaleMatrix(ref Vector3d vector, out Matrix4d result)
|
|
{
|
|
result.R0C0 = vector.X;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = vector.Y;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = vector.Z;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = 0;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
/// <summary>Gets left viewing matrix derived from an eye point, left reference point indicating the center of the scene, and an UP vector.</summary>
|
|
/// <param name="eyeX">The eye position X coordinate.</param>
|
|
/// <param name="eyeY">The eye position Y coordinate.</param>
|
|
/// <param name="eyeZ">The eye position Z coordinate.</param>
|
|
/// <param name="centerX">The center position X coordinate.</param>
|
|
/// <param name="centerY">The center position Y coordinate.</param>
|
|
/// <param name="centerZ">The center position Z coordinate.</param>
|
|
/// <param name="upX">The up direction X coordinate.</param>
|
|
/// <param name="upY">The up direction Y coordinate.</param>
|
|
/// <param name="upZ">The up direction Z coordinate.</param>
|
|
/// <returns>A viewing matrix derived from an eye point, left reference point indicating the center of the scene, and an UP vector.</returns>
|
|
public static void LookAt(double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ, out Matrix4d result)
|
|
{
|
|
Vector3d eye = new Vector3d(eyeX, eyeY, eyeZ);
|
|
Vector3d center = new Vector3d(centerX, centerY, centerZ);
|
|
Vector3d up = new Vector3d(upX, upY, upZ);
|
|
LookAt(ref eye, ref center, ref up, out result);
|
|
}
|
|
|
|
/// <summary>Gets left viewing matrix derived from an eye point, left reference point indicating the center of the scene, and an UP vector.</summary>
|
|
/// <param name="eye">The position of the eye.</param>
|
|
/// <param name="center">The position of reference point.</param>
|
|
/// <param name="up">The direction of the up vector</param>
|
|
/// <returns>A viewing matrix derived from an eye point, left reference point indicating the center of the scene, and an UP vector.</returns>
|
|
public static void LookAt(ref Vector3d eye, ref Vector3d center, ref Vector3d up, out Matrix4d result)
|
|
{
|
|
Vector3d f;
|
|
center.Subtract(ref eye, out f);
|
|
f.Normalize();
|
|
|
|
Vector3d upNormalized;
|
|
up.Normalize(out upNormalized);
|
|
|
|
Vector3d s;
|
|
Vector3d.CrossProduct(ref f, ref upNormalized, out s);
|
|
s.Normalize();
|
|
|
|
Vector3d u;
|
|
Vector3d.CrossProduct(ref s, ref f, out u);
|
|
|
|
result.R0C0 = s.X;
|
|
result.R0C1 = u.X;
|
|
result.R0C2 = -f.X;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = s.Y;
|
|
result.R1C1 = u.Y;
|
|
result.R1C2 = -f.Y;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = s.Z;
|
|
result.R2C1 = u.Z;
|
|
result.R2C2 = -f.Z;
|
|
result.R2C3 = 0;
|
|
result.R3C0 = -eye.X * s.X - eye.Y * s.Y - eye.Z * s.Z;
|
|
result.R3C1 = -eye.X * u.X - eye.Y * u.Y - eye.Z * u.Z;
|
|
result.R3C2 = +eye.X * f.X + eye.Y * f.Y + eye.Z * f.Z;
|
|
result.R3C3 = 1;
|
|
}
|
|
|
|
/// <summary>Gets left perspective matrix that produces left perspective projection.</summary>
|
|
/// <param name="matrix">The matrix vertical clipping plane.</param>
|
|
/// <param name="right">The right vertical clipping plane.</param>
|
|
/// <param name="bottom">The bottom horizontal clipping plane.</param>
|
|
/// <param name="top">The top horizontal clipping plane.</param>
|
|
/// <param name="near">The distances to the near depth clipping plane. Must be positive.</param>
|
|
/// <param name="far">The distances to the far depth clipping plane. Must be positive.</param>
|
|
/// <returns>A perspective matrix for the perspective projection.</returns>
|
|
public static void Frustum(double left, double right, double bottom, double top, double near, double far, out Matrix4d result)
|
|
{
|
|
double horizontalDelta = right - left;
|
|
double verticalDelta = top - bottom;
|
|
double negativeDepthDelta = -(far - near);
|
|
double near2 = near * 2;
|
|
|
|
result.R0C0 = near2 / horizontalDelta;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = near2 / verticalDelta;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = (right + left) / horizontalDelta;
|
|
result.R2C1 = (top + bottom) / verticalDelta;
|
|
result.R2C2 = (far + near) / negativeDepthDelta;
|
|
result.R2C3 = -1;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = near2 * far / negativeDepthDelta;
|
|
result.R3C3 = 0;
|
|
}
|
|
|
|
/// <summary>Gets left viewing frustum into the world coordinate system.</summary>
|
|
/// <param name="fovy">The field of view angle, in degrees, in the y direction.</param>
|
|
/// <param name="aspect">the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).</param>
|
|
/// <param name="near">the distance from the viewer to the near clipping plane (always positive).</param>
|
|
/// <param name="far">the distance from the viewer to the far clipping plane (always positive).</param>
|
|
/// <returns>A viewing frustum into the world coordinate system.</returns>
|
|
public static void Perspective(double fovy, double aspect, double near, double far, out Matrix4d result)
|
|
{
|
|
double cot = System.Math.Tan(fovy * Functions.DTOR / 2.0d);
|
|
double f = 1 / cot;
|
|
|
|
result.R0C0 = f / aspect;
|
|
result.R0C1 = 0;
|
|
result.R0C2 = 0;
|
|
result.R0C3 = 0;
|
|
result.R1C0 = 0;
|
|
result.R1C1 = f;
|
|
result.R1C2 = 0;
|
|
result.R1C3 = 0;
|
|
result.R2C0 = 0;
|
|
result.R2C1 = 0;
|
|
result.R2C2 = (far + near) / (near - far);
|
|
result.R2C3 = -1;
|
|
result.R3C0 = 0;
|
|
result.R3C1 = 0;
|
|
result.R3C2 = (2 * far * near) / (near - far);
|
|
result.R3C3 = 0;
|
|
}
|
|
|
|
public void Quaternion(out Quaterniond quaternion)
|
|
{
|
|
quaternion = new Quaterniond(ref this);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Constants
|
|
|
|
/// <summary>The identity matrix.</summary>
|
|
public static readonly Matrix4d Identity = new Matrix4d
|
|
(
|
|
1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1
|
|
);
|
|
|
|
/// <summary>A matrix of all zeros.</summary>
|
|
public static readonly Matrix4d Zero = new Matrix4d
|
|
(
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0
|
|
);
|
|
|
|
#endregion
|
|
|
|
|
|
#region HashCode
|
|
|
|
/// <summary>Returns the hash code for this instance.</summary>
|
|
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
|
public override int GetHashCode()
|
|
{
|
|
return
|
|
R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^ R0C3.GetHashCode() ^
|
|
R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^ R1C3.GetHashCode() ^
|
|
R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode() ^ R2C3.GetHashCode() ^
|
|
R3C0.GetHashCode() ^ R3C1.GetHashCode() ^ R3C2.GetHashCode() ^ R3C3.GetHashCode();
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region String
|
|
|
|
/// <summary>Returns the fully qualified type name of this instance.</summary>
|
|
/// <returns>A System.String containing left fully qualified type name.</returns>
|
|
public override string ToString()
|
|
{
|
|
return String.Format(
|
|
"|{00}, {01}, {02}, {03}|\n" +
|
|
"|{04}, {05}, {06}, {07}|\n" +
|
|
"|{08}, {09}, {10}, {11}|\n" +
|
|
"|{12}, {13}, {14}, {15}|",
|
|
R0C0, R0C1, R0C2, R0C3,
|
|
R1C0, R1C1, R1C2, R1C3,
|
|
R2C0, R2C1, R2C2, R2C3,
|
|
R3C0, R3C1, R3C2, R3C3);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|