I binged the whole day to release this ultimate math module for practical game development. It includes various functions to help ease your development.
I know that there is a lot of math modules out there, but most of those are focusing on including mythical constants and glorious mathematical functions that have little to no use in game development. So today am happy to release this module to the community as open source (MIT LICENCE) in github!
I’ll be happy to see your contributions, and even happier to include your fixes and new features!
There is still a lot to add, and functions that I have to document in the near future, I
l’ll update you when there is a new update!
This module is not yet tested fully, in fact I made the whole code in one sit character by character, I have no idea how I survived all that math and programming in one go
Imma complete documentation and create unit tests when I get some rest! otherwise I’ll be happy if you can help me improve this module
CodesOtakuModules/Math.lua at main · CodesOtakuYT/CodesOtakuModules (github.com)
{
----> Constants
PI = PI, -- Ratio of a circle's circumference to its diameter.
TAU = TAU, -- PI*2
E = E, -- Euler's number
PHI = PHI, -- Golden Ratio
----> Pure mathematical functions
nrt = nrt, -- Nth root; (x, n)
cbrt = cbrt, -- Cubic root; (x)
inverse = inverse, -- 1/x; (x)
ln = ln, -- Natural logarithm; (x)
log2 = log2, -- Log of base 2
cos = cos, -- cos(x)
sin = sin, -- sin(x)
ncos = ncos, -- -cos(x), it might seem silly, but I added this so I can optimize derivative and integral by referencing it, so you can pass in this function to integral, and it's already optimized
nsin = nsin, -- -sin(x)
sec = sec, -- Secant(x), I don't use this functions usually, but it might be helpful if you have a formula that use them and you're too lazy like me
csc = csc, -- Co-secant(x),
cot = cot, -- Co-tangent(x),
versin = versin, -- versin(θ) = 1 - cos(θ) = 2sin²(θ/2)
coversin = coversin, -- coversine(θ) = 1 - sin(θ)
exsec = exsec, -- exsecant(θ) = sec(θ) - 1 = 1 / cos(θ) - 1
haversin = haversin, -- haversine(θ) = sin²(0⁄2) = 1 - cos(θ) / 2
ease = ease, -- https://godotengine.org/qa/59172/how-do-i-properly-use-the-ease-function
smoothStep = smoothStep, -- https://thebookofshaders.com/glossary/?search=smoothstep
factorial = factorial, -- x!
fibonacci = fibonacci, -- fib(x-1)+fib(x-2)
----> Practical mathematical functions
numberLength = numberLength, -- returns the number of digits in the number #tostring(number)
fract = fract, -- return the fractional part of a number, what's after the comma
toFract = toFract, -- return the number after the comma like 0.number
wrap = wrap, -- it cycles a arbitrary value between min and max, equivalent to the modulo operator but with configurable minimum
step = step, -- returns the closest multiple of factor to x, can be used to snap a position's components to a grid (Minecraft...)
snap = snap, -- the same as step, but can also handle seperation, Ex: your grid have a border
stepDecimals = stepDecimals, -- round the number to n digits after the comma
lerp = lerp, -- takes a range [a -> b] and a t value [0->1]. it returns a value travalling from a to b linearly, where t is the percentage it advanced (Ex: 50% = 0.5)
invLerp = invLerp, inverseLerp = invLerp, -- takes a range [c -> d] and a value x, it returns the t value of the value in range, basically where the value is relative to the range.
map = map, -- lerp(o1, o2, inverseLerp(i1, i2, x)), remaps a value x from the range [i1->i2] to [o1->o2], can be useful to create sliders.
lerpExp = lerpExp, -- exponential lerp
invLerpExp = invLerpExp, inverseLerpExp = invLerpExp, -- inverse exponential lerp
----> Conversion
cartesian2polar = cartesian2polar, -- x, y to rau, angle
cylindrical2cartesian = cylindrical2cartesian, -- rau, angle, z to x,y,z
spherical2cartesian = spherical2cartesian, -- rau, angle, theta to x,y,z
polar2cartesian = polar2cartesian, -- rau, angle to x,y
----> Comparaison functions
approxEq = approxEq, -- Returns true if x approximately equals y, where EPSILON is the tolerance, error or deviation allowed; (x, y, epsilon?)
approxZero = approxZero, -- Returns true if x approximately equals 0
----> Calculus
derivative = derivative, -- calculate the derivative of f using it's definite derivative (optimized) or numerically if none found
integral = integral, -- calculate the integral of f from x1 to x2 using it's definite primitive (optimized) or numerically if none found
integralAbs = integralAbs, -- the absolute version of the integral, the sign of f(x) is ignored
addDefiniteFunction = addDefiniteFunction, -- takes 2 functions. a function and it's derivative, it will be used by the functions above if the definite version exist, as it's much better and accurate than the numerical method
productDerivative = productDerivative, -- (f*g)' = f'g-g'f the chain rule
quotientDerivative = quotientDerivative, -- (f/g)' = (f'g-g'f)/(g^2) the chain rule and the derivative of the inverse of f(x)
compositeDerivative = compositeDerivative, -- (f(g))' = f'(g)*g'
----> Table math
sumT = sumT, -- Sum of the values; (table)
differenceT = differenceT, -- Difference of the values; (table)
productT = productT, -- Product of the values; (table)
quotientT = quotientT, -- Quotient of the values; (table)
meanT = meanT, -- Average of the values; (table)
modeT = modeT, -- The middle value or the average of the middle values in the sorted version of the table; (table)
maxT = maxT, -- The maximum value in the table, if isOverride is true, return the last maximum found, otherwise the first; (table, isOverride?)
minT = minT, -- The minumum value in the table;, if isOverride is true, return the last minimum found, otherwise the first; (table, isOverride?)
countValuesT = countValuesT, -- Returns a table with the count of all the values in the table; (table)
rangeT = rangeT, -- Returns {min, minIndex}, {max, maxIndex}; (table)
processPairsT = processPairsT, -- Gets a table with 2*n elements, it returns a table with n elements by processing each pair with the function f
mapT = mapT, -- Gets a table [x1, x2, x3...xn] and a function, returns [f(x1), f(x2), f(x3)...f(xn)]
filterT = filterT, -- Gets a table and a function, returns a new table with the elements that evaluated the function f(value, key) to true
countT = countT, -- Accumulates the result of a function f(v, k) traversing a table, returns the accumulated value
countMulT = countMulT, -- The same as countT but with multiplication
sampleT = sampleT, -- Sample function output n times from x1 to x2 linearly
----> Vector math
distanceV = distanceV, -- Returns the distance between the position vec1 and vec2
midPosV = midPosV, -- Returns the middle position between the position vec1 and vec2, equivalent to lerp(vec1, vec2, 0.5)
applyV = applyV, -- Returns a new Vector3 by applying a function on the X, Y and Z components of a Vector3
absV = absV, -- Returns a new Vector3 where all the components of the vector are absolute (positive or nil)
-- Random
randomItemT = randomItemT, -- Returns a random key, value in table
random = random, -- returns a random number in range [a,b]
randomN = randomN, -- returns a random integer in range [a,b]
----> Helper functions
copyT = copyT, -- Returns a copy of a table
invertT = invertT, -- the keys becomes the values and vice versa, takes a table [y1 = x1, y2 = x2...yn = xn], returns [x1 = y1, x2 = y2...xn = yn]
zipT = zipT, -- takes 2 tables and zip them together {{t1[1], t2[1]}, {t1[2], t2[2]}...{t1[n], t2[n]}}
unzipT = unzipT, -- the inverse of zip, takes 1 table of pairs and unzip it into 2 tables
valuesT = valuesT, -- return a table of all the values inside the table, there is also recursive mode for nested tables
keysT = keysT, -- the same as valuesT, but for table keys