DOF/sqr/Core/BaseTool/Math.nut

438 lines
16 KiB
Plaintext
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.

/*
文件名:MathClass.nut
路径:System/BaseTool/MathClass.nut
创建日期:2024-05-10 16:02
文件用途:数学库
*/
class Math {
function getDirectionToTargetX(objX, x) {
if (objX > x)
return 0;
else
return 1;
}
/*
* @函数作用: 取随机值 左闭右闭
* @参数 name
* @返回值
*/
function Rand(Min, Max) {
local In = rand();
local Ret = (Min + (Max - Min + 1) * (In / (RAND_MAX + 1).tofloat())).tointeger();
return Ret;
}
function getCollisionByObjBox(obj, box) {
local x = obj.X;
local y = obj.Y;
local z = obj.Z;
local ArrBuf = [];
if (obj.Direction == 1) {
local pleft = [x + box[0], y + box[1], z + box[2]];
local pright = [x + box[0] + box[3], y + box[1] + box[4], z + box[2] + box[5]];
ArrBuf.extend(pleft);
ArrBuf.extend(pright);
} else {
local pleft = [x - box[0], y + box[1], z + box[2]];
local pright = [x - box[0] - box[3], y + box[1] + box[4], z + box[2] + box[5]];
ArrBuf.extend(pleft);
ArrBuf.extend(pright);
}
return ArrBuf;
}
function GetDistancePos(startX, direction, offsetX) {
if (direction == 0)
return startX - offsetX;
return startX + offsetX;
}
//通过坐标获得两点旋转角度
function getRorateAngleByCurrentPos(x1, y1, z1, x2, y2, z2) {
return 0;
}
//贝塞尔曲线构造的抛物线运动支持开始z轴(obj,curT,lastZ,moveT)
function sq_BParabola(currentT, maxT, initZPos, jumpHeight, lastZPos) {
local z = getBeizeri(currentT, maxT, initZPos, initZPos + jumpHeight, initZPos + jumpHeight, lastZPos);
return z.tointeger();
}
//获得抛物线(不支持开始z轴)
function sq_Parabola(x, b, c) {
local a = (-b.tofloat() * 4) / (c.tofloat() * c.tofloat());
return a.tofloat() * (x.tofloat() - c.tofloat() / 2) * (x.tofloat() - c.tofloat() / 2) + b.tofloat();
}
//获得两点之间平面的距离.
function Get2D_Distance(x1, y1, x2, y2) {
local offsetX = x1 - x2;
local offsetY = (y1 - y2) * 0.29;
return sqrt(offsetX * offsetX + offsetY * offsetY);
}
//判断给定的角度是否在startA和endA角度之间(startA与endA形成的锐角内)
function CheckAngleIsInArea(judge, startA, endA) {
if (startA< 0)
startA = startA + 360.0;
if (endA< 0)
endA = endA + 360.0;
if (startA > 360.0)
startA = startA - 360.0;
if (endA > 360.0)
endA = endA - 360.0;
if (startA > 0 && startA< 90 && endA > 270 && endA< 360) {
if (judge > 270 && judge< 360) {
if (endA< judge && judge< startA + 360)
return true;
} else if (judge< 90) {
if (endA< judge + 360 && judge + 360< startA + 360)
return true;
}
} else {
if (endA > judge && judge > startA)
return true;
}
return false;
}
//弧度制转为角度制
function toDegree(x) {
return x * 57.29577;
}
//角度转为弧度
function toRadian(x) {
return x * 0.01745;
}
//立方体与立方体之间碰撞 暂未测试
function CubeAndCubeCollection(c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ) {
if (pointIsInCubeArea(c1StartX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1StartY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1EndY, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1StartY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, c1EndY, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, (c1StartY + c1EndY) / 2, c1StartZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, (c1StartY + c1EndY) / 2, c1EndZ, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1StartX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1StartY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea(c1EndX, c1EndY, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2StartY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2EndY, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2StartY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, c2EndY, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, (c2StartY + c2EndY) / 2, c2StartZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, (c2StartY + c2EndY) / 2, c2EndZ, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2StartX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2StartY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea(c2EndX, c2EndY, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
if (pointIsInCubeArea((c1StartX + c1EndX) / 2, (c1StartY + c1EndY) / 2, (c1StartZ + c1EndZ) / 2, c2StartX, c2StartY, c2StartZ, c2EndX, c2EndY, c2EndZ))
return true;
if (pointIsInCubeArea((c2StartX + c2EndX) / 2, (c2StartY + c2EndY) / 2, (c2StartZ + c2EndZ) / 2, c1StartX, c1StartY, c1StartZ, c1EndX, c1EndY, c1EndZ))
return true;
return false;
}
//判断该点是否在给定参数的立方体内
function pointIsInCubeArea(px, py, pz, startX, startY, startZ, endX, endY, endZ) {
local cubeCenterX = (startX + endX) / 2;
local cubeXLen = abs(startX - endX) / 2;
local cubeCenterY = (startY + endY) / 2;
local cubeYLen = abs(startY - endY) / 2;
local cubeCenterZ = (startZ + endZ) / 2;
local cubeZLen = abs(startZ - endZ) / 2;
if (abs(px - cubeCenterX) <= cubeXLen && abs(py - cubeCenterY) <= cubeYLen && abs(pz - cubeCenterZ) <= cubeZLen)
return true;
return false;
}
//判断(px,py)是否在这个四边形内如果在就返回true否则返回false,
//一定要注意1234的坐标必须能首尾组成四边形不能跳坐标否则判断会直接失效
function pointIsIn4PointArea(px, py, x1, y1, x2, y2, x3, y3, x4, y4) {
local area = get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4);
local pointArea1 = get3PointArea(x1, y1, x2, y2, px, py);
local pointArea2 = get3PointArea(x2, y2, x3, y3, px, py);
local pointArea3 = get3PointArea(x3, y3, x4, y4, px, py);
local pointArea4 = get3PointArea(x4, y4, x1, y1, px, py);
if (abs(area - pointArea1 - pointArea2 - pointArea3 - pointArea4)< 10.0)
return true;
return false;
}
//判断一个点是否存在于一个矩形中
function PointIsInSquare(x1, y1, SquareArr) {
return Sq_Is_Point_In_Square(x1, y1, SquareArr);
}
//判断一个点是否存在于一个矩形中 返回是哪一个矩形
function PointIsInWhichRectangle(x1, y1, SquareArr) {
return Sq_Is_Point_In_WhichRectangle(x1, y1, SquareArr);
}
//获得给定4个点形成的四边形面积
function get4PointArea(x1, y1, x2, y2, x3, y3, x4, y4) {
local area1 = get3PointArea(x1, y1, x2, y2, x3, y3)
local area2 = get3PointArea(x2, y2, x3, y3, x4, y4)
return area1 + area2;
}
//获得给定3个点形成的三角形面积
function get3PointArea(x1, y1, x2, y2, x3, y3) {
return abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2;
/*
local l1 = sqrt(pow((x1- x2), 2) + pow((y1- y2), 2));
local l2 = sqrt(pow((x1- x3), 2) + pow((y1- y3), 2));
local l3 = sqrt(pow((x2- x3), 2) + pow((y2- y3), 2));
return sqrt((l1 + l2 + l3) * (l1 + l2- l3) * (l1- l2 + l3) * (l2 + l3- l1)) / 4;
*/
}
//获得该数的符号
function getSign(var) {
if (var< 0)
return 1;
else if (var > 0)
return -1;
return 0;
}
//简便性能高的开平方
function sqrt(sum) {
local i = (sum / 2).tofloat();
local isb = 0;
for (isb = 0; isb< 10; isb++) {
i = (i - ((i * i - sum) / (2 * i))).tofloat();
}
return i;
}
//四舍五入
function Round(var) {
local v =
var -
var.tointeger();
if (v< 0.5)
return var.tointeger();
return var.tointeger() + 1;
}
//除以两个值并四舍五入
function DivideAndRound(var1, var2) {
local ret = var1.tofloat() / var2.tofloat();
return Round(ret);
}
//总是舍去
function Floor(var) {
return var.tointeger();
}
//currentRate 越接近maxRate ,返回值由sv越接近ev
function getUniformVelocity(sv, ev, currentRate, maxRate) {
local rate = currentRate.tofloat() / maxRate.tofloat();
local varyValue = ev - sv;
return sv + varyValue * rate;
}
function sq_GetAccel(sv, ev, currentRate, maxRate, increaseFeature) {
local rate = currentRate.tofloat() / maxRate.tofloat();
local varyValue = ev - sv;
local increaseRate = 1.0;
if (increaseFeature) {
increaseRate = pow(50, rate) / 50; //慢->快
} else {
// 修正后的减速逻辑计算,例如采用线性变换结合幂次运算来实现更合理的减速效果
// 先将rate映射到一个更合适的范围这里从[0,1]映射到[0.1, 1],可调整)
local mappedRate = rate * 0.9 + 0.1;
increaseRate = pow(mappedRate, 2); // 幂次可调整这里取2来让减速更明显可根据实际情况修改
}
return sv + varyValue * increaseRate;
}
//根据原数值 浮动比例 最终倍率 获得最终值
function getFinalValueByFloatRate(originalValue, floatRate, finalRate) {
// 计算 Value 的 15%
local fifteenPercent = originalValue * 0.15;
// 计算浮动范围的下限和上限
local lowerBound = originalValue - fifteenPercent;
local upperBound = originalValue + fifteenPercent;
// 根据 Rate 计算最终值
local finalValue = lowerBound + floatRate * (upperBound - lowerBound);
return finalValue;
}
function Max(a, b) {
if (a< b)
return b;
return a;
}
function Min(a, b) {
if (a > b)
return b;
return a;
}
//获得贝塞尔曲线(2阶)
function getBeizeri(var1, var2, p0, p1, p2, p3) {
local t = var1.tofloat() / var2.tofloat();
local t1 = 1.0 - t;
local v1 = t1 * t1 * t1;
local v2 = t1 * t1;
local v3 = t1;
local v4 = t * t * t;
local ret = p0 * v1;
ret = ret + 3.0 * p1 * t * v2;
ret = ret + 3.0 * p2 * t * t * v3;
ret = ret + p3 * v4;
return ret;
}
//获得贝塞尔曲线角度
function getBeizeriAngle(var1, var2, p0, p1, p2, p3) {
local t = var1.tofloat() / var2.tofloat();
local t1 = 1.0 - t;
local v1 = t1 * t1;
local v2 = t1;
local v3 = t1;
local v4 = t * t;
local ret = 2.0 * p0 * v1;
ret = ret + 6.0 * p1 * t * v2;
ret = ret + 6.0 * p2 * t * v3;
ret = ret + 2.0 * p3 * v4;
return ret;
}
function IsIntersectRect(x1, y1, width1, height1, x2, y2, width2, height2) {
// 计算矩形1的边界
local right1 = x1 + width1;
local bottom1 = y1 + height1;
// 计算矩形2的边界
local right2 = x2 + width2;
local bottom2 = y2 + height2;
// 检查是否有重叠
return !(right1< x2 || bottom1< y2 || x1 > right2 || y1 > bottom2);
}
}
//初始化随机数
srand(time());
Math.Rand(0, 1);