Closed ytgui closed 5 years ago
import math
import random
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def hermite(t):
return t * t * (3 - 2 * t)
def quintic(t):
return t * t * t * (t * (t * 6 - 15) + 10)
def lerp(t, a, b):
assert(0.0 <= t <= 1.0)
t = hermite(t)
return a + t * (b - a)
def normalize(v):
v = np.array(v)
norm = np.linalg.norm(v)
if norm == 0:
return v
return v / norm
class PerlinNoise2D:
def __init__(self, h, w, stride):
self.h = h
self.w = w
self.stride = stride
self.permutation = np.zeros(shape=[h // stride + 1, w // stride + 1, 2])
for iy in range(h // stride + 1):
for ix in range(w // stride + 1):
self.permutation[iy, ix] = normalize(np.random.randn(2))
def __call__(self, x, y):
#
ix0 = x // self.stride
ix1 = (x // self.stride) + 1
iy0 = y // self.stride
iy1 = (y // self.stride) + 1
#
nx0 = self.grid_gradient(ix0, iy0, x, y)
nx1 = self.grid_gradient(ix1, iy0, x, y)
value0 = lerp((x - ix0 * self.stride) / self.stride, nx0, nx1)
#
nx0 = self.grid_gradient(ix0, iy1, x, y)
nx1 = self.grid_gradient(ix1, iy1, x, y)
value1 = lerp((x - ix0 * self.stride) / self.stride, nx0, nx1)
#
return lerp((y - iy0 * self.stride) / self.stride, value0, value1)
def grid_gradient(self, ix, iy, x, y):
dx = (x - ix) / self.stride
dy = (y - iy) / self.stride
dx, dy = normalize([dx, dy])
assert(0.0 <= np.sqrt(dx ** 2 + dy ** 2) <= 1.0 + 1e-3)
return (dx * self.permutation[iy, ix, 0] + dy * self.permutation[iy, ix, 1])
def main_1():
step = 256
h, w = 512, 512
generator = PerlinNoise2D(h, w, step)
terrain = np.zeros(shape=[h, w])
for y in range(h):
for x in range(w):
terrain[y, x] = generator(x, y)
plt.imshow(terrain)
# plt.savefig("perlin/1.png")
fig = plt.figure()
ax = fig.gca(projection='3d')
# Make data.
X = np.linspace(-1, 1, w)
Y = np.linspace(-1, 1, h)
X, Y = np.meshgrid(X, Y)
# Plot the surface.
ax.set_zlim(-2.5, 2.5)
ax.plot_surface(X, Y, terrain, linewidth=0, antialiased=False)
# plt.savefig("perlin/2.png")
plt.show()
if __name__ == "__main__":
main_1()
https://en.wikipedia.org/wiki/Perlin_noise/ https://www.scratchapixel.com/