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