Files
Main/Assets/GameAssets/Resources/Lua/Common/CustomLib/Utility/Math.lua

264 lines
6.7 KiB
Lua
Raw Normal View History

2025-01-25 04:38:09 +08:00
------------------------------------------------
--作者: xihan
--日期: 2019-05-06
--文件: Math.lua
--模块: 无
--描述: 数学
------------------------------------------------
---------------------[lua自带的]-----------------
-- math.maxinteger 最大值 9223372036854775807
-- math.mininteger 最小值 -9223372036854775808
-- math.huge 无穷大 inf
-- math.tointeger 转整数
-- math.pi 圆周率 math.pi 3.1415926535898
-- math.abs 取绝对值 math.abs(-2012) 2012
-- math.ceil 向上取整 math.ceil(9.1) 10
-- math.floor 向下取整 math.floor(9.9) 9
-- math.max 取参数最大值 math.max(2,4,6,8) 8
-- math.min 取参数最小值 math.min(2,4,6,8) 2
-- math.sqrt 开平方 math.sqrt(65536) 256.0
-- math.modf 取整数和小数部分 math.modf(20.12) 20 0.12
-- math.randomseed 设随机数种子 math.randomseed(os.time())
-- math.random 取随机数 math.random(5,90) 5~90
-- math.rad 角度转弧度 math.rad(180) 3.1415926535898
-- math.deg 弧度转角度 math.deg(math.pi) 180.0
-- math.exp e的x次方 math.exp(4) 54.598150033144
-- math.log 计算x的自然对数 math.log(54.598150033144) 4.0
-- math.sin 正弦 math.sin(math.rad(30)) 0.5
-- math.cos 余弦 math.cos(math.rad(60)) 0.5
-- math.tan 正切 math.tan(math.rad(45)) 1.0
-- math.asin 反正弦 math.deg(math.asin(0.5)) 30.0
-- math.acos 反余弦 math.deg(math.acos(0.5)) 60.0
-- math.atan 反正切 math.deg(math.atan(1)) 45.0
-- math.type 获取类型是integer还是float
-- math.fmod 取模 math.fmod(65535,2) 1
------------------------------------------------
local L_Floor = math.floor
local L_Abs = math.abs
--角度转弧度
math.Deg2Rad = math.pi / 180
--弧度转角度
math.Rad2Deg = 180 / math.pi
--机械极小值
math.Epsilon = 1.401298e-45
--value的p次幂
function math.Pow(value, p)
return value^p;
end
--大约(小数第一位四舍五入)
function math.Round(num)
return L_Floor(num + 0.5)
end
--函数返回一个数字的符号, 指示数字是正数,负数还是零
function math.Sign(num)
if num > 0 then
num = 1
elseif num < 0 then
num = -1
else
num = 0
end
return num
end
--限制value的值在min和max之间, 如果value小于min,返回min如果value大于于max,返回max
function math.Clamp(num, min, max)
if num < min then
num = min
elseif num > max then
num = max
end
return num
end
local Clamp = math.Clamp
--线性插值
function math.Lerp(from, to, t)
return from + (to - from) * Clamp(t, 0, 1)
end
--非限制线性插值
function math.LerpUnclamped(a, b, t)
return a + (b - a) * t;
end
--重复
function math.Repeat(t, length)
return t - (L_Floor(t / length) * length)
end
--插值角度
function math.LerpAngle(a, b, t)
local _num = math.Repeat(b - a, 360)
if _num > 180 then
_num = _num - 360
end
return a + _num * Clamp(t, 0, 1)
end
--移向
function math.MoveTowards(current, target, maxDelta)
if L_Abs(target - current) <= maxDelta then
return target
end
return current + math.Sign(target - current) * maxDelta
end
--增量角
function math.DeltaAngle(current, target)
local _num = math.Repeat(target - current, 360)
if _num > 180 then
_num = _num - 360
end
return _num
end
--移动角
function math.MoveTowardsAngle(current, target, maxDelta)
target = current + math.DeltaAngle(current, target)
return math.MoveTowards(current, target, maxDelta)
end
--近似
function math.Approximately(a, b)
return L_Abs(b - a) < math.max(1e-6 * math.max(L_Abs(a), L_Abs(b)), 1.121039e-44)
end
--反插值
function math.InverseLerp(from, to, value)
if from < to then
if value < from then
return 0
end
if value > to then
return 1
end
value = value - from
value = value/(to - from)
return value
end
if from <= to then
return 0
end
if value < to then
return 1
end
if value > from then
return 0
end
return 1.0 - ((value - to) / (from - to))
end
--乒乓
function math.PingPong(t, length)
t = math.Repeat(t, length * 2)
return length - L_Abs(t - length)
end
--是否是非数字值
function math.IsNan(number)
return not (number == number)
end
--伽玛函数
function math.Gamma(value, absmax, gamma)
local _flag = false
if value < 0 then
_flag = true
end
local _num = L_Abs(value)
if _num > absmax then
return (not _flag) and _num or -_num
end
local _num2 = (_num / absmax )^ gamma * absmax
return (not _flag) and _num2 or -_num2
end
--平滑阻尼
function math.SmoothDamp(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime)
maxSpeed = maxSpeed or math.huge
deltaTime = deltaTime or Time.deltaTime
smoothTime = math.max(0.0001, smoothTime)
local _num = 2 / smoothTime
local _num2 = _num * deltaTime
local _num3 = 1 / (1 + _num2 + 0.48 * _num2 * _num2 + 0.235 * _num2 * _num2 * _num2)
local _num4 = current - target
local _num5 = target
local max = maxSpeed * smoothTime
_num4 = Clamp(_num4, -max, max)
target = current - _num4
local _num7 = (currentVelocity + (_num * _num4)) * deltaTime
currentVelocity = (currentVelocity - _num * _num7) * _num3
local _num8 = target + (_num4 + _num7) * _num3
if (_num5 > current) == (_num8 > _num5) then
_num8 = _num5
currentVelocity = (_num8 - _num5) / deltaTime
end
return _num8,currentVelocity
end
--平滑阻尼角度
function math.SmoothDampAngle(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime)
deltaTime = deltaTime or Time.deltaTime
maxSpeed = maxSpeed or math.huge
target = current + math.DeltaAngle(current, target)
return math.SmoothDamp(current, target, currentVelocity, smoothTime, maxSpeed, deltaTime)
end
--平滑插值
function math.SmoothStep(from, to, t)
t = Clamp(t, 0, 1)
t = -2 * t * t * t + 3 * t * t
return to * t + from * (1 - t)
end
--水平角
function math.HorizontalAngle(dir)
return math.deg(math.atan(dir.x, dir.z))
end
--伽马转线性
function math.GammaToLinearSpaceExact(value)
if value <= 0.04045 then
return value / 12.92;
elseif value < 1.0 then
return math.Pow((value + 0.055)/1.055, 2.4);
else
return math.Pow(value, 2.2);
end
end
--线性转伽马
function math.LinearToGammaSpaceExact(value)
if value <= 0.0 then
return 0.0;
elseif value <= 0.0031308 then
return 12.92 * value;
elseif value < 1.0 then
return 1.055 * math.Pow(value, 0.4166667) - 0.055;
else
return math.Pow(value, 0.45454545);
end
end
--将数字转为整数或者小数。如72.0返回72 72.5返回72.5 支持负数
function math.FormatNumber(value)
local t1, t2 = math.modf(value)
if t2 == 0 then
--小数部分如果等于0则返回整数部分
return t1
else
--小数部分如果大于0则直接返回
return value
end
end