整理了一下项目中用到的一些 math 方法。一部分是 C# UnityEngine.Mathf 类移植来的,对于即写C#又写Lua的就不会那么割裂~~(其实 Unity 的 Mathf 来源于 C# 的 System.Math 但又添加了 Unity 里常用的一些方法)。甚至还非常迫真地添加了英文注释,看起来真的很像原生方法 XD

---Clamps n between 0 and 1.
---@param n number
---@return number
function math.clamp01(n)
  return math.min(math.max(n, 0), 1)
end

---Clamps n1 between n2 and n3.
---@param n1 number
---@param n2 number @min or max [included]
---@param n3 number @max or min [included]
---@return number
function math.clamp(n1, n2, n3)
  if n3 > n2 then
    return math.min(math.max(n1, n2), n3)
  else
    return math.min(math.max(n1, n3), n2)
  end
end

---Returns n raised to power p.
---@param n number
---@param p number
---@return number
function math.pow(n, p)
  return n ^ p
end

---Returns value rounded to the nearest integer.
---@param value number
---@return number
function math.round(value)
  if value >= 0 then
    return math.floor(value + 0.5)
  elseif value < 0 then
    return math.ceil(value - 0.5)
  end
end

---Returns value rounded to the nearest even number.
---@param value number
---@return number
function math.round_to_even(value)
  return math.round(value / 2) * 2
end

---指定浮点数位数
---理论来说应该用 string,浮点数仍然有精度问题,
---但是用于计算中精度问题影响较小可以忽略~~
function math.get_precise_decimal(decimal, n)
  return math.round(decimal * (10 ^ n)) / (10 ^ n)
end

---一些向量的计算
function math.distance2(x1, y1, x2, y2)
  return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
end

function math.squared_distance2(x1, y1, x2, y2)
  return (x2 - x1) ^ 2 + (y2 - y1) ^ 2
end

---Returns the distance between a and b.
---@return number
function math.distance3(x1, y1, z1, x2, y2, z2)
  return math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2 + (z2 - z1) ^ 2)
end

function math.squared_distance3(x1, y1, z1, x2, y2, z2)
  return (x2 - x1) ^ 2 + (y2 - y1) ^ 2 + (z2 - z1) ^ 2
end
---Compares two numbers and returns true if they are similar.
---@param n1 number
---@param n2 number
---@param precision number
---@return boolean
function math.approximately(n1, n2, precision)
  precision = precision or 10 ^ -6
  return math.abs(n2 - n1) < precision
end

---Returns the sign of value.
---@param value number
---@return number
function math.sign(value)
  return value >= 0 and 1 or -1
end

---Returns the sign mark of value.
---@param value number
---@return string
function math.signmark(value)
  return value >= 0 and '+' or '-'
end

---指定范围的随机数
---@param value number
---@param range number range (0, 1)
function math.random_by_range(value, range)
  return math.random(math.ceil(value * (1 - range)), math.floor(value * (1 + range)))
end
---Linearly interpolates between a and b by t.
---@param a number
---@param b number
---@param t number @ number between 0 ~ 1
---@return number
function math.lerp(a, b, t)
  return a + (b - a) * math.clamp01(t)
end

---Calculates the linear parameter t that produces
---the interpolant value within the range [a, b].
---@param a number
---@param b number
---@param value number
---@return number @ number between 0 ~ 1
function math.inverse_lerp(a, b, value)
  if a == b then return 0 end
  return (math.clamp(value, a, b) - a) / (b - a)
end