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 //
 29 // POINT
 30 //
 31 //--------------------------------------------------------
 32 /**
 33  * @class
 34  * @param {Number} x
 35  * @param {Number} y
 36  * Constructor
 37  */
 38 cc.Point = function (x, y) {
 39     this.x = x || 0;
 40     this.y = y || 0;
 41 };
 42 
 43 /**
 44  * Helper macro that creates a cc.Point.
 45  * @param {Number|cc.Point} x a Number or a size object
 46  * @param {Number} y
 47  * @return {cc.Point}
 48  * @example
 49  * var point1 = cc.p();
 50  * var point2 = cc.p(100,100,100,100);
 51  * var point3 = cc.p(point2);
 52  */
 53 cc.p = function (x, y) {
 54     // This can actually make use of "hidden classes" in JITs and thus decrease
 55     // memory usage and overall performance drastically
 56     // return cc.p(x, y);
 57     // but this one will instead flood the heap with newly allocated hash maps
 58     // giving little room for optimization by the JIT,
 59     // note: we have tested this item on Chrome and firefox, it is faster than cc.p(x, y)
 60     if (x == undefined)
 61         return {x: 0, y: 0};
 62     if (y == undefined)
 63         return {x: x.x, y: x.y};
 64     return {x: x, y: y};
 65 };
 66 
 67 /**
 68  * @function
 69  * @param {cc.Point} point1
 70  * @param {cc.Point} point2
 71  * @return {Boolean}
 72  */
 73 cc.pointEqualToPoint = function (point1, point2) {
 74     return point1 && point2 && (point1.x === point2.x) && (point1.y === point2.y);
 75 };
 76 
 77 
 78 //--------------------------------------------------------
 79 //
 80 // SIZE
 81 //
 82 //--------------------------------------------------------
 83 
 84 /**
 85  * @class
 86  * @param {Number} width
 87  * @param {Number} height
 88  * Constructor
 89  */
 90 cc.Size = function (width, height) {
 91     this.width = width || 0;
 92     this.height = height || 0;
 93 };
 94 
 95 /**
 96  * @function
 97  * @param {Number|cc.Size} w width or a size object
 98  * @param {Number} h height
 99  * @return {cc.Size}
100  * @example
101  * var size1 = cc.size();
102  * var size2 = cc.size(100,100,100,100);
103  * var size3 = cc.size(size2);
104  */
105 cc.size = function (w, h) {
106     // This can actually make use of "hidden classes" in JITs and thus decrease
107     // memory usage and overall performance drastically
108     //return cc.size(w, h);
109     // but this one will instead flood the heap with newly allocated hash maps
110     // giving little room for optimization by the JIT
111     // note: we have tested this item on Chrome and firefox, it is faster than cc.size(w, h)
112     if (w === undefined)
113         return {width: 0, height: 0};
114     if (h === undefined)
115         return {width: w.width, height: w.height};
116     return {width: w, height: h};
117 };
118 
119 /**
120  * @function
121  * @param {cc.Size} size1
122  * @param {cc.Size} size2
123  * @return {Boolean}
124  */
125 cc.sizeEqualToSize = function (size1, size2) {
126     return (size1 && size2 && (size1.width == size2.width) && (size1.height == size2.height));
127 };
128 
129 
130 //--------------------------------------------------------
131 //
132 // RECT
133 //
134 //--------------------------------------------------------
135 
136 /**
137  * @class
138  * @param {Number} x a Number value as x
139  * @param {Number} y  a Number value as y
140  * @param {Number} width
141  * @param {Number} height
142  * Constructor
143  */
144 cc.Rect = function (x, y, width, height) {
145     this.x = x||0;
146     this.y = y||0;
147     this.width = width||0;
148     this.height = height||0;
149 };
150 
151 /**
152  * Return a new Rect
153  * @param {Number|cc.Rect} x a number or a rect object
154  * @param {Number} y
155  * @param {Number} w
156  * @param {Number} h
157  * @returns {cc.Rect}
158  * @example
159  * var rect1 = cc.rect();
160  * var rect2 = cc.rect(100,100,100,100);
161  * var rect3 = cc.rect(rect2);
162  */
163 cc.rect = function (x, y, w, h) {
164     if (x === undefined)
165         return {x: 0, y: 0, width: 0, height: 0};
166     if (y === undefined)
167         return {x: x.x, y: x.y, width: x.width, height: x.height};
168     return {x: x, y: y, width: w, height: h };
169 };
170 
171 /**
172  * whether the rect1 equals the rect2
173  * @function
174  * @param {cc.Rect} rect1
175  * @param {cc.Rect} rect2
176  * @return {Boolean}
177  */
178 cc.rectEqualToRect = function (rect1, rect2) {
179     return rect1 && rect2 && (rect1.x === rect2.x) && (rect1.y === rect2.y) && (rect1.width === rect2.width) && (rect1.height === rect2.height);
180 };
181 
182 cc._rectEqualToZero = function(rect){
183     return rect && (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0);
184 };
185 
186 /**
187  * return whether the rect1 contains rect2
188  * @function
189  * @param {cc.Rect} rect1
190  * @param {cc.Rect} rect2
191  * @return {Boolean}
192  */
193 cc.rectContainsRect = function (rect1, rect2) {
194     if (!rect1 || !rect2)
195         return false;
196     return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) ||
197         ( rect1.x + rect1.width <= rect2.x + rect2.width) ||
198         ( rect1.y + rect1.height <= rect2.y + rect2.height));
199 };
200 
201 /**
202  * return the rightmost x-value of 'rect'
203  * @function
204  * @param {cc.Rect} rect
205  * @return {Number}
206  */
207 cc.rectGetMaxX = function (rect) {
208     return (rect.x + rect.width);
209 };
210 
211 /**
212  * return the midpoint x-value of 'rect'
213  * @function
214  * @param {cc.Rect} rect
215  * @return {Number}
216  */
217 cc.rectGetMidX = function (rect) {
218     return (rect.x + rect.width / 2.0);
219 };
220 /**
221  * return the leftmost x-value of 'rect'
222  * @function
223  * @param {cc.Rect} rect
224  * @return {Number}
225  */
226 cc.rectGetMinX = function (rect) {
227     return rect.x;
228 };
229 
230 /**
231  * Return the topmost y-value of `rect'
232  * @function
233  * @param {cc.Rect} rect
234  * @return {Number}
235  */
236 cc.rectGetMaxY = function (rect) {
237     return(rect.y + rect.height);
238 };
239 
240 /**
241  * Return the midpoint y-value of `rect'
242  * @function
243  * @param {cc.Rect} rect
244  * @return {Number}
245  */
246 cc.rectGetMidY = function (rect) {
247     return rect.y + rect.height / 2.0;
248 };
249 
250 /**
251  * Return the bottommost y-value of `rect'
252  * @function
253  * @param {cc.Rect} rect
254  * @return {Number}
255  */
256 cc.rectGetMinY = function (rect) {
257     return rect.y;
258 };
259 
260 /**
261  * @function
262  * @param {cc.Rect} rect
263  * @param {cc.Point} point
264  * @return {Boolean}
265  */
266 cc.rectContainsPoint = function (rect, point) {
267     return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) &&
268         point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ;
269 };
270 
271 /**
272  * @function
273  * @param {cc.Rect} rectA
274  * @param {cc.Rect} rectB
275  * @return {Boolean}
276  */
277 cc.rectIntersectsRect = function (rectA, rectB) {
278     return !(cc.rectGetMaxX(rectA) < cc.rectGetMinX(rectB) ||
279         cc.rectGetMaxX(rectB) < cc.rectGetMinX(rectA) ||
280         cc.rectGetMaxY(rectA) < cc.rectGetMinY(rectB) ||
281         cc.rectGetMaxY(rectB) < cc.rectGetMinY(rectA));
282 };
283 
284 /**
285  * @function
286  * @param {cc.Rect} rectA
287  * @param {cc.Rect} rectB
288  * @return {Boolean}
289  */
290 cc.rectOverlapsRect = function (rectA, rectB) {
291     return !((rectA.x + rectA.width < rectB.x) ||
292         (rectB.x + rectB.width < rectA.x) ||
293         (rectA.y + rectA.height < rectB.y) ||
294         (rectB.y + rectB.height < rectA.y));
295 };
296 
297 /**
298  * Returns the smallest rectangle that contains the two source rectangles.
299  * @function
300  * @param {cc.Rect} rectA
301  * @param {cc.Rect} rectB
302  * @return {cc.Rect}
303  */
304 cc.rectUnion = function (rectA, rectB) {
305     var rect = cc.rect(0, 0, 0, 0);
306     rect.x = Math.min(rectA.x, rectB.x);
307     rect.y = Math.min(rectA.y, rectB.y);
308     rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x;
309     rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y;
310     return rect;
311 };
312 
313 /**
314  * Returns the overlapping portion of 2 rectangles
315  * @function
316  * @param {cc.Rect} rectA
317  * @param {cc.Rect} rectB
318  * @return {cc.Rect}
319  */
320 cc.rectIntersection = function (rectA, rectB) {
321     var intersection = cc.rect(
322         Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)),
323         Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)),
324         0, 0);
325 
326     intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection);
327     intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
328     return intersection;
329 };
330 
331 
332