Efficient 4x4 matrix inverse (affine transform)

后端 未结 5 665
自闭症患者
自闭症患者 2020-12-23 02:20

I was hoping someone can point out an efficient formula for 4x4 affine matrix transform. Currently my code uses cofactor expansion and it allocates a temporary array for ea

5条回答
  •  独厮守ぢ
    2020-12-23 02:58

    To follow-up on pkhaler's and Robin Hilliard's excellent responses above, here is Robin's ActionScript 3 code converted into a C# method. Hopefully this can save some typing for other C# developers, as well as C/C++ and Java developers in need of a 4x4 matrix inversion function:

    public static double[,] GetInverse(double[,] a)
    {
        var s0 = a[0, 0] * a[1, 1] - a[1, 0] * a[0, 1];
        var s1 = a[0, 0] * a[1, 2] - a[1, 0] * a[0, 2];
        var s2 = a[0, 0] * a[1, 3] - a[1, 0] * a[0, 3];
        var s3 = a[0, 1] * a[1, 2] - a[1, 1] * a[0, 2];
        var s4 = a[0, 1] * a[1, 3] - a[1, 1] * a[0, 3];
        var s5 = a[0, 2] * a[1, 3] - a[1, 2] * a[0, 3];
    
        var c5 = a[2, 2] * a[3, 3] - a[3, 2] * a[2, 3];
        var c4 = a[2, 1] * a[3, 3] - a[3, 1] * a[2, 3];
        var c3 = a[2, 1] * a[3, 2] - a[3, 1] * a[2, 2];
        var c2 = a[2, 0] * a[3, 3] - a[3, 0] * a[2, 3];
        var c1 = a[2, 0] * a[3, 2] - a[3, 0] * a[2, 2];
        var c0 = a[2, 0] * a[3, 1] - a[3, 0] * a[2, 1];
    
        // Should check for 0 determinant
        var invdet = 1.0 / (s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0);
    
        var b = new double[4, 4];
    
        b[0, 0] = ( a[1, 1] * c5 - a[1, 2] * c4 + a[1, 3] * c3) * invdet;
        b[0, 1] = (-a[0, 1] * c5 + a[0, 2] * c4 - a[0, 3] * c3) * invdet;
        b[0, 2] = ( a[3, 1] * s5 - a[3, 2] * s4 + a[3, 3] * s3) * invdet;
        b[0, 3] = (-a[2, 1] * s5 + a[2, 2] * s4 - a[2, 3] * s3) * invdet;
    
        b[1, 0] = (-a[1, 0] * c5 + a[1, 2] * c2 - a[1, 3] * c1) * invdet;
        b[1, 1] = ( a[0, 0] * c5 - a[0, 2] * c2 + a[0, 3] * c1) * invdet;
        b[1, 2] = (-a[3, 0] * s5 + a[3, 2] * s2 - a[3, 3] * s1) * invdet;
        b[1, 3] = ( a[2, 0] * s5 - a[2, 2] * s2 + a[2, 3] * s1) * invdet;
    
        b[2, 0] = ( a[1, 0] * c4 - a[1, 1] * c2 + a[1, 3] * c0) * invdet;
        b[2, 1] = (-a[0, 0] * c4 + a[0, 1] * c2 - a[0, 3] * c0) * invdet;
        b[2, 2] = ( a[3, 0] * s4 - a[3, 1] * s2 + a[3, 3] * s0) * invdet;
        b[2, 3] = (-a[2, 0] * s4 + a[2, 1] * s2 - a[2, 3] * s0) * invdet;
    
        b[3, 0] = (-a[1, 0] * c3 + a[1, 1] * c1 - a[1, 2] * c0) * invdet;
        b[3, 1] = ( a[0, 0] * c3 - a[0, 1] * c1 + a[0, 2] * c0) * invdet;
        b[3, 2] = (-a[3, 0] * s3 + a[3, 1] * s1 - a[3, 2] * s0) * invdet;
        b[3, 3] = ( a[2, 0] * s3 - a[2, 1] * s1 + a[2, 2] * s0) * invdet;
    
        return b;
    }
    

提交回复
热议问题