288 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| --- Extends Lua 5.2 math.
 | |
| -- @module Utils.math
 | |
| -- @see math
 | |
| -- @usage local math = require('__stdlib__/stdlib/utils/math')
 | |
| local Math = {}
 | |
| 
 | |
| Math.frexp = math.frexp
 | |
| Math.sqrt = math.sqrt
 | |
| Math.asin = math.asin
 | |
| Math.random = math.random
 | |
| Math.huge = math.huge
 | |
| Math.abs = math.abs
 | |
| Math.ldexp = math.ldexp
 | |
| Math.exp = math.exp
 | |
| Math.pow = math.pow
 | |
| Math.pi = math.pi
 | |
| Math.tan = math.tan
 | |
| Math.acos = math.acos
 | |
| Math.ceil = math.ceil
 | |
| Math.atan2 = math.atan2
 | |
| Math.tanh = math.tanh
 | |
| Math.sin = math.sin
 | |
| Math.min = math.min
 | |
| Math.deg = math.deg
 | |
| Math.sinh = math.sinh
 | |
| Math.rad = math.rad
 | |
| Math.randomseed = math.randomseed
 | |
| Math.cosh = math.cosh
 | |
| Math.modf = math.modf
 | |
| Math.cos = math.cos
 | |
| Math.atan = math.atan
 | |
| Math.max = math.max
 | |
| Math.log = math.log
 | |
| Math.fmod = math.fmod
 | |
| Math.floor = math.floor
 | |
| 
 | |
| for k, v in pairs(math) do if not Math[k] then Math[k] = v end end
 | |
| 
 | |
| local math_abs = math.abs
 | |
| local math_floor = math.floor
 | |
| local math_ceil = math.ceil
 | |
| local math_min = math.min
 | |
| local math_max = math.max
 | |
| local math_huge = math.huge
 | |
| local math_pi = math.pi
 | |
| local math_log = math.log
 | |
| local unpack = table.unpack
 | |
| 
 | |
| -- (( Math Constants
 | |
| Math.DEG2RAD = math_pi / 180
 | |
| Math.RAD2DEG = 180 / math_pi
 | |
| Math.EPSILON = 1.401298e-45
 | |
| 
 | |
| Math.MAXINT8 = 128
 | |
| Math.MININT8 = -128
 | |
| Math.MAXUINT8 = 255
 | |
| 
 | |
| Math.MAX_INT8 = Math.MAXINT8
 | |
| Math.MIN_INT8 = Math.MININT8
 | |
| Math.MAX_UINT8 = Math.MAXUINT8
 | |
| 
 | |
| Math.MAXINT16 = 32768
 | |
| Math.MININT16 = -32768
 | |
| Math.MAXUINT16 = 65535
 | |
| Math.MAX_INT16 = Math.MAXINT16
 | |
| Math.MIN_INT16 = Math.MININT16
 | |
| Math.MAX_UINT16 = Math.MAXUINT16
 | |
| 
 | |
| Math.MAXINT = 2147483648
 | |
| Math.MAX_INT = Math.MAXINT
 | |
| Math.MAXINT32 = Math.MAXINT
 | |
| Math.MAX_INT32 = Math.MAXINT
 | |
| 
 | |
| Math.MAXUINT = 4294967296
 | |
| Math.MAX_UINT = Math.MAXUINT
 | |
| Math.MAXUINT32 = Math.MAXUINT
 | |
| Math.MAX_UINT32 = Math.MAXUINT
 | |
| 
 | |
| Math.MININT = -2147483648
 | |
| Math.MIN_INT = Math.MININT
 | |
| Math.MININT32 = Math.MININT
 | |
| Math.MIN_INT32 = Math.MININT
 | |
| 
 | |
| Math.MAXINT64 = 9223372036854775808
 | |
| Math.MININT64 = -9223372036854775808
 | |
| Math.MAXUINT64 = 18446744073709551615
 | |
| Math.MAX_INT64 = Math.MAXINT64
 | |
| Math.MIN_INT64 = Math.MININT64
 | |
| Math.MAX_UINT64 = Math.MAXUINT64
 | |
| -- ))
 | |
| 
 | |
| local function tuple(...)
 | |
