예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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
        }
예제 #3
0
        /// <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));
            }
        }
예제 #4
0
        /// <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 &lt; 0 or &gt; 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 + "!");
        }