1 /** 2 * Returns a {@link pv.Vector} for the specified <i>x</i> and <i>y</i> 3 * coordinate. This is a convenience factory method, equivalent to <tt>new 4 * pv.Vector(x, y)</tt>. 5 * 6 * @see pv.Vector 7 * @param {number} x the <i>x</i> coordinate. 8 * @param {number} y the <i>y</i> coordinate. 9 * @returns {pv.Vector} a vector for the specified coordinates. 10 */ 11 pv.vector = function(x, y) { 12 return new pv.Vector(x, y); 13 }; 14 15 /** 16 * Constructs a {@link pv.Vector} for the specified <i>x</i> and <i>y</i> 17 * coordinate. This constructor should not be invoked directly; use 18 * {@link pv.vector} instead. 19 * 20 * @class Represents a two-dimensional vector; a 2-tuple <i>⟨x, 21 * y⟩</i>. The intent of this class is to simplify vector math. Note that 22 * in performance-sensitive cases it may be more efficient to represent 2D 23 * vectors as simple objects with <tt>x</tt> and <tt>y</tt> attributes, rather 24 * than using instances of this class. 25 * 26 * @param {number} x the <i>x</i> coordinate. 27 * @param {number} y the <i>y</i> coordinate. 28 */ 29 pv.Vector = function(x, y) { 30 this.x = x; 31 this.y = y; 32 }; 33 34 /** 35 * Returns a vector perpendicular to this vector: <i>⟨-y, x⟩</i>. 36 * 37 * @returns {pv.Vector} a perpendicular vector. 38 */ 39 pv.Vector.prototype.perp = function() { 40 return new pv.Vector(-this.y, this.x); 41 }; 42 43 /** 44 * Returns a normalized copy of this vector: a vector with the same direction, 45 * but unit length. If this vector has zero length this method returns a copy of 46 * this vector. 47 * 48 * @returns {pv.Vector} a unit vector. 49 */ 50 pv.Vector.prototype.norm = function() { 51 var l = this.length(); 52 return this.times(l ? (1 / l) : 1); 53 }; 54 55 /** 56 * Returns the magnitude of this vector, defined as <i>sqrt(x * x + y * y)</i>. 57 * 58 * @returns {number} a length. 59 */ 60 pv.Vector.prototype.length = function() { 61 return Math.sqrt(this.x * this.x + this.y * this.y); 62 }; 63 64 /** 65 * Returns a scaled copy of this vector: <i>⟨x * k, y * k⟩</i>. 66 * To perform the equivalent divide operation, use <i>1 / k</i>. 67 * 68 * @param {number} k the scale factor. 69 * @returns {pv.Vector} a scaled vector. 70 */ 71 pv.Vector.prototype.times = function(k) { 72 return new pv.Vector(this.x * k, this.y * k); 73 }; 74 75 /** 76 * Returns this vector plus the vector <i>v</i>: <i>⟨x + v.x, y + 77 * v.y⟩</i>. If only one argument is specified, it is interpreted as the 78 * vector <i>v</i>. 79 * 80 * @param {number} x the <i>x</i> coordinate to add. 81 * @param {number} y the <i>y</i> coordinate to add. 82 * @returns {pv.Vector} a new vector. 83 */ 84 pv.Vector.prototype.plus = function(x, y) { 85 return (arguments.length == 1) 86 ? new pv.Vector(this.x + x.x, this.y + x.y) 87 : new pv.Vector(this.x + x, this.y + y); 88 }; 89 90 /** 91 * Returns this vector minus the vector <i>v</i>: <i>⟨x - v.x, y - 92 * v.y⟩</i>. If only one argument is specified, it is interpreted as the 93 * vector <i>v</i>. 94 * 95 * @param {number} x the <i>x</i> coordinate to subtract. 96 * @param {number} y the <i>y</i> coordinate to subtract. 97 * @returns {pv.Vector} a new vector. 98 */ 99 pv.Vector.prototype.minus = function(x, y) { 100 return (arguments.length == 1) 101 ? new pv.Vector(this.x - x.x, this.y - x.y) 102 : new pv.Vector(this.x - x, this.y - y); 103 }; 104 105 /** 106 * Returns the dot product of this vector and the vector <i>v</i>: <i>x * v.x + 107 * y * v.y</i>. If only one argument is specified, it is interpreted as the 108 * vector <i>v</i>. 109 * 110 * @param {number} x the <i>x</i> coordinate to dot. 111 * @param {number} y the <i>y</i> coordinate to dot. 112 * @returns {number} a dot product. 113 */ 114 pv.Vector.prototype.dot = function(x, y) { 115 return (arguments.length == 1) 116 ? this.x * x.x + this.y * x.y 117 : this.x * x + this.y * y; 118 }; 119