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