|     return type(...) == 'table' and ... or { ... }
 | |
| end
 | |
| 
 | |
| function Math.log10(x)
 | |
|     return math_log(x, 10)
 | |
| end
 | |
| 
 | |
| --- Round a number.
 | |
| -- @tparam number x
 | |
| -- @treturn number the rounded number
 | |
| function Math.round(x)
 | |
|     return x >= 0 and math_floor(x + 0.5) or math_ceil(x - 0.5)
 | |
| end
 | |
| 
 | |
| -- Returns the number x rounded to p decimal places.
 | |
| -- @tparam number x
 | |
| -- @tparam[opt=0] int p the number of decimal places to round to
 | |
| -- @treturn number rounded to p decimal spaces.
 | |
| function Math.round_to(x, p)
 | |
|     local e = 10 ^ (p or 0)
 | |
|     return math_floor(x * e + 0.5) / e
 | |
| end
 | |
| 
 | |
| -- Returns the number floored to p decimal spaces.
 | |
| -- @tparam number x
 | |
| -- @tparam[opt=0] int p the number of decimal places to floor to
 | |
| -- @treturn number floored to p decimal spaces.
 | |
| function Math.floor_to(x, p)
 | |
|     if (p or 0) == 0 then return math_floor(x) end
 | |
|     local e = 10 ^ p
 | |
|     return math_floor(x * e) / e
 | |
| end
 | |
| 
 | |
| -- Returns the number ceiled to p decimal spaces.
 | |
| -- @tparam number x
 | |
| -- @tparam[opt=0] int p the number of decimal places to ceil to
 | |
| -- @treturn number ceiled to p decimal spaces.
 | |
| function Math.ceil_to(x, p)
 | |
|     local e = 10 ^ (p or 0)
 | |
|     return math_ceil(x * e + 0.5) / e
 | |
| end
 | |
| 
 | |
| -- Various average (means) algorithms implementation
 | |
| -- See: http://en.wikipedia.org/wiki/Average
 | |
| 
 | |
| --- Calculates the sum of a sequence of values.
 | |
| -- @tparam tuple ... a tuple of numbers
 | |
| -- @treturn the sum
 | |
| function Math.sum(...)
 | |
|     local x = tuple(...)
 | |
|     local s = 0
 | |
|     for _, v in ipairs(x) do s = s + v end
 | |
|     return s
 | |
| end
 | |
| 
 | |
| --- Calculates the arithmetic mean of a set of values.
 | |
| -- @tparam array x an array of numbers
 | |
| -- @treturn number the arithmetic mean
 | |
| function Math.arithmetic_mean(...)
 | |
|     local x = tuple(...)
 | |
