from random import random, randrange
from math import floor, sqrt
from matplotlib import cm, pyplot as plt
from mpl_toolkits.mplot3d.axes3d import *
import numpy as np
TABLE_SIZE = 255
gradients = []
permutations = []
for i in range( TABLE_SIZE ):
x = random() * 2 - 1
y = random() * 2 - 1
l = sqrt( x * x + y * y )
x /= l
y /= l
gradients.append( x )
gradients.append( y )
permutations.append( i )
for i in range( TABLE_SIZE ):
t = permutations[ i ]
idx = randrange( TABLE_SIZE )
permutations[ i ] = permutations[ idx ]
permutations[ idx ] = t
print( permutations )
for i in range( TABLE_SIZE ):
permutations.append( permutations[ i ] )
def hash_pos( x, y ):
return permutations[ ( permutations[ x % TABLE_SIZE ] + y ) % TABLE_SIZE ]
def smooth_step( x ):
return ( x ** 3 ) * ( x * (x * 6 - 15 ) + 10 )
def linterpolate( a, b, weight ):
return a + weight * ( b - a )
def perlin_at( x, y ):
lx = floor( x )
ty = floor( y )
rx = ( lx + 1 )
by = ( ty + 1 )
xd = x - floor( x )
yd = y - floor( y )
xweight = smooth_step( xd )
yweight = smooth_step( yd )
tl_x = gradients[ 2 * hash_pos( lx, ty ) ]
tl_y = gradients[ 2 * hash_pos( lx, ty ) + 1 ]
tr_x = gradients[ 2 * hash_pos( rx, ty ) ]
tr_y = gradients[ 2 * hash_pos( rx, ty ) + 1 ]
bl_x = gradients[ 2 * hash_pos( lx, by ) ]
bl_y = gradients[ 2 * hash_pos( lx, by ) + 1 ]
br_x = gradients[ 2 * hash_pos( rx, by ) ]
br_y = gradients[ 2 * hash_pos( rx, by ) + 1 ]
ld = xd
rd = xd - 1
td = yd
bd = yd - 1
t = linterpolate( tl_x * ld + tl_y * td, tr_x * rd + tr_y * td, xweight )
b = linterpolate( bl_x * ld + bl_y * bd, br_x * rd + br_y * bd, xweight )
return linterpolate( t, b, yweight )
STEP = 0.10
RANGE = 20
HEIGHT = 0.15
STEPS = floor( RANGE / STEP )
z = []
xi = np.linspace( 0, RANGE, STEPS )
yi = np.linspace( 0, RANGE, STEPS )
for i in xi:
for j in xi:
z.append( perlin_at( i, j ) )
z = np.array( z )
x, y = np.meshgrid( xi, yi )
z = z.reshape( x.shape )
fig = plt.figure()
a = Axes3D( fig )
a.plot_surface( x, y, z, rstride = 1, cstride = 1, cmap = cm.jet, linewidth = 1, antialiased = True )
a.get_proj = lambda: np.dot(Axes3D.get_proj(a), np.diag([1, 1, HEIGHT, 1]))
plt.show()
fig = plt.figure()
a = Axes3D( fig )
a.plot_surface( x, y, z, rstride = 1, cstride = 1, cmap = cm.jet, linewidth = 1, antialiased = True )
a.view_init(azim=0, elev=90)
plt.show()