1 /** 2 * The Render Engine 3 * Point2D 4 * 5 * @fileoverview A Point2D 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.Point2D", 36 "requires":[ 37 "R.math.PooledMathObject", 38 "R.math.Math2D" 39 ] 40 }); 41 42 /** 43 * @class A 2D point class with helpful methods for manipulation 44 * 45 * @param x {R.math.Point2D|Number} If this arg is a R.math.Point2D, its values will be 46 * copied into the new point. 47 * @param y {Number} The Y coordinate of the point. Only required if X 48 * was a number. 49 * @constructor 50 * @description Create a new 2D point. 51 * @extends R.math.PooledMathObject 52 */ 53 R.math.Point2D = function () { 54 "use strict"; 55 return R.math.PooledMathObject.extend(/** @scope R.math.Point2D.prototype */{ 56 57 x:0, 58 y:0, 59 __POINT2D:true, 60 61 /** 62 * @private 63 */ 64 constructor:function (x, y) { 65 this.base("Point2D"); 66 this.__POINT2D = true; 67 return this.set(x, y); 68 }, 69 70 /** 71 * Release this point into the pool for reuse. 72 */ 73 release:function () { 74 this.base(); 75 this.x = 0; 76 this.y = 0; 77 }, 78 79 /** 80 * Returns a simplified version of a R.math.Point2D. The simplified version is 81 * an array with two elements: X, Y. 82 * @return {Array} 83 */ 84 simplify:function () { 85 return [this.x, this.y]; 86 }, 87 88 /** 89 * Returns <tt>true</tt> if this point is equal to the specified point. 90 * 91 * @param point {R.math.Point2D} The point to compare to 92 * @return {Boolean} <tt>true</tt> if the two points are equal 93 */ 94 equals:function (point) { 95 return (this.x == point.x && this.y == point.y); 96 }, 97 98 /** 99 * Set the position of a 2D point. 100 * 101 * @param x {R.math.Point2D|Number|Array} If this arg is a R.math.Point2D, its values will be 102 * copied into the new point. 103 * @param y {Number} The Y coordinate of the point. Only required if X 104 * was a number. 105 */ 106 set:function (x, y) { 107 if (R.isArray(x)) { 108 // An array 109 this.x = x[0]; 110 this.y = x[1]; 111 } 112 else if (x.__POINT2D) { // Instead of an "instanceof" check 113 this.x = x.x; 114 this.y = x.y; 115 } 116 else { 117 AssertWarn((y != null), "Undefined Y value for point initialized to zero."); 118 this.x = x; 119 this.y = y || 0; 120 } 121 return this; 122 }, 123 124 /** 125 * Set the X coordinate. 126 * 127 * @param x {Number} The X coordinate 128 */ 129 setX:function (x) { 130 this.x = x; 131 }, 132 133 /** 134 * Set the Y coordinate. 135 * 136 * @param y {Number} The Y coordinate 137 */ 138 setY:function (y) { 139 this.y = y; 140 }, 141 142 /** 143 * A method that mutates this point by adding the point to it. 144 * 145 * @param point {R.math.Point2D} A point 146 * @return {R.math.Point2D} This point 147 */ 148 add:function (point) { 149 Assert(point != null, "Adding undefined point"); 150 this.x += point.x; 151 this.y += point.y; 152 return this; 153 }, 154 155 /** 156 * A mutator method that adds the scalar value to each component of this point. 157 * @param scalar {Number} A number 158 * @return {R.math.Point2D} This point 159 */ 160 addScalar:function (scalar) { 161 Assert(scalar != null, "Adding undefined scalar"); 162 this.x += scalar; 163 this.y += scalar; 164 return this; 165 }, 166 167 /** 168 * A mutator method that subtracts the specified point from this point. 169 * @param point {Point2D} a point 170 * @return {R.math.Point2D} This point 171 */ 172 sub:function (point) { 173 Assert(point != null, "Subtracting undefined point"); 174 this.x -= point.x; 175 this.y -= point.y; 176 return this; 177 }, 178 179 /** 180 * A mutator method that multiplies the components of this point with another. 181 * @param point {R.math.Point2D} A point 182 * @return {R.math.Point2D} This point 183 */ 184 convolve:function (point) { 185 Assert(point != null, "Convolving undefined point"); 186 this.x *= point.x; 187 this.y *= point.y; 188 return this; 189 }, 190 191 /** 192 * A mutator method that divides the components of this point by another. The point 193 * cannot contain zeros for its components. 194 * @param point {R.math.Point2D} A point 195 * @return {R.math.Point2D} This point 196 */ 197 convolveInverse:function (point) { 198 Assert(point != null, "Inverse convolving undefined point"); 199 Assert((point.x != 0 && point.y != 0), "Division by zero in Point2D.convolveInverse"); 200 this.x /= point.x; 201 this.y /= point.y; 202 return this; 203 }, 204 205 /** 206 * A mutator methor that multiplies the components of this point by a scalar value. 207 * @param scalar {Number} A number 208 * @return {R.math.Point2D} This point 209 */ 210 mul:function (scalar) { 211 Assert(scalar != null, "Multiplying undefined scalar"); 212 this.x *= scalar; 213 this.y *= scalar; 214 return this; 215 }, 216 217 /** 218 * A mutator method that divides the components of this point by a scalar value. 219 * @param scalar {Number} A number - cannot be zero 220 * @return {R.math.Point2D} This point 221 */ 222 div:function (scalar) { 223 Assert(scalar != null, "Dividing undefined scalar"); 224 Assert((scalar != 0), "Division by zero in Point2D.divScalar"); 225 this.x /= scalar; 226 this.y /= scalar; 227 return this; 228 }, 229 230 /** 231 * A mutator method that negates this point, inversing it's components. 232 * @return {R.math.Point2D} This point 233 */ 234 neg:function () { 235 this.x *= -1; 236 this.y *= -1; 237 return this; 238 }, 239 240 /** 241 * Returns true if the point is the zero point. 242 * @return {Boolean} <tt>true</tt> if the point's elements are both zero. 243 */ 244 isZero:function () { 245 return this.x == 0 && this.y == 0; 246 }, 247 248 /** 249 * Returns the distance between this and another point. 250 * @param point {R.math.Point2D} The point to compare against 251 * @return {Number} The distance between the two points 252 */ 253 dist:function (point) { 254 Assert(point != null, "Cannot solve distance to undefined point"); 255 return Math.sqrt((point.x - this.x) * (point.x - this.x) + 256 (point.y - this.y) * (point.y - this.y)); 257 }, 258 259 /** 260 * Mutator method which transforms this point by the specified matrix 261 * @param matrix {Matrix} The matrix to transform this point by. <tt>Matrix</tt> 262 * is defined in the Sylvester library. 263 * 264 * @return {R.math.Point2D} This point 265 */ 266 transform:function (matrix) { 267 var v = matrix.multiply({ modulus:true, elements:[this.x, this.y, 1] }); 268 this.x = v.elements[0]; 269 this.y = v.elements[1]; 270 return this; 271 }, 272 273 jitter:function (amt) { 274 var j = R.math.Point2D.create(R.lang.Math2.randomRange(-amt, amt, true), 275 R.lang.Math2.randomRange(-amt, amt, true)); 276 277 this.add(j); 278 j.destroy(); 279 return this; 280 }, 281 282 /** 283 * Returns a printable version of this object fixed to two decimal places. 284 * @return {String} Formatted as "x,y" 285 */ 286 toString:function () { 287 return Number(this.x).toFixed(2) + "," + Number(this.y).toFixed(2); 288 } 289 290 }, /** @scope R.math.Point2D.prototype */{ 291 /** 292 * Return the classname of the this object 293 * @return {String} "R.math.Point2D" 294 */ 295 getClassName:function () { 296 return "R.math.Point2D"; 297 }, 298 299 /** @private */ 300 resolved:function () { 301 R.math.Point2D.ZERO = R.math.Point2D.create(0, 0); 302 if (Object.freeze) { 303 Object.freeze(R.math.Point2D.ZERO); 304 } 305 }, 306 307 /** 308 * The "zero" point. This point should not be modified. 309 * @type {Point2D} 310 */ 311 ZERO:null 312 }); 313 };