90 lines
2.7 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
math = math == nil and {} or math;
math.pi = math.pi == nil and 3.14159265358979 or math.pi;
---clamp
---@param v number @number
---@param Min number @min
---@param Max number @max
---@return number @clamp v between Min and Max
function math.clamp(v, Min, Max)
local min = math.min(Min, Max)
local max = math.max(Min, Max)
if v < min then return min end
if v > max then return max end
return v
end
--- 随机bool变量
function math.randBool() return math.pop() > 0.5; end
---clamp
---@param a number @First number to compare
---@param b number @Second number to compare
---@param Tolerance number @Maximum allowed difference for considering them as 'nearly equal'
---@return boolean @true if a and b are nearly equal
function math.isNearlyEqual(a, b, Tolerance)
if Tolerance == nil then Tolerance = 0.01 end
return math.abs(a - b) <= Tolerance;
end
--- 一个存放随机数的列表
math.RandomList = {};
function math.init(InCount)
for i = 1, InCount do table.insert(math.RandomList, math.random()); end
end
function math.pop()
local val = math.RandomList[1]
if val == nil then
math.init(100);
return math.pop();
end
table.remove(math.RandomList, 1);
return val;
end
--- 在给定圆内随机生成一个给定半径的圆,返回圆的中心点
---@param Center FVector 给定圆
---@param Radius float 给定圆的半径
---@param MinRadius float 目标生成圆的半径圆的半径
function math.randomCircleInCircle(Center, Radius, MinRadius)
local TargetRadius = Radius - MinRadius;
if TargetRadius <= 0 then return Center; end
local ResCenter = math.randomPointInCircle(Center, TargetRadius);
ResCenter.Z = Center.Z;
return ResCenter;
end
---@param c FVector
---@param R float
---@param r float
function math.randCircle(c, R, r)
local x = math.pop() * 2 * (R - r) + (c.X - (R - r));
local a = math.pop() * math.pi;
local p = math.getCirclePoint(c, math.abs(x), {X = x, Y = c.Y, }, a);
return { X = p.X, Y = p.Y, Z = c.Z, };
end
--- 获取圆上一点与圆心连接的线形成 θ 角度的另一个点(逆时针)
---@param o FVector2D 圆点所在坐标
---@param r float 圆的半径
---@param p FVector2D 圆上的一点
---@param t float 跟 @p 到 @o 形成夹角为 t 的线,弧度值
function math.getCirclePoint(o, r, p, t)
local angle = math.atan((p.Y - o.Y) / (p.X - o.X)) + t
return { X = o.X + r * math.cos(angle), Y = o.Y + r * math.sin(angle), };
end
--- 在一个圆中随机生成一个点
---@param o FVector2D
---@param r float
function math.randomPointInCircle(o, r)
local angle = math.pop() * 2 * math.pi;
local tr = r * math.sqrt(math.pop());
local x = o.X + tr * math.cos(angle);
local y = o.Y + tr * math.sin(angle);
return { X = x, Y = y };
end