2017-02-09 1 views
4

Je suis en train de produire du bruit 2D Perlin utilisant numpy, mais au lieu de je reçois quelque chose lisse ceci:génératrices de bruit 2D Perlin avec numpy

my broken perlin noise, with ugly squares everywhere

Bien sûr, je mélange mes dimensions quelque part , probablement quand je combine les quatre gradients ... Mais je ne peux pas le trouver et mon cerveau fond en ce moment. Quelqu'un peut-il m'aider à cerner le problème?

Quoi qu'il en soit, voici le code:

%matplotlib inline 
import numpy as np 
import matplotlib.pyplot as plt 

def perlin(x,y,seed=0): 
    # permutation table 
    np.random.seed(seed) 
    p = np.arange(256,dtype=int) 
    np.random.shuffle(p) 
    p = np.stack([p,p]).flatten() 
    # coordinates of the first corner 
    xi = x.astype(int) 
    yi = y.astype(int) 
    # internal coordinates 
    xf = x - xi 
    yf = y - yi 
    # fade factors 
    u = fade(xf) 
    v = fade(yf) 
    # noise components 
    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) 
    # combine noises 
    x1 = lerp(n00,n10,u) 
    x2 = lerp(n10,n11,u) 
    return lerp(x2,x1,v) 

def lerp(a,b,x): 
    "linear interpolation" 
    return a + x * (b-a) 

def fade(t): 
    "6t^5 - 15t^4 + 10t^3" 
    return 6 * t**5 - 15 * t**4 + 10 * t**3 

def gradient(h,x,y): 
    "grad converts h to the right gradient vector and return the dot product with (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,5,100,endpoint=False) 
y,x = np.meshgrid(lin,lin) 

plt.imshow(perlin(x,y,seed=0)) 
+3

votre interpolation utilise angle 'n10' deux fois et passe sous silence 'n01' –

+0

Bonne prise! Après avoir dormi, j'ai fait deux autres corrections et maintenant ça marche ... en éditant le post original. – tomtom

Répondre

3

Merci à Paul Panzer et une bonne nuit de sommeil, il travaille maintenant ...

def perlin(x,y,seed=0): 
    # permutation table 
    np.random.seed(seed) 
    p = np.arange(256,dtype=int) 
    np.random.shuffle(p) 
    p = np.stack([p,p]).flatten() 
    # coordinates of the top-left 
    xi = x.astype(int) 
    yi = y.astype(int) 
    # internal coordinates 
    xf = x - xi 
    yf = y - yi 
    # fade factors 
    u = fade(xf) 
    v = fade(yf) 
    # noise components 
    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) 
    # combine noises 
    x1 = lerp(n00,n10,u) 
    x2 = lerp(n01,n11,u) # FIX1: I was using n10 instead of n01 
    return lerp(x1,x2,v) # FIX2: I also had to reverse x1 and x2 here 

def lerp(a,b,x): 
    "linear interpolation" 
    return a + x * (b-a) 

def fade(t): 
    "6t^5 - 15t^4 + 10t^3" 
    return 6 * t**5 - 15 * t**4 + 10 * t**3 

def gradient(h,x,y): 
    "grad converts h to the right gradient vector and return the dot product with (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,5,100,endpoint=False) 
x,y = np.meshgrid(lin,lin) # FIX3: I thought I had to invert x and y here but it was a mistake 

plt.imshow(perlin(x,y,seed=2),origin='upper')