forked from: flash on 2014-3-18

by imo_ forked from flash on 2014-3-18 (diff: 221)
♥0 | Line 317 | Modified 2014-03-19 03:20:50 | MIT License
play

ActionScript3 source code

/**
 * Copyright imo_ ( http://wonderfl.net/user/imo_ )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vlKs
 */

// forked from imo_'s flash on 2014-3-18
package {
    import flash.text.TextFormat;
    import flash.text.TextField;
    import flash.display.Sprite;
    import com.bit101.components.*;
    public class GenInvMat extends Sprite {
        private var ta:TextArea;
        
        public function GenInvMat() {
            Style.embedFonts = false;
            Style.fontName = "Courier New";
            Style.fontSize = 12;
            ta = new TextArea(this, 0, 0, "");
            ta.editable = false;
            ta.width = 465;
            ta.height = 465;
            calc();
        }
        
        private function join(...nums:Array):String {
            var len:int = nums.length;
            var txt:String = "| ";
            for (var i:int = 0; i < len; i++) {
                if (i != 0) txt += " ";
                txt += Number(nums[i]).toFixed(4);
            }
            txt += " |";
            return txt;
        }
        
        private function log(txt:Object):void {
            if (txt is Mat) {
                var m:Mat = Mat(txt);
                log(join(m.e00, m.e01, m.e02, m.e03));
                log(join(m.e10, m.e11, m.e12, m.e13));
                log(join(m.e20, m.e21, m.e22, m.e23));
                log(join(m.e30, m.e31, m.e32, m.e33));
                return;
            }
            ta.text += txt + "\n";
        }
        
        private function calc():void {
            log("General Inverse Matrix Calculation Test");
            log("");
            var mat:Mat = new Mat(); // a matrix whose det = 0
            mat.e00 = 2; mat.e01 = 1; mat.e02 = 1; mat.e03 = 0;
            mat.e10 = 1; mat.e11 = 2; mat.e12 = 0; mat.e13 = 1;
            mat.e20 = 1; mat.e21 = 0; mat.e22 = 2; mat.e23 = 1;
            mat.e30 = 0; mat.e31 = 1; mat.e32 = 1; mat.e33 = 2;
            var invMat:Mat = calcMain(mat);
            var tmp:Mat = new Mat();
            log("M: ");
            log(mat);
            log("");
            log("M+: ");
            log(invMat);
            log("");
            log("MM+ (= (MM+)*): ");
            tmp.mul(mat, invMat);
            log(tmp);
            log("");
            log("M+M (= (M+M)*): ");
            tmp.mul(invMat, mat);
            log(tmp);
            log("");
            log("MM+M (= M): ");
            tmp.mul(mat, invMat);
            tmp.mul(tmp, mat);
            log(tmp);
            log("");
            log("M+MM+ (= M+): ");
            tmp.mul(invMat, mat);
            tmp.mul(tmp, invMat);
            log(tmp);
            log("");
        }
        
        private function calcMain(m:Mat):Mat {
            log("calculating...");
            var inv:Mat = new Mat();
            compute(m, inv);
            log("done.");
            log("");
            return inv;
        }
        
        private function compute(m:Mat, inv:Mat):void {
            
            // --- variables ---
            
            var len:Number;
            var d0:Number;
            var d1:Number;
            var d2:Number;
            var c0:Number;
            var c1:Number;
            var c2:Number;
            var c3:Number;
            var i00:Number;
            var i01:Number;
            var i02:Number;
            var i03:Number;
            var i10:Number;
            var i11:Number;
            var i12:Number;
            var i13:Number;
            var i20:Number;
            var i21:Number;
            var i22:Number;
            var i23:Number;
            var i30:Number;
            var i31:Number;
            var i32:Number;
            var i33:Number;
            var e00:Number;
            var e01:Number;
            var e02:Number;
            var e03:Number;
            var e10:Number;
            var e11:Number;
            var e12:Number;
            var e13:Number;
            var e20:Number;
            var e21:Number;
            var e22:Number;
            var e23:Number;
            var e30:Number;
            var e31:Number;
            var e32:Number;
            var e33:Number;
            
            // --- input ---
            
            e00 = m.e00;
            e01 = m.e01;
            e02 = m.e02;
            e03 = m.e03;
            e10 = m.e10;
            e11 = m.e11;
            e12 = m.e12;
            e13 = m.e13;
            e20 = m.e20;
            e21 = m.e21;
            e22 = m.e22;
            e23 = m.e23;
            e30 = m.e30;
            e31 = m.e31;
            e32 = m.e32;
            e33 = m.e33;
            
            // --- compute ---
            
            // calc A1+
            if ((len = e00 * e00 + e10 * e10 + e20 * e20 + e30 * e30) > 1e-10) { // a1 != 0
                len = 1 / len;
            } else { // a1 == 0
                len = 0;
            }
            i00 = e00 * len;
            i01 = e10 * len;
            i02 = e20 * len;
            i03 = e30 * len;
            // calc d2
            d0 = i00 * e01 + i01 * e11 + i02 * e21 + i03 * e31;
            // calc c2
            c0 = e01 - e00 * d0;
            c1 = e11 - e10 * d0;
            c2 = e21 - e20 * d0;
            c3 = e31 - e30 * d0;
            // calc b2
            if ((len = c0 * c0 + c1 * c1 + c2 * c2 + c3 * c3) > 1e-10) { // c != 0
                len = 1 / len;
                c0 *= len;
                c1 *= len;
                c2 *= len;
                c3 *= len;
            } else { // c == 0
                len = d0 / (1 + d0 * d0);
                c0 = i00 * len;
                c1 = i01 * len;
                c2 = i02 * len;
                c3 = i03 * len;
            }
            // calc A2+
            i00 -= d0 * c0;
            i01 -= d0 * c1;
            i02 -= d0 * c2;
            i03 -= d0 * c3;
            i10 = c0;
            i11 = c1;
            i12 = c2;
            i13 = c3;
            // calc d3
            d0 = i00 * e02 + i01 * e12 + i02 * e22 + i03 * e32;
            d1 = i10 * e02 + i11 * e12 + i12 * e22 + i13 * e32;
            // calc c3
            c0 = e02 - e00 * d0 - e01 * d1;
            c1 = e12 - e10 * d0 - e11 * d1;
            c2 = e22 - e20 * d0 - e21 * d1;
            c3 = e32 - e30 * d0 - e31 * d1;
            // calc b3
            if ((len = c0 * c0 + c1 * c1 + c2 * c2 + c3 * c3) > 1e-10) { // c != 0
                len = 1 / len;
                c0 *= len;
                c1 *= len;
                c2 *= len;
                c3 *= len;
            } else { // c == 0
                len = 1 / (1 + d0 * d0 + d1 * d1);
                c0 = (d0 * i00 + d1 * i10) * len;
                c1 = (d0 * i01 + d1 * i11) * len;
                c2 = (d0 * i02 + d1 * i12) * len;
                c3 = (d0 * i03 + d1 * i13) * len;
            }
            // calc A3+
            i00 -= d0 * c0;
            i01 -= d0 * c1;
            i02 -= d0 * c2;
            i03 -= d0 * c3;
            i10 -= d1 * c0;
            i11 -= d1 * c1;
            i12 -= d1 * c2;
            i13 -= d1 * c3;
            i20 = c0;
            i21 = c1;
            i22 = c2;
            i23 = c3;
            // calc d4
            d0 = i00 * e03 + i01 * e13 + i02 * e23 + i03 * e33;
            d1 = i10 * e03 + i11 * e13 + i12 * e23 + i13 * e33;
            d2 = i20 * e03 + i21 * e13 + i22 * e23 + i23 * e33;
            // calc c4
            c0 = e03 - e00 * d0 - e01 * d1 - e02 * d2;
            c1 = e13 - e10 * d0 - e11 * d1 - e12 * d2;
            c2 = e23 - e20 * d0 - e21 * d1 - e22 * d2;
            c3 = e33 - e30 * d0 - e31 * d1 - e32 * d2;
            // calc b4
            if ((len = c0 * c0 + c1 * c1 + c2 * c2 + c3 * c3) > 1e-10) { // c != 0
                len = 1 / len;
                c0 *= len;
                c1 *= len;
                c2 *= len;
                c3 *= len;
            } else { // c == 0
                len = 1 / (1 + d0 * d0 + d1 * d1 + d2 * d2);
                c0 = (d0 * i00 + d1 * i10 + d2 * i20) * len;
                c1 = (d0 * i01 + d1 * i11 + d2 * i21) * len;
                c2 = (d0 * i02 + d1 * i12 + d2 * i22) * len;
                c3 = (d0 * i03 + d1 * i13 + d2 * i23) * len;
            }
            // calc A4+
            i00 -= d0 * c0;
            i01 -= d0 * c1;
            i02 -= d0 * c2;
            i03 -= d0 * c3;
            i10 -= d1 * c0;
            i11 -= d1 * c1;
            i12 -= d1 * c2;
            i13 -= d1 * c3;
            i20 -= d2 * c0;
            i21 -= d2 * c1;
            i22 -= d2 * c2;
            i23 -= d2 * c3;
            i30 = c0;
            i31 = c1;
            i32 = c2;
            i33 = c3;
            
            // --- output ---
            
            inv.e00 = i00;
            inv.e01 = i01;
            inv.e02 = i02;
            inv.e03 = i03;
            inv.e10 = i10;
            inv.e11 = i11;
            inv.e12 = i12;
            inv.e13 = i13;
            inv.e20 = i20;
            inv.e21 = i21;
            inv.e22 = i22;
            inv.e23 = i23;
            inv.e30 = i30;
            inv.e31 = i31;
            inv.e32 = i32;
            inv.e33 = i33;
        }
    }
}

class Mat {
    public var e00:Number;
    public var e01:Number;
    public var e02:Number;
    public var e03:Number;
    public var e10:Number;
    public var e11:Number;
    public var e12:Number;
    public var e13:Number;
    public var e20:Number;
    public var e21:Number;
    public var e22:Number;
    public var e23:Number;
    public var e30:Number;
    public var e31:Number;
    public var e32:Number;
    public var e33:Number;
    
    public function Mat() {
        e00 = 1; e01 = 0; e02 = 0; e03 = 0;
        e10 = 0; e11 = 1; e12 = 0; e13 = 0;
        e20 = 0; e21 = 0; e22 = 1; e23 = 0;
        e30 = 0; e31 = 0; e32 = 0; e33 = 1;
    }
    
    public function mul(m1:Mat, m2:Mat):void {
        var t00:Number = m1.e00 * m2.e00 + m1.e01 * m2.e10 + m1.e02 * m2.e20 + m1.e03 * m2.e30;
        var t01:Number = m1.e00 * m2.e01 + m1.e01 * m2.e11 + m1.e02 * m2.e21 + m1.e03 * m2.e31;
        var t02:Number = m1.e00 * m2.e02 + m1.e01 * m2.e12 + m1.e02 * m2.e22 + m1.e03 * m2.e32;
        var t03:Number = m1.e00 * m2.e03 + m1.e01 * m2.e13 + m1.e02 * m2.e23 + m1.e03 * m2.e33;
        var t10:Number = m1.e10 * m2.e00 + m1.e11 * m2.e10 + m1.e12 * m2.e20 + m1.e13 * m2.e30;
        var t11:Number = m1.e10 * m2.e01 + m1.e11 * m2.e11 + m1.e12 * m2.e21 + m1.e13 * m2.e31;
        var t12:Number = m1.e10 * m2.e02 + m1.e11 * m2.e12 + m1.e12 * m2.e22 + m1.e13 * m2.e32;
        var t13:Number = m1.e10 * m2.e03 + m1.e11 * m2.e13 + m1.e12 * m2.e23 + m1.e13 * m2.e33;
        var t20:Number = m1.e20 * m2.e00 + m1.e21 * m2.e10 + m1.e22 * m2.e20 + m1.e23 * m2.e30;
        var t21:Number = m1.e20 * m2.e01 + m1.e21 * m2.e11 + m1.e22 * m2.e21 + m1.e23 * m2.e31;
        var t22:Number = m1.e20 * m2.e02 + m1.e21 * m2.e12 + m1.e22 * m2.e22 + m1.e23 * m2.e32;
        var t23:Number = m1.e20 * m2.e03 + m1.e21 * m2.e13 + m1.e22 * m2.e23 + m1.e23 * m2.e33;
        var t30:Number = m1.e30 * m2.e00 + m1.e31 * m2.e10 + m1.e32 * m2.e20 + m1.e33 * m2.e30;
        var t31:Number = m1.e30 * m2.e01 + m1.e31 * m2.e11 + m1.e32 * m2.e21 + m1.e33 * m2.e31;
        var t32:Number = m1.e30 * m2.e02 + m1.e31 * m2.e12 + m1.e32 * m2.e22 + m1.e33 * m2.e32;
        var t33:Number = m1.e30 * m2.e03 + m1.e31 * m2.e13 + m1.e32 * m2.e23 + m1.e33 * m2.e33;
        e00 = t00;
        e01 = t01;
        e02 = t02;
        e03 = t03;
        e10 = t10;
        e11 = t11;
        e12 = t12;
        e13 = t13;
        e20 = t20;
        e21 = t21;
        e22 = t22;
        e23 = t23;
        e30 = t30;
        e31 = t31;
        e32 = t32;
        e33 = t33;
    }

}

Forked