Example #1
0
    /// <summary>
    /// Inverts the largest nonsingular submatrix in the matrix, excluding 2x2's that involve M13 or M31, and excluding 1x1's that include nondiagonal elements.
    /// </summary>
    /// <param name="matrix">FixMatrix to be inverted.</param>
    /// <param name="result">Inverted matrix.</param>
    public static void AdaptiveInvert(fix3x3 matrix, out fix3x3 result)
    {
        // Perform full Gauss-invert and return if successful
        if (Invert(matrix, out result))
        {
            return;
        }

        int submatrix;
        fix determinantInverse = F64.C1 / matrix.AdaptiveDeterminant(out submatrix);
        fix m11, m12, m13, m21, m22, m23, m31, m32, m33;

        switch (submatrix)
        {
        case 1:     //Upper left matrix, m11, m12, m21, m22.
            m11 = matrix.M22 * determinantInverse;
            m12 = -matrix.M12 * determinantInverse;
            m13 = F64.C0;

            m21 = -matrix.M21 * determinantInverse;
            m22 = matrix.M11 * determinantInverse;
            m23 = F64.C0;

            m31 = F64.C0;
            m32 = F64.C0;
            m33 = F64.C0;
            break;

        case 2:     //Lower right matrix, m22, m23, m32, m33.
            m11 = F64.C0;
            m12 = F64.C0;
            m13 = F64.C0;

            m21 = F64.C0;
            m22 = matrix.M33 * determinantInverse;
            m23 = -matrix.M23 * determinantInverse;

            m31 = F64.C0;
            m32 = -matrix.M32 * determinantInverse;
            m33 = matrix.M22 * determinantInverse;
            break;

        case 3:     //Corners, m11, m31, m13, m33.
            m11 = matrix.M33 * determinantInverse;
            m12 = F64.C0;
            m13 = -matrix.M13 * determinantInverse;

            m21 = F64.C0;
            m22 = F64.C0;
            m23 = F64.C0;

            m31 = -matrix.M31 * determinantInverse;
            m32 = F64.C0;
            m33 = matrix.M11 * determinantInverse;
            break;

        case 4:     //M11
            m11 = F64.C1 / matrix.M11;
            m12 = F64.C0;
            m13 = F64.C0;

            m21 = F64.C0;
            m22 = F64.C0;
            m23 = F64.C0;

            m31 = F64.C0;
            m32 = F64.C0;
            m33 = F64.C0;
            break;

        case 5:     //M22
            m11 = F64.C0;
            m12 = F64.C0;
            m13 = F64.C0;

            m21 = F64.C0;
            m22 = F64.C1 / matrix.M22;
            m23 = F64.C0;

            m31 = F64.C0;
            m32 = F64.C0;
            m33 = F64.C0;
            break;

        case 6:     //M33
            m11 = F64.C0;
            m12 = F64.C0;
            m13 = F64.C0;

            m21 = F64.C0;
            m22 = F64.C0;
            m23 = F64.C0;

            m31 = F64.C0;
            m32 = F64.C0;
            m33 = F64.C1 / matrix.M33;
            break;

        default:     //Completely singular.
            m11 = F64.C0; m12 = F64.C0; m13 = F64.C0; m21 = F64.C0; m22 = F64.C0; m23 = F64.C0; m31 = F64.C0; m32 = F64.C0; m33 = F64.C0;
            break;
        }

        result.M11 = m11;
        result.M12 = m12;
        result.M13 = m13;

        result.M21 = m21;
        result.M22 = m22;
        result.M23 = m23;

        result.M31 = m31;
        result.M32 = m32;
        result.M33 = m33;
    }