/**
* Returns a {@link pv.Vector} for the specified x and y
* coordinate. This is a convenience factory method, equivalent to new
* pv.Vector(x, y).
*
* @see pv.Vector
* @param {number} x the x coordinate.
* @param {number} y the y coordinate.
* @returns {pv.Vector} a vector for the specified coordinates.
*/
pv.vector = function(x, y) {
return new pv.Vector(x, y);
};
/**
* Constructs a {@link pv.Vector} for the specified x and y
* coordinate. This constructor should not be invoked directly; use
* {@link pv.vector} instead.
*
* @class Represents a two-dimensional vector; a 2-tuple ⟨x,
* y⟩. The intent of this class is to simplify vector math. Note that
* in performance-sensitive cases it may be more efficient to represent 2D
* vectors as simple objects with x and y attributes, rather
* than using instances of this class.
*
* @param {number} x the x coordinate.
* @param {number} y the y coordinate.
*/
pv.Vector = function(x, y) {
this.x = x;
this.y = y;
};
/**
* Returns a vector perpendicular to this vector: ⟨-y, x⟩.
*
* @returns {pv.Vector} a perpendicular vector.
*/
pv.Vector.prototype.perp = function() {
return new pv.Vector(-this.y, this.x);
};
/**
* Returns a normalized copy of this vector: a vector with the same direction,
* but unit length. If this vector has zero length this method returns a copy of
* this vector.
*
* @returns {pv.Vector} a unit vector.
*/
pv.Vector.prototype.norm = function() {
var l = this.length();
return this.times(l ? (1 / l) : 1);
};
/**
* Returns the magnitude of this vector, defined as sqrt(x * x + y * y).
*
* @returns {number} a length.
*/
pv.Vector.prototype.length = function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
/**
* Returns a scaled copy of this vector: ⟨x * k, y * k⟩.
* To perform the equivalent divide operation, use 1 / k.
*
* @param {number} k the scale factor.
* @returns {pv.Vector} a scaled vector.
*/
pv.Vector.prototype.times = function(k) {
return new pv.Vector(this.x * k, this.y * k);
};
/**
* Returns this vector plus the vector v: ⟨x + v.x, y +
* v.y⟩. If only one argument is specified, it is interpreted as the
* vector v.
*
* @param {number} x the x coordinate to add.
* @param {number} y the y coordinate to add.
* @returns {pv.Vector} a new vector.
*/
pv.Vector.prototype.plus = function(x, y) {
return (arguments.length == 1)
? new pv.Vector(this.x + x.x, this.y + x.y)
: new pv.Vector(this.x + x, this.y + y);
};
/**
* Returns this vector minus the vector v: ⟨x - v.x, y -
* v.y⟩. If only one argument is specified, it is interpreted as the
* vector v.
*
* @param {number} x the x coordinate to subtract.
* @param {number} y the y coordinate to subtract.
* @returns {pv.Vector} a new vector.
*/
pv.Vector.prototype.minus = function(x, y) {
return (arguments.length == 1)
? new pv.Vector(this.x - x.x, this.y - x.y)
: new pv.Vector(this.x - x, this.y - y);
};
/**
* Returns the dot product of this vector and the vector v: x * v.x +
* y * v.y. If only one argument is specified, it is interpreted as the
* vector v.
*
* @param {number} x the x coordinate to dot.
* @param {number} y the y coordinate to dot.
* @returns {number} a dot product.
*/
pv.Vector.prototype.dot = function(x, y) {
return (arguments.length == 1)
? this.x * x.x + this.y * x.y
: this.x * x + this.y * y;
};