2020-07-23 11:00:46 +08:00
|
|
|
|
module es {
|
|
|
|
|
|
export class MathHelper {
|
|
|
|
|
|
public static readonly Epsilon: number = 0.00001;
|
|
|
|
|
|
public static readonly Rad2Deg = 57.29578;
|
|
|
|
|
|
public static readonly Deg2Rad = 0.0174532924;
|
2020-08-12 18:08:12 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 表示pi除以2的值(1.57079637)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static readonly PiOver2 = Math.PI / 2;
|
2020-06-16 00:04:28 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 将弧度转换成角度。
|
|
|
|
|
|
* @param radians 用弧度表示的角
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static toDegrees(radians: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return radians * 57.295779513082320876798154814105;
|
|
|
|
|
|
}
|
2020-06-08 11:49:45 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 将角度转换为弧度
|
|
|
|
|
|
* @param degrees
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static toRadians(degrees: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return degrees * 0.017453292519943295769236907684886;
|
|
|
|
|
|
}
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* mapps值(在leftMin - leftMax范围内)到rightMin - rightMax范围内的值
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
* @param leftMin
|
|
|
|
|
|
* @param leftMax
|
|
|
|
|
|
* @param rightMin
|
|
|
|
|
|
* @param rightMax
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin);
|
|
|
|
|
|
}
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static lerp(value1: number, value2: number, amount: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return value1 + (value2 - value1) * amount;
|
|
|
|
|
|
}
|
2020-06-15 08:46:38 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static clamp(value: number, min: number, max: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (value < min)
|
|
|
|
|
|
return min;
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (value > max)
|
|
|
|
|
|
return max;
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return value;
|
|
|
|
|
|
}
|
2020-06-10 17:41:53 +08:00
|
|
|
|
|
2020-08-26 19:56:48 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 给定圆心、半径和角度,得到圆周上的一个点。0度是3点钟。
|
|
|
|
|
|
* @param circleCenter
|
|
|
|
|
|
* @param radius
|
|
|
|
|
|
* @param angleInDegrees
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
let radians = MathHelper.toRadians(angleInDegrees);
|
2020-08-26 19:56:48 +08:00
|
|
|
|
return new Vector2(Math.cos(radians) * radians + circleCenter.x,
|
|
|
|
|
|
Math.sin(radians) * radians + circleCenter.y);
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|
2020-06-23 09:10:40 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 如果值为偶数,返回true
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static isEven(value: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return value % 2 == 0;
|
|
|
|
|
|
}
|
2020-07-09 16:16:04 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 数值限定在0-1之间
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static clamp01(value: number) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (value < 0)
|
|
|
|
|
|
return 0;
|
2020-07-17 11:07:57 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
if (value > 1)
|
|
|
|
|
|
return 1;
|
2020-07-17 11:07:57 +08:00
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return value;
|
|
|
|
|
|
}
|
2020-07-17 11:07:57 +08:00
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static angleBetweenVectors(from: Vector2, to: Vector2) {
|
2020-07-23 11:00:46 +08:00
|
|
|
|
return Math.atan2(to.y - from.y, to.x - from.x);
|
|
|
|
|
|
}
|
2020-08-12 12:16:35 +08:00
|
|
|
|
|
2020-12-28 16:59:16 +08:00
|
|
|
|
public static angleToVector(angleRadians: number, length: number) {
|
2020-12-07 21:01:21 +08:00
|
|
|
|
return new Vector2(Math.cos(angleRadians) * length, Math.sin(angleRadians) * length);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-12 12:16:35 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 增加t并确保它总是大于或等于0并且小于长度
|
|
|
|
|
|
* @param t
|
|
|
|
|
|
* @param length
|
|
|
|
|
|
*/
|
2020-12-28 16:59:16 +08:00
|
|
|
|
public static incrementWithWrap(t: number, length: number) {
|
|
|
|
|
|
t++;
|
2020-08-12 12:16:35 +08:00
|
|
|
|
if (t == length)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
|
}
|
2020-08-22 12:21:40 +08:00
|
|
|
|
|
2020-12-28 16:59:16 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 以roundToNearest为步长,将值舍入到最接近的数字。例如:在125中找到127到最近的5个结果
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
* @param roundToNearest
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static roundToNearest(value: number, roundToNearest: number) {
|
|
|
|
|
|
return Math.round(value / roundToNearest) * roundToNearest;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 检查传递的值是否在某个阈值之下。对于小规模、精确的比较很有用
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
* @param ep
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static withinEpsilon(value: number, ep: number = this.Epsilon) {
|
|
|
|
|
|
return Math.abs(value) < ep;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-22 12:21:40 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 由上移量向上移。start可以小于或大于end。例如:开始是2,结束是10,移位是4,结果是6
|
|
|
|
|
|
* @param start
|
|
|
|
|
|
* @param end
|
|
|
|
|
|
* @param shift
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static approach(start: number, end: number, shift: number): number {
|
|
|
|
|
|
if (start < end)
|
|
|
|
|
|
return Math.min(start + shift, end);
|
|
|
|
|
|
|
|
|
|
|
|
return Math.max(start - shift, end);
|
|
|
|
|
|
}
|
2020-07-09 16:16:04 +08:00
|
|
|
|
}
|
2020-07-23 11:00:46 +08:00
|
|
|
|
}
|