58 lines
1.3 KiB
Python
58 lines
1.3 KiB
Python
|
import numpy as np
|
||
|
import matplotlib.pyplot as plt
|
||
|
|
||
|
# Generate a height map using Perlin noise
|
||
|
def generate_perlin_noise(size, scale, seed=None):
|
||
|
if seed:
|
||
|
np.random.seed(seed)
|
||
|
|
||
|
def fade(t):
|
||
|
return 6 * t**5 - 15 * t**4 + 10 * t**3
|
||
|
|
||
|
def lerp(a, b, t):
|
||
|
return a + t * (b - a)
|
||
|
|
||
|
def gradient(h, x, y):
|
||
|
vectors = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]])
|
||
|
g = vectors[h % 4]
|
||
|
return g[:, :, 0] * x + g[:, :, 1] * y
|
||
|
|
||
|
lin = np.linspace(0, scale, size, endpoint=False)
|
||
|
x, y = np.meshgrid(lin, lin)
|
||
|
|
||
|
p = np.arange(256, dtype=int)
|
||
|
np.random.shuffle(p)
|
||
|
p = np.stack([p, p]).flatten()
|
||
|
|
||
|
xi = x.astype(int) & 255
|
||
|
yi = y.astype(int) & 255
|
||
|
|
||
|
xf = x - xi
|
||
|
yf = y - yi
|
||
|
|
||
|
u = fade(xf)
|
||
|
v = fade(yf)
|
||
|
|
||
|
n00 = gradient(p[p[xi] + yi], xf, yf)
|
||
|
n01 = gradient(p[p[xi] + yi + 1], xf, yf - 1)
|
||
|
n11 = gradient(p[p[xi + 1] + yi + 1], xf - 1, yf - 1)
|
||
|
n10 = gradient(p[p[xi + 1] + yi], xf - 1, yf)
|
||
|
|
||
|
x1 = lerp(n00, n10, u)
|
||
|
x2 = lerp(n01, n11, u)
|
||
|
|
||
|
return lerp(x1, x2, v)
|
||
|
|
||
|
# Parameters for the height map
|
||
|
size = 512
|
||
|
scale = 100
|
||
|
|
||
|
# Generate the height map
|
||
|
height_map = generate_perlin_noise(size, scale, seed=42)
|
||
|
|
||
|
# Plot the height map
|
||
|
plt.imshow(height_map, cmap='gray')
|
||
|
plt.axis('off')
|
||
|
plt.savefig('heightmap.png', bbox_inches='tight', pad_inches=0)
|
||
|
plt.show()
|