mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2024-11-14 06:40:21 +01:00
103 lines
2.1 KiB
Lua
103 lines
2.1 KiB
Lua
|
-- gaussian.lua
|
||
|
|
||
|
local function get_box_size(sigma, n)
|
||
|
local v = sigma^2 / n
|
||
|
local r_ideal = ((12*v + 1) ^ 0.5 - 1) / 2
|
||
|
local r_down = math.floor(r_ideal)
|
||
|
local r_up = math.ceil(r_ideal)
|
||
|
local v_down = ((2*r_down+1)^2 - 1) / 12
|
||
|
local v_up = ((2*r_up+1)^2 - 1) / 12
|
||
|
local m_ideal = (v - v_down) / (v_up - v_down) * n
|
||
|
local m = math.floor(m_ideal+0.5)
|
||
|
|
||
|
local sizes = {}
|
||
|
for i=1, n do
|
||
|
sizes[i] = i<=m and 2*r_up+1 or 2*r_down+1
|
||
|
end
|
||
|
|
||
|
return sizes
|
||
|
end
|
||
|
|
||
|
local function box_blur_1d(map, size, first, incr, len, map2)
|
||
|
local n = math.ceil(size/2)
|
||
|
first = first or 1
|
||
|
incr = incr or 1
|
||
|
len = len or math.floor((#map-first)/incr)+1
|
||
|
local last = first + (len-1)*incr
|
||
|
|
||
|
local nth = first+(n-1)*incr
|
||
|
local sum = 0
|
||
|
for i=first, nth, incr do
|
||
|
if i == first then
|
||
|
sum = sum + map[i]
|
||
|
else
|
||
|
sum = sum + 2*map[i]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local i_left = nth
|
||
|
local incr_left = -incr
|
||
|
local i_right = nth
|
||
|
local incr_right = incr
|
||
|
|
||
|
map2 = map2 or {}
|
||
|
for i=first, last, incr do
|
||
|
map2[i] = sum / size
|
||
|
i_right = i_right + incr_right
|
||
|
sum = sum - map[i_left] + map[i_right]
|
||
|
i_left = i_left + incr_left
|
||
|
|
||
|
if i_left == first then
|
||
|
incr_left = incr
|
||
|
end
|
||
|
if i_right == last then
|
||
|
incr_right = -incr
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return map2
|
||
|
end
|
||
|
|
||
|
local function box_blur_2d(map1, size, map2)
|
||
|
local X, Y = map1.X, map1.Y
|
||
|
map2 = map2 or {}
|
||
|
for y=1, Y do
|
||
|
box_blur_1d(map1, size, (y-1)*X+1, 1, X, map2)
|
||
|
end
|
||
|
for x=1, X do
|
||
|
box_blur_1d(map2, size, x, X, Y, map1)
|
||
|
end
|
||
|
|
||
|
return map1
|
||
|
end
|
||
|
|
||
|
--[[local function gaussian_blur(map, std, tail)
|
||
|
local exp = math.exp
|
||
|
|
||
|
local kernel_mid = math.ceil(std*tail) + 1
|
||
|
local kernel_size = kernel_mid * 2 - 1
|
||
|
local kernel = {}
|
||
|
local cst1 = 1/(std*(2*math.pi)^0.5)
|
||
|
local cst2 = -1/(2*std^2)
|
||
|
for i=1, kernel_size do
|
||
|
kernel[i] = cst1 * exp((i-kernel_mid)^2 * cst2)
|
||
|
end
|
||
|
|
||
|
]]
|
||
|
|
||
|
local function gaussian_blur_approx(map, sigma, n, map2)
|
||
|
map2 = map2 or {}
|
||
|
local sizes = get_box_size(sigma, n)
|
||
|
for i=1, n do
|
||
|
box_blur_2d(map, sizes[i], map2)
|
||
|
end
|
||
|
return map
|
||
|
end
|
||
|
|
||
|
return {
|
||
|
get_box_size = get_box_size,
|
||
|
box_blur_1d = box_blur_1d,
|
||
|
box_blur_2d = box_blur_2d,
|
||
|
gaussian_blur_approx = gaussian_blur_approx,
|
||
|
}
|