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