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