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 nil; end if TargetRadius == 0 then return Center; end local X = Center.X + (math.randBool() and 1 or -1) * math.pop() * TargetRadius; local Y = Center.Y + (math.randBool() and 1 or -1) * math.pop() * TargetRadius; local ResCenter = {}; local ANum = math.sqrt((X - Center.X) ^ 2 + (Y - Center.Y) ^ 2) if ANum > TargetRadius then ResCenter = { X = Center.X - TargetRadius + ANum, Y = Center.Y - TargetRadius + ANum, Z = Center.Z, }; end ResCenter = {X = X, Y = Y, Z = Center.Z, }; -- 检查一下距离 local Dis = math.sqrt((ResCenter.X - Center.X) ^ 2 + (ResCenter.Y - Center.Y) ^ 2 + (Center.Z and (ResCenter.Z - Center.Z) ^ 2 or 0)) if Dis > TargetRadius then return math.randomCircleInCircle(Center, Radius, MinRadius); end 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