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


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

```actionscript: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。