|     return (Math.sum(x) / #x)
 | |
| end
 | |
| 
 | |
| Math.avg = Math.arithmetic_mean
 | |
| Math.average = Math.arithmetic_mean
 | |
| 
 | |
| --- Calculates the geometric mean of a set of values.
 | |
| -- @tparam array x an array of numbers
 | |
| -- @treturn number the geometric mean
 | |
| function Math.geometric_mean(...)
 | |
|     local x = tuple(...)
 | |
|     local prod = 1
 | |
|     for _, v in ipairs(x) do prod = prod * v end
 | |
|     return (prod ^ (1 / #x))
 | |
| end
 | |
| 
 | |
| --- Calculates the harmonic mean of a set of values.
 | |
| -- @tparam tuple ... an array of numbers
 | |
| -- @treturn number the harmonic mean
 | |
| function Math.harmonic_mean(...)
 | |
|     local x = tuple(...)
 | |
|     local s = 0
 | |
|     for _, v in ipairs(x) do s = s + (1 / v) end
 | |
|     return (#x / s)
 | |
| end
 | |
| 
 | |
| --- Calculates the quadratic mean of a set of values.
 | |
| -- @tparam tuple ... an array of numbers
 | |
| -- @treturn number the quadratic mean
 | |
| function Math.quadratic_mean(...)
 | |
|     local x = tuple(...)
 | |
|     local squares = 0
 | |
|     for _, v in ipairs(x) do squares = squares + (v * v) end
 | |
|     return math.sqrt((1 / #x) * squares)
 | |
| end
 | |
| 
 | |
| --- Calculates the generalized mean (to a specified power) of a set of values.
 | |
| -- @tparam number p power
 | |
| -- @tparam tuple ... an array of numbers
 | |
| -- @treturn number the generalized mean
 | |
| function Math.generalized_mean(p, ...)
 | |
|     local x = tuple(...)
 | |
|     local sump = 0
 | |
|     for _, v in ipairs(x) do sump = sump + (v ^ p) end
 | |
|     return ((1 / #x) * sump) ^ (1 / p)
 | |
| end
 | |
| 
 | |
| --- Calculates the weighted mean of a set of values.
 | |
| -- @tparam array x an array of numbers
 | |
| -- @tparam array w an array of number weights for each value
 | |
| -- @treturn number the weighted mean
 | |
| function Math.weighted_mean(x, w)
 | |
|     local sump = 0
 | |
|     for i, v in ipairs(x) do sump = sump + (v * w[i]) end
 | |
|     return sump / Math.sum(w)
 | |
| end
 | |
| 
 | |
| --- Calculates the midrange mean of a set of values.
 | |
| -- @tparam array x an array of numbers
 | |
| -- @treturn number the midrange mean
 | |
| function Math.midrange_mean(...)
 | |
|     local x = tuple(...)
 | |
|     return 0.5 * (math_min(unpack(x)) + math_max(unpack(x)))
 | |
| end
 | |
| 
 | |
| --- Calculates the energetic mean of a set of values.
 | |
| -- @tparam array x an array of numbers
 | |
| -- @treturn number the energetic mean
 | |
| function Math.energetic_mean(...)
 | |
|     local x = tuple(...)
 | |
|     local s = 0
 | |
|     for _, v in ipairs(x) do s = s + (10 ^ (v / 10)) end
 | |
|     return 10 * Math.log10((1 / #x) * s)
 | |
| end
 | |
| 
 | |
| --- Returns the number x clamped between the numbers min and max.
 | |
| -- @tparam number x
 | |
| -- @tparam[opt=0] number min
 | |
| -- @tparam[opt=1] number max
 | |
| -- @treturn number clamped between min and max
 | |
| function Math.clamp(x, min, max)
 | |
|     min, max = min or 0, max or 1
 | |
|     return x < min and min or (x > max and max or x)
 | |
| end
 | |
| 
 | |
| --- Linear interpolation or 2 numbers.
 | |
| -- @tparam number a
 | |
| -- @tparam number b
 | |
| -- @tparam float amount
 | |
| -- @treturn number
 | |
| function Math.lerp(a, b, amount)
 | |
|     return a + (b - a) * Math.clamp(amount, 0, 1)
 | |
| end
 | |
| 
 | |
| --- Smooth.
 | |
| -- @tparam number a
 | |
| -- @tparam number b
 | |
| -- @tparam float amount
 | |
| -- @treturn number
 | |
| function Math.smooth(a, b, amount)
 | |
|     local t = Math.clamp(amount, 0, 1)
 | |
|     local m = t * t * (3 - 2 * t)
 | |
|     return a + (b - a) * m
 | |
| end
 | |
| 
 | |
| --- Approximately the same
 | |
| -- @tparam number a
 | |
| -- @tparam number b
 | |
| -- @treturn boolean
 | |
| function Math.approximately(a, b)
 | |
|     return math_abs(b - a) < math_max(1e-6 * math_max(math_abs(a), math_abs(b)), 1.121039e-44)
 | |
| end
 | |
| 
 | |
| --- Is x a number.
 | |
| -- @tparam number x
 | |
| -- @treturn boolean
 | |
| function Math.is_number(x)
 | |
|     return x == x and x ~= math_huge
 | |
| end
 | |
| 
 | |
| --- Is x an integer.
 | |
| -- @tparam number x
 | |
| -- @treturn boolean
 | |
| function Math.is_integer(x)
 | |
|     return x == math_ceil(x)
 | |
| end
 | |
| 
 | |
| --- Is x unsigned.
 | |
| -- @tparam number x
 | |
| -- @treturn boolean
 | |
| function Math.is_unsigned(x)
 | |
|     return x >= 0
 | |
| end
 | |
| 
 | |
| return Math
 |