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