mirror of https://gitea.it/1414codeforge/gear
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.3 KiB
Lua
143 lines
4.3 KiB
Lua
10 months ago
|
--- Extended math functions
|
||
|
--
|
||
|
-- @module gear.mathx
|
||
|
-- @copyright 2022 The 1414 Code Forge
|
||
|
-- @author Lorenzo Cogotti
|
||
|
|
||
|
local floor = math.floor
|
||
|
local min, max = math.min, math.max
|
||
|
local cos, pi = math.cos, math.pi
|
||
|
local random = love and love.math.random or math.random
|
||
|
|
||
|
local mathx = setmetatable({}, math)
|
||
|
|
||
|
|
||
|
--- Clamp x within range [a,b] (where b >= a).
|
||
|
--
|
||
|
-- @number x value to clamp.
|
||
|
-- @number a interval lower bound (inclusive).
|
||
|
-- @number b interval upper bound (inclusive).
|
||
|
-- @treturn number clamped value.
|
||
|
function mathx.clamp(x, a, b) return min(max(x, a), b) end
|
||
|
|
||
|
--- Sign function.
|
||
|
--
|
||
|
-- @number x value whose sign should be returned.
|
||
|
-- @treturn number sign of x, -1 if negative, 1 if positive, 0 otherwise.
|
||
|
function mathx.sign(x) return x > 0 and 1 or x < 0 and -1 or 0 end
|
||
|
|
||
|
--- sign() variant returning 1 if x is non-negative.
|
||
|
--
|
||
|
-- @number x value whose sign should be returned.
|
||
|
-- @treturn number sign of x, -1 if negative, 1 if non-negative.
|
||
|
function mathx.sign2(x) return x >= 0 and 1 or -1 end
|
||
|
|
||
|
--- Linear interpolation between a and b.
|
||
|
--
|
||
|
-- @number a first interpolation point.
|
||
|
-- @number b second interpolation point.
|
||
|
-- @number t the interpolation factor, a real number within [0,1].
|
||
|
-- @treturn number the interpolated value.
|
||
|
function mathx.lerp(a, b, t) return a*(1 - t) + b*t end
|
||
|
|
||
|
--- Less accurate, but slightly faster, variant of lerp().
|
||
|
function mathx.lerp2(a, b, t) return a + (b - a)*t end
|
||
|
|
||
|
--- Cosine interpolation between a and b.
|
||
|
--
|
||
|
-- @number a first interpolation point.
|
||
|
-- @number b second interpolation point.
|
||
|
-- @number t the interpolation factor, a real number within [0,1].
|
||
|
-- @treturn number interpolated value.
|
||
|
function mathx.cerp(a, b, t)
|
||
|
local tt = (1 - cos(t * pi)) * 0.5
|
||
|
return a*(1 - tt) + b*tt
|
||
|
end
|
||
|
|
||
|
--- Cubic interpolation between a, b, c and d.
|
||
|
--
|
||
|
-- @number a first interpolation point.
|
||
|
-- @number b second interpolation point.
|
||
|
-- @number c third interpolation point.
|
||
|
-- @number d fourth interpolation point.
|
||
|
-- @number t the interpolation factor, a real number within [0,1].
|
||
|
-- @treturn number the interpolated value.
|
||
|
function mathx.cberp(a, b, c, d, t)
|
||
|
local tt = t * t
|
||
|
local a0 = d - c - a + b
|
||
|
return a0*t*tt + (a - b - a0)*tt + (c - a)*t + b
|
||
|
end
|
||
|
|
||
|
--- Catmull-Rom spline interpolation between a, b, c and d.
|
||
|
--
|
||
|
-- @number a first interpolation point.
|
||
|
-- @number b second interpolation point.
|
||
|
-- @number c third interpolation point.
|
||
|
-- @number d fourth interpolation point.
|
||
|
-- @number t the interpolation factor, a real number within [0,1].
|
||
|
-- @treturn number the interpolated value.
|
||
|
function mathx.catmullrom(a, b, c, d, t)
|
||
|
local tt = t * t
|
||
|
local mha = -a * 0.5
|
||
|
local hd = d * 0.5
|
||
|
return (mha + 1.5*b - 1.5*c + hd)*t*tt + (a - 2.5*b + 2*c - hd)*tt + (mha + 0.5*c)*t + b
|
||
|
end
|
||
|
|
||
|
--- Hermite interpolation between a, b, c and d.
|
||
|
--
|
||
|
-- @number a first interpolation point.
|
||
|
-- @number b second interpolation point.
|
||
|
-- @number c third interpolation point.
|
||
|
-- @number d fourth interpolation point.
|
||
|
-- @number t the interpolation factor, a real number within [0,1].
|
||
|
-- @number tension the tension factor, 1 is high, 0 normal (default), -1 is low.
|
||
|
-- @number bias the bias factor, 0 is even (default), positive is towards the first segment, negative towards the other.
|
||
|
-- @treturn number the interpolated value.
|
||
|
function mathx.herp(a, b, c, d, t, tension, bias)
|
||
|
tension = tension or 0
|
||
|
bias = bias or 0
|
||
|
|
||
|
local b0 = 1 + bias
|
||
|
local b1 = 1 - bias
|
||
|
local ht = (1 - tension) * 0.5
|
||
|
local s0 = b0 * ht
|
||
|
local s1 = b1 * ht
|
||
|
|
||
|
local tt = t * t
|
||
|
local ttt = tt * t
|
||
|
local ttt2 = ttt * 2
|
||
|
local tt3 = tt * 3
|
||
|
|
||
|
local m0 = (b - a)*s0 + (c - b)*s1
|
||
|
local m1 = (c - b)*s0 + (d - c)*s1
|
||
|
|
||
|
local a0 = ttt2 - tt3 + 1
|
||
|
local a1 = ttt - tt*2 + t
|
||
|
local a2 = ttt - tt
|
||
|
local a3 = tt3 - ttt2
|
||
|
|
||
|
return a0*b + a1*m0 + a2*m1 + a3*c
|
||
|
end
|
||
|
|
||
|
--- Pseudo-random sign value.
|
||
|
--
|
||
|
-- @treturn number the pseudo-random sign value, either -1, 0, or 1.
|
||
|
function mathx.rsign() return random(-1, 1) end
|
||
|
|
||
|
--- rsign() variant returning -1 or 1.
|
||
|
--
|
||
|
-- @treturn number the pseudo-random sign value, either -1 or 1.
|
||
|
function mathx.rsign2() return random(2) == 2 and 1 or -1 end
|
||
|
|
||
|
--- Precise pseudo-random number within [min,max] (where max >= min).
|
||
|
--
|
||
|
-- @number min interval lower bound (inclusive).
|
||
|
-- @number max interval upper bound (inclusive).
|
||
|
-- @treturn number the pseudo-random real number within [a,b].
|
||
|
function mathx.prandom(min, max)
|
||
|
local t = random()
|
||
|
return min * (1 - t) + max * t
|
||
|
end
|
||
|
|
||
|
return mathx
|