Show:

File: src/geometry/Vector.js

                                /**
                                * The `Matter.Vector` module contains methods for creating and manipulating vectors.
                                * Vectors are the basis of all the geometry related operations in the engine.
                                * A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
                                *
                                * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
                                *
                                * @class Vector
                                */
                                
                                // TODO: consider params for reusing vector objects
                                
                                var Vector = {};
                                
                                module.exports = Vector;
                                
                                (function() {
                                
                                    /**
                                     * Creates a new vector.
                                     * @method create
                                     * @param {number} x
                                     * @param {number} y
                                     * @return {vector} A new vector
                                     */
                                    Vector.create = function(x, y) {
                                        return { x: x || 0, y: y || 0 };
                                    };
                                
                                    /**
                                     * Returns a new vector with `x` and `y` copied from the given `vector`.
                                     * @method clone
                                     * @param {vector} vector
                                     * @return {vector} A new cloned vector
                                     */
                                    Vector.clone = function(vector) {
                                        return { x: vector.x, y: vector.y };
                                    };
                                
                                    /**
                                     * Returns the magnitude (length) of a vector.
                                     * @method magnitude
                                     * @param {vector} vector
                                     * @return {number} The magnitude of the vector
                                     */
                                    Vector.magnitude = function(vector) {
                                        return Math.sqrt((vector.x * vector.x) + (vector.y * vector.y));
                                    };
                                
                                    /**
                                     * Returns the magnitude (length) of a vector (therefore saving a `sqrt` operation).
                                     * @method magnitudeSquared
                                     * @param {vector} vector
                                     * @return {number} The squared magnitude of the vector
                                     */
                                    Vector.magnitudeSquared = function(vector) {
                                        return (vector.x * vector.x) + (vector.y * vector.y);
                                    };
                                
                                    /**
                                     * Rotates the vector about (0, 0) by specified angle.
                                     * @method rotate
                                     * @param {vector} vector
                                     * @param {number} angle
                                     * @param {vector} [output]
                                     * @return {vector} The vector rotated about (0, 0)
                                     */
                                    Vector.rotate = function(vector, angle, output) {
                                        var cos = Math.cos(angle), sin = Math.sin(angle);
                                        if (!output) output = {};
                                        var x = vector.x * cos - vector.y * sin;
                                        output.y = vector.x * sin + vector.y * cos;
                                        output.x = x;
                                        return output;
                                    };
                                
                                    /**
                                     * Rotates the vector about a specified point by specified angle.
                                     * @method rotateAbout
                                     * @param {vector} vector
                                     * @param {number} angle
                                     * @param {vector} point
                                     * @param {vector} [output]
                                     * @return {vector} A new vector rotated about the point
                                     */
                                    Vector.rotateAbout = function(vector, angle, point, output) {
                                        var cos = Math.cos(angle), sin = Math.sin(angle);
                                        if (!output) output = {};
                                        var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin);
                                        output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos);
                                        output.x = x;
                                        return output;
                                    };
                                
                                    /**
                                     * Normalises a vector (such that its magnitude is `1`).
                                     * @method normalise
                                     * @param {vector} vector
                                     * @return {vector} A new vector normalised
                                     */
                                    Vector.normalise = function(vector) {
                                        var magnitude = Vector.magnitude(vector);
                                        if (magnitude === 0)
                                            return { x: 0, y: 0 };
                                        return { x: vector.x / magnitude, y: vector.y / magnitude };
                                    };
                                
                                    /**
                                     * Returns the dot-product of two vectors.
                                     * @method dot
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @return {number} The dot product of the two vectors
                                     */
                                    Vector.dot = function(vectorA, vectorB) {
                                        return (vectorA.x * vectorB.x) + (vectorA.y * vectorB.y);
                                    };
                                
                                    /**
                                     * Returns the cross-product of two vectors.
                                     * @method cross
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @return {number} The cross product of the two vectors
                                     */
                                    Vector.cross = function(vectorA, vectorB) {
                                        return (vectorA.x * vectorB.y) - (vectorA.y * vectorB.x);
                                    };
                                
                                    /**
                                     * Returns the cross-product of three vectors.
                                     * @method cross3
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @param {vector} vectorC
                                     * @return {number} The cross product of the three vectors
                                     */
                                    Vector.cross3 = function(vectorA, vectorB, vectorC) {
                                        return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x);
                                    };
                                
                                    /**
                                     * Adds the two vectors.
                                     * @method add
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @param {vector} [output]
                                     * @return {vector} A new vector of vectorA and vectorB added
                                     */
                                    Vector.add = function(vectorA, vectorB, output) {
                                        if (!output) output = {};
                                        output.x = vectorA.x + vectorB.x;
                                        output.y = vectorA.y + vectorB.y;
                                        return output;
                                    };
                                
                                    /**
                                     * Subtracts the two vectors.
                                     * @method sub
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @param {vector} [output]
                                     * @return {vector} A new vector of vectorA and vectorB subtracted
                                     */
                                    Vector.sub = function(vectorA, vectorB, output) {
                                        if (!output) output = {};
                                        output.x = vectorA.x - vectorB.x;
                                        output.y = vectorA.y - vectorB.y;
                                        return output;
                                    };
                                
                                    /**
                                     * Multiplies a vector and a scalar.
                                     * @method mult
                                     * @param {vector} vector
                                     * @param {number} scalar
                                     * @return {vector} A new vector multiplied by scalar
                                     */
                                    Vector.mult = function(vector, scalar) {
                                        return { x: vector.x * scalar, y: vector.y * scalar };
                                    };
                                
                                    /**
                                     * Divides a vector and a scalar.
                                     * @method div
                                     * @param {vector} vector
                                     * @param {number} scalar
                                     * @return {vector} A new vector divided by scalar
                                     */
                                    Vector.div = function(vector, scalar) {
                                        return { x: vector.x / scalar, y: vector.y / scalar };
                                    };
                                
                                    /**
                                     * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction.
                                     * @method perp
                                     * @param {vector} vector
                                     * @param {bool} [negate=false]
                                     * @return {vector} The perpendicular vector
                                     */
                                    Vector.perp = function(vector, negate) {
                                        negate = negate === true ? -1 : 1;
                                        return { x: negate * -vector.y, y: negate * vector.x };
                                    };
                                
                                    /**
                                     * Negates both components of a vector such that it points in the opposite direction.
                                     * @method neg
                                     * @param {vector} vector
                                     * @return {vector} The negated vector
                                     */
                                    Vector.neg = function(vector) {
                                        return { x: -vector.x, y: -vector.y };
                                    };
                                
                                    /**
                                     * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians.
                                     * @method angle
                                     * @param {vector} vectorA
                                     * @param {vector} vectorB
                                     * @return {number} The angle in radians
                                     */
                                    Vector.angle = function(vectorA, vectorB) {
                                        return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x);
                                    };
                                
                                    /**
                                     * Temporary vector pool (not thread-safe).
                                     * @property _temp
                                     * @type {vector[]}
                                     * @private
                                     */
                                    Vector._temp = [
                                        Vector.create(), Vector.create(), 
                                        Vector.create(), Vector.create(), 
                                        Vector.create(), Vector.create()
                                    ];
                                
                                })();