完善mathhelper类与vector2

This commit is contained in:
yhh
2021-05-03 08:17:48 +08:00
parent 74bd0c161f
commit 16cdfa0426
5 changed files with 502 additions and 13 deletions

View File

@@ -508,12 +508,26 @@ declare module es {
* @returns 指定向量的线性插值结果
*/
static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2;
/**
* 创建一个新的Vector2其中包含指定矢量的线性插值
* @param value1
* @param value2
* @param amount
* @returns
*/
static lerpPrecise(value1: Vector2, value2: Vector2, amount: number): Vector2;
/**
* 创建一个新的Vector2该Vector2包含了通过指定的Matrix进行的二维向量变换。
* @param position
* @param matrix
*/
static transform(position: Vector2, matrix: Matrix2D): Vector2;
/**
* 创建一个新的Vector2其中包含由指定的Matrix转换的指定法线
* @param normal
* @param matrix
*/
static transformNormal(normal: Vector2, matrix: Matrix): Vector2;
/**
* 返回两个向量之间的距离
* @param value1
@@ -533,6 +547,21 @@ declare module es {
* @returns 矢量反演的结果
*/
static negate(value: Vector2): Vector2;
/**
* 创建一个新的Vector2其中包含给定矢量和法线的反射矢量
* @param vector
* @param normal
* @returns
*/
static reflect(vector: Vector2, normal: Vector2): Vector2;
/**
* 创建一个新的Vector2其中包含指定矢量的三次插值
* @param value1
* @param value2
* @param amount
* @returns
*/
static smoothStep(value1: Vector2, value2: Vector2, amount: number): Vector2;
/**
*
* @param value
@@ -587,6 +616,31 @@ declare module es {
* @returns 如果实例相同true 否则false
*/
equals(other: Vector2 | object): boolean;
isValid(): boolean;
/**
* 创建一个新的Vector2其中包含来自两个向量的最小值
* @param value1
* @param value2
* @returns
*/
static min(value1: Vector2, value2: Vector2): Vector2;
/**
* 创建一个新的Vector2其中包含两个向量的最大值
* @param value1
* @param value2
* @returns
*/
static max(value1: Vector2, value2: Vector2): Vector2;
/**
* 创建一个新的Vector2其中包含Hermite样条插值
* @param value1
* @param tangent1
* @param value2
* @param tangent2
* @param amount
* @returns
*/
static hermite(value1: Vector2, tangent1: Vector2, value2: Vector2, tangent2: Vector2, amount: number): Vector2;
clone(): Vector2;
}
}
@@ -2346,6 +2400,24 @@ declare module es {
* @param degrees
*/
static toRadians(degrees: number): number;
/**
* 返回由给定三角形和两个归一化重心(面积)坐标定义的点的一个轴的笛卡尔坐标
* @param value1
* @param value2
* @param value3
* @param amount1
* @param amount2
*/
static barycentric(value1: number, value2: number, value3: number, amount1: number, amount2: number): number;
/**
* 使用指定位置执行Catmull-Rom插值
* @param value1
* @param value2
* @param value3
* @param value4
* @param amount
*/
static catmullRom(value1: number, value2: number, value3: number, value4: number, amount: number): number;
/**
* 将值在leftMin-leftMax范围内映射到一个在rightMin-rightMax范围内的值
* @param value
@@ -2372,6 +2444,24 @@ declare module es {
* @returns
*/
static map10(value: number, min: number, max: number): number;
/**
* 使用三次方程在两个值之间进行插值
* @param value1
* @param value2
* @param amount
*/
static smoothStep(value1: number, value2: number, amount: number): number;
/**
* 将给定角度减小到π到-π之间的值
* @param angle
*/
static wrapAngle(angle: number): number;
/**
* 确定值是否以2为底
* @param value
* @returns
*/
static isPowerOfTwo(value: number): boolean;
static lerp(from: number, to: number, t: number): number;
/**
* 使度数的角度在a和b之间
@@ -2405,6 +2495,11 @@ declare module es {
*/
static signThreshold(value: number, threshold: number): number;
static inverseLerp(from: number, to: number, t: number): number;
/**
* 在两个值之间线性插值
* 此方法是MathHelper.Lerp的效率较低更精确的版本。
*/
static lerpPrecise(value1: number, value2: number, amount: number): number;
static clamp(value: number, min: number, max: number): number;
static snap(value: number, increment: number): number;
/**
@@ -2588,6 +2683,22 @@ declare module es {
* @returns
*/
static lissajouDamped(xFrequency?: number, yFrequency?: number, xMagnitude?: number, yMagnitude?: number, phase?: number, damping?: number, oscillationInterval?: number): Vector2;
/**
* 执行Hermite样条插值
* @param value1
* @param tangent1
* @param value2
* @param tangent2
* @param amount
* @returns
*/
static hermite(value1: number, tangent1: number, value2: number, tangent2: number, amount: number): any;
/**
* 此函数用于确保数不是NaN或无穷大
* @param x
* @returns
*/
static isValid(x: number): boolean;
}
}
declare module es {

View File

@@ -1213,6 +1213,16 @@ var es;
Vector2.lerp = function (value1, value2, amount) {
return new Vector2(es.MathHelper.lerp(value1.x, value2.x, amount), es.MathHelper.lerp(value1.y, value2.y, amount));
};
/**
* 创建一个新的Vector2其中包含指定矢量的线性插值
* @param value1
* @param value2
* @param amount
* @returns
*/
Vector2.lerpPrecise = function (value1, value2, amount) {
return new Vector2(es.MathHelper.lerpPrecise(value1.x, value2.x, amount), es.MathHelper.lerpPrecise(value1.y, value2.y, amount));
};
/**
* 创建一个新的Vector2该Vector2包含了通过指定的Matrix进行的二维向量变换。
* @param position
@@ -1221,6 +1231,14 @@ var es;
Vector2.transform = function (position, matrix) {
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
*/
Vector2.transformNormal = function (normal, matrix) {
return new Vector2((normal.x * matrix.m11) + (normal.y * matrix.m21), (normal.x * matrix.m12) + (normal.y * matrix.m22));
};
/**
* 返回两个向量之间的距离
* @param value1
@@ -1251,6 +1269,29 @@ var es;
value.y = -value.y;
return value;
};
/**
* 创建一个新的Vector2其中包含给定矢量和法线的反射矢量
* @param vector
* @param normal
* @returns
*/
Vector2.reflect = function (vector, normal) {
var result = new Vector2();
var 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
*/
Vector2.smoothStep = function (value1, value2, amount) {
return new Vector2(es.MathHelper.smoothStep(value1.x, value2.x, amount), es.MathHelper.smoothStep(value1.y, value2.y, amount));
};
/**
*
* @param value
@@ -1344,6 +1385,39 @@ var es;
}
return false;
};
Vector2.prototype.isValid = function () {
return es.MathHelper.isValid(this.x) && es.MathHelper.isValid(this.y);
};
/**
* 创建一个新的Vector2其中包含来自两个向量的最小值
* @param value1
* @param value2
* @returns
*/
Vector2.min = function (value1, value2) {
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
*/
Vector2.max = function (value1, value2) {
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
*/
Vector2.hermite = function (value1, tangent1, value2, tangent2, amount) {
return new Vector2(es.MathHelper.hermite(value1.x, tangent1.x, value2.x, tangent2.x, amount), es.MathHelper.hermite(value1.y, tangent1.y, value2.y, tangent2.y, amount));
};
Vector2.prototype.clone = function () {
return new Vector2(this.x, this.y);
};
@@ -5749,6 +5823,33 @@ var es;
MathHelper.toRadians = function (degrees) {
return degrees * 0.017453292519943295769236907684886;
};
/**
* 返回由给定三角形和两个归一化重心(面积)坐标定义的点的一个轴的笛卡尔坐标
* @param value1
* @param value2
* @param value3
* @param amount1
* @param amount2
*/
MathHelper.barycentric = function (value1, value2, value3, amount1, amount2) {
return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
};
/**
* 使用指定位置执行Catmull-Rom插值
* @param value1
* @param value2
* @param value3
* @param value4
* @param amount
*/
MathHelper.catmullRom = function (value1, value2, value3, value4, amount) {
// 使用来自http://www.mvps.org/directx/articles/catmull/的公式
var amountSquared = amount * amount;
var amountCubed = amountSquared * amount;
return (0.5 * (2 * value2 + (value3 - value1) * amount +
(2 * value1 - 5 * value2 + 4 * value3 - value4) * amountSquared +
(3 * value2 - value1 - 3 * value3 + value4) * amountCubed));
};
/**
* 将值在leftMin-leftMax范围内映射到一个在rightMin-rightMax范围内的值
* @param value
@@ -5781,6 +5882,39 @@ var es;
MathHelper.map10 = function (value, min, max) {
return 1 - this.map01(value, min, max);
};
/**
* 使用三次方程在两个值之间进行插值
* @param value1
* @param value2
* @param amount
*/
MathHelper.smoothStep = function (value1, value2, amount) {
var result = this.clamp(amount, 0, 1);
result = MathHelper.hermite(value1, 0, value2, 0, result);
return result;
};
/**
* 将给定角度减小到π到-π之间的值
* @param angle
*/
MathHelper.wrapAngle = function (angle) {
if ((angle > -Math.PI) && (angle <= Math.PI))
return angle;
angle %= Math.PI * 2;
if (angle <= -Math.PI)
return angle + 2 * Math.PI;
if (angle > Math.PI)
return angle - 2 * Math.PI;
return angle;
};
/**
* 确定值是否以2为底
* @param value
* @returns
*/
MathHelper.isPowerOfTwo = function (value) {
return (value > 0) && ((value % (value - 1)) == 0);
};
MathHelper.lerp = function (from, to, t) {
return from + (to - from) * this.clamp01(t);
};
@@ -5848,6 +5982,13 @@ var es;
}
return (t - from) / (to - from);
};
/**
* 在两个值之间线性插值
* 此方法是MathHelper.Lerp的效率较低更精确的版本。
*/
MathHelper.lerpPrecise = function (value1, value2, amount) {
return ((1 - amount) * value1) + (value2 * amount);
};
MathHelper.clamp = function (value, min, max) {
if (value < min)
return min;
@@ -6155,6 +6296,41 @@ var es;
var y = damped * Math.cos(es.Time.totalTime * yFrequency) * yMagnitude;
return new es.Vector2(x, y);
};
/**
* 执行Hermite样条插值
* @param value1
* @param tangent1
* @param value2
* @param tangent2
* @param amount
* @returns
*/
MathHelper.hermite = function (value1, tangent1, value2, tangent2, amount) {
var v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result;
var sCubed = s * s * s;
var sSquared = s * s;
if (amount == 0)
result = value1;
else if (amount == 1)
result = value2;
else
result = (2 * v1 - 2 * v2 + t2 + t1) * sCubed +
(3 * v2 - 3 * v1 - 2 * t1 - t2) * sSquared +
t1 * s +
v1;
return result;
};
/**
* 此函数用于确保数不是NaN或无穷大
* @param x
* @returns
*/
MathHelper.isValid = function (x) {
if (Number.isNaN(x)) {
return false;
}
return !Number.isFinite(x);
};
MathHelper.Epsilon = 0.00001;
MathHelper.Rad2Deg = 57.29578;
MathHelper.Deg2Rad = 0.0174532924;

File diff suppressed because one or more lines are too long

View File

@@ -24,6 +24,35 @@ module es {
return degrees * 0.017453292519943295769236907684886;
}
/**
* 返回由给定三角形和两个归一化重心(面积)坐标定义的点的一个轴的笛卡尔坐标
* @param value1
* @param value2
* @param value3
* @param amount1
* @param amount2
*/
public static barycentric(value1: number, value2: number, value3: number, amount1: number, amount2: number) {
return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
}
/**
* 使用指定位置执行Catmull-Rom插值
* @param value1
* @param value2
* @param value3
* @param value4
* @param amount
*/
public static catmullRom(value1: number, value2: number, value3: number, value4: number, amount: number) {
// 使用来自http://www.mvps.org/directx/articles/catmull/的公式
let amountSquared = amount * amount;
let amountCubed = amountSquared * amount;
return (0.5 * (2 * value2 + (value3 - value1) * amount +
(2 * value1 - 5 * value2 + 4 * value3 - value4) * amountSquared +
(3 * value2 - value1 - 3 * value3 + value4) * amountCubed));
}
/**
* 将值在leftMin-leftMax范围内映射到一个在rightMin-rightMax范围内的值
* @param value
@@ -59,6 +88,43 @@ module es {
return 1 - this.map01(value, min, max);
}
/**
* 使用三次方程在两个值之间进行插值
* @param value1
* @param value2
* @param amount
*/
public static smoothStep(value1: number, value2: number, amount: number) {
let result = this.clamp(amount, 0, 1);
result = MathHelper.hermite(value1, 0, value2, 0, result);
return result;
}
/**
* 将给定角度减小到π到-π之间的值
* @param angle
*/
public static wrapAngle(angle: number) {
if ((angle > -Math.PI) && (angle <= Math.PI))
return angle;
angle %= Math.PI * 2;
if (angle <= -Math.PI)
return angle + 2 * Math.PI;
if (angle > Math.PI)
return angle - 2 * Math.PI;
return angle;
}
/**
* 确定值是否以2为底
* @param value
* @returns
*/
public static isPowerOfTwo(value: number) {
return (value > 0) && ((value % (value - 1)) == 0);
}
public static lerp(from: number, to: number, t: number) {
return from + (to - from) * this.clamp01(t);
}
@@ -122,18 +188,26 @@ module es {
if (from < to) {
if (t < from)
return 0;
else if(t > to)
else if (t > to)
return 1;
} else {
if (t < to)
return 1;
else if(t > from)
else if (t > from)
return 0;
}
return (t - from) / (to - from);
}
/**
* 在两个值之间线性插值
* 此方法是MathHelper.Lerp的效率较低更精确的版本。
*/
public static lerpPrecise(value1: number, value2: number, amount: number) {
return ((1 - amount) * value1) + (value2 * amount);
}
public static clamp(value: number, min: number, max: number) {
if (value < min)
return min;
@@ -185,7 +259,7 @@ module es {
*/
public static roundWithRoundedAmount(value: number, roundedAmount: Ref<number>) {
let rounded = Math.round(value);
roundedAmount.value = value - (rounded * Math.round(value/ rounded));
roundedAmount.value = value - (rounded * Math.round(value / rounded));
return rounded;
}
@@ -231,7 +305,7 @@ module es {
* @returns
*/
public static decrementWithWrap(t: number, length: number) {
t --;
t--;
if (t < 0)
return length - 1;
@@ -249,13 +323,13 @@ module es {
}
public static closestPowerOfTwoGreaterThan(x: number) {
x --;
x--;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return (x + 1);
}
@@ -465,16 +539,56 @@ module es {
* @param oscillationInterval
* @returns
*/
public static lissajouDamped(xFrequency: number = 2, yFrequency: number = 3, xMagnitude: number = 1,
public static lissajouDamped(xFrequency: number = 2, yFrequency: number = 3, xMagnitude: number = 1,
yMagnitude: number = 1, phase: number = 0.5, damping: number = 0,
oscillationInterval: number = 5) {
let wrappedTime = this.pingPong(Time.totalTime, oscillationInterval);
let damped = Math.pow(Math.E, -damping * wrappedTime);
let wrappedTime = this.pingPong(Time.totalTime, oscillationInterval);
let damped = Math.pow(Math.E, -damping * wrappedTime);
let x = damped * Math.sin(Time.totalTime * xFrequency + phase) * xMagnitude;
let y = damped * Math.cos(Time.totalTime * yFrequency) * yMagnitude;
let x = damped * Math.sin(Time.totalTime * xFrequency + phase) * xMagnitude;
let y = damped * Math.cos(Time.totalTime * yFrequency) * yMagnitude;
return new Vector2(x, y);
return new Vector2(x, y);
}
/**
* 执行Hermite样条插值
* @param value1
* @param tangent1
* @param value2
* @param tangent2
* @param amount
* @returns
*/
public static hermite(value1: number, tangent1: number, value2: number, tangent2: number, amount: number) {
let v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result;
let sCubed = s * s * s;
let sSquared = s * s;
if (amount == 0)
result = value1;
else if (amount == 1)
result = value2;
else
result = (2 * v1 - 2 * v2 + t2 + t1) * sCubed +
(3 * v2 - 3 * v1 - 2 * t1 - t2) * sSquared +
t1 * s +
v1;
return result;
}
/**
* 此函数用于确保数不是NaN或无穷大
* @param x
* @returns
*/
public static isValid(x: number) {
if (Number.isNaN(x)) {
return false;
}
return !Number.isFinite(x);
}
}
}

View File

@@ -145,6 +145,18 @@ module es {
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
@@ -155,6 +167,16 @@ module es {
(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
@@ -189,6 +211,32 @@ module es {
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
@@ -294,6 +342,46 @@ module es {
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);
}