/**
* Constructor for the minimal requirements for being a {@link Vector}.
*
* @memberof PhSim
* @constructor
* @param {Number} x
* @param {Number} y
*
*/
var Vector = function(x,y) {
/**
* x-coordinate of the vector
* @type {Number}
*/
this.x;
/**
* y-coordinate of the vector
* @type {Number}
*/
this.y;
if(typeof x === "number") {
this.x = x;
}
else {
console.trace();
throw "Expecting a number in argument 1";
}
if(typeof y === "number") {
this.y = y;
}
else {
console.trace()
throw "Expecting a number in argument 2"
}
}
/**
*
* Perform vector addition
*
* @function
* @param {Vector} vector1 - The first vector
* @param {Vector} vector2 - The second vector
*
* @param {Boolean} [newObj = true] - Boolean that determines the return value.
* If true, then it returns a new Vector object `vector` such that
* `vector.x === vector1.x + vector2.x` and `vector.x === vector1.y + vector2.y`
*
* If false, then `vector2.x` is added to `vector1.x`, `vector2.y` is added to `vector1.y`
* and then `vector1` is returned.
*
* @returns {Vector} - The sum of the two vectors. New object if `newObj` is true. Returns
* `vector1` otherwise.
*/
Vector.add = function(vector1,vector2,newObj = true) {
if(newObj) {
return new Vector(vector1.x + vector2.x, vector1.y + vector2.y);
}
else {
vector1.x = vector1.x + vector2.x;
vector1.y = vector1.y + vector2.y;
return vector1;
}
}
/**
*
* Perform vector subtraction
*
* @function
* @param {Vector} vector1
* @param {Vector} vector2
*
* * @param {Boolean} [newObj = true] - Boolean that determines the return value.
* If true, then it returns a new Vector object `vector` such that
* `vector.x === vector1.x - vector2.x` and `vector.x === vector1.y - vector2.y`
*
* If false, then `vector2.x` is subtracted from `vector1.x`, `vector2.y` is subtracted
* from `vector1.y` and then `vector1` is returned.
*
* @returns {Vector} - The difference between the two vectors. New object if `newObj` is true. Returns
* `vector1` otherwise.
*/
Vector.subtract = function(vector1,vector2,newObj = true) {
if(newObj) {
return new Vector(vector1.x - vector2.x, vector1.y - vector2.y); }
else {
vector1.x = vector1.x - vector2.x;
vector1.y = vector1.y - vector2.y;
return vector1;
}
}
/**
*
* Multiply a vector by a scalar
*
* @function
* @param {Vector} vector
* @param {Number} scalar
* @returns {Vector}
*
*/
Vector.scale = function(vector,scalar) {
return new Vector(vector.x * scalar,vector.y * scalar)
}
/**
*
* Divide a vector by a scalar
*
* @function
* @param {Vector} vector
* @param {Number} scalar
* @returns {Vector}
*
*/
Vector.divide = function(vector,scalar) {
return new Vector(vector.x * (1/scalar),vector.y * (1/scalar));
}
/**
*
* Get distance between two vectors.
*
* @function
* @param {Vector} vector1
* @param {Vector} vector2
* @returns - The vector distance
*
*/
Vector.distance = function(vector1,vector2) {
var l1 = Math.pow(vector1.x - vector2.x,2);
var l2 = Math.pow(vector1.y - vector2.y,2);
return Math.sqrt(l1+l2);
}
/**
*
* Get length of the vector
*
* @function
* @param {Vector} vector
* @returns {Number} - The length of the vector
*/
Vector.getLength = function(vector) {
return Math.sqrt(Math.pow(vector.x,2)+Math.pow(vector.y,2))
}
/**
*
* Get normalized vector of some vector.
*
* @function
* @param {Vector} vector - Vector to normalize.
* @returns {Vector} - The Unit Vector
*/
Vector.unitVector = function(vector) {
return Vector.scale(vector,1/Vector.getLength(vector));
}
/**
* Apply a linear transformation defined by a 2x2 matrix to a vector.
*
* @function
* @param {Number} a11 - Element found in row 1, column 1
* @param {Number} a12 - Element found in row 1, column 2
* @param {Number} a21 - Element found in row 2, column 1
* @param {Number} a22 - Element found in row 2, column 2
* @param {Number} x - x-coordinate of vector to be transformed
* @param {Number} y - y-coordinate of vector to be transformed
* @returns - The transformed vector
*/
Vector.applyTransformation = function(a11,a12,a21,a22,x,y) {
return new Vector(a11 * x + a12 * y,a21 * x + a22 * y);
}
/**
*
* Rotate a vector (x,y) by angle a
*
* @function
* @param {Number} x - x-coordinate
* @param {Number} y - y-coordinate
* @param {Number} a - Angle in radians
* @returns {Vector}
*/
Vector.rotate = function(x,y,a) {
return Vector.applyTransformation(Math.cos(a),Math.sin(a),-Math.cos(a),Math.sin(a),x,y);
}
/**
* Get SVG point
* @param {Number} x
* @param {Number} y
* @returns {String} - SVG Vector String
*/
Vector.svgVector = function(x,y) {
return x + "," + y;
}
/**
* Calculate dot product of `vector1` and `vector2`.
*
* @function
* @since 0.2.0-alpha
* @param {Vector} vector1
* @param {Vector} vector2
* @returns {Number} - The dot product
*/
Vector.dotProduct = function(vector1,vector2) {
return vector1.x * vector2.x + vector1.y * vector2.y;
}
/**
*
* Gets angle between two lines that both end at `vertex`.
*
* That is, suppose that `A` is the point `ray1`, `B` is the point `ray2` and that
* `C` is the point `vertex`. Then, `vectorToArray` returns the angle between the lines
* `AC` and `BC`.
*
* @function
* @since 0.2.0-alpha
* @param {Vector} vertex
* @param {Vector} ray1
* @param {Vector} ray2
* @returns {Number} - The angle
*/
Vector.vectorToArray = function(vertex,ray1,ray2) {
ray1.x = ray1.x - vertex.x;
ray1.y = ray1.y - vertex.y;
ray2.x = ray2.x - vertex.x;
ray2.y = ray2.y - vertex.y;
return Math.acos(Vector.dotProduct(ray1,ray2));
}
module.exports = Vector;