mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2025-07-04 01:10:39 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
0a1c08648d | |||
290b998735 | |||
30136bf60a | |||
9475b49b8d | |||
36b49a7fe2 | |||
103cd49d78 | |||
25c5cb2e1f |
@ -7,6 +7,8 @@ local blocksize = mapgen_rivers.blocksize
|
|||||||
local sea_level = mapgen_rivers.sea_level
|
local sea_level = mapgen_rivers.sea_level
|
||||||
local riverbed_slope = mapgen_rivers.riverbed_slope
|
local riverbed_slope = mapgen_rivers.riverbed_slope
|
||||||
|
|
||||||
|
local MAP_BOTTOM = -31000
|
||||||
|
|
||||||
-- Linear interpolation
|
-- Linear interpolation
|
||||||
local function interp(v00, v01, v11, v10, xf, zf)
|
local function interp(v00, v01, v11, v10, xf, zf)
|
||||||
local v0 = v01*xf + v00*(1-xf)
|
local v0 = v01*xf + v00*(1-xf)
|
||||||
@ -17,15 +19,14 @@ end
|
|||||||
local function heightmaps(minp, maxp)
|
local function heightmaps(minp, maxp)
|
||||||
|
|
||||||
local polygons = make_polygons(minp, maxp)
|
local polygons = make_polygons(minp, maxp)
|
||||||
local incr = maxp.x-minp.x+1
|
local incr = maxp.z-minp.z+1
|
||||||
local i0 = (minp.z-minp.z) * incr + (minp.x-minp.x) + 1
|
|
||||||
|
|
||||||
local terrain_height_map = {}
|
local terrain_height_map = {}
|
||||||
local lake_height_map = {}
|
local lake_height_map = {}
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
for x=minp.x, maxp.x do
|
|
||||||
for z=minp.z, maxp.z do
|
for z=minp.z, maxp.z do
|
||||||
|
for x=minp.x, maxp.x do
|
||||||
local poly = polygons[i]
|
local poly = polygons[i]
|
||||||
|
|
||||||
if poly then
|
if poly then
|
||||||
@ -106,8 +107,8 @@ local function heightmaps(minp, maxp)
|
|||||||
terrain_height_map[i] = terrain_height
|
terrain_height_map[i] = terrain_height
|
||||||
lake_height_map[i] = lake_height
|
lake_height_map[i] = lake_height
|
||||||
else
|
else
|
||||||
terrain_height_map[i] = -31000
|
terrain_height_map[i] = MAP_BOTTOM
|
||||||
lake_height_map[i] = -31000
|
lake_height_map[i] = MAP_BOTTOM
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
87
init.lua
87
init.lua
@ -8,13 +8,16 @@ local blocksize = mapgen_rivers.blocksize
|
|||||||
local sea_level = mapgen_rivers.sea_level
|
local sea_level = mapgen_rivers.sea_level
|
||||||
local riverbed_slope = mapgen_rivers.riverbed_slope
|
local riverbed_slope = mapgen_rivers.riverbed_slope
|
||||||
local elevation_chill = mapgen_rivers.elevation_chill
|
local elevation_chill = mapgen_rivers.elevation_chill
|
||||||
|
local use_distort = mapgen_rivers.distort
|
||||||
|
local use_biomes = mapgen_rivers.biomes
|
||||||
|
local use_biomegen_mod = use_biomes and minetest.global_exists('biomegen')
|
||||||
|
use_biomes = use_biomes and not use_biomegen_mod
|
||||||
|
|
||||||
|
if use_biomegen_mod then
|
||||||
|
biomegen.set_elevation_chill(elevation_chill)
|
||||||
|
end
|
||||||
dofile(modpath .. 'noises.lua')
|
dofile(modpath .. 'noises.lua')
|
||||||
|
|
||||||
local make_polygons = dofile(modpath .. 'polygons.lua')
|
|
||||||
|
|
||||||
local transform_quadri = dofile(modpath .. 'geometry.lua')
|
|
||||||
|
|
||||||
local heightmaps = dofile(modpath .. 'heightmap.lua')
|
local heightmaps = dofile(modpath .. 'heightmap.lua')
|
||||||
|
|
||||||
-- Linear interpolation
|
-- Linear interpolation
|
||||||
@ -48,21 +51,32 @@ local function generate(minp, maxp, seed)
|
|||||||
y = chulens.y+1,
|
y = chulens.y+1,
|
||||||
z = chulens.z,
|
z = chulens.z,
|
||||||
}
|
}
|
||||||
|
if use_distort then
|
||||||
noise_x_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_x, mapsize)
|
noise_x_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_x, mapsize)
|
||||||
noise_z_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_z, mapsize)
|
noise_z_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_z, mapsize)
|
||||||
|
noise_distort_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_amplitude, chulens)
|
||||||
|
end
|
||||||
|
if use_biomes then
|
||||||
noise_heat_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat, chulens)
|
noise_heat_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat, chulens)
|
||||||
noise_heat_blend_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat_blend, chulens)
|
noise_heat_blend_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat_blend, chulens)
|
||||||
noise_distort_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_amplitude, chulens)
|
end
|
||||||
init = true
|
init = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local minp2d = {x=minp.x, y=minp.z}
|
local minp2d = {x=minp.x, y=minp.z}
|
||||||
|
if use_distort then
|
||||||
noise_x_obj:get_3d_map_flat(minp, noise_x_map)
|
noise_x_obj:get_3d_map_flat(minp, noise_x_map)
|
||||||
noise_z_obj:get_3d_map_flat(minp, noise_z_map)
|
noise_z_obj:get_3d_map_flat(minp, noise_z_map)
|
||||||
noise_distort_obj:get_2d_map_flat(minp2d, noise_distort_map)
|
noise_distort_obj:get_2d_map_flat(minp2d, noise_distort_map)
|
||||||
|
end
|
||||||
|
if use_biomes then
|
||||||
noise_heat_obj:get_2d_map_flat(minp2d, noise_heat_map)
|
noise_heat_obj:get_2d_map_flat(minp2d, noise_heat_map)
|
||||||
noise_heat_blend_obj:get_2d_map_flat(minp2d, noise_heat_blend_map)
|
noise_heat_blend_obj:get_2d_map_flat(minp2d, noise_heat_blend_map)
|
||||||
|
end
|
||||||
|
|
||||||
|
local terrain_map, lake_map, incr, i_origin
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
local xmin, xmax, zmin, zmax = minp.x, maxp.x, minp.z, maxp.z
|
local xmin, xmax, zmin, zmax = minp.x, maxp.x, minp.z, maxp.z
|
||||||
local i = 0
|
local i = 0
|
||||||
local i2d = 0
|
local i2d = 0
|
||||||
@ -87,9 +101,12 @@ local function generate(minp, maxp, seed)
|
|||||||
|
|
||||||
local pminp = {x=math.floor(xmin), z=math.floor(zmin)}
|
local pminp = {x=math.floor(xmin), z=math.floor(zmin)}
|
||||||
local pmaxp = {x=math.floor(xmax)+1, z=math.floor(zmax)+1}
|
local pmaxp = {x=math.floor(xmax)+1, z=math.floor(zmax)+1}
|
||||||
local incr = pmaxp.z-pminp.z+1
|
incr = pmaxp.x-pminp.x+1
|
||||||
local i_origin = 1 - pminp.x*incr - pminp.z
|
i_origin = 1 - pminp.z*incr - pminp.x
|
||||||
local terrain_map, lake_map = heightmaps(pminp, pmaxp)
|
terrain_map, lake_map = heightmaps(pminp, pmaxp)
|
||||||
|
else
|
||||||
|
terrain_map, lake_map = heightmaps(minp, maxp)
|
||||||
|
end
|
||||||
|
|
||||||
local c_stone = minetest.get_content_id("default:stone")
|
local c_stone = minetest.get_content_id("default:stone")
|
||||||
local c_dirt = minetest.get_content_id("default:dirt")
|
local c_dirt = minetest.get_content_id("default:dirt")
|
||||||
@ -118,26 +135,38 @@ local function generate(minp, maxp, seed)
|
|||||||
for x = minp.x, maxp.x do
|
for x = minp.x, maxp.x do
|
||||||
local ivm = a:index(x, minp.y, z)
|
local ivm = a:index(x, minp.y, z)
|
||||||
local ground_above = false
|
local ground_above = false
|
||||||
local temperature = noise_heat_map[i2d]+noise_heat_blend_map[i2d]
|
local temperature
|
||||||
|
if use_biomes then
|
||||||
|
temperature = noise_heat_map[i2d]+noise_heat_blend_map[i2d]
|
||||||
|
end
|
||||||
|
local terrain, lake
|
||||||
|
if not use_distort then
|
||||||
|
terrain = terrain_map[i2d]
|
||||||
|
lake = lake_map[i2d]
|
||||||
|
end
|
||||||
|
|
||||||
for y = maxp.y+1, minp.y, -1 do
|
for y = maxp.y+1, minp.y, -1 do
|
||||||
|
if use_distort then
|
||||||
local xn = noise_x_map[nid]
|
local xn = noise_x_map[nid]
|
||||||
local zn = noise_z_map[nid]
|
local zn = noise_z_map[nid]
|
||||||
local x0 = math.floor(xn)
|
local x0 = math.floor(xn)
|
||||||
local z0 = math.floor(zn)
|
local z0 = math.floor(zn)
|
||||||
|
|
||||||
local i0 = i_origin + x0*incr + z0
|
local i0 = i_origin + z0*incr + x0
|
||||||
local i1 = i0+incr
|
local i1 = i0+1
|
||||||
local i2 = i1+1
|
local i2 = i1+incr
|
||||||
local i3 = i0+1
|
local i3 = i2-1
|
||||||
|
|
||||||
|
terrain = interp(terrain_map[i0], terrain_map[i1], terrain_map[i2], terrain_map[i3], xn-x0, zn-z0)
|
||||||
|
lake = math.min(lake_map[i0], lake_map[i1], lake_map[i2], lake_map[i3])
|
||||||
|
end
|
||||||
|
|
||||||
local terrain = interp(terrain_map[i0], terrain_map[i1], terrain_map[i2], terrain_map[i3], xn-x0, zn-z0)
|
|
||||||
if y <= maxp.y then
|
if y <= maxp.y then
|
||||||
local lake = math.min(lake_map[i0], lake_map[i1], lake_map[i2], lake_map[i3])
|
|
||||||
|
|
||||||
local is_lake = lake > terrain
|
local is_lake = lake > terrain
|
||||||
local ivm = a:index(x, y, z)
|
local ivm = a:index(x, y, z)
|
||||||
if y <= terrain then
|
if y <= terrain then
|
||||||
if y <= terrain-1 or ground_above then
|
if not use_biomes or y <= terrain-1 or ground_above then
|
||||||
data[ivm] = c_stone
|
data[ivm] = c_stone
|
||||||
elseif is_lake or y < sea_level then
|
elseif is_lake or y < sea_level then
|
||||||
data[ivm] = c_sand
|
data[ivm] = c_sand
|
||||||
@ -152,8 +181,7 @@ local function generate(minp, maxp, seed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif y <= lake and lake > sea_level then
|
elseif y <= lake and lake > sea_level then
|
||||||
local temperature_y = temperature - y*elevation_chill
|
if not use_biomes or temperature - y*elevation_chill >= 0 then
|
||||||
if temperature_y >= 0 then
|
|
||||||
data[ivm] = c_rwater
|
data[ivm] = c_rwater
|
||||||
else
|
else
|
||||||
data[ivm] = c_ice
|
data[ivm] = c_ice
|
||||||
@ -166,16 +194,29 @@ local function generate(minp, maxp, seed)
|
|||||||
ground_above = y <= terrain
|
ground_above = y <= terrain
|
||||||
|
|
||||||
ivm = ivm + ystride
|
ivm = ivm + ystride
|
||||||
|
if use_distort then
|
||||||
nid = nid + incrY
|
nid = nid + incrY
|
||||||
end
|
end
|
||||||
nid = nid + incrX
|
|
||||||
i2d = i2d + 1
|
|
||||||
end
|
|
||||||
nid = nid + incrZ
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
|
nid = nid + incrX
|
||||||
|
end
|
||||||
|
i2d = i2d + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
|
nid = nid + incrZ
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_biomegen_mod then
|
||||||
|
biomegen.generate_all(data, a, vm, minp, maxp, seed)
|
||||||
|
else
|
||||||
vm:set_data(data)
|
vm:set_data(data)
|
||||||
minetest.generate_ores(vm, minp, maxp)
|
mietest.generate_ores(vm, minp, maxp)
|
||||||
|
end
|
||||||
|
|
||||||
vm:set_lighting({day = 0, night = 0})
|
vm:set_lighting({day = 0, night = 0})
|
||||||
vm:calc_lighting()
|
vm:calc_lighting()
|
||||||
vm:update_liquids()
|
vm:update_liquids()
|
||||||
|
4
mod.conf
Normal file
4
mod.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
name = mapgen_rivers
|
||||||
|
title = Map generator with realistic rivers
|
||||||
|
depends = default
|
||||||
|
optional_depends = biomegen
|
56
polygons.lua
56
polygons.lua
@ -96,7 +96,7 @@ local function make_polygons(minp, maxp)
|
|||||||
init = true
|
init = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local chulens = maxp.z - minp.z + 1
|
local chulens = maxp.x - minp.x + 1
|
||||||
|
|
||||||
local polygons = {}
|
local polygons = {}
|
||||||
-- Determine the minimum and maximum coordinates of the polygons that could be on the chunk, knowing that they have an average size of 'blocksize' and a maximal offset of 0.5 blocksize.
|
-- Determine the minimum and maximum coordinates of the polygons that could be on the chunk, knowing that they have an average size of 'blocksize' and a maximal offset of 0.5 blocksize.
|
||||||
@ -115,44 +115,44 @@ local function make_polygons(minp, maxp)
|
|||||||
local poly_z = {offset_z[iA]+zp, offset_z[iB]+zp, offset_z[iC]+zp+1, offset_z[iD]+zp+1}
|
local poly_z = {offset_z[iA]+zp, offset_z[iB]+zp, offset_z[iC]+zp+1, offset_z[iD]+zp+1}
|
||||||
local polygon = {x=poly_x, z=poly_z, i={iA, iB, iC, iD}}
|
local polygon = {x=poly_x, z=poly_z, i={iA, iB, iC, iD}}
|
||||||
|
|
||||||
local bounds = {} -- Will be a list of the intercepts of polygon edges for every X position (scanline algorithm)
|
local bounds = {} -- Will be a list of the intercepts of polygon edges for every Z position (scanline algorithm)
|
||||||
-- Calculate the min and max X positions
|
-- Calculate the min and max Z positions
|
||||||
local xmin = math.max(math.floor(blocksize*math.min(unpack(poly_x)))+1, minp.x)
|
local zmin = math.max(math.floor(blocksize*math.min(unpack(poly_z)))+1, minp.z)
|
||||||
local xmax = math.min(math.floor(blocksize*math.max(unpack(poly_x))), maxp.x)
|
local zmax = math.min(math.floor(blocksize*math.max(unpack(poly_z))), maxp.z)
|
||||||
-- And initialize the arrays
|
-- And initialize the arrays
|
||||||
for x=xmin, xmax do
|
for z=zmin, zmax do
|
||||||
bounds[x] = {}
|
bounds[z] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local i1 = 4
|
local i1 = 4
|
||||||
for i2=1, 4 do -- Loop on 4 edges
|
for i2=1, 4 do -- Loop on 4 edges
|
||||||
local x1, x2 = poly_x[i1], poly_x[i2]
|
|
||||||
-- Calculate the integer X positions over which this edge spans
|
|
||||||
local lxmin = math.floor(blocksize*math.min(x1, x2))+1
|
|
||||||
local lxmax = math.floor(blocksize*math.max(x1, x2))
|
|
||||||
if lxmin <= lxmax then -- If there is at least one position in it
|
|
||||||
local z1, z2 = poly_z[i1], poly_z[i2]
|
local z1, z2 = poly_z[i1], poly_z[i2]
|
||||||
-- Calculate coefficient of the equation defining the edge: Z=aX+b
|
-- Calculate the integer Z positions over which this edge spans
|
||||||
local a = (z1-z2) / (x1-x2)
|
local lzmin = math.floor(blocksize*math.min(z1, z2))+1
|
||||||
local b = blocksize*(z1 - a*x1)
|
local lzmax = math.floor(blocksize*math.max(z1, z2))
|
||||||
for x=math.max(lxmin, minp.x), math.min(lxmax, maxp.x) do
|
if lzmin <= lzmax then -- If there is at least one position in it
|
||||||
-- For every X position involved, add the intercepted Z position in the table
|
local x1, x2 = poly_x[i1], poly_x[i2]
|
||||||
table.insert(bounds[x], a*x+b)
|
-- Calculate coefficient of the equation defining the edge: X=aZ+b
|
||||||
|
local a = (x1-x2) / (z1-z2)
|
||||||
|
local b = blocksize*(x1 - a*z1)
|
||||||
|
for z=math.max(lzmin, minp.z), math.min(lzmax, maxp.z) do
|
||||||
|
-- For every Z position involved, add the intercepted X position in the table
|
||||||
|
table.insert(bounds[z], a*z+b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
i1 = i2
|
i1 = i2
|
||||||
end
|
end
|
||||||
for x=xmin, xmax do
|
|
||||||
-- Now sort the bounds list
|
|
||||||
local xlist = bounds[x]
|
|
||||||
table.sort(xlist)
|
|
||||||
local c = math.floor(#xlist/2)
|
|
||||||
for l=1, c do
|
|
||||||
-- Take pairs of Z coordinates: all positions between them belong to the polygon.
|
|
||||||
local zmin = math.max(math.floor(xlist[l*2-1])+1, minp.z)
|
|
||||||
local zmax = math.min(math.floor(xlist[l*2]), maxp.z)
|
|
||||||
local i = (x-minp.x) * chulens + (zmin-minp.z) + 1
|
|
||||||
for z=zmin, zmax do
|
for z=zmin, zmax do
|
||||||
|
-- Now sort the bounds list
|
||||||
|
local zlist = bounds[z]
|
||||||
|
table.sort(zlist)
|
||||||
|
local c = math.floor(#zlist/2)
|
||||||
|
for l=1, c do
|
||||||
|
-- Take pairs of X coordinates: all positions between them belong to the polygon.
|
||||||
|
local xmin = math.max(math.floor(zlist[l*2-1])+1, minp.x)
|
||||||
|
local xmax = math.min(math.floor(zlist[l*2]), maxp.x)
|
||||||
|
local i = (z-minp.z) * chulens + (xmin-minp.x) + 1
|
||||||
|
for x=xmin, xmax do
|
||||||
-- Fill the map at these places
|
-- Fill the map at these places
|
||||||
polygons[i] = polygon
|
polygons[i] = polygon
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
@ -47,7 +47,8 @@ mapgen_rivers.sea_level = get_settings('sea_level', 'int', 1)
|
|||||||
mapgen_rivers.min_catchment = get_settings('min_catchment', 'float', 25)
|
mapgen_rivers.min_catchment = get_settings('min_catchment', 'float', 25)
|
||||||
mapgen_rivers.max_catchment = get_settings('max_catchment', 'float', 40000)
|
mapgen_rivers.max_catchment = get_settings('max_catchment', 'float', 40000)
|
||||||
mapgen_rivers.riverbed_slope = get_settings('riverbed_slope', 'float', 0.4) * mapgen_rivers.blocksize
|
mapgen_rivers.riverbed_slope = get_settings('riverbed_slope', 'float', 0.4) * mapgen_rivers.blocksize
|
||||||
--mapgen_rivers.distort = get_settings('distort', 'bool', true) To be implemented: should be possible to disable distorsion
|
mapgen_rivers.distort = get_settings('distort', 'bool', true)
|
||||||
|
mapgen_rivers.biomes = get_settings('biomes', 'bool', true)
|
||||||
mapgen_rivers.glaciers = get_settings('glaciers', 'bool', true)
|
mapgen_rivers.glaciers = get_settings('glaciers', 'bool', true)
|
||||||
mapgen_rivers.glacier_factor = get_settings('glacier_factor', 'float', 8)
|
mapgen_rivers.glacier_factor = get_settings('glacier_factor', 'float', 8)
|
||||||
mapgen_rivers.elevation_chill = get_settings('elevation_chill', 'float', 0.25)
|
mapgen_rivers.elevation_chill = get_settings('elevation_chill', 'float', 0.25)
|
||||||
|
11
settings.py
Normal file
11
settings.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
def read_config_file(fname):
|
||||||
|
settings = {}
|
||||||
|
|
||||||
|
with open(fname, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
slist = line.split('=', 1)
|
||||||
|
if len(slist) >= 2:
|
||||||
|
prefix, suffix = slist
|
||||||
|
settings[prefix.strip()] = suffix.strip()
|
||||||
|
|
||||||
|
return settings
|
14
terrain_default.conf
Normal file
14
terrain_default.conf
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
mapsize = 1000
|
||||||
|
scale = 400
|
||||||
|
vscale = 300
|
||||||
|
offset = 0
|
||||||
|
persistence = 0.6
|
||||||
|
lacunarity = 2.0
|
||||||
|
|
||||||
|
K = 1
|
||||||
|
m = 0.35
|
||||||
|
d = 0.8
|
||||||
|
sea_level = 0
|
||||||
|
|
||||||
|
time = 10
|
||||||
|
niter = 10
|
@ -7,24 +7,48 @@ from erosion import EvolutionModel
|
|||||||
import bounds
|
import bounds
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import settings
|
||||||
|
|
||||||
# Always place in this script's parent directory
|
# Always place in this script's parent directory
|
||||||
os.chdir(os.path.dirname(sys.argv[0]))
|
os.chdir(os.path.dirname(sys.argv[0]))
|
||||||
argc = len(sys.argv)
|
argc = len(sys.argv)
|
||||||
|
|
||||||
if argc > 1:
|
params = {}
|
||||||
mapsize = int(sys.argv[1])
|
|
||||||
else:
|
if argc > 1:
|
||||||
mapsize = 400
|
if os.path.isfile(sys.argv[1]):
|
||||||
|
params = settings.read_config_file(sys.argv[1])
|
||||||
|
else:
|
||||||
|
mapsize = int(sys.argv[1])
|
||||||
|
|
||||||
|
def get_setting(name, default):
|
||||||
|
if name in params:
|
||||||
|
return params[name]
|
||||||
|
return default
|
||||||
|
|
||||||
|
mapsize = int(get_setting('mapsize', 400))
|
||||||
|
scale = float(get_setting('scale', 200.0))
|
||||||
|
vscale = float(get_setting('vscale', 200.0))
|
||||||
|
offset = float(get_setting('offset', 0.0))
|
||||||
|
persistence = float(get_setting('persistence', 0.5))
|
||||||
|
lacunarity = float(get_setting('lacunarity', 2.0))
|
||||||
|
|
||||||
|
K = float(get_setting('K', 1.0))
|
||||||
|
m = float(get_setting('m', 0.35))
|
||||||
|
d = float(get_setting('d', 1.0))
|
||||||
|
sea_level = float(get_setting('sea_level', 0.0))
|
||||||
|
flex_radius = float(get_setting('flex_radius', 20.0))
|
||||||
|
|
||||||
|
time = float(get_setting('time', 10.0))
|
||||||
|
niter = int(get_setting('niter', 10))
|
||||||
|
|
||||||
scale = mapsize / 2
|
|
||||||
n = np.zeros((mapsize+1, mapsize+1))
|
n = np.zeros((mapsize+1, mapsize+1))
|
||||||
|
|
||||||
# Set noise parameters
|
# Set noise parameters
|
||||||
params = {
|
params = {
|
||||||
"octaves" : int(np.ceil(np.log2(mapsize)))+1,
|
"octaves" : int(np.ceil(np.log2(mapsize)))+1,
|
||||||
"persistence" : 0.5,
|
"persistence" : persistence,
|
||||||
"lacunarity" : 2.,
|
"lacunarity" : lacunarity,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine noise offset randomly
|
# Determine noise offset randomly
|
||||||
@ -36,36 +60,28 @@ for x in range(mapsize+1):
|
|||||||
for y in range(mapsize+1):
|
for y in range(mapsize+1):
|
||||||
n[x,y] = noise.snoise2(x/scale + xbase, y/scale + ybase, **params)
|
n[x,y] = noise.snoise2(x/scale + xbase, y/scale + ybase, **params)
|
||||||
|
|
||||||
nn = n*mapsize/5 + mapsize/20
|
nn = n*vscale + offset
|
||||||
|
|
||||||
# Initialize landscape evolution model
|
# Initialize landscape evolution model
|
||||||
print('Initializing model')
|
print('Initializing model')
|
||||||
model = EvolutionModel(nn, K=1, m=0.35, d=1, sea_level=0)
|
model = EvolutionModel(nn, K=1, m=0.35, d=1, sea_level=0, flex_radius=flex_radius)
|
||||||
|
|
||||||
|
dt = time/niter
|
||||||
|
|
||||||
# Run the model's processes: the order in which the processes are run is arbitrary and could be changed.
|
# Run the model's processes: the order in which the processes are run is arbitrary and could be changed.
|
||||||
print('Flow calculation 1')
|
print('Initial flow calculation')
|
||||||
model.calculate_flow()
|
model.calculate_flow()
|
||||||
|
|
||||||
print('Advection 1')
|
for i in range(niter):
|
||||||
model.advection(2)
|
print('Iteration {:d} of {:d}'.format(i+1, niter))
|
||||||
|
print('Diffusion')
|
||||||
print('Isostatic equilibration 1')
|
model.diffusion(dt)
|
||||||
model.adjust_isostasy()
|
print('Advection')
|
||||||
|
model.advection(dt)
|
||||||
print('Flow calculation 2')
|
print('Isostatic equilibration')
|
||||||
model.calculate_flow()
|
model.adjust_isostasy()
|
||||||
|
print('Flow calculation')
|
||||||
print('Diffusion')
|
model.calculate_flow()
|
||||||
model.diffusion(4)
|
|
||||||
|
|
||||||
print('Advection 2')
|
|
||||||
model.advection(2)
|
|
||||||
|
|
||||||
print('Isostatic equilibration 2')
|
|
||||||
model.adjust_isostasy()
|
|
||||||
|
|
||||||
print('Flow calculation 3')
|
|
||||||
model.calculate_flow()
|
|
||||||
|
|
||||||
print('Done')
|
print('Done')
|
||||||
|
|
||||||
|
14
view_map.py
14
view_map.py
@ -5,21 +5,21 @@ import zlib
|
|||||||
import matplotlib.colors as mcol
|
import matplotlib.colors as mcol
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
def view_map(dem, lakes, rivers):
|
def view_map(dem, lakes, rivers, scale):
|
||||||
plt.subplot(1,3,1)
|
plt.subplot(1,3,1)
|
||||||
plt.pcolormesh(dem, cmap='viridis')
|
plt.pcolormesh(np.arange(dem.shape[0]+1)*scale, np.arange(dem.shape[1]+1)*scale, dem, cmap='viridis')
|
||||||
plt.gca().set_aspect('equal', 'box')
|
plt.gca().set_aspect('equal', 'box')
|
||||||
plt.colorbar(orientation='horizontal')
|
plt.colorbar(orientation='horizontal')
|
||||||
plt.title('Raw elevation')
|
plt.title('Raw elevation')
|
||||||
|
|
||||||
plt.subplot(1,3,2)
|
plt.subplot(1,3,2)
|
||||||
plt.pcolormesh(lakes, cmap='viridis')
|
plt.pcolormesh(np.arange(lakes.shape[0]+1)*scale, np.arange(lakes.shape[1]+1)*scale, lakes, cmap='viridis')
|
||||||
plt.gca().set_aspect('equal', 'box')
|
plt.gca().set_aspect('equal', 'box')
|
||||||
plt.colorbar(orientation='horizontal')
|
plt.colorbar(orientation='horizontal')
|
||||||
plt.title('Lake surface elevation')
|
plt.title('Lake surface elevation')
|
||||||
|
|
||||||
plt.subplot(1,3,3)
|
plt.subplot(1,3,3)
|
||||||
plt.pcolormesh(rivers, cmap='Blues', norm=mcol.LogNorm())
|
plt.pcolormesh(np.arange(rivers.shape[0]+1)*scale, np.arange(rivers.shape[1]+1)*scale, rivers, cmap='Blues', norm=mcol.LogNorm())
|
||||||
plt.gca().set_aspect('equal', 'box')
|
plt.gca().set_aspect('equal', 'box')
|
||||||
plt.colorbar(orientation='horizontal')
|
plt.colorbar(orientation='horizontal')
|
||||||
plt.title('Rivers flux')
|
plt.title('Rivers flux')
|
||||||
@ -29,8 +29,12 @@ def view_map(dem, lakes, rivers):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
scale = 1
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
os.chdir(sys.argv[1])
|
os.chdir(sys.argv[1])
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
scale = int(sys.argv[2])
|
||||||
|
|
||||||
def load_map(name, dtype, shape):
|
def load_map(name, dtype, shape):
|
||||||
dtype = np.dtype(dtype)
|
dtype = np.dtype(dtype)
|
||||||
@ -45,4 +49,4 @@ if __name__ == "__main__":
|
|||||||
lakes = load_map('lakes', '>i2', shape)
|
lakes = load_map('lakes', '>i2', shape)
|
||||||
rivers = load_map('rivers', '>u4', shape)
|
rivers = load_map('rivers', '>u4', shape)
|
||||||
|
|
||||||
view_map(dem, lakes, rivers)
|
view_map(dem, lakes, rivers, scale)
|
||||||
|
Reference in New Issue
Block a user