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