1 
  2 /**
  3  * @class Matrix类表示一个转换矩阵,它确定如何将点从一个坐标空间映射到另一个坐标空间。
  4  * @param {Number} a 缩放或旋转图像时影响像素沿 x 轴定位的值。
  5  * @param {Number} b 旋转或倾斜图像时影响像素沿 y 轴定位的值。
  6  * @param {Number} c 旋转或倾斜图像时影响像素沿 x 轴定位的值。
  7  * @param {Number} d 缩放或旋转图像时影响像素沿 y 轴定位的值。
  8  * @param {Number} tx 沿 x 轴平移每个点的距离。
  9  * @param {Number} ty 沿 y 轴平移每个点的距离。
 10  * @module hilo/geom/Matrix
 11  * @requires hilo/core/Class
 12  */
 13 var Matrix = Class.create(/** @lends Matrix.prototype */{
 14     constructor: function Matrix(a, b, c, d, tx, ty){
 15         this.a = a;
 16         this.b = b;
 17         this.c = c;
 18         this.d = d;
 19         this.tx = tx;
 20         this.ty = ty;
 21     },
 22     
 23     /**
 24      * 将某个矩阵与当前矩阵连接,从而将这两个矩阵的几何效果有效地结合在一起。
 25      * @param {Matrix} mtx 要连接到源矩阵的矩阵。
 26      * @returns {Matrix} 一个Matrix对象。
 27      */
 28     concat: function(mtx){
 29         var args = arguments, 
 30             a = this.a, b = this.b, c = this.c, d = this.d, 
 31             tx = this.tx, ty = this.ty;
 32 
 33         if(args.length >= 6){
 34             var ma = args[0], mb = args[1], mc = args[2],
 35                 md = args[3], mx = args[4], my = args[5];
 36         }else{
 37             ma = mtx.a;
 38             mb = mtx.b;
 39             mc = mtx.c;
 40             md = mtx.d;
 41             mx = mtx.tx;
 42             my = mtx.ty;
 43         }
 44         
 45         this.a = a * ma + b * mc;
 46         this.b = a * mb + b * md;
 47         this.c = c * ma + d * mc;
 48         this.d = c * mb + d * md;
 49         this.tx = tx * ma + ty * mc + mx;
 50         this.ty = tx * mb + ty * md + my;
 51         return this;
 52     },
 53 
 54     /**
 55      * 对 Matrix 对象应用旋转转换。
 56      * @param {Number} angle 旋转的角度。
 57      * @returns {Matrix} 一个Matrix对象。
 58      */
 59     rotate: function(angle){
 60         var sin = Math.sin(angle), cos = Math.cos(angle),
 61             a = this.a, b = this.b, c = this.c, d = this.d,
 62             tx = this.tx, ty = this.ty;
 63         
 64         this.a = a * cos - b * sin;
 65         this.b = a * sin + b * cos;
 66         this.c = c * cos - d * sin;
 67         this.d = c * sin + d * cos;
 68         this.tx = tx * cos - ty * sin;
 69         this.ty = tx * sin + ty * cos;
 70         return this;
 71     },
 72 
 73     /**
 74      * 对矩阵应用缩放转换。
 75      * @param {Number} sx 用于沿 x 轴缩放对象的乘数。
 76      * @param {Number} sy 用于沿 y 轴缩放对象的乘数。
 77      * @returns {Matrix} 一个Matrix对象。
 78      */
 79     scale: function(sx, sy){
 80         this.a *= sx;
 81         this.d *= sy;
 82         this.tx *= sx;
 83         this.ty *= sy;
 84         return this;
 85     },
 86 
 87     /**
 88      * 沿 x 和 y 轴平移矩阵,由 dx 和 dy 参数指定。
 89      * @param {Number} dx 沿 x 轴向右移动的量(以像素为单位)。
 90      * @param {Number} dy 沿 y 轴向右移动的量(以像素为单位)。
 91      * @returns {Matrix} 一个Matrix对象。
 92      */
 93     translate: function(dx, dy){
 94         this.tx += dx;
 95         this.ty += dy;
 96         return this;
 97     },
 98 
 99     /**
100      * 为每个矩阵属性设置一个值,该值将导致 null 转换。通过应用恒等矩阵转换的对象将与原始对象完全相同。
101      * @returns {Matrix} 一个Matrix对象。
102      */
103     identity: function(){
104         this.a = this.d = 1;
105         this.b = this.c = this.tx = this.ty = 0;
106         return this;
107     },
108 
109     /**
110      * 执行原始矩阵的逆转换。您可以将一个逆矩阵应用于对象来撤消在应用原始矩阵时执行的转换。
111      * @returns {Matrix} 一个Matrix对象。
112      */
113     invert: function(){
114         var a = this.a;
115         var b = this.b;
116         var c = this.c;
117         var d = this.d;
118         var tx = this.tx;
119         var i = a * d - b * c;
120         
121         this.a = d / i;
122         this.b = -b / i;
123         this.c = -c / i;
124         this.d = a / i;
125         this.tx = (c * this.ty - d * tx) / i;
126         this.ty = -(a * this.ty - b * tx) / i;
127         return this;
128     },
129 
130     /**
131      * 返回将 Matrix 对象表示的几何转换应用于指定点所产生的结果。
132      * @param {Object} point 想要获得其矩阵转换结果的点。
133      * @param {Boolean} round 是否对点的坐标进行向上取整。
134      * @param {Boolean} returnNew 是否返回一个新的点。
135      * @returns {Object} 由应用矩阵转换所产生的点。
136      */
137     transformPoint: function(point, round, returnNew){
138         var x = point.x * this.a + point.y * this.c + this.tx,
139             y = point.x * this.b + point.y * this.d + this.ty;
140 
141         if(round){
142             x = x + 0.5 >> 0;
143             y = y + 0.5 >> 0;
144         }
145         if(returnNew) return {x:x, y:y};
146         point.x = x;
147         point.y = y;
148         return point;
149     }
150 
151 });