UNPKG

arcade-physics

Version:
651 lines 17.9 kB
"use strict"; /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2020 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Vector2 = void 0; // Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji // and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl // let Class = require('../utils/Class') const FuzzyEqual = require('../math/fuzzy/Equal'); /** * @classdesc * A representation of a vector in 2D space. * * A two-component vector. * * @class Vector2 * @memberof Phaser.Math * @constructor * @since 3.0.0 * * @param {number|Phaser.Types.Math.Vector2Like} [x] - The x component, or an object with `x` and `y` properties. * @param {number} [y] - The y component. */ class Vector2 { constructor(x, y) { /** * The x component of this Vector. * * @name Phaser.Math.Vector2#x * @type {number} * @default 0 * @since 3.0.0 */ this.x = 0; /** * The y component of this Vector. * * @name Phaser.Math.Vector2#y * @type {number} * @default 0 * @since 3.0.0 */ this.y = 0; if (typeof x === 'object') { this.x = x.x || 0; this.y = x.y || 0; } else { if (y === undefined) { y = x; } this.x = x || 0; this.y = y || 0; } } /** * Make a clone of this Vector2. * * @method Phaser.Math.Vector2#clone * @since 3.0.0 * * @return {Phaser.Math.Vector2} A clone of this Vector2. */ clone() { return new Vector2(this.x, this.y); } /** * Copy the components of a given Vector into this Vector. * * @method Phaser.Math.Vector2#copy * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to copy the components from. * * @return {Phaser.Math.Vector2} This Vector2. */ copy(src) { this.x = src.x || 0; this.y = src.y || 0; return this; } /** * Set the component values of this Vector from a given Vector2Like object. * * @method Phaser.Math.Vector2#setFromObject * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector. * * @return {Phaser.Math.Vector2} This Vector2. */ setFromObject(obj) { this.x = obj.x || 0; this.y = obj.y || 0; return this; } /** * Set the `x` and `y` components of the this Vector to the given `x` and `y` values. * * @method Phaser.Math.Vector2#set * @since 3.0.0 * * @param {number} x - The x value to set for this Vector. * @param {number} [y=x] - The y value to set for this Vector. * * @return {Phaser.Math.Vector2} This Vector2. */ set(x, y) { if (y === undefined) { y = x; } this.x = x; this.y = y; return this; } /** * This method is an alias for `Vector2.set`. * * @method Phaser.Math.Vector2#setTo * @since 3.4.0 * * @param {number} x - The x value to set for this Vector. * @param {number} [y=x] - The y value to set for this Vector. * * @return {Phaser.Math.Vector2} This Vector2. */ setTo(x, y) { return this.set(x, y); } /** * Sets the `x` and `y` values of this object from a given polar coordinate. * * @method Phaser.Math.Vector2#setToPolar * @since 3.0.0 * * @param {number} azimuth - The angular coordinate, in radians. * @param {number} [radius=1] - The radial coordinate (length). * * @return {Phaser.Math.Vector2} This Vector2. */ setToPolar(azimuth, radius) { if (radius == null) { radius = 1; } this.x = Math.cos(azimuth) * radius; this.y = Math.sin(azimuth) * radius; return this; } /** * Check whether this Vector is equal to a given Vector. * * Performs a strict equality check against each Vector's components. * * @method Phaser.Math.Vector2#equals * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. * * @return {boolean} Whether the given Vector is equal to this Vector. */ equals(v) { return this.x === v.x && this.y === v.y; } /** * Check whether this Vector is approximately equal to a given Vector. * * @method Phaser.Math.Vector2#fuzzyEquals * @since 3.23.0 * * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. * @param {number} [epsilon=0.0001] - The tolerance value. * * @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`. */ fuzzyEquals(v, epsilon) { return FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon); } /** * Calculate the angle between this Vector and the positive x-axis, in radians. * * @method Phaser.Math.Vector2#angle * @since 3.0.0 * * @return {number} The angle between this Vector, and the positive x-axis, given in radians. */ angle() { // computes the angle in radians with respect to the positive x-axis let angle = Math.atan2(this.y, this.x); if (angle < 0) { angle += 2 * Math.PI; } return angle; } /** * Set the angle of this Vector. * * @method Phaser.Math.Vector2#setAngle * @since 3.23.0 * * @param {number} angle - The angle, in radians. * * @return {Phaser.Math.Vector2} This Vector2. */ setAngle(angle) { return this.setToPolar(angle, this.length()); } /** * Add a given Vector to this Vector. Addition is component-wise. * * @method Phaser.Math.Vector2#add * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to add to this Vector. * * @return {Phaser.Math.Vector2} This Vector2. */ add(src) { this.x += src.x; this.y += src.y; return this; } /** * Subtract the given Vector from this Vector. Subtraction is component-wise. * * @method Phaser.Math.Vector2#subtract * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to subtract from this Vector. * * @return {Phaser.Math.Vector2} This Vector2. */ subtract(src) { this.x -= src.x; this.y -= src.y; return this; } /** * Perform a component-wise multiplication between this Vector and the given Vector. * * Multiplies this Vector by the given Vector. * * @method Phaser.Math.Vector2#multiply * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to multiply this Vector by. * * @return {Phaser.Math.Vector2} This Vector2. */ multiply(src) { this.x *= src.x; this.y *= src.y; return this; } /** * Scale this Vector by the given value. * * @method Phaser.Math.Vector2#scale * @since 3.0.0 * * @param {number} value - The value to scale this Vector by. * * @return {Phaser.Math.Vector2} This Vector2. */ scale(value) { if (isFinite(value)) { this.x *= value; this.y *= value; } else { this.x = 0; this.y = 0; } return this; } /** * Perform a component-wise division between this Vector and the given Vector. * * Divides this Vector by the given Vector. * * @method Phaser.Math.Vector2#divide * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to divide this Vector by. * * @return {Phaser.Math.Vector2} This Vector2. */ divide(src) { this.x /= src.x; this.y /= src.y; return this; } /** * Negate the `x` and `y` components of this Vector. * * @method Phaser.Math.Vector2#negate * @since 3.0.0 * * @return {Phaser.Math.Vector2} This Vector2. */ negate() { this.x = -this.x; this.y = -this.y; return this; } /** * Calculate the distance between this Vector and the given Vector. * * @method Phaser.Math.Vector2#distance * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. * * @return {number} The distance from this Vector to the given Vector. */ distance(src) { const dx = src.x - this.x; const dy = src.y - this.y; return Math.sqrt(dx * dx + dy * dy); } /** * Calculate the distance between this Vector and the given Vector, squared. * * @method Phaser.Math.Vector2#distanceSq * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. * * @return {number} The distance from this Vector to the given Vector, squared. */ distanceSq(src) { const dx = src.x - this.x; const dy = src.y - this.y; return dx * dx + dy * dy; } /** * Calculate the length (or magnitude) of this Vector. * * @method Phaser.Math.Vector2#length * @since 3.0.0 * * @return {number} The length of this Vector. */ length() { const x = this.x; const y = this.y; return Math.sqrt(x * x + y * y); } /** * Set the length (or magnitude) of this Vector. * * @method Phaser.Math.Vector2#setLength * @since 3.23.0 * * @param {number} length * * @return {Phaser.Math.Vector2} This Vector2. */ setLength(length) { return this.normalize().scale(length); } /** * Calculate the length of this Vector squared. * * @method Phaser.Math.Vector2#lengthSq * @since 3.0.0 * * @return {number} The length of this Vector, squared. */ lengthSq() { const x = this.x; const y = this.y; return x * x + y * y; } /** * Normalize this Vector. * * Makes the vector a unit length vector (magnitude of 1) in the same direction. * * @method Phaser.Math.Vector2#normalize * @since 3.0.0 * * @return {Phaser.Math.Vector2} This Vector2. */ normalize() { const x = this.x; const y = this.y; let len = x * x + y * y; if (len > 0) { len = 1 / Math.sqrt(len); this.x = x * len; this.y = y * len; } return this; } /** * Rotate this Vector to its perpendicular, in the positive direction. * * @method Phaser.Math.Vector2#normalizeRightHand * @since 3.0.0 * * @return {Phaser.Math.Vector2} This Vector2. */ normalizeRightHand() { const x = this.x; this.x = this.y * -1; this.y = x; return this; } /** * Rotate this Vector to its perpendicular, in the negative direction. * * @method Phaser.Math.Vector2#normalizeLeftHand * @since 3.23.0 * * @return {Phaser.Math.Vector2} This Vector2. */ normalizeLeftHand() { const x = this.x; this.x = this.y; this.y = x * -1; return this; } /** * Calculate the dot product of this Vector and the given Vector. * * @method Phaser.Math.Vector2#dot * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to dot product with this Vector2. * * @return {number} The dot product of this Vector and the given Vector. */ dot(src) { return this.x * src.x + this.y * src.y; } /** * Calculate the cross product of this Vector and the given Vector. * * @method Phaser.Math.Vector2#cross * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to cross with this Vector2. * * @return {number} The cross product of this Vector and the given Vector. */ cross(src) { return this.x * src.y - this.y * src.x; } /** * Linearly interpolate between this Vector and the given Vector. * * Interpolates this Vector towards the given Vector. * * @method Phaser.Math.Vector2#lerp * @since 3.0.0 * * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to interpolate towards. * @param {number} [t=0] - The interpolation percentage, between 0 and 1. * * @return {Phaser.Math.Vector2} This Vector2. */ lerp(src, t) { if (t === undefined) { t = 0; } const ax = this.x; const ay = this.y; this.x = ax + t * (src.x - ax); this.y = ay + t * (src.y - ay); return this; } /** * Transform this Vector with the given Matrix. * * @method Phaser.Math.Vector2#transformMat3 * @since 3.0.0 * * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with. * * @return {Phaser.Math.Vector2} This Vector2. */ transformMat3(mat) { const x = this.x; const y = this.y; const m = mat.val; this.x = m[0] * x + m[3] * y + m[6]; this.y = m[1] * x + m[4] * y + m[7]; return this; } /** * Transform this Vector with the given Matrix. * * @method Phaser.Math.Vector2#transformMat4 * @since 3.0.0 * * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with. * * @return {Phaser.Math.Vector2} This Vector2. */ transformMat4(mat) { const x = this.x; const y = this.y; const m = mat.val; this.x = m[0] * x + m[4] * y + m[12]; this.y = m[1] * x + m[5] * y + m[13]; return this; } /** * Make this Vector the zero vector (0, 0). * * @method Phaser.Math.Vector2#reset * @since 3.0.0 * * @return {Phaser.Math.Vector2} This Vector2. */ reset() { this.x = 0; this.y = 0; return this; } /** * Limit the length (or magnitude) of this Vector. * * @method Phaser.Math.Vector2#limit * @since 3.23.0 * * @param {number} max - The maximum length. * * @return {Phaser.Math.Vector2} This Vector2. */ limit(max) { const len = this.length(); if (len && len > max) { this.scale(max / len); } return this; } /** * Reflect this Vector off a line defined by a normal. * * @method Phaser.Math.Vector2#reflect * @since 3.23.0 * * @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line. * * @return {Phaser.Math.Vector2} This Vector2. */ reflect(normal) { normal = normal.clone().normalize(); return this.subtract(normal.scale(2 * this.dot(normal))); } /** * Reflect this Vector across another. * * @method Phaser.Math.Vector2#mirror * @since 3.23.0 * * @param {Phaser.Math.Vector2} axis - A vector to reflect across. * * @return {Phaser.Math.Vector2} This Vector2. */ mirror(axis) { return this.reflect(axis).negate(); } /** * Rotate this Vector by an angle amount. * * @method Phaser.Math.Vector2#rotate * @since 3.23.0 * * @param {number} delta - The angle to rotate by, in radians. * * @return {Phaser.Math.Vector2} This Vector2. */ rotate(delta) { const cos = Math.cos(delta); const sin = Math.sin(delta); return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y); } } exports.Vector2 = Vector2; /** * A static zero Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.ZERO * @type {Phaser.Math.Vector2} * @since 3.1.0 */ Vector2.ZERO = new Vector2(); /** * A static right Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.RIGHT * @type {Phaser.Math.Vector2} * @since 3.16.0 */ Vector2.RIGHT = new Vector2(1, 0); /** * A static left Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.LEFT * @type {Phaser.Math.Vector2} * @since 3.16.0 */ Vector2.LEFT = new Vector2(-1, 0); /** * A static up Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.UP * @type {Phaser.Math.Vector2} * @since 3.16.0 */ Vector2.UP = new Vector2(0, -1); /** * A static down Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.DOWN * @type {Phaser.Math.Vector2} * @since 3.16.0 */ Vector2.DOWN = new Vector2(0, 1); /** * A static one Vector2 for use by reference. * * This constant is meant for comparison operations and should not be modified directly. * * @constant * @name Phaser.Math.Vector2.ONE * @type {Phaser.Math.Vector2} * @since 3.16.0 */ Vector2.ONE = new Vector2(1, 1); //# sourceMappingURL=Vector2.js.map