/// <summary> /// Multiplies the two matrices. Remember that Matrix multiplication is not commutative. /// </summary> /// <param name="matA">The first matrix.</param> /// <param name="matB">The second matrix.</param> /// <param name="resultantDimension">The number of rows and columns in <paramref name="matA"/> and /// <paramref name="matB"/> that should be used in the multiplication calculation. The resultant matrix will /// also have this many rows and columns filled in.</param> /// <returns><paramref name="matA"/> x <paramref name="matB"/></returns> public static Matrix Multiply(Matrix matA, Matrix matB, int resultantDimension = 4) { Assure.BetweenOrEqualTo(resultantDimension, 1, 4, "Resultant dimension must be between 1 and 4."); switch (resultantDimension) { case 1: return(new Matrix(r0C0: Vector4.Dot(matA.RowA, matB.ColumnA))); case 2: return(new Matrix( r0C0: Vector4.Dot(matA.RowA, matB.ColumnA), r0C1: Vector4.Dot(matA.RowA, matB.ColumnB), r1C0: Vector4.Dot(matA.RowB, matB.ColumnA), r1C1: Vector4.Dot(matA.RowB, matB.ColumnB) )); case 3: Vector4 matBColA = matB.ColumnA; Vector4 matBColB = matB.ColumnB; Vector4 matBColC = matB.ColumnC; return(new Matrix( r0C0: Vector4.Dot(matA.RowA, matBColA), r0C1: Vector4.Dot(matA.RowA, matBColB), r0C2: Vector4.Dot(matA.RowA, matBColC), r1C0: Vector4.Dot(matA.RowB, matBColA), r1C1: Vector4.Dot(matA.RowB, matBColB), r1C2: Vector4.Dot(matA.RowB, matBColC), r2C0: Vector4.Dot(matA.RowC, matBColA), r2C1: Vector4.Dot(matA.RowC, matBColB), r2C2: Vector4.Dot(matA.RowC, matBColC) )); case 4: return(matA * matB); default: Logger.Warn("Matrix.Multiply called with resultantDimension of: " + resultantDimension + "!"); return(ZERO); } }
public void TestBetweenOrEqualTo() { // Define variables and constants const int FIVE = 5; const int FOUR = 4; const int THREE = 3; // Set up context // Execute Assure.BetweenOrEqualTo(FOUR, THREE, FIVE); Assure.BetweenOrEqualTo(FOUR, FOUR, FIVE); try { Assure.BetweenOrEqualTo(THREE, FOUR, FIVE); Assert.Fail(); } catch (AssuranceFailedException) { } // Assert outcome }
/// <summary> /// Returns the determinant of this Matrix, used to calculate the <see cref="Cofactor"/> and <see cref="Inverse"/>. /// </summary> /// <param name="dimension">The number of rows and columns in this matrix to use in the determinant calculation.</param> /// <returns>The determinant of this matrix.</returns> public float GetDeterminant(int dimension = 4) { Assure.BetweenOrEqualTo(dimension, 1, 4, "Input dimension must be between 1 and 4."); switch (dimension) { case 1: return(RowA.X); case 2: return(RowA.X * RowB.Y - RowA.Y * RowB.X); case 3: return(RowA.X * (RowB.Y * RowC.Z - RowB.Z * RowC.Y) - RowA.Y * (RowB.X * RowC.Z - RowB.Z * RowC.X) + RowA.Z * (RowB.X * RowC.Y - RowB.Y * RowC.X)); default: return (RowA.X * GetMinor(0, 0).GetDeterminant(3) - RowA.Y * GetMinor(0, 1).GetDeterminant(3) + RowA.Z * GetMinor(0, 2).GetDeterminant(3) - RowA.W * GetMinor(0, 3).GetDeterminant(3)); } }
/// <summary> /// Returns a new <see cref="Matrix"/> that is the same as this Matrix, except with the row indexed by /// <paramref name="row"/> and the column indexed by <paramref name="column"/> removed. /// </summary> /// <remarks> /// The three remaining rows and columns will be 'squeezed up' in to a 3x3 matrix, and the fourth row and fourth /// column will be filled with zeroes. An example follows: /// <code> /// Matrix matrix = new Matrix( /// 00f, 01f, 02f, 03f, /// 10f, 11f, 12f, 13f, /// 20f, 21f, 22f, 23f, /// 30f, 31f, 32f, 33f /// ); /// /// Matrix minor22 = matrix.GetMinor(2, 2); /// /// // minor22: /// // [00f, 01f, 03f, 00f] /// // [10f, 11f, 13f, 00f] /// // [30f, 31f, 33f, 00f] /// // [00f, 00f, 00f, 00f] /// </code> /// </remarks> /// <param name="row">The row index to remove, from 0 to 3.</param> /// <param name="column">The column index to remove, from 0 to 3.</param> /// <exception cref="ArgumentException">Thrown if <paramref name="row"/> or <paramref name="column"/> /// are < 0 or > 3.</exception> /// <returns>The requested matrix minor.</returns> public Matrix GetMinor(int row, int column) { Assure.BetweenOrEqualTo(row, 0, 3, "Row index must be between 0 and 3."); Assure.BetweenOrEqualTo(column, 0, 3, "Column index must be between 0 and 3."); switch (row) { case 0: switch (column) { case 0: // Row 0 Column 0 return(new Matrix(RowB[1, 2, 3], RowC[1, 2, 3], RowD[1, 2, 3], Vector4.ZERO)); case 1: // Row 0 Column 1 return(new Matrix(RowB[0, 2, 3], RowC[0, 2, 3], RowD[0, 2, 3], Vector4.ZERO)); case 2: // Row 0 Column 2 return(new Matrix(RowB[0, 1, 3], RowC[0, 1, 3], RowD[0, 1, 3], Vector4.ZERO)); case 3: // Row 0 Column 3 return(new Matrix(RowB[0, 1, 2], RowC[0, 1, 2], RowD[0, 1, 2], Vector4.ZERO)); } break; case 1: switch (column) { case 0: // Row 1 Column 0 return(new Matrix(RowA[1, 2, 3], RowC[1, 2, 3], RowD[1, 2, 3], Vector4.ZERO)); case 1: // Row 1 Column 1 return(new Matrix(RowA[0, 2, 3], RowC[0, 2, 3], RowD[0, 2, 3], Vector4.ZERO)); case 2: // Row 1 Column 2 return(new Matrix(RowA[0, 1, 3], RowC[0, 1, 3], RowD[0, 1, 3], Vector4.ZERO)); case 3: // Row 1 Column 3 return(new Matrix(RowA[0, 1, 2], RowC[0, 1, 2], RowD[0, 1, 2], Vector4.ZERO)); } break; case 2: switch (column) { case 0: // Row 2 Column 0 return(new Matrix(RowA[1, 2, 3], RowB[1, 2, 3], RowD[1, 2, 3], Vector4.ZERO)); case 1: // Row 2 Column 1 return(new Matrix(RowA[0, 2, 3], RowB[0, 2, 3], RowD[0, 2, 3], Vector4.ZERO)); case 2: // Row 2 Column 2 return(new Matrix(RowA[0, 1, 3], RowB[0, 1, 3], RowD[0, 1, 3], Vector4.ZERO)); case 3: // Row 2 Column 3 return(new Matrix(RowA[0, 1, 2], RowB[0, 1, 2], RowD[0, 1, 2], Vector4.ZERO)); } break; case 3: switch (column) { case 0: // Row 3 Column 0 return(new Matrix(RowA[1, 2, 3], RowB[1, 2, 3], RowC[1, 2, 3], Vector4.ZERO)); case 1: // Row 3 Column 1 return(new Matrix(RowA[0, 2, 3], RowB[0, 2, 3], RowC[0, 2, 3], Vector4.ZERO)); case 2: // Row 3 Column 2 return(new Matrix(RowA[0, 1, 3], RowB[0, 1, 3], RowC[0, 1, 3], Vector4.ZERO)); case 3: // Row 3 Column 3 return(new Matrix(RowA[0, 1, 2], RowB[0, 1, 2], RowC[0, 1, 2], Vector4.ZERO)); } break; } throw new ArgumentException("Matrix minor requested with row: " + row + ", column: " + column + "!"); }