/** * 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;