1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga 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 cc.__AffineTransformMake = function (a, b, c, d, tx, ty) {
 47     return {a: a, b: b, c: c, d: d, tx: tx, ty: ty};
 48 };
 49 
 50 /**
 51  * @memberOf cc
 52  * @function
 53  * @param {Number} a
 54  * @param {Number} b
 55  * @param {Number} c
 56  * @param {Number} d
 57  * @param {Number} tx
 58  * @param {Number} ty
 59  * @return {cc.AffineTransform}
 60  * Constructor
 61  */
 62 cc.AffineTransformMake = function (a, b, c, d, tx, ty) {
 63     return {a: a, b: b, c: c, d: d, tx: tx, ty: ty};
 64 };
 65 
 66 cc.__PointApplyAffineTransform = function (point, t) {
 67     return {x: t.a * point.x + t.c * point.y + t.tx, y: t.b * point.x + t.d * point.y + t.ty};
 68 };
 69 
 70 /**
 71  * @memberOf cc
 72  * @function
 73  * @param {cc.Point} point
 74  * @param {cc.AffineTransform} t
 75  * @return {cc.Point}
 76  * Constructor
 77  */
 78 cc.PointApplyAffineTransform = function (point, t) {
 79     return {x: t.a * point.x + t.c * point.y + t.tx, y: t.b * point.x + t.d * point.y + t.ty};
 80 };
 81 
 82 cc._PointApplyAffineTransform = function (x, y, t) {
 83     return {x: t.a * x + t.c * y + t.tx,
 84         y: t.b * x + t.d * y + t.ty};
 85 };
 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  * @param {cc.Size} size
 95  * @param {cc.AffineTransform} t
 96  * @return {cc.Size}
 97  * Constructor
 98  */
 99 cc.SizeApplyAffineTransform = function (size, t) {
100     return {width: t.a * size.width + t.c * size.height, height: t.b * size.width + t.d * size.height};
101 };
102 
103 /**
104  * @memberOf cc
105  * @function
106  * @return {cc.AffineTransform}
107  * Constructor
108  */
109 cc.AffineTransformMakeIdentity = function () {
110     return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
111 };
112 
113 /**
114  * @memberOf cc
115  * @function
116  * @return {cc.AffineTransform}
117  * Constructor
118  */
119 cc.AffineTransformIdentity = function () {
120     return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
121 };
122 
123 /**
124  * @memberOf cc
125  * @function
126  * @param {cc.Rect} rect
127  * @param {cc.AffineTransform} anAffineTransform
128  * @return {cc.Rect}
129  * Constructor
130  */
131 cc.RectApplyAffineTransform = function (rect, anAffineTransform) {
132     var top = cc.rectGetMinY(rect);
133     var left = cc.rectGetMinX(rect);
134     var right = cc.rectGetMaxX(rect);
135     var bottom = cc.rectGetMaxY(rect);
136 
137     var topLeft = cc._PointApplyAffineTransform(left, top, anAffineTransform);
138     var topRight = cc._PointApplyAffineTransform(right, top, anAffineTransform);
139     var bottomLeft = cc._PointApplyAffineTransform(left, bottom, anAffineTransform);
140     var bottomRight = cc._PointApplyAffineTransform(right, bottom, anAffineTransform);
141 
142     var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
143     var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
144     var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
145     var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
146 
147     return cc.rect(minX, minY, (maxX - minX), (maxY - minY));
148 };
149 
150 cc._RectApplyAffineTransformIn = function(rect, anAffineTransform){
151     var top = cc.rectGetMinY(rect);
152     var left = cc.rectGetMinX(rect);
153     var right = cc.rectGetMaxX(rect);
154     var bottom = cc.rectGetMaxY(rect);
155 
156     var topLeft = cc._PointApplyAffineTransform(left, top, anAffineTransform);
157     var topRight = cc._PointApplyAffineTransform(right, top, anAffineTransform);
158     var bottomLeft = cc._PointApplyAffineTransform(left, bottom, anAffineTransform);
159     var bottomRight = cc._PointApplyAffineTransform(right, bottom, anAffineTransform);
160 
161     var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
162     var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
163     var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
164     var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
165 
166     rect.x = minX;
167     rect.y = minY;
168     rect.width = maxX - minX;
169     rect.height = maxY - minY;
170     return rect;
171 };
172 
173 /**
174  * @memberOf cc
175  * @function
176  * @param {cc.AffineTransform} t
177  * @param {Number} tx
178  * @param {Number}ty
179  * @return {cc.AffineTransform}
180  * Constructor
181  */
182 cc.AffineTransformTranslate = function (t, tx, ty) {
183     return {
184         a: t.a,
185         b: t.b,
186         c: t.c,
187         d: t.d,
188         tx: t.tx + t.a * tx + t.c * ty,
189         ty: t.ty + t.b * tx + t.d * ty
190     };
191 };
192 
193 /**
194  * @memberOf cc
195  * @function
196  * @param {cc.AffineTransform} t
197  * @param {Number} sx
198  * @param {Number} sy
199  * @return {cc.AffineTransform}
200  * Constructor
201  */
202 cc.AffineTransformScale = function (t, sx, sy) {
203     return {a: t.a * sx, b: t.b * sx, c: t.c * sy, d: t.d * sy, tx: t.tx, ty: t.ty};
204 };
205 
206 /**
207  * @memberOf cc
208  * @function
209  * @param {cc.AffineTransform} aTransform
210  * @param {Number} anAngle
211  * @return {cc.AffineTransform}
212  * Constructor
213  */
214 cc.AffineTransformRotate = function (aTransform, anAngle) {
215     var fSin = Math.sin(anAngle);
216     var fCos = Math.cos(anAngle);
217 
218     return {a: aTransform.a * fCos + aTransform.c * fSin,
219         b: aTransform.b * fCos + aTransform.d * fSin,
220         c: aTransform.c * fCos - aTransform.a * fSin,
221         d: aTransform.d * fCos - aTransform.b * fSin,
222         tx: aTransform.tx,
223         ty: aTransform.ty};
224 };
225 
226 /**
227  * Concatenate `t2' to `t1' and return the result:<br/>
228  * t' = t1 * t2
229  * @memberOf cc
230  * @function
231  * @param {cc.AffineTransform} t1
232  * @param {cc.AffineTransform} t2
233  * @return {cc.AffineTransform}
234  * Constructor
235  */
236 cc.AffineTransformConcat = function (t1, t2) {
237     return {a: t1.a * t2.a + t1.b * t2.c,                          //a
238         b: t1.a * t2.b + t1.b * t2.d,                               //b
239         c: t1.c * t2.a + t1.d * t2.c,                               //c
240         d: t1.c * t2.b + t1.d * t2.d,                               //d
241         tx: t1.tx * t2.a + t1.ty * t2.c + t2.tx,                    //tx
242         ty: t1.tx * t2.b + t1.ty * t2.d + t2.ty};				    //ty
243 };
244 
245 /**
246  * Return true if `t1' and `t2' are equal, false otherwise.
247  * @memberOf cc
248  * @function
249  * @param {cc.AffineTransform} t1
250  * @param {cc.AffineTransform} t2
251  * @return {Boolean}
252  * Constructor
253  */
254 cc.AffineTransformEqualToTransform = function (t1, t2) {
255     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));
256 };
257 
258 /**
259  * @memberOf cc
260  * @function
261  * @param {cc.AffineTransform} t
262  * @return {cc.AffineTransform}
263  * Constructor
264  */
265 cc.AffineTransformInvert = function (t) {
266     var determinant = 1 / (t.a * t.d - t.b * t.c);
267     return {a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
268         tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)};
269 };
270