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
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