1 /**
  2  * The Render Engine
  3  * Vector3D
  4  *
  5  * @fileoverview A Vector3D 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.Vector3D",
 36     "requires":[
 37         "R.math.Point3D",
 38         "R.math.Math2D"
 39     ]
 40 });
 41 
 42 /**
 43  * @class A 3D vector class with helpful manipulation methods.
 44  *
 45  * @param x {R.math.Point3D|Number} If this arg is a R.math.Vector3D, its values will be
 46  *                           copied into the new vector.  If a number,
 47  *                           the X length of the vector.
 48  * @param y {Number} The Y length of the vector.  Only required if X
 49  *                   was a number.
 50  * @param z {Number} The Z length of the vector.  Only required if X
 51  *                   was a number.
 52  * @constructor
 53  * @description Create a new 3D Vector
 54  * @extends R.math.Point3D
 55  */
 56 R.math.Vector3D = function () {
 57     "use strict";
 58     return R.math.Point3D.extend(/** @scope R.math.Vector3D.prototype */{
 59 
 60         /**
 61          * @private
 62          */
 63         constructor:function (x, y, z) {
 64             this.base(x, y, z);
 65         },
 66 
 67         /**
 68          * A mutator method that normalizes this vector, returning a unit length vector.
 69          * @return {R.math.Vector3D} This vector, normalized
 70          * @see #len
 71          */
 72         normalize:function () {
 73             var ln = this.len();
 74             if (ln != 0) {
 75                 this.x /= ln;
 76                 this.y /= ln;
 77                 this.z /= ln;
 78             }
 79             return this;
 80         },
 81 
 82         /**
 83          * Get the magnitude/length of this vector.
 84          *
 85          * @return {Number} A value representing the length (magnitude) of the vector.
 86          */
 87         len:function () {
 88             return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
 89         },
 90 
 91         /**
 92          * Get the dot product of this vector and another.
 93          * @param vector {R.math.Vector3D} The Point to perform the operation against.
 94          * @return {Number} The dot product
 95          */
 96         dot:function (vector) {
 97             return (this.x * vector.x) + (this.y * vector.y) + (this.z * vector.z);
 98         },
 99 
100         /**
101          * A mutator method that gets the cross product of this vector and another.
102          * @param vector {R.math.Vector3D} The vector to perform the operation against.
103          * @return {R.math.Vector3D} This vector
104          */
105         cross:function (vector) {
106             this.x = this.y - vector.y;
107             this.y = vector.x - this.x;
108             this.z = (this.x * vector.y) - (this.y * vector.x);
109             return this;
110         },
111 
112         /**
113          * Returns the angle (in degrees) between two vectors.  This assumes that the
114          * point is being used to represent a vector, and that the supplied point
115          * is also a vector.
116          *
117          * @param vector {R.math.Vector3D} The vector to perform the angular determination against
118          * @return {Number} The angle between two vectors, in degrees
119          */
120         angleBetween:function (vector) {
121             var v1 = $V([this.x, this.y, this.z]), v2 = $V([vector.x, vector.y, vector.z]);
122             return R.math.Math2D.radToDeg(v1.angleFrom(v2));
123         }
124 
125     }, /** @scope R.math.Vector3D.prototype */{
126         /**
127          * Return the classname of the this object
128          * @return {String} "R.math.Vector3D"
129          */
130         getClassName:function () {
131             return "R.math.Vector3D";
132         },
133 
134         /** @private */
135         resolved:function () {
136             R.math.Vector3D.ZERO = R.math.Vector3D.create(0, 0, 0);
137             if (Object.freeze) {
138                 Object.freeze(R.math.Vector3D.ZERO);
139             }
140         },
141 
142         /**
143          * The "zero" vector. This vector should not be modified.
144          * @type {R.math.Vector3D}
145          * @memberOf R.math.Vector3D
146          */
147         ZERO:null
148     });
149 };