mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2024-11-11 05:10:23 +01:00
75 lines
2.1 KiB
Python
75 lines
2.1 KiB
Python
import numpy as np
|
|
|
|
def make_bounds(dirs, rivers):
|
|
"""
|
|
Give an array of all horizontal and vertical bounds
|
|
"""
|
|
|
|
(Y, X) = dirs.shape
|
|
bounds_h = np.zeros((Y, X-1), dtype='i4')
|
|
bounds_v = np.zeros((Y-1, X), dtype='i4')
|
|
|
|
bounds_v += (rivers * (dirs==1))[:-1,:]
|
|
bounds_h += (rivers * (dirs==2))[:,:-1]
|
|
bounds_v -= (rivers * (dirs==3))[1:,:]
|
|
bounds_h -= (rivers * (dirs==4))[:,1:]
|
|
|
|
return bounds_h, bounds_v
|
|
|
|
def get_fixed(dirs):
|
|
"""
|
|
Give the list of points that should not be twisted
|
|
"""
|
|
|
|
borders = np.zeros(dirs.shape, dtype='?')
|
|
borders[-1,:] |= dirs[-1,:]==1
|
|
borders[:,-1] |= dirs[:,-1]==2
|
|
borders[0,:] |= dirs[0,:]==3
|
|
borders[:,0] |= dirs[:,0]==4
|
|
|
|
donors = np.zeros(dirs.shape, dtype='?')
|
|
donors[1:,:] |= dirs[:-1,:]==1
|
|
donors[:,1:] |= dirs[:,:-1]==2
|
|
donors[:-1,:] |= dirs[1:,:]==3
|
|
donors[:,:-1] |= dirs[:,1:]==4
|
|
return borders | ~donors
|
|
|
|
def twist(bounds_x, bounds_y, fixed, d=0.1, n=5):
|
|
"""
|
|
Twist the grid (define an offset for every node). Model river bounds as if they were elastics.
|
|
Smoothes preferentially big rivers.
|
|
"""
|
|
|
|
moveable = ~fixed
|
|
|
|
(Y, X) = fixed.shape
|
|
offset_x = np.zeros((Y, X))
|
|
offset_y = np.zeros((Y, X))
|
|
|
|
for i in range(n):
|
|
force_long = np.abs(bounds_x) * (1+np.diff(offset_x, axis=1))
|
|
force_trans = np.abs(bounds_y) * np.diff(offset_x, axis=0)
|
|
|
|
force_x = np.zeros((Y, X))
|
|
force_x[:,:-1] = force_long
|
|
force_x[:,1:] -= force_long
|
|
force_x[:-1,:]+= force_trans
|
|
force_x[1:,:] -= force_trans
|
|
|
|
force_long = np.abs(bounds_y) * (1+np.diff(offset_y, axis=0))
|
|
force_trans = np.abs(bounds_x) * np.diff(offset_y, axis=1)
|
|
|
|
force_y = np.zeros((Y, X))
|
|
force_y[:-1,:] = force_long
|
|
force_y[1:,:] -= force_long
|
|
force_y[:,:-1]+= force_trans
|
|
force_y[:,1:] -= force_trans
|
|
|
|
length = np.hypot(force_x, force_y)
|
|
length[length==0] = 1
|
|
coeff = d / length * moveable # Normalize, take into account the direction only
|
|
offset_x += force_x * coeff
|
|
offset_y += force_y * coeff
|
|
|
|
return offset_x, offset_y
|