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

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.

主站蜘蛛池模板: 舞阳县| 万州区| 枣阳市| 海丰县| 荥阳市| 巴东县| 洛宁县| 准格尔旗| 社旗县| 商河县| 深圳市| 长海县| 蒙城县| 泉州市| 金坛市| 秦安县| 江西省| 舒城县| 乐昌市| 上思县| 沂南县| 噶尔县| 马边| 交口县| 虹口区| 怀仁县| 抚州市| 景德镇市| 义马市| 台中县| 平乡县| 汉沽区| 巴里| 新津县| 新龙县| 攀枝花市| 息烽县| 河北区| 济阳县| 浦县| 龙胜|