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