-
Notifications
You must be signed in to change notification settings - Fork 51
Open
Description
I got this error when generating noise
Traceback (most recent call last):
File "c:/Software/Test Software/PerlinNoise.py", line 93, in <module>
noise = terrain.generate_fractal_noise_2d((100,100),(10,10),3)
File "c:/Software/Test Software/PerlinNoise.py", line 85, in generate_fractal_noise_2d
noise += amplitude * self.generate_perlin_noise_2d(shape, (int(frequency*res[0]), int(frequency*res[1])))
File "c:/Software/Test Software/PerlinNoise.py", line 69, in generate_perlin_noise_2d
n00 = np.sum(grid * g00, 2)
ValueError: operands could not be broadcast together with shapes (100,100,2) (80,80,2)
I realized it was due to this line
delta = (res[0] / shape[0], res[1] / shape[1])
d = (shape[0] // res[0], shape[1] // res[1])
grid = np.mgrid[0:res[0]:delta[0],0:res[1]:delta[1]].transpose(1, 2, 0) % 1
# Gradients
angles = 2*np.pi*self.random.rand(res[0]+1, res[1]+1)
gradients = np.dstack((np.cos(angles), np.sin(angles)))
g00 = gradients[0:-1,0:-1].repeat(d[0], 0).repeat(d[1], 1)
g10 = gradients[1:,0:-1].repeat(d[0], 0).repeat(d[1], 1)
g01 = gradients[0:-1,1:].repeat(d[0], 0).repeat(d[1], 1)
g11 = gradients[1:,1:].repeat(d[0], 0).repeat(d[1], 1)
Grid must be a integer multiple of the gradiant size when repeating the gradient or else the sizes will not line up.
for the above example the shape of the grid was (100, 100, 2)
and the shape of g00 was (80, 80, 2)
. so they were not able to be broadcast by the np.sum function.
This was my fix
def generate_perlin_noise_2d(self,shape, res):
def f(t):
return 6*t**5 - 15*t**4 + 10*t**3
delta = (res[0] / shape[0], res[1] / shape[1])
d = (shape[0] // res[0], shape[1] // res[1])
grid = np.mgrid[0:res[0]:delta[0],0:res[1]:delta[1]].transpose(1, 2, 0) % 1
# Gradients
angles = 2*np.pi*self.random.rand(res[0]+1, res[1]+1)
gradients = np.dstack((np.cos(angles), np.sin(angles)))
if d[0]*delta[0] != 1:
d = (d[0] + 1,d[1])
if d[1]*delta[1] != 1:
d = (d[0],d[1] + 1)
g00 = gradients[0:-1,0:-1].repeat(d[0], 0).repeat(d[1], 1)
g10 = gradients[1:,0:-1].repeat(d[0], 0).repeat(d[1], 1)
g01 = gradients[0:-1,1:].repeat(d[0], 0).repeat(d[1], 1)
g11 = gradients[1:,1:].repeat(d[0], 0).repeat(d[1], 1)
# Ramps
n00 = np.sum(grid * g00[:len(grid),:len(grid[0])], 2)
n10 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1])) * g10[:len(grid),:len(grid[0])], 2)
n01 = np.sum(np.dstack((grid[:,:,0], grid[:,:,1]-1)) * g01[:len(grid),:len(grid[0])], 2)
n11 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1]-1)) * g11[:len(grid),:len(grid[0])], 2)
# Interpolation
t = f(grid)
n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10
n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11
return np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1)
The idea was just to repeat one more time then slice the matrix for the sum.
This way any number should be able to be entered and there are still no loops.
I don't know if this is even an issue for most people, I just wanted to put it here.
Metadata
Metadata
Assignees
Labels
No labels