1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * @memberOf cc
 29  * @function
 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 cc.AffineTransform = 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 
 46 /**
 47  * @memberOf cc
 48  * @function
 49  * @param {Number} a
 50  * @param {Number} b
 51  * @param {Number} c
 52  * @param {Number} d
 53  * @param {Number} tx
 54  * @param {Number} ty
 55  * @return {cc.AffineTransform}
 56  * Constructor
 57  */
 58 cc.AffineTransformMake = function (a, b, c, d, tx, ty) {
 59     return {a: a, b: b, c: c, d: d, tx: tx, ty: ty};
 60 };
 61 
 62 /**
 63  * @memberOf cc
 64  * @function
 65  * @param {cc.Point} point
 66  * @param {cc.AffineTransform} t
 67  * @return {cc.Point}
 68  * Constructor
 69  */
 70 cc.PointApplyAffineTransform = function (point, t) {
 71     return {x: t.a * point.x + t.c * point.y + t.tx, y: t.b * point.x + t.d * point.y + t.ty};
 72 };
 73 
 74 cc._PointApplyAffineTransform = function (x, y, t) {
 75     return {x: t.a * x + t.c * y + t.tx,
 76         y: t.b * x + t.d * y + t.ty};
 77 };
 78 
 79 /**
 80  * @memberOf cc
 81  * @function
 82  * @param {cc.Size} size
 83  * @param {cc.AffineTransform} t
 84  * @return {cc.Size}
 85  * Constructor
 86  */
 87 cc.SizeApplyAffineTransform = function (size, t) {
 88     return {width: t.a * size.width + t.c * size.height, height: t.b * size.width + t.d * size.height};
 89 };
 90 
 91 /**
 92  * @memberOf cc
 93  * @function
 94  * @return {cc.AffineTransform}
 95  * Constructor
 96  */
 97 cc.AffineTransformMakeIdentity = function () {
 98     return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
 99 };
