Unrelated fun!
In my spare time, I completed a pretty cool erosion function which I would like to keep. It looks like this:
It features a wind/elements based approach which acts to smooth the surface, alongside a rivers-based approach which creates the channels. together they create very realistic models of different features!
This is the river model, and the terrain it is acting on;
These are some examples of erosion creating flat:
and the rest are all images with different random seeds. Very happy with it!
def depo_func(J):
##takes an array of terrain heights and returns the deposition rate
J=np.array(J)
x1=[]
X0=[]
for i in range(len(J)):
for j in range(len(J[0])):
x=[]
if i==0:
x.append(0)
if j==0:
x.append(0)
x.append(J[1,0])
x.append(J[0,1])
elif j==len(J)-1:
x.append(0)
x.append(J[0,j-1])
x.append(J[1,j])
else:
x.append(J[0,j-1])
x.append(J[0,j+1])
x.append(J[1,j])
elif i==len(J)-1:
x.append(0)
if j==0:
x.append(0)
x.append(J[i-1,0])
x.append(J[i,1])
elif j==len(J)-1:
x.append(0)
x.append(J[i,j-1])
x.append(J[i-1,j])
else:
x.append(J[i,j-1])
x.append(J[i,j+1])
x.append(J[i-1,j])
elif j==0:
x.append(0)
x.append(J[i-1,0])
x.append(J[i+1,0])
x.append(J[i,1])
elif j==len(J)-1:
x.append(0)
x.append(J[i-1,j])
x.append(J[i+1,j])
x.append(J[i,j-1])
else:
x.append(J[i,j+1])
x.append(J[i+1,j])
x.append(J[i,j-1])
x.append(J[i-1,j])
X=np.mean(x)
X= X-J[i,j]
X0.append(X)
x1.append(X0)
X0=[]
return(x1)
def erosion_func(J,erosion_rate):
##takes an array of terrain heights and returns the eroded landscape
x1=depo_func(J)
x1=np.array(x1)
J=np.array(J)
o=[]
O=[]
for i in range(len(J)):
for j in range(len(J[0])):
o.append(J[i,j]+x1[i,j]*erosion_rate)
O.append(o)
o=[]
return(O)
def whichdirectionislowest(J,coordinate_storage):
###takes in location in array, and calculates coordinates of lowest neighbour
###returns new coordinates
J=np.array(J)
currentheight=J[coordinate_storage[0],coordinate_storage[1]]
if coordinate_storage[0]==0 or coordinate_storage[1]==0 or coordinate_storage[0]==len(J)-1 or coordinate_storage[1]==len(J)-1:
c=0
else:
removal=0#ticker as to whether we are on the bottom edge
##x is coordinate storage 0, y is coordinate storage 1
##choose the lowest number nearby
lowest=[]
#add 100*X1 to make sure it doesn’t refill places already full
row_1=J[coordinate_storage[0]-1]
row_2=J[coordinate_storage[0]]
row_3=J[coordinate_storage[0]+1]
lowest.append(row_1[coordinate_storage[1]])
lowest.append(row_2[coordinate_storage[1]+1])
lowest.append(row_2[coordinate_storage[1]-1])
lowest.append(row_3[coordinate_storage[1]])
if min(lowest)>currentheight:
c=0
elif lowest[0]==min(lowest):
coordinate_storage=[coordinate_storage[0]-1,coordinate_storage[1]]
elif lowest[1]==min(lowest):
coordinate_storage=[coordinate_storage[0],coordinate_storage[1]+1]
elif lowest[2]==min(lowest):
coordinate_storage=[coordinate_storage[0],coordinate_storage[1]-1]
elif lowest[3]==min(lowest):
coordinate_storage=[coordinate_storage[0]+1,coordinate_storage[1]]
lowest.append(currentheight)
currentheight=min(lowest)
return(coordinate_storage)
J=np.array(J)
##execution
for i in range(100):
print(i)
J=erosion_func(J,0.2)
J=rivererosion(J,0.02)
plt.imshow(J)
plt.contourf(J)
Recent comments