Skip to content

Commit a230771

Browse files
committed
Refined mountain-levels.
Altitude-factor for temperature-calculation makes use of the new levels. River-generation makes use of the new levels. Ancient map-generation makes use of the new levels.
1 parent 5b9b83b commit a230771

File tree

5 files changed

+40
-29
lines changed

5 files changed

+40
-29
lines changed

worldengine/drawing_functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ def _find_mountains_mask(world, factor):
100100
_mask = numpy.zeros((factor * world.height, factor * world.width), dtype=float)
101101
for y in range(factor * world.height):
102102
for x in range(factor * world.width):
103-
if world.is_mountain((int(x / factor), int(y / factor))):
103+
if world.is_low_mountain((int(x / factor), int(y / factor)), atleast=True): # maybe use is_medium_mountain()?
104104
v = len(world.tiles_around((int(x / factor), int(y / factor)),
105105
radius=3,
106-
predicate=world.is_mountain))
106+
predicate=lambda pos: world.is_low_mountain(pos, atleast=True)))
107107
if v > 32:
108108
_mask[y, x] = v / 4.0 # force conversion to float, Python 2 will *not* do it automatically
109109
return _mask

worldengine/generation.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,14 @@ def initialize_ocean_and_thresholds(world, ocean_level=1.0):
105105
"""
106106
e = world.elevation['data']
107107
ocean = fill_ocean(e, ocean_level)
108-
pl = find_threshold_f(e, 0.70, ocean=ocean) # the highest x% of land are declared plains
109-
hl = find_threshold_f(e, 0.35, ocean=ocean) # the highest x% are declared hills
110-
ml = find_threshold_f(e, 0.10, ocean=ocean) # the highest x% are declared low mountains
111-
mml = find_threshold_f(e, 0.06, ocean=ocean) # the highest x% are declared medium mountains
112-
hml = find_threshold_f(e, 0.02, ocean=ocean) # the highest x% are declared high mountains
108+
109+
# values chosen to emulate the exponential behavior seen here:
110+
# http://www.ngdc.noaa.gov/mgg/global/etopo1_surface_histogram.html
111+
pl = find_threshold_f(e, 0.95, ocean=ocean) # the highest x% of land are declared plains; save some for beaches (?)
112+
hl = find_threshold_f(e, 0.50, ocean=ocean) # the highest x% are declared hills
113+
ml = find_threshold_f(e, 0.25, ocean=ocean) # the highest x% are declared low mountains
114+
mml = find_threshold_f(e, 0.12, ocean=ocean) # the highest x% are declared medium mountains
115+
hml = find_threshold_f(e, 0.06, ocean=ocean) # the highest x% are declared high mountains
113116
e_th = [('sea', ocean_level),
114117
('plain', pl),
115118
('hill', hl),

worldengine/simulations/erosion.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,7 @@ def river_sources(world, water_flow, water_path):
152152
while not neighbour_seed_found:
153153

154154
# have we found a seed?
155-
if world.is_mountain((cx, cy)) and \
156-
water_flow[cy, cx] >= RIVER_TH:
157-
155+
if world.is_low_mountain((cx, cy), atleast=True) and water_flow[cy, cx] >= RIVER_TH:
158156
# try not to create seeds around other seeds
159157
for seed in river_source_list:
160158
sx, sy = seed

worldengine/simulations/temperature.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ def is_applicable(world):
1010
return not world.has_temperature()
1111

1212
def execute(self, world, seed):
13-
e = world.elevation['data']
14-
ml = world.start_mountain_th() # returns minimum elevation value for mountains (i.e. hills)
1513
ocean = world.ocean
1614

17-
t = self._calculate(world, seed, e, ml)
15+
t = self._calculate(world, seed)
1816
t_th = [
1917
('polar', find_threshold_f(t, world.temps[0], ocean)),
2018
('alpine', find_threshold_f(t, world.temps[1], ocean)),
@@ -27,13 +25,18 @@ def execute(self, world, seed):
2725
world.set_temperature(t, t_th)
2826

2927
@staticmethod
30-
def _calculate(world, seed, elevation, mountain_level):
28+
def _calculate(world, seed):
3129
width = world.width
3230
height = world.height
31+
e = world.elevation['data']
32+
mountain_level = world.start_mountain_th() # returns minimum elevation value for mountains (i.e. hills)
33+
highest_mountain_level = e.max() # world.level_of_mountain(numpy.unravel_index(e.argmax(), e.shape)) # height of the highest point relative to mountain_level
3334

3435
rng = numpy.random.RandomState(seed) # create our own random generator
3536
base = rng.randint(0, 4096)
3637
temp = numpy.zeros((height, width), dtype=float)
38+
39+
min_altitude_factor = 0.3 # used for the top of the highest mountain; must be in [0, 1]
3740

3841
'''
3942
Set up variables to take care of some orbital parameters:
@@ -89,13 +92,8 @@ def _calculate(world, seed, elevation, mountain_level):
8992
base=base) * (border - x) / border)
9093

9194
t = (latitude_factor * 12 + n * 1) / 13.0 / distance_to_sun
92-
if elevation[y, x] > mountain_level: # vary temperature based on height
93-
if elevation[y, x] > (mountain_level + 29):
94-
altitude_factor = 0.033
95-
else:
96-
altitude_factor = 1.00 - (
97-
float(elevation[y, x] - mountain_level) / 30)
98-
t *= altitude_factor
99-
temp[y, x] = t
95+
96+
# vary temperature based on height
97+
temp[y, x] = t * numpy.interp(e[y, x], [mountain_level, highest_mountain_level], [1.00, min_altitude_factor])
10098

10199
return temp

worldengine/world.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,35 +430,47 @@ def is_mountain(self, pos): # general test
430430
x, y = pos
431431
return mountain_level <= self.elevation['data'][y, x]
432432

433-
def is_hill(self, pos):
433+
def is_hill(self, pos, atleast=False):
434434
if self.ocean[pos[1], pos[0]]:
435435
return False
436436
hill_level = self.elevation['thresholds'][2][1]
437437
low_mountain_level = self.elevation['thresholds'][3][1]
438438
x, y = pos
439-
return hill_level <= self.elevation['data'][y, x] < low_mountain_level
439+
if atleast:
440+
return hill_level <= self.elevation['data'][y, x]
441+
else:
442+
return hill_level <= self.elevation['data'][y, x] < low_mountain_level
440443

441-
def is_low_mountain(self, pos):
444+
def is_low_mountain(self, pos, atleast=False):
442445
if self.ocean[pos[1], pos[0]]:
443446
return False
444447
low_mountain_level = self.elevation['thresholds'][3][1]
445448
mountain_level = self.elevation['thresholds'][4][1]
446449
x, y = pos
447-
return low_mountain_level <= self.elevation['data'][y, x] < mountain_level
450+
if atleast:
451+
return low_mountain_level <= self.elevation['data'][y, x]
452+
else:
453+
return low_mountain_level <= self.elevation['data'][y, x] < mountain_level
448454

449-
def is_medium_mountain(self, pos):
455+
def is_medium_mountain(self, pos, atleast=False):
450456
if self.ocean[pos[1], pos[0]]:
451457
return False
452458
mountain_level = self.elevation['thresholds'][4][1]
453459
high_mountain_level = self.elevation['thresholds'][5][1]
454460
x, y = pos
455-
return mountain_level <= self.elevation['data'][y, x] < high_mountain_level
461+
if atleast:
462+
return mountain_level <= self.elevation['data'][y, x]
463+
else:
464+
return mountain_level <= self.elevation['data'][y, x] < high_mountain_level
456465

457-
def is_high_mountain(self, pos):
466+
def is_high_mountain(self, pos, atleast=False):
467+
# atleast is not used here (there is no higher threshold anyway); it is there to give all functions of this type the same signature
458468
if self.ocean[pos[1], pos[0]]:
459469
return False
460470
high_mountain_level = self.elevation['thresholds'][5][1]
461471
x, y = pos
472+
if atleast:
473+
pass
462474
return high_mountain_level <= self.elevation['data'][y, x]
463475

464476
def level_of_mountain(self, pos):

0 commit comments

Comments
 (0)