Files
esengine/source/src/Math/Vector2.ts
2021-05-03 08:17:48 +08:00

390 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
module es {
/** 2d 向量 */
export class Vector2 implements IEquatable<Vector2> {
public x: number = 0;
public y: number = 0;
/**
* 从两个值构造一个带有X和Y的二维向量。
* @param x 二维空间中的x坐标
* @param y 二维空间的y坐标
*/
constructor(x?: number, y?: number) {
this.x = x ? x : 0;
this.y = y != undefined ? y : this.x;
}
public static get zero() {
return new Vector2(0, 0);
}
public static get one() {
return new Vector2(1, 1);
}
public static get unitX() {
return new Vector2(1, 0);
}
public static get unitY() {
return new Vector2(0, 1);
}
/**
*
* @param value1
* @param value2
*/
public static add(value1: Vector2, value2: Vector2) {
let result: Vector2 = Vector2.zero;
result.x = value1.x + value2.x;
result.y = value1.y + value2.y;
return result;
}
/**
*
* @param value1
* @param value2
*/
public static divide(value1: Vector2, value2: Vector2) {
let result: Vector2 = Vector2.zero;
result.x = value1.x / value2.x;
result.y = value1.y / value2.y;
return result;
}
/**
*
* @param value1
* @param value2
*/
public static multiply(value1: Vector2, value2: Vector2) {
let result: Vector2 = new Vector2(0, 0);
result.x = value1.x * value2.x;
result.y = value1.y * value2.y;
return result;
}
/**
*
* @param value1
* @param value2
* @returns
*/
public static multiplyScaler(value1: Vector2, value2: number) {
let result = new Vector2(0, 0);
result.x = value1.x * value2;
result.y = value1.x * value2;
return result;
}
/**
*
* @param value1
* @param value2
*/
public static subtract(value1: Vector2, value2: Vector2) {
let result: Vector2 = new Vector2(0, 0);
result.x = value1.x - value2.x;
result.y = value1.y - value2.y;
return result;
}
/**
* 创建一个新的Vector2
* 它包含来自另一个向量的标准化值。
* @param value
*/
public static normalize(value: Vector2) {
let nValue = new Vector2(value.x, value.y);
let val = 1 / Math.sqrt((nValue.x * nValue.x) + (nValue.y * nValue.y));
nValue.x *= val;
nValue.y *= val;
return nValue;
}
/**
* 返回两个向量的点积
* @param value1
* @param value2
*/
public static dot(value1: Vector2, value2: Vector2): number {
return (value1.x * value2.x) + (value1.y * value2.y);
}
/**
* 返回两个向量之间距离的平方
* @param value1
* @param value2
*/
public static distanceSquared(value1: Vector2, value2: Vector2) {
let v1 = value1.x - value2.x, v2 = value1.y - value2.y;
return (v1 * v1) + (v2 * v2);
}
/**
* 将指定的值限制在一个范围内
* @param value1
* @param min
* @param max
*/
public static clamp(value1: Vector2, min: Vector2, max: Vector2) {
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x),
MathHelper.clamp(value1.y, min.y, max.y));
}
/**
* 创建一个新的Vector2其中包含指定向量的线性插值
* @param value1 第一个向量
* @param value2 第二个向量
* @param amount 加权值(0.0-1.0之间)
* @returns 指定向量的线性插值结果
*/
public static lerp(value1: Vector2, value2: Vector2, amount: number) {
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
}
/**
* 创建一个新的Vector2其中包含指定矢量的线性插值
* @param value1
* @param value2
* @param amount
* @returns
*/
public static lerpPrecise(value1: Vector2, value2: Vector2, amount: number) {
return new Vector2(MathHelper.lerpPrecise(value1.x, value2.x, amount),
MathHelper.lerpPrecise(value1.y, value2.y, amount));
}
/**
* 创建一个新的Vector2该Vector2包含了通过指定的Matrix进行的二维向量变换。
* @param position
* @param matrix
*/
public static transform(position: Vector2, matrix: Matrix2D) {
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31,
(position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
}
/**
* 创建一个新的Vector2其中包含由指定的Matrix转换的指定法线
* @param normal
* @param matrix
*/
public static transformNormal(normal: Vector2, matrix: Matrix) {
return new Vector2((normal.x * matrix.m11) + (normal.y * matrix.m21),
(normal.x * matrix.m12) + (normal.y * matrix.m22));
}
/**
* 返回两个向量之间的距离
* @param value1
* @param value2
* @returns 两个向量之间的距离
*/
public static distance(value1: Vector2, value2: Vector2): number {
let v1 = value1.x - value2.x, v2 = value1.y - value2.y;
return Math.sqrt((v1 * v1) + (v2 * v2));
}
/**
* 返回两个向量之间的角度,单位是度数
* @param from
* @param to
*/
public static angle(from: Vector2, to: Vector2): number{
from = Vector2.normalize(from);
to = Vector2.normalize(to);
return Math.acos(MathHelper.clamp(Vector2.dot(from, to), -1, 1)) * MathHelper.Rad2Deg;
}
/**
* 创建一个包含指定向量反转的新Vector2
* @param value
* @returns 矢量反演的结果
*/
public static negate(value: Vector2) {
value.x = -value.x;
value.y = -value.y;
return value;
}
/**
* 创建一个新的Vector2其中包含给定矢量和法线的反射矢量
* @param vector
* @param normal
* @returns
*/
public static reflect(vector: Vector2, normal: Vector2) {
let result: Vector2 = new Vector2();
let val = 2 * ((vector.x * normal.x) + (vector.y * normal.y));
result.x = vector.x - (normal.x * val);
result.y = vector.y - (normal.y * val);
return result;
}
/**
* 创建一个新的Vector2其中包含指定矢量的三次插值
* @param value1
* @param value2
* @param amount
* @returns
*/
public static smoothStep(value1: Vector2, value2: Vector2, amount: number) {
return new Vector2(MathHelper.smoothStep(value1.x, value2.x, amount),
MathHelper.smoothStep(value1.y, value2.y, amount));
}
/**
*
* @param value
*/
public add(value: Vector2): Vector2 {
this.x += value.x;
this.y += value.y;
return this;
}
/**
*
* @param value
*/
public divide(value: Vector2): Vector2 {
this.x /= value.x;
this.y /= value.y;
return this;
}
/**
*
* @param value
*/
public multiply(value: Vector2): Vector2 {
this.x *= value.x;
this.y *= value.y;
return this;
}
/**
*
* @param value
* @returns
*/
public multiplyScaler(value: number): Vector2 {
this.x *= value;
this.y *= value;
return this;
}
/**
* 从当前Vector2减去一个Vector2
* @param value 要减去的Vector2
* @returns 当前Vector2
*/
public subtract(value: Vector2) {
this.x -= value.x;
this.y -= value.y;
return this;
}
/**
* 将这个Vector2变成一个方向相同的单位向量
*/
public normalize() {
let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
this.x *= val;
this.y *= val;
}
/** 返回它的长度 */
public length() {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
}
/**
* 返回该Vector2的平方长度
* @returns 这个Vector2的平方长度
*/
public lengthSquared(): number {
return (this.x * this.x) + (this.y * this.y);
}
/**
* 四舍五入X和Y值
*/
public round(): Vector2 {
return new Vector2(Math.round(this.x), Math.round(this.y));
}
/**
* 返回以自己为中心点的左右角,单位为度
* @param left
* @param right
*/
public angleBetween(left: Vector2, right: Vector2) {
let one = Vector2.subtract(left, this);
let two = Vector2.subtract(right, this);
return Vector2Ext.angle(one, two);
}
/**
* 比较当前实例是否等于指定的对象
* @param other 要比较的对象
* @returns 如果实例相同true 否则false
*/
public equals(other: Vector2 | object): boolean {
if (other instanceof Vector2){
return other.x == this.x && other.y == this.y;
}
return false;
}
public isValid(): boolean {
return MathHelper.isValid(this.x) && MathHelper.isValid(this.y);
}
/**
* 创建一个新的Vector2其中包含来自两个向量的最小值
* @param value1
* @param value2
* @returns
*/
public static min(value1: Vector2, value2: Vector2) {
return new Vector2(value1.x < value2.x ? value1.x : value2.x,
value1.y < value2.y ? value1.y : value2.y);
}
/**
* 创建一个新的Vector2其中包含两个向量的最大值
* @param value1
* @param value2
* @returns
*/
public static max(value1: Vector2, value2: Vector2) {
return new Vector2(value1.x > value2.x ? value1.x : value2.x,
value1.y > value2.y ? value1.y : value2.y);
}
/**
* 创建一个新的Vector2其中包含Hermite样条插值
* @param value1
* @param tangent1
* @param value2
* @param tangent2
* @param amount
* @returns
*/
public static hermite(value1: Vector2, tangent1: Vector2, value2: Vector2, tangent2: Vector2, amount: number){
return new Vector2(MathHelper.hermite(value1.x, tangent1.x, value2.x, tangent2.x, amount),
MathHelper.hermite(value1.y, tangent1.y, value2.y, tangent2.y, amount));
}
public clone(): Vector2 {
return new Vector2(this.x, this.y);
}
}
}