phaser/src/math/Vector2.js

581 lines
13 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
2018-03-20 15:06:30 +00:00
// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji
// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl
2017-09-15 03:04:51 +00:00
var Class = require('../utils/Class');
2018-03-20 22:51:54 +00:00
/**
* @typedef {object} Vector2Like
*
* @property {number} x - The x component.
* @property {number} y - The y component.
2018-03-20 22:51:54 +00:00
*/
2018-01-31 17:48:30 +00:00
/**
2018-02-07 15:27:21 +00:00
* @classdesc
* A representation of a vector in 2D space.
2018-01-31 17:48:30 +00:00
*
* A two-component vector.
*
2018-01-31 17:48:30 +00:00
* @class Vector2
2018-10-10 09:49:13 +00:00
* @memberof Phaser.Math
2018-01-31 17:48:30 +00:00
* @constructor
* @since 3.0.0
*
* @param {number|Vector2Like} [x] - The x component, or an object with `x` and `y` properties.
* @param {number} [y] - The y component.
2018-01-31 17:48:30 +00:00
*/
2017-09-15 03:04:51 +00:00
var Vector2 = new Class({
initialize:
function Vector2 (x, y)
{
2018-02-07 15:27:21 +00:00
/**
* The x component of this Vector.
*
* @name Phaser.Math.Vector2#x
* @type {number}
* @default 0
* @since 3.0.0
*/
2018-03-20 22:51:54 +00:00
this.x = 0;
2018-02-07 15:27:21 +00:00
/**
* The y component of this Vector.
*
* @name Phaser.Math.Vector2#y
* @type {number}
* @default 0
* @since 3.0.0
*/
2018-03-20 22:51:54 +00:00
this.y = 0;
2018-02-07 15:27:21 +00:00
if (typeof x === 'object')
{
this.x = x.x || 0;
this.y = x.y || 0;
}
else
{
2017-10-17 03:18:29 +00:00
if (y === undefined) { y = x; }
this.x = x || 0;
this.y = y || 0;
}
2017-09-15 03:04:51 +00:00
},
2018-01-26 06:19:27 +00:00
/**
* Make a clone of this Vector2.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#clone
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} A clone of this Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
clone: function ()
{
return new Vector2(this.x, this.y);
},
2018-01-26 06:19:27 +00:00
/**
* Copy the components of a given Vector into this Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#copy
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to copy the components from.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
copy: function (src)
{
this.x = src.x || 0;
this.y = src.y || 0;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Set the component values of this Vector from a given Vector2Like object.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#setFromObject
* @since 3.0.0
*
* @param {Vector2Like} obj - The object containing the component values to set for this Vector.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
setFromObject: function (obj)
{
this.x = obj.x || 0;
this.y = obj.y || 0;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
2018-01-26 06:19:27 +00:00
*
* @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.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
set: function (x, y)
{
if (y === undefined) { y = x; }
this.x = x;
this.y = y;
2017-09-15 03:04:51 +00:00
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: function (x, y)
{
return this.set(x, y);
},
2018-01-26 06:19:27 +00:00
/**
2018-03-19 11:25:46 +00:00
* Sets the `x` and `y` values of this object from a given polar coordinate.
2018-01-26 06:19:27 +00:00
*
* @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).
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-11-09 15:30:33 +00:00
setToPolar: function (azimuth, radius)
{
if (radius == null) { radius = 1; }
this.x = Math.cos(azimuth) * radius;
this.y = Math.sin(azimuth) * radius;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Check whether this Vector is equal to a given Vector.
2018-01-26 06:19:27 +00:00
*
* Performs a strict equality check against each Vector's components.
*
2018-01-26 06:19:27 +00:00
* @method Phaser.Math.Vector2#equals
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} v - The vector to compare with this Vector.
2018-01-26 06:19:27 +00:00
*
* @return {boolean} Whether the given Vector is equal to this Vector.
2018-01-26 06:19:27 +00:00
*/
2017-09-21 16:11:56 +00:00
equals: function (v)
{
return ((this.x === v.x) && (this.y === v.y));
},
2017-09-20 22:10:03 +00:00
2018-01-26 06:19:27 +00:00
/**
* Calculate the angle between this Vector and the positive x-axis, in radians.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#angle
* @since 3.0.0
*
* @return {number} The angle between this Vector, and the positive x-axis, given in radians.
2018-01-26 06:19:27 +00:00
*/
2017-09-21 16:11:56 +00:00
angle: function ()
{
2017-09-20 22:10:03 +00:00
// computes the angle in radians with respect to the positive x-axis
var angle = Math.atan2(this.y, this.x);
if (angle < 0)
{
angle += 2 * Math.PI;
}
return angle;
},
2018-01-26 06:19:27 +00:00
/**
* Add a given Vector to this Vector. Addition is component-wise.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#add
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to add to this Vector.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
add: function (src)
{
this.x += src.x;
this.y += src.y;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Subtract the given Vector from this Vector. Subtraction is component-wise.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#subtract
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to subtract from this Vector.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
subtract: function (src)
{
this.x -= src.x;
this.y -= src.y;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Perform a component-wise multiplication between this Vector and the given Vector.
*
* Multiplies this Vector by the given Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#multiply
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to multiply this Vector by.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
multiply: function (src)
{
this.x *= src.x;
this.y *= src.y;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Scale this Vector by the given value.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#scale
* @since 3.0.0
*
* @param {number} value - The value to scale this Vector by.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
scale: function (value)
{
if (isFinite(value))
{
this.x *= value;
this.y *= value;
}
else
{
this.x = 0;
this.y = 0;
}
2017-09-15 03:04:51 +00:00
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Perform a component-wise division between this Vector and the given Vector.
*
* Divides this Vector by the given Vector.
2018-04-25 10:25:29 +00:00
*
2018-01-26 06:19:27 +00:00
* @method Phaser.Math.Vector2#divide
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to divide this Vector by.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
divide: function (src)
{
this.x /= src.x;
this.y /= src.y;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Negate the `x` and `y` components of this Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#negate
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
negate: function ()
{
this.x = -this.x;
this.y = -this.y;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Calculate the distance between this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#distance
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
2018-01-26 06:19:27 +00:00
*
* @return {number} The distance from this Vector to the given Vector.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
distance: function (src)
{
var dx = src.x - this.x;
var dy = src.y - this.y;
return Math.sqrt(dx * dx + dy * dy);
},
2018-01-26 06:19:27 +00:00
/**
* Calculate the distance between this Vector and the given Vector, squared.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#distanceSq
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector to calculate the distance to.
2018-01-26 06:19:27 +00:00
*
* @return {number} The distance from this Vector to the given Vector, squared.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
distanceSq: function (src)
{
var dx = src.x - this.x;
var dy = src.y - this.y;
return dx * dx + dy * dy;
},
2018-01-26 06:19:27 +00:00
/**
* Calculate the length (or magnitude) of this Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#length
* @since 3.0.0
*
* @return {number} The length of this Vector.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
length: function ()
{
var x = this.x;
var y = this.y;
return Math.sqrt(x * x + y * y);
},
2018-01-26 06:19:27 +00:00
/**
* Calculate the length of this Vector squared.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#lengthSq
* @since 3.0.0
*
* @return {number} The length of this Vector, squared.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
lengthSq: function ()
{
var x = this.x;
var y = this.y;
return x * x + y * y;
},
2018-01-26 06:19:27 +00:00
/**
* Normalize this Vector.
*
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#normalize
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
normalize: function ()
{
var x = this.x;
var y = this.y;
var len = x * x + y * y;
if (len > 0)
{
len = 1 / Math.sqrt(len);
2017-09-15 03:04:51 +00:00
this.x = x * len;
this.y = y * len;
}
2018-03-20 15:06:30 +00:00
2017-09-15 03:04:51 +00:00
return this;
},
2017-09-21 01:03:37 +00:00
/**
* Right-hand normalize (make unit length) this Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#normalizeRightHand
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-21 01:03:37 +00:00
normalizeRightHand: function ()
{
var x = this.x;
this.x = this.y * -1;
this.y = x;
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Calculate the dot product of this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#dot
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector2 to dot product with this Vector2.
2018-01-26 06:19:27 +00:00
*
* @return {number} The dot product of this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
dot: function (src)
{
return this.x * src.x + this.y * src.y;
},
2018-01-26 06:19:27 +00:00
/**
2018-10-19 15:14:51 +00:00
* Calculate the cross product of this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#cross
* @since 3.0.0
*
2018-10-19 15:14:51 +00:00
* @param {Phaser.Math.Vector2} src - The Vector2 to cross with this Vector2.
2018-01-26 06:19:27 +00:00
*
2018-10-19 15:14:51 +00:00
* @return {number} The cross product of this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
cross: function (src)
{
return this.x * src.y - this.y * src.x;
},
2018-01-26 06:19:27 +00:00
/**
* Linearly interpolate between this Vector and the given Vector.
2018-01-26 06:19:27 +00:00
*
* Interpolates this Vector towards the given Vector.
*
2018-01-26 06:19:27 +00:00
* @method Phaser.Math.Vector2#lerp
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} src - The Vector2 to interpolate towards.
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
lerp: function (src, t)
{
if (t === undefined) { t = 0; }
var ax = this.x;
var ay = this.y;
this.x = ax + t * (src.x - ax);
this.y = ay + t * (src.y - ay);
return this;
},
2018-01-26 06:19:27 +00:00
/**
* Transform this Vector with the given Matrix.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#transformMat3
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
transformMat3: function (mat)
{
var x = this.x;
var y = this.y;
var 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;
},
2018-01-26 06:19:27 +00:00
/**
* Transform this Vector with the given Matrix.
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#transformMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
2018-01-26 06:19:27 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
2017-09-15 03:04:51 +00:00
transformMat4: function (mat)
{
var x = this.x;
var y = this.y;
var 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;
},
2018-01-26 06:19:27 +00:00
/**
* Make this Vector the zero vector (0, 0).
2018-01-26 06:19:27 +00:00
*
* @method Phaser.Math.Vector2#reset
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Math.Vector2} This Vector2.
2018-01-26 06:19:27 +00:00
*/
reset: function ()
2017-09-15 03:04:51 +00:00
{
this.x = 0;
this.y = 0;
return this;
}
});
/**
* A static zero Vector2 for use by reference.
2019-01-04 13:33:56 +00:00
*
* This constant is meant for comparison operations and should not be modified directly.
*
* @constant
* @name Phaser.Math.Vector2.ZERO
2019-01-09 14:19:27 +00:00
* @type {Phaser.Math.Vector2}
2018-02-15 14:31:15 +00:00
* @since 3.1.0
*/
Vector2.ZERO = new Vector2();
2017-09-15 03:04:51 +00:00
module.exports = Vector2;