官术网_书友最值得收藏!

Matrix inverse

The inverse of matrix M is denoted as Matrix inverse. Multiplying a matrix by its inverse will result in the identity matrix. Not every matrix has an inverse. Only matrices with a non-zero determinant have an inverse. Finding the inverse of a matrix is one of the more expensive operations we are going to perform. However, not every matrix has an inverse! Only square matrices with a non-zero determinant have an inverse.

To find the inverse of a matrix, first find the inverse of its determinantMatrix inverse. If this scalar is zero, the matrix has no inverse. If it's non-zero, perform a component wise scalar multiplication of the inverse determinant and the adjugate of the matrix:

Matrix inverse

Getting ready

Having already implemented both the Determinant and Adjugate functions, all we have to do is make sure the matrix actually has an inverse. We do this by checking the determinant against 0, using the CMP macro we copied over from vectors.cpp. If the determinant is 0, we just return the identity matrix. Doing so prevents us from triggering a possible divide by 0 exception.

How to do it…

Follow these steps to implement a function which returns the inverse of two, three and four dimensional square matrices:

  1. Add the declaration for the inverse functions to matrices.h:
    mat2 Inverse(const mat2& mat);
    mat3 Inverse(const mat3& mat);
    mat4 Inverse(const mat4& mat);
  2. Implement these functions in matrices.cpp:
    mat2 Inverse(const mat2& mat) {
        float det = Determinant(mat);
        if (CMP(det, 0.0f)) { return mat2(); }
        return Adjugate(mat) * (1.0f / det);
    }
    mat3 Inverse(const mat3& mat) {
        float det = Determinant(mat);
        if (CMP(det, 0.0f)) { return mat3(); }
        return Adjugate(mat) * (1.0f / det);
    }
    mat4 Inverse(const mat4& mat) {
        float det = Determinant(mat);
        if (CMP(det, 0.0f)) { return mat4(); }
        return Adjugate(mat) * (1.0f / det);
    }

How it works…

Finding the inverse of a matrix comes down to two functions we have already implemented; Determinant and Adjugate. The reason only matrices with a non-zero determinant have an inverse is this part of the inverse equation: How it works…. If the determinant of the matrix were 0, we would have a divide by 0 to deal with. Because division by 0 is undefined, so is the inverse of any matrix that has a determinant of 0.

There's more…

Loops in code are expensive! To a much lesser extent, so are function calls. Our matrix inverse function heavily relies on both! Inverting a 4 X 4 matrix is such a common operation; you should really consider expanding this function. You've already seen an expanded function, the determinant of a 2 X 2 matrix.

Expanding the inverse

Expanding a function is just a fancy way of saying we're planning to unroll all loops and write out every operation the computer has to do in a linear fashion. For the 2 X 2 matrix, the expanded code looks like this:

mat2 Inverse(const mat2& mat) {
    float det = mat._11 * mat._22 - mat._12 * mat._21;
    if (CMP(det, 0.0f)) { 
        return mat2(); 
    }
    mat2 result;
    float i_det = 1.0f / det;     //To avoid excessive division
    result._11 =  mat._22 * i_det;//Do reciprocal multiplication
    result._12 = -mat._12 * i_det;
    result._21 = -mat._21 * i_det;
    result._22 =  mat._11 * i_det;
    return result;
}

Expanding 4 X 4 matrix multiplication would take almost two pages of text; instead of including it here, I've gone ahead and included it in the downloadable code for this book.

主站蜘蛛池模板: 舒兰市| 黎川县| 桓仁| 潜山县| 克什克腾旗| 信宜市| 永顺县| 全椒县| 西昌市| 安徽省| 保德县| 剑阁县| 乾安县| 桦南县| 固安县| 林芝县| 闵行区| 白朗县| 鄂托克前旗| 鄢陵县| 新竹县| 大丰市| 始兴县| 永胜县| 闵行区| 新巴尔虎右旗| 舟曲县| 衡南县| 八宿县| 夏河县| 剑阁县| 炎陵县| 富蕴县| 朔州市| 湘西| 旬邑县| 聂荣县| 上高县| 石狮市| 正镶白旗| 高邮市|