1 /** 2 * The Render Engine 3 * Circle2D 4 * 5 * @fileoverview A Circle2D class 6 * 7 * @author: Brett Fattori (brettf@renderengine.com) 8 * @author: $Author: bfattori $ 9 * @version: $Revision: 1555 $ 10 * 11 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com) 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy 14 * of this software and associated documentation files (the "Software"), to deal 15 * in the Software without restriction, including without limitation the rights 16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 * copies of the Software, and to permit persons to whom the Software is 18 * furnished to do so, subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 * THE SOFTWARE. 30 * 31 */ 32 33 // The class this file defines and its required classes 34 R.Engine.define({ 35 "class":"R.math.Circle2D", 36 "requires":[ 37 "R.math.PooledMathObject", 38 "R.math.Point2D", 39 "R.math.Rectangle2D", 40 "R.math.Math2D" 41 ] 42 }); 43 44 /** 45 * @class A 2D circle class with helpful manipulation methods. 46 * @extends R.math.PooledMathObject 47 * @constructor 48 * @param x {Number} The center X coordinate 49 * @param y {Number} The center Y coordinate 50 * @param radius {Number} The radius of the circle 51 * @description Create a circle object specifying the X and Y center position and 52 * the radius. 53 */ 54 R.math.Circle2D = function () { 55 "use strict"; 56 return R.math.PooledMathObject.extend(/** @scope R.math.Circle2D.prototype */{ 57 58 center:null, 59 radius:0, 60 __CIRCLE2D:true, 61 62 /** @private */ 63 constructor:function (x, y, radius) { 64 this.__CIRCLE2D = true; 65 this.center = R.math.Point2D.create(0, 0); 66 this.radius = 0; 67 this.set(x, y, radius); 68 }, 69 70 /** 71 * Destroy the instance of the circle 72 */ 73 destroy:function () { 74 if (this.center) { 75 this.center.destroy(); 76 } 77 this.base(); 78 }, 79 80 /** 81 * Release the circle back into the pool for reuse. 82 */ 83 release:function () { 84 this.base(); 85 this.center = null; 86 this.radius = 0; 87 }, 88 89 /** 90 * Set the values of this circle. 91 * 92 * @param x {Number|R.math.Point2D|R.math.Circle2D} An optional value to initialize the X coordinate of the circle 93 * @param y {Number} An optional value to initialize the Y coordinate of the circle 94 * @param radius {Number} An optional value to initialize the radius 95 */ 96 set:function (x, y, radius) { 97 if (x.__CIRCLE2D) { 98 this.center.set(x.getCenter()); 99 this.radius = x.getRadius(); 100 } 101 else if (x.__POINT2D) { 102 this.center.set(x); 103 this.radius = y; 104 } 105 else { 106 this.center.set(x || 0, y || 0); 107 this.radius = radius || 0.0; 108 } 109 }, 110 111 /** 112 * Get an object with the elements containing centerX, centerY, and radius 113 * as the elements x, y, and r. 114 * 115 * @return {Object} An object with the specified elements 116 */ 117 get:function () { 118 var c = this.getCenter(); 119 return { 120 x:c.x, 121 y:c.y, 122 r:this.getRadius() 123 }; 124 }, 125 126 /** 127 * Returns <tt>true</tt> if this circle is equal to the specified circle. 128 * 129 * @param circle {R.math.Circle2D} The circle to compare to 130 * @return {Boolean} <tt>true</tt> if the two circles are equal 131 */ 132 equals:function (circle) { 133 return (this.center.equals(circle.getCenter()) && this.radius == circle.getRadius()); 134 }, 135 136 /** 137 * Offset this circle by the given amount in the X and Y axis. The first parameter 138 * can be either a {@link Point2D}, or the value for the X axis. If the X axis is specified, 139 * the second parameter should be the amount to offset in the Y axis. 140 * 141 * @param offsetPtOrX {R.math.Point2D|int} Either a {@link R.math.Point2D} which contains the offset in X and Y, or an integer 142 * representing the offset in the X axis. 143 * @param offsetY {int} If <code>offsetPtOrX</code> is an integer value for the offset in the X axis, this should be 144 * the offset along the Y axis. 145 */ 146 offset:function (offsetPtOrX, offsetY) { 147 var offs = R.math.Point2D.create(0, 0); 148 if (offsetPtOrX.__POINT2D) { 149 offs.set(offsetPtOrX); 150 } 151 else { 152 offs.set(offsetPtOrX, offsetY); 153 } 154 155 this.center.add(offs); 156 offs.destroy(); 157 return this; 158 }, 159 160 /** 161 * Get the center point of this circle. 162 * @return {R.math.Point2D} The center point 163 */ 164 getCenter:function () { 165 return this.center; 166 }, 167 168 /** 169 * Get the radius of this circle 170 * @return {Number} The radius 171 */ 172 getRadius:function () { 173 return this.radius; 174 }, 175 176 /** 177 * Determine if this circle intersects another circle. 178 * 179 * @param circle A {@link R.math.Circle2D} to compare against 180 * @return {Boolean} <tt>true</tt> if the two circles intersect. 181 */ 182 isIntersecting:function (circle) { 183 var c1 = this.getCenter(); 184 var c2 = circle.getCenter(); 185 var dX = (c1.x - c2.x) * (c1.x - c2.x); 186 var dY = (c1.y - c2.y) * (c1.y - c2.y); 187 var r2 = (this.getRadius() + circle.getRadius()) * (this.getRadius() + circle.getRadius()); 188 return (dX + dY <= r2); 189 }, 190 191 /** 192 * Determine if this circle is contained within the specified circle. 193 * 194 * @param circle {R.math.Circle2D} A circle to compare against 195 * @return {Boolean} <tt>true</tt> if the this circle is fully contained in the specified circle. 196 */ 197 isContained:function (circle) { 198 var d = circle.getCenter().dist(this.getCenter()); 199 return (d < (this.getRadius() + circle.getRadius())); 200 }, 201 202 /** 203 * Determine if this circle contains the specified circle. 204 * 205 * @param circle {R.math.Circle2D} A circle to compare against 206 * @return {Boolean} <tt>true</tt> if the rectangle is fully contained within this rectangle. 207 */ 208 containsCircle:function (circle) { 209 return circle.isContained(this); 210 }, 211 212 /** 213 * Returns <tt>true</tt> if this circle contains the specified point. 214 * 215 * @param point {R.math.Point2D} The point to test 216 * @return {Boolean} <tt>true</tt> if the point is within the circle 217 */ 218 containsPoint:function (point) { 219 var c1 = this.getCenter(); 220 var r = this.getRadius(); 221 return (c1.dist(point) <= r); 222 }, 223 224 /** 225 * Returns a printable version of this object. 226 * @return {String} Formatted like "cX,cY r#" 227 */ 228 toString:function () { 229 return this.center.toString() + " r" + Number(this.radius).toFixed(2); 230 } 231 232 }, /** @scope R.math.Circle2D.prototype */{ 233 /** 234 * Return the classname of the this object 235 * @return {String} "R.math.Circle2D" 236 */ 237 getClassName:function () { 238 return "R.math.Circle2D"; 239 }, 240 241 /** 242 * Approximate a circle from the given rectangle 243 * @param rect {R.math.Rectangle2D} The rectangle to use 244 * @return {R.math.Circle2D} 245 */ 246 approximateFromRectangle:function (rect) { 247 // Determine the center & radius 248 var r = Math.max(rect.getHalfWidth(), rect.getHalfHeight()), 249 c = rect.getCenter(); 250 return R.math.Circle2D.create(c.x, c.y, r); 251 } 252 253 }); 254 255 };