You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.5 KiB
106 lines
2.5 KiB
|
|
RANDOM_CALLS_COUNT = 0
|
|
|
|
-- https://stackoverflow.com/a/32387452/12464892
|
|
local function bitwise_and(a, b)
|
|
local result = 0
|
|
local bit = 1
|
|
while a > 0 and b > 0 do
|
|
if a % 2 == 1 and b % 2 == 1 then
|
|
result = result + bit
|
|
end
|
|
bit = bit * 2 -- shift left
|
|
a = math.floor(a/2) -- shift-right
|
|
b = math.floor(b/2)
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- https://stackoverflow.com/a/20177466/12464892
|
|
local A1, A2 = 727595, 798405 -- 5^17=D20*A1+A2
|
|
local D20, D40 = 1048576, 1099511627776 -- 2^20, 2^40
|
|
local X1, X2 = 0, 1
|
|
local function rand()
|
|
local U = X2*A2
|
|
local V = (X1*A2 + X2*A1) % D20
|
|
V = (V*D20 + U) % D40
|
|
X1 = math.floor(V/D20)
|
|
X2 = V - X1*D20
|
|
return V/D40
|
|
end
|
|
|
|
local SEED_BOUNDS = 2^20 - 1
|
|
local function randomseed2(seed)
|
|
-- 0 <= X1 <= 2^20-1, 1 <= X2 <= 2^20-1 (must be odd!)
|
|
-- ensure the number is odd, and within bounds of the generator
|
|
local seed = bitwise_and(seed, 1)
|
|
local v = math.clamp(math.abs(seed), 0, SEED_BOUNDS)
|
|
X1 = v
|
|
X2 = v + 1
|
|
end
|
|
|
|
local R = math.random
|
|
local RS = math.randomseed
|
|
local function random(n, m)
|
|
RANDOM_CALLS_COUNT = RANDOM_CALLS_COUNT + 1
|
|
|
|
local r
|
|
if n then
|
|
-- @TODO there are some bugs with calling math.random or am.rand
|
|
-- with n or m values, so usually we should just avoid it... not sure what's it about yet
|
|
log('calling random with "n" %g', n)
|
|
if m then
|
|
r = math.floor(R() * (m - n) + n)
|
|
else
|
|
r = math.floor(R() * n)
|
|
end
|
|
else
|
|
r = R()
|
|
end
|
|
|
|
return r
|
|
end
|
|
|
|
math.randomseed = function(seed)
|
|
RANDOM_CALLS_COUNT = 0
|
|
R = am.rand(seed)
|
|
math.random = random
|
|
end
|
|
|
|
-- whenever we refer to math.random, actually use the function 'random' above
|
|
math.random = random
|
|
|
|
function g_octave_noise(x, y, num_octaves, seed)
|
|
local seed = seed or os.time()
|
|
local noise = 0
|
|
|
|
for oct = 1, num_octaves do
|
|
local f = 1/4^oct
|
|
local l = 2^oct
|
|
local pos = vec2(x + seed, y + seed)
|
|
noise = noise + f * math.simplex(pos * l)
|
|
end
|
|
|
|
return noise
|
|
end
|
|
|
|
-- @TODO test, fix
|
|
function poisson_knuth(lambda)
|
|
local e = 2.71828
|
|
|
|
local L = e^-lambda
|
|
local k = 0
|
|
local p = 1
|
|
|
|
while p > L do
|
|
k = k + 1
|
|
p = p * math.random()
|
|
end
|
|
|
|
return k - 1
|
|
end
|
|
|
|
-- seed the random number generator with the current time
|
|
-- os.clock() is better if the program has been running for a little bit.
|
|
math.randomseed(os.time())
|
|
|