LoginSignup
4
4

More than 5 years have passed since last update.

4 x 4 行列の逆行列を求める

Last updated at Posted at 2012-07-25

何度も心折れそうになりました。
ちょっといじくれば他の言語でも使えます。きっと。

ActionScript
class Mat44 {
    public var e00:Number, e01:Number, e02:Number, e03:Number;
    public var e10:Number, e11:Number, e12:Number, e13:Number;
    public var e20:Number, e21:Number, e22:Number, e23:Number;
    public var e30:Number, e31:Number, e32:Number, e33:Number;

    /*
     * this = m^-1
     */
    public function invert(m:Mat44):void {
        var e1021_1120:Number = m.e10 * m.e21 - m.e11 * m.e20;
        var e1022_1220:Number = m.e10 * m.e22 - m.e12 * m.e20;
        var e1023_1320:Number = m.e10 * m.e23 - m.e13 * m.e20;
        var e1031_1130:Number = m.e10 * m.e31 - m.e11 * m.e30;
        var e1032_1230:Number = m.e10 * m.e32 - m.e12 * m.e30;
        var e1033_1330:Number = m.e10 * m.e33 - m.e13 * m.e30;
        var e1122_1221:Number = m.e11 * m.e22 - m.e12 * m.e21;
        var e1123_1321:Number = m.e11 * m.e23 - m.e13 * m.e21;
        var e1132_1231:Number = m.e11 * m.e32 - m.e12 * m.e31;
        var e1133_1331:Number = m.e11 * m.e33 - m.e13 * m.e31;
        var e1220_2022:Number = m.e12 * m.e20 - m.e20 * m.e22;
        var e1223_1322:Number = m.e12 * m.e23 - m.e13 * m.e22;
        var e1223_2223:Number = m.e12 * m.e33 - m.e22 * m.e23;
        var e1233_1332:Number = m.e12 * m.e33 - m.e13 * m.e32;
        var e2031_2130:Number = m.e20 * m.e31 - m.e21 * m.e30;
        var e2032_2033:Number = m.e20 * m.e32 - m.e20 * m.e33;
        var e2032_2230:Number = m.e20 * m.e32 - m.e22 * m.e30;
        var e2033_2330:Number = m.e20 * m.e33 - m.e23 * m.e30;
        var e2132_2231:Number = m.e21 * m.e32 - m.e22 * m.e31;
        var e2133_2331:Number = m.e21 * m.e33 - m.e23 * m.e31;
        var e2230_2330:Number = m.e22 * m.e30 - m.e23 * m.e30;
        var e2233_2332:Number = m.e22 * m.e33 - m.e23 * m.e32;
        var det:Number =
            m.e00 * (m.e11 * e2233_2332 - m.e12 * e2133_2331 + m.e13 * e2132_2231) +
            m.e01 * (-m.e10 * e2233_2332 - m.e12 * e2032_2033 + m.e13 * e2230_2330) +
            m.e02 * (m.e10 * e2133_2331 - m.e11 * e2033_2330 + m.e13 * e2031_2130) +
            m.e03 * (-m.e10 * e2132_2231 + m.e11 * e2032_2230 - m.e12 * e2031_2130)
        ;
        if (det != 0) det = 1 / det;
        var t00:Number = m.e11 * e2233_2332 - m.e12 * e2133_2331 + m.e13 * e2132_2231;
        var t01:Number = -m.e01 * e2233_2332 + m.e02 * e2133_2331 - m.e03 * e2132_2231;
        var t02:Number = m.e01 * e1233_1332 - m.e02 * e1133_1331 + m.e03 * e1132_1231;
        var t03:Number = -m.e01 * e1223_2223 + m.e02 * e1123_1321 - m.e03 * e1122_1221;
        var t10:Number = -m.e10 * e2233_2332 + m.e12 * e2033_2330 - m.e13 * e2032_2230;
        var t11:Number = m.e00 * e2233_2332 - m.e02 * e2033_2330 + m.e03 * e2032_2230;
        var t12:Number = -m.e00 * e1233_1332 + m.e02 * e1033_1330 - m.e03 * e1032_1230;
        var t13:Number = m.e00 * e1223_1322 - m.e02 * e1023_1320 - m.e03 * e1220_2022;
        var t20:Number = m.e10 * e2133_2331 - m.e11 * e2033_2330 + m.e13 * e2031_2130;
        var t21:Number = -m.e00 * e2133_2331 + m.e01 * e2033_2330 - m.e03 * e2031_2130;
        var t22:Number = m.e00 * e1133_1331 - m.e01 * e1033_1330 + m.e03 * e1031_1130;
        var t23:Number = -m.e00 * e1123_1321 + m.e01 * e1023_1320 - m.e03 * e1021_1120;
        var t30:Number = -m.e10 * e2132_2231 + m.e11 * e2032_2230 - m.e12 * e2031_2130;
        var t31:Number = m.e00 * e2132_2231 - m.e01 * e2032_2230 + m.e02 * e2031_2130;
        var t32:Number = -m.e00 * e1132_1231 + m.e01 * e1032_1230 - m.e02 * e1031_1130;
        var t33:Number = m.e00 * e1122_1221 - m.e01 * e1022_1220 + m.e02 * e1021_1120;
        e00 = det * t00; e01 = det * t01; e02 = det * t02; e03 = det * t03;
        e10 = det * t10; e11 = det * t11; e12 = det * t12; e13 = det * t13;
        e20 = det * t20; e21 = det * t21; e22 = det * t22; e23 = det * t23;
        e30 = det * t30; e31 = det * t31; e32 = det * t32; e33 = det * t33;
    }
    /*public function invert(m:Mat44):void {
        var det:Number =
            m.e00*m.e11*m.e22*m.e33+m.e00*m.e12*m.e23*m.e31+m.e00*m.e13*m.e21*m.e32+
            m.e01*m.e10*m.e23*m.e32+m.e01*m.e12*m.e20*m.e33+m.e01*m.e13*m.e22*m.e30+
            m.e02*m.e10*m.e21*m.e33+m.e02*m.e11*m.e23*m.e30+m.e02*m.e13*m.e20*m.e31+
            m.e03*m.e10*m.e22*m.e31+m.e03*m.e11*m.e20*m.e32+m.e03*m.e12*m.e21*m.e30-
            m.e00*m.e11*m.e23*m.e32-m.e00*m.e12*m.e21*m.e33-m.e00*m.e13*m.e22*m.e31-
            m.e01*m.e10*m.e22*m.e33-m.e01*m.e12*m.e23*m.e30-m.e01*m.e13*m.e20*m.e32-
            m.e02*m.e10*m.e23*m.e31-m.e02*m.e11*m.e20*m.e33-m.e02*m.e13*m.e21*m.e30-
            m.e03*m.e10*m.e21*m.e32-m.e03*m.e11*m.e22*m.e30-m.e03*m.e12*m.e20*m.e31
        ;
        if (det != 0) det = 1 / det;
        var t00:Number=m.e11*m.e22*m.e33+m.e12*m.e23*m.e31+m.e13*m.e21*m.e32-m.e11*m.e23*m.e32-m.e12*m.e21*m.e33-m.e13*m.e22*m.e31;
        var t01:Number=m.e01*m.e23*m.e32+m.e02*m.e21*m.e33+m.e03*m.e22*m.e31-m.e01*m.e22*m.e33-m.e02*m.e23*m.e31-m.e03*m.e21*m.e32;
        var t02:Number=m.e01*m.e12*m.e33+m.e02*m.e13*m.e31+m.e03*m.e11*m.e32-m.e01*m.e13*m.e32-m.e02*m.e11*m.e33-m.e03*m.e12*m.e31;
        var t03:Number=m.e01*m.e23*m.e22+m.e02*m.e11*m.e23+m.e03*m.e12*m.e21-m.e01*m.e12*m.e23-m.e02*m.e13*m.e21-m.e03*m.e11*m.e22;
        var t10:Number=m.e10*m.e23*m.e32+m.e12*m.e20*m.e33+m.e13*m.e22*m.e30-m.e10*m.e22*m.e33-m.e12*m.e23*m.e30-m.e13*m.e20*m.e32;
        var t11:Number=m.e00*m.e22*m.e33+m.e02*m.e23*m.e30+m.e03*m.e20*m.e32-m.e00*m.e23*m.e32-m.e02*m.e20*m.e33-m.e03*m.e22*m.e30;
        var t12:Number=m.e00*m.e13*m.e32+m.e02*m.e10*m.e33+m.e03*m.e12*m.e30-m.e00*m.e12*m.e33-m.e02*m.e13*m.e30-m.e03*m.e10*m.e32;
        var t13:Number=m.e00*m.e12*m.e23+m.e02*m.e13*m.e20+m.e03*m.e20*m.e22-m.e00*m.e13*m.e22-m.e02*m.e10*m.e23-m.e03*m.e12*m.e20;
        var t20:Number=m.e10*m.e21*m.e33+m.e11*m.e23*m.e30+m.e13*m.e20*m.e31-m.e10*m.e23*m.e31-m.e11*m.e20*m.e33-m.e13*m.e21*m.e30;
        var t21:Number=m.e00*m.e23*m.e31+m.e01*m.e20*m.e33+m.e03*m.e21*m.e30-m.e00*m.e21*m.e33-m.e01*m.e23*m.e30-m.e03*m.e20*m.e31;
        var t22:Number=m.e00*m.e11*m.e33+m.e01*m.e13*m.e30+m.e03*m.e10*m.e31-m.e00*m.e13*m.e31-m.e01*m.e10*m.e33-m.e03*m.e11*m.e30;
        var t23:Number=m.e00*m.e13*m.e21+m.e01*m.e10*m.e23+m.e03*m.e11*m.e20-m.e00*m.e11*m.e23-m.e01*m.e13*m.e20-m.e03*m.e10*m.e21;
        var t30:Number=m.e10*m.e22*m.e31+m.e11*m.e20*m.e32+m.e12*m.e21*m.e30-m.e10*m.e21*m.e32-m.e11*m.e22*m.e30-m.e12*m.e20*m.e31;
        var t31:Number=m.e00*m.e21*m.e32+m.e01*m.e22*m.e30+m.e02*m.e20*m.e31-m.e00*m.e22*m.e31-m.e01*m.e20*m.e32-m.e02*m.e21*m.e30;
        var t32:Number=m.e00*m.e12*m.e31+m.e01*m.e10*m.e32+m.e02*m.e11*m.e30-m.e00*m.e11*m.e32-m.e01*m.e12*m.e30-m.e02*m.e10*m.e31;
        var t33:Number=m.e00*m.e11*m.e22+m.e01*m.e12*m.e20+m.e02*m.e10*m.e21-m.e00*m.e12*m.e21-m.e01*m.e10*m.e22-m.e02*m.e11*m.e20;
        e00=det*t00;e01=det*t01;e02=det*t02;e03=det*t03;
        e10=det*t10;e11=det*t11;e12=det*t12;e13=det*t13;
        e20=det*t20;e21=det*t21;e22=det*t22;e23=det*t23;
        e30=det*t30;e31=det*t31;e32=det*t32;e33=det*t33;
    }*/
}

参考:http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/tech23.html

P.S. 少し最適化。これ以上やると汚くなるのでSTOP。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4