100 
101 /**
102  * @memberOf cc
103  * @function
104  * @return {cc.AffineTransform}
105  * Constructor
106  */
107 cc.AffineTransformIdentity = function () {
108     return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
109 };
110 
111 /**
112  * @memberOf cc
113  * @function
114  * @param {cc.Rect} rect
115  * @param {cc.AffineTransform} anAffineTransform
116  * @return {cc.Rect}
117  * Constructor
118  */
119 cc.RectApplyAffineTransform = function (rect, anAffineTransform) {
120     var top = cc.rectGetMinY(rect);
121     var left = cc.rectGetMinX(rect);
122     var right = cc.rectGetMaxX(rect);
123     var bottom = cc.rectGetMaxY(rect);
124 
125     var topLeft = cc._PointApplyAffineTransform(left, top, anAffineTransform);
126     var topRight = cc._PointApplyAffineTransform(right, top, anAffineTransform);
127     var bottomLeft = cc._PointApplyAffineTransform(left, bottom, anAffineTransform);
128     var bottomRight = cc._PointApplyAffineTransform(right, bottom, anAffineTransform);
129 
130     var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
131     var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
132     var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
133     var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
134 
135     return cc.rect(minX, minY, (maxX - minX), (maxY - minY));
136 };
137 
138 cc._RectApplyAffineTransformIn = function(rect, anAffineTransform){
139     var top = cc.rectGetMinY(rect);
140     var left = cc.rectGetMinX(rect);
141     var right = cc.rectGetMaxX(rect);
142     var bottom = cc.rectGetMaxY(rect);
143 
144     var topLeft = cc._PointApplyAffineTransform(left, top, anAffineTransform);
145     var topRight = cc._PointApplyAffineTransform(right, top, anAffineTransform);
146     var bottomLeft = cc._PointApplyAffineTransform(left, bottom, anAffineTransform);
147     var bottomRight = cc._PointApplyAffineTransform(right, bottom, anAffineTransform);
148 
149     var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
150     var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
151     var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
152     var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
153 
154     rect.x = minX;
155     rect.y = minY;
156     rect.width = maxX - minX;
157     rect.height = maxY - minY;
158     return rect;
159 };
160 
161 /**
162  * @memberOf cc
163  * @function
164  * @param {cc.AffineTransform} t
165  * @param {Number} tx
166  * @param {Number}ty
167  * @return {cc.AffineTransform}
168  * Constructor
169  */
170 cc.AffineTransformTranslate = function (t, tx, ty) {
171     return {
172         a: t.a,
173         b: t.b,
174         c: t.c,
175         d: t.d,
176         tx: t.tx + t.a * tx + t.c * ty,
177         ty: t.ty + t.b * tx + t.d * ty
178     };
179 };
180 
181 /**
182  * @memberOf cc
183  * @function
184  * @param {cc.AffineTransform} t
185  * @param {Number} sx
186  * @param {Number} sy
187  * @return {cc.AffineTransform}
188  * Constructor
189  */
190 cc.AffineTransformScale = function (t, sx, sy) {
191     return {a: t.a * sx, b: t.b * sx, c: t.c * sy, d: t.d * sy, tx: t.tx, ty: t.ty};
192 };
193 
194 /**
195  * @memberOf cc
196  * @function
197  * @param {cc.AffineTransform} aTransform
198  * @param {Number} anAngle
199  * @return {cc.AffineTransform}
200  * Constructor
201  */
202 cc.AffineTransformRotate = function (aTransform, anAngle) {
203     var fSin = Math.sin(anAngle);
204     var fCos = Math.cos(anAngle);
205 
206     return {a: aTransform.a * fCos + aTransform.c * fSin,
207         b: aTransform.b * fCos + aTransform.d * fSin,
208         c: aTransform.c * fCos - aTransform.a * fSin,
209         d: aTransform.d * fCos - aTransform.b * fSin,
210         tx: aTransform.tx,
211         ty: aTransform.ty};
212 };
213 
214 /**
215  * Concatenate `t2' to `t1' and return the result:<br/>
216  * t' = t1 * t2
217  * @memberOf cc
218  * @function
219  * @param {cc.AffineTransform} t1
220  * @param {cc.AffineTransform} t2
221  * @return {cc.AffineTransform}
222  * Constructor
223  */
224 cc.AffineTransformConcat = function (t1, t2) {
225     return {a: t1.a * t2.a + t1.b * t2.c,                          //a
226         b: t1.a * t2.b + t1.b * t2.d,                               //b
227         c: t1.c * t2.a + t1.d * t2.c,                               //c
228         d: t1.c * t2.b + t1.d * t2.d,                               //d
229         tx: t1.tx * t2.a + t1.ty * t2.c + t2.tx,                    //tx
230         ty: t1.tx * t2.b + t1.ty * t2.d + t2.ty};				    //ty
231 };
232 
233 /**
234  * Return true if `t1' and `t2' are equal, false otherwise.
235  * @memberOf cc
236  * @function
237  * @param {cc.AffineTransform} t1
238  * @param {cc.AffineTransform} t2
239  * @return {Boolean}
240  * Constructor
241  */
242 cc.AffineTransformEqualToTransform = function (t1, t2) {
243     return ((t1.a === t2.a) && (t1.b === t2.b) && (t1.c === t2.c) && (t1.d === t2.d) && (t1.tx === t2.tx) && (t1.ty === t2.ty));
244 };
245 
246 /**
247  * Get the invert value of an AffineTransform object
248  * @memberOf cc
249  * @function
250  * @param {cc.AffineTransform} t
251  * @return {cc.AffineTransform}
252  * Constructor
253  */
254 cc.AffineTransformInvert = function (t) {
255     var determinant = 1 / (t.a * t.d - t.b * t.c);
256     return {a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
257         tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)};
258 };
259