Advertisement
Guest User

matrix.as

a guest
Apr 2nd, 2012
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package ASUtil.Math
  2. {
  3.     import flash.geom.Matrix;
  4.     import flash.geom.Matrix3D;
  5.    
  6.     public class matrix extends Object
  7.     {
  8.        
  9.         public static const opMul:String = "Multiplication";
  10.         public static const opAdd:String = "Addition";
  11.         public static const opSub:String = "Subtract";
  12.         public static const opInv:String = "Inverse";
  13.         public static const opFMX:String = "ToFlashMatrix";
  14.         public static const opFM3:String = "ToFlashMatrix3D";
  15.        
  16.         private var data:Vector.<Number>;
  17.         private var W:uint;
  18.         private var H:uint;
  19.        
  20.         public var newLine:Boolean = true;
  21.        
  22.         public function matrix ( width:uint, height:uint, ... dat )
  23.         {
  24.            
  25.             data = new Vector.<Number> ( width * height, true );
  26.            
  27.             W = width;
  28.             H = height;
  29.            
  30.             if ( dat.length > W * H )
  31.                 throw new Error ( "More data provided than fits in matrix.", 0 );
  32.            
  33.             for ( var n:uint = 0; n < dat.length; n ++ )
  34.                 data [ n ] = dat [ n ];
  35.            
  36.         };
  37.        
  38.         public function setElement ( x:uint, y:uint, value:Number ) : void
  39.         {
  40.            
  41.             if ( x >= W || y >= H )
  42.                 throw new Error ( "The coordinance ( " + x + ", " + y + " ) is out of the matrix bounds.", 1 );
  43.            
  44.             data [ x + y * W ] = value;
  45.            
  46.         };
  47.        
  48.         public function add ( mat:matrix ) : matrix
  49.         {
  50.            
  51.             if ( mat.width != W || mat.height != H )
  52.                 throw new Error ( "Mismatched dimensions for adding.", 2 );
  53.            
  54.             var ret:matrix = new matrix ( W, H );
  55.            
  56.             for ( var x:uint = 0; x < W; x ++ )
  57.             {
  58.                
  59.                 for ( var y:uint = 0; y < H; y ++ )
  60.                 {
  61.                    
  62.                     ret.setElement ( x, y, data [ x + y * H ] + mat.getElement ( x, y ) );
  63.                    
  64.                 }
  65.                
  66.             }
  67.            
  68.             return ret;
  69.            
  70.         };
  71.        
  72.         public function sub ( mat:matrix ) : matrix
  73.         {
  74.            
  75.             if ( mat.width != W || mat.height != H )
  76.                 throw new Error ( "Mismatched dimensions for adding.", 3 );
  77.            
  78.             var ret:matrix = new matrix ( W, H );
  79.            
  80.             for ( var x:uint = 0; x < W; x ++ )
  81.             {
  82.                
  83.                 for ( var y:uint = 0; y < H; y ++ )
  84.                 {
  85.                    
  86.                     ret.setElement ( x, y, data [ x + y * H ] - mat.getElement ( x, y ) );
  87.                    
  88.                 }
  89.                
  90.             }
  91.            
  92.             return ret;
  93.            
  94.         };
  95.        
  96.         public function mulUniform ( val:Number ):matrix
  97.         {
  98.            
  99.             var ret:matrix = new matrix ( W, H );
  100.            
  101.             for ( var n:uint = 0; n < W * H; n ++ )
  102.             {
  103.                
  104.                 ret.setElement ( n % W, ( n - n % W ) / W, val * data [ n ] );
  105.                
  106.             }
  107.            
  108.             return ret;
  109.            
  110.         };
  111.        
  112.         public function mulMatrix ( mat:matrix ) : matrix
  113.         {
  114.            
  115.             if ( W != mat.height )
  116.                 throw new Error ( "Mismatched dimensions for multiplication.", 4 );
  117.            
  118.             var ret:matrix = new matrix ( mat.width, H );
  119.             var curr:Number;
  120.            
  121.             for ( var x:uint = 0; x < mat.width; x ++ )
  122.                 for ( var y:uint = 0; y < H; y ++ )
  123.                 {
  124.                    
  125.                     curr = 0;
  126.                    
  127.                     for ( var n:uint = 0; n < W; n ++ )
  128.                         curr += mat.getElement ( x, n ) * data [ n * W + y ];
  129.                    
  130.                     ret.setElement ( x, y, curr );
  131.                    
  132.                 }
  133.            
  134.             return ret;
  135.            
  136.         };
  137.        
  138.         public function inverse () : matrix
  139.         {
  140.            
  141.             if ( !operationSupported ( opInv ) )
  142.                 throw new Error ( "inversion is not possible on this matrix.", 5 );
  143.            
  144.             var ret:matrix = new matrix ( W, H );
  145.             var mul:Number;
  146.            
  147.             if ( W == 1 )
  148.                 ret.setElement ( 0, 0, 1 / data [ 0 ] );
  149.            
  150.             if ( W == 2 )
  151.             {
  152.                
  153.                 mul = 1 / ( data [ 0 ] * data [ 3 ] - data [ 1 ] * data [ 2 ] );
  154.                
  155.                 ret.setElement ( 0, 0, data [ 3 ] * mul );
  156.                 ret.setElement ( 1, 0, -data [ 1 ] * mul );
  157.                
  158.                 ret.setElement ( 0, 1, -data [ 2 ] * mul );
  159.                 ret.setElement ( 1, 1, data [ 0 ] * mul );
  160.                
  161.             }
  162.            
  163.             if ( W == 3 )
  164.             {
  165.                
  166.                 mul = 1 / ( data [ 0 ] * ( ( data [ 4 ] * data [ 8 ] ) - ( data [ 5 ] * data [ 7 ] ) ) + data [ 1 ] * ( ( data [ 5 ] * data [ 6 ] ) - ( data [ 8 ] * data [ 3 ] ) ) + data [ 2 ] * ( ( data [ 3 ] * data [ 7 ] ) - ( data [ 4 ] * data [ 6 ] ) ) );
  167.                
  168.                 ret.setElement ( 0, 0, ( data [ 4 ] * data [ 8 ] - data [ 5 ] * data [ 7 ] ) );
  169.                 ret.setElement ( 0, 1, ( data [ 2 ] * data [ 7 ] - data [ 1 ] * data [ 8 ] ) );
  170.                 ret.setElement ( 0, 2, ( data [ 1 ] * data [ 5 ] - data [ 2 ] * data [ 4 ] ) );
  171.                
  172.                 ret.setElement ( 1, 0, ( data [ 5 ] * data [ 6 ] - data [ 3 ] * data [ 8 ] ) );
  173.                 ret.setElement ( 1, 1, ( data [ 0 ] * data [ 8 ] - data [ 2 ] * data [ 6 ] ) );
  174.                 ret.setElement ( 1, 2, ( data [ 2 ] * data [ 3 ] - data [ 0 ] * data [ 5 ] ) );
  175.                
  176.                 ret.setElement ( 2, 0, ( data [ 3 ] * data [ 7 ] - data [ 4 ] * data [ 6 ] ) );
  177.                 ret.setElement ( 2, 1, ( data [ 6 ] * data [ 1 ] - data [ 0 ] * data [ 7 ] ) );
  178.                 ret.setElement ( 2, 2, ( data [ 0 ] * data [ 4 ] - data [ 1 ] * data [ 3 ] ) );
  179.                
  180.                 ret = ret.mulUniform ( mul );
  181.                
  182.             }
  183.            
  184.             return ret;
  185.                
  186.         }
  187.        
  188.         public function getElement ( x:uint, y:uint ) : Number
  189.         {
  190.            
  191.             return data [ x + y * W ];
  192.            
  193.         };
  194.        
  195.         public function get width () : uint
  196.         {
  197.            
  198.             return W;
  199.            
  200.         };
  201.        
  202.         public function get height () : uint
  203.         {
  204.            
  205.             return H;
  206.            
  207.         };
  208.        
  209.         public function getRawData () : Vector.<Number>
  210.         {
  211.            
  212.             return data;
  213.            
  214.         };
  215.        
  216.         public function operationSupported ( operation:String, second:matrix = null ) : Boolean
  217.         {
  218.            
  219.             if ( !( operation == opFMX || operation == opFM3 || operation == opInv || second != null ) )
  220.                 throw new Error ( "Second matrix not provided to test for operability.", 6 );
  221.            
  222.             switch ( operation )
  223.             {
  224.                
  225.                 case opInv:
  226.                     if ( ( W == 3 && H == 3 ) || ( W == 2 && H == 2 ) || ( W == 1 && H == 1 ) )
  227.                         return true;
  228.                     else
  229.                         return false;
  230.                     break;
  231.                
  232.                 case opAdd:
  233.                     if ( W == second.width && H == second.height )
  234.                         return true;
  235.                     else
  236.                         return false;
  237.                     break;
  238.                
  239.                 case opSub:
  240.                     if ( W == second.width && H == second.height )
  241.                         return true;
  242.                     else
  243.                         return false;
  244.                     break;
  245.                
  246.                 case opMul:
  247.                    
  248.                     if ( W == second.height )
  249.                         return true;
  250.                     else
  251.                         return false;
  252.                    
  253.                 case opFMX:
  254.                    
  255.                     if ( W == 3 && H == 3 || W == 3 && H == 2 )
  256.                         return true;
  257.                     else
  258.                         return false;
  259.                     break;
  260.                
  261.                 case opFM3:
  262.                    
  263.                     if ( W == 4 && H == 4 )
  264.                         return true;
  265.                     else
  266.                         return false;
  267.                    
  268.                     break;
  269.                    
  270.                 default:
  271.                    
  272.                     throw new Error ( operation + " is not an operation you can test for.", 7 );
  273.                    
  274.                     break;
  275.                    
  276.             }
  277.            
  278.             return false;
  279.            
  280.         };
  281.        
  282.         public function toString () : String
  283.         {
  284.            
  285.             var out:String = ( newLine ) ? '' : '[ ';
  286.             var maxL:Vector.<uint> = new Vector.<uint> ( W, true );
  287.            
  288.             var qx:uint;
  289.             var sp:String;
  290.             var sa:String;
  291.            
  292.             for ( var n:uint = 0; n < W * H; n ++ )
  293.             {
  294.                
  295.                 qx = n % W;
  296.                 maxL [ qx ] = Math.max ( maxL [ qx ], data [ n ].toString ().length );
  297.                
  298.             }
  299.            
  300.             for ( var y:uint = 0; y < H; y ++ )
  301.             for ( var x:uint = 0; x < W; x ++ )
  302.             {
  303.                
  304.                 sp = '';
  305.                 sa = data [ x + y * W ].toString ( 10 );
  306.                
  307.                 while ( sa.length < maxL [ x ] && newLine )
  308.                     sa = ' ' + sa;
  309.                
  310.                 if ( x == 0 )
  311.                     out += '[ ';
  312.                
  313.                 out += sa;
  314.                
  315.                 if ( x < W - 1 )
  316.                     out += ', ';
  317.                 else
  318.                 {
  319.                    
  320.                     out += ' ]';
  321.                         if ( y < H - 1 )
  322.                             out += ( newLine ) ? '\n' : ' ';
  323.                
  324.                 }
  325.                
  326.             }
  327.            
  328.             out += ( newLine ) ? '' : ' ]';
  329.            
  330.             var t:String = '';
  331.            
  332.             if ( out.indexOf ( "\n" ) != 0 )
  333.             {
  334.                
  335.                 var u:uint = 0;
  336.                 while ( u ++ < out.indexOf ( "\n" ) )
  337.                     t += '-';
  338.                
  339.             }
  340.             else
  341.             {
  342.                
  343.                 var g:uint = 0;
  344.                 while ( g ++ < out.length )
  345.                     t += '-';
  346.                
  347.             }
  348.            
  349.             if ( newLine )
  350.                 out = "Matrix:\n" + t + '\n' + out + '\n' + t;
  351.            
  352.             return out;
  353.            
  354.         };
  355.        
  356.         public function toFlashMatrix () : flash.geom.Matrix
  357.         {
  358.            
  359.             if ( ! operationSupported ( opFMX ) )
  360.                 throw new Error ( "Cannot convert to flash matrix. ( wrond dimentions )", 8 );
  361.            
  362.             var ret:flash.geom.Matrix = new flash.geom.Matrix ( data [ 0 ], data [ 1 ], data [ 3 ], data [ 4 ], data [ 2 ], data [ 5 ] );
  363.             return ret;
  364.            
  365.         }
  366.        
  367.         public function toFlashMatrix3D () : flash.geom.Matrix3D
  368.         {
  369.            
  370.             if ( ! operationSupported ( opFM3 ) )
  371.                 throw new Error ( "Cannot convert to flash matrix. ( wrond dimentions )", 9 );
  372.            
  373.             var ret:flash.geom.Matrix3D = new flash.geom.Matrix3D ( data );
  374.             return ret;
  375.            
  376.         }
  377.        
  378.         public static function generateIdentity ( size:uint ) : matrix
  379.         {
  380.            
  381.             var ret:matrix = new matrix ( size, size );
  382.             var i:uint = 0;
  383.            
  384.             while ( i ++ < size )
  385.                 ret.setElement ( i - 1, i - 1, 1 );
  386.            
  387.             return ret;
  388.            
  389.         };
  390.        
  391.         public static function fromFlashMatrix ( mat:flash.geom.Matrix ) : matrix
  392.         {
  393.            
  394.             return new matrix ( 3, 3, mat.a, mat.b, mat.tx, mat.c, mat.d, mat.ty, 0, 0, 1 );
  395.            
  396.         }
  397.        
  398.         public static function fromFlashMatrix3D ( mat:flash.geom.Matrix3D ) : matrix
  399.         {
  400.            
  401.             return new matrix ( 4, 4, mat.rawData );
  402.            
  403.         }
  404.        
  405.     };
  406.    
  407. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement