完善MathHelper/RectangleExt/Vector2Ext

This commit is contained in:
yhh
2021-05-02 20:03:56 +08:00
parent da595e1eb9
commit 74bd0c161f
6 changed files with 529 additions and 6 deletions

View File

@@ -25,7 +25,7 @@ module es {
}
/**
* mapps值(在leftMin - leftMax范围内)到rightMin - rightMax范围内的值
* 将值(在leftMin-leftMax范围内)映射到一个在rightMin-rightMax范围内的值
* @param value
* @param leftMin
* @param leftMax
@@ -36,6 +36,29 @@ module es {
return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin);
}
/**
* 将值从任意范围映射到0到1范围
* @param value
* @param min
* @param max
* @returns
*/
public static map01(value: number, min: number, max: number) {
return (value - min) * 1 / (max - min);
}
/**
* 将值从某个任意范围映射到1到0范围
* 这相当于map01的取反
* @param value
* @param min
* @param max
* @returns
*/
public static map10(value: number, min: number, max: number) {
return 1 - this.map01(value, min, max);
}
public static lerp(from: number, to: number, t: number) {
return from + (to - from) * this.clamp01(t);
}
@@ -145,6 +168,27 @@ module es {
return value % 2 == 0;
}
/**
* 如果值是奇数则返回true
* @param value
* @returns
*/
public static isOdd(value: number) {
return value % 2 != 0;
}
/**
* 将值四舍五入并返回它和四舍五入后的数值
* @param value
* @param roundedAmount
* @returns
*/
public static roundWithRoundedAmount(value: number, roundedAmount: Ref<number>) {
let rounded = Math.round(value);
roundedAmount.value = value - (rounded * Math.round(value/ rounded));
return rounded;
}
/**
* 数值限定在0-1之间
* @param value
@@ -180,6 +224,41 @@ module es {
return t;
}
/**
* 递减t并确保其始终大于或等于0且小于长度
* @param t
* @param length
* @returns
*/
public static decrementWithWrap(t: number, length: number) {
t --;
if (t < 0)
return length - 1;
return t;
}
/**
* 返回sqrtx * x + y * y
* @param x
* @param y
* @returns
*/
public static hypotenuse(x: number, y: number) {
return Math.sqrt(x * x + y * y);
}
public static closestPowerOfTwoGreaterThan(x: number) {
x --;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return (x + 1);
}
/**
* 以roundToNearest为步长将值舍入到最接近的数字。例如在125中找到127到最近的5个结果
* @param value
@@ -269,6 +348,17 @@ module es {
return num;
}
/**
* 检查值是否介于最小值/最大值(包括最小值/最大值)之间
* @param value
* @param min
* @param max
* @returns
*/
public static between(value: number, min: number, max: number) {
return value >= min && value <= max;
}
/**
* 计算以弧度为单位的两个给定角度之间的最短差
* @param current

View File

@@ -104,7 +104,7 @@ module es {
let maxX = Number.NEGATIVE_INFINITY;
let maxY = Number.NEGATIVE_INFINITY;
for (let i = 0; i < points.length; i ++) {
for (let i = 0; i < points.length; i++) {
let pt = points[i];
if (pt.x < minX)
@@ -136,7 +136,7 @@ module es {
* @param deltaX
* @param deltaY
*/
public static getSweptBroadphaseBounds(rect: Rectangle, deltaX: number, deltaY: number){
public static getSweptBroadphaseBounds(rect: Rectangle, deltaX: number, deltaY: number) {
let broadphasebox = Rectangle.empty;
broadphasebox.x = deltaX > 0 ? rect.x : rect.x + deltaX;
@@ -216,5 +216,134 @@ module es {
return new Vector2(depthX, depthY);
}
public static getClosestPointOnBoundsToOrigin(rect: Rectangle) {
let max = this.getMax(rect);
let minDist = Math.abs(rect.location.x);
let boundsPoint = new Vector2(rect.location.x, 0);
if (Math.abs(max.x) < minDist) {
minDist = Math.abs(max.x);
boundsPoint.x = max.x;
boundsPoint.y = 0;
}
if (Math.abs(max.y) < minDist) {
minDist = Math.abs(max.y);
boundsPoint.x = 0;
boundsPoint.y = max.y;
}
if (Math.abs(rect.location.y) < minDist) {
minDist = Math.abs(rect.location.y);
boundsPoint.x = 0;
boundsPoint.y = rect.location.y;
}
return boundsPoint;
}
/**
* 将Rectangle中或上的最接近点返回给定点
* @param rect
* @param point
*/
public static getClosestPointOnRectangleToPoint(rect: Rectangle, point: Vector2) {
// 对于每个轴,如果该点在盒子外面,则将在盒子上,否则不理会它
let res = new Vector2();
res.x = MathHelper.clamp(point.x, rect.left, rect.right)
res.y = MathHelper.clamp(point.y, rect.top, rect.bottom);
return res;
}
/**
* 获取矩形边界上与给定点最接近的点
* @param rect
* @param point
*/
public static getClosestPointOnRectangleBorderToPoint(rect: Rectangle, point: Vector2) {
// 对于每个轴,如果该点在盒子外面,则将在盒子上,否则不理会它
let res = new Vector2();
res.x = MathHelper.clamp(point.x, rect.left, rect.right)
res.y = MathHelper.clamp(point.y, rect.top, rect.bottom);
// 如果点在矩形内我们需要将res推到边框因为它将在矩形内
if (rect.contains(res.x, res.y)) {
let dl = rect.x - rect.left;
let dr = rect.right - res.x;
let dt = res.y - rect.top;
let db = rect.bottom - res.y;
let min = Math.min(dl, dr, dt, db);
if (min == dt)
res.y = rect.top;
else if (min == db)
res.y = rect.bottom;
else if (min == dl)
res.x == rect.left;
else
res.x = rect.right;
}
return res;
}
public static getMax(rect: Rectangle) {
return new Vector2(rect.right, rect.bottom);
}
/**
* 以Vector2的形式获取矩形的中心点
* @param rect
* @returns
*/
public static getCenter(rect: Rectangle) {
return new Vector2(rect.x + rect.width / 2, rect.y + rect.height / 2);
}
/**
* 给定多边形的点即可计算边界
* @param points
*/
public static boundsFromPolygonPoints(points: Vector2[]) {
// 我们需要找到最小/最大x / y值
let minX = Number.POSITIVE_INFINITY;
let minY = Number.POSITIVE_INFINITY;
let maxX = Number.NEGATIVE_INFINITY;
let maxY = Number.NEGATIVE_INFINITY;
for (let i = 0; i < points.length; i++) {
let pt = points[i];
if (pt.x < minX)
minX = pt.x;
if (pt.x > maxX)
maxX = pt.x
if (pt.y < minY)
minY = pt.y;
if (pt.y > maxY)
maxY = pt.y;
}
return this.fromMinMaxVector(new Vector2(minX, minY), new Vector2(maxX, maxY));
}
/**
* 缩放矩形
* @param rect
* @param scale
*/
public static scale(rect: Rectangle, scale: Vector2) {
rect.x = rect.x * scale.x;
rect.y = rect.y * scale.y;
rect.width = rect.width * scale.x;
rect.height = rect.height * scale.y;
}
public static translate(rect: Rectangle, vec: Vector2) {
rect.location.add(vec);
}
}
}

View File

@@ -51,6 +51,18 @@ module es {
return Math.acos(MathHelper.clamp(Vector2.dot(from, to), -1, 1)) * MathHelper.Rad2Deg;
}
/**
* 返回以自度为中心的左右角度
* @param self
* @param left
* @param right
*/
public static angleBetween(self: Vector2, left: Vector2, right: Vector2) {
let one = Vector2.subtract(left, self);
let two = Vector2.subtract(right, self);
return this.angle(one, two);
}
/**
* 给定两条直线(ab和cd),求交点
* @param a