Python 柏林噪声问题:结果中清晰可见的线条

Python 柏林噪声问题:结果中清晰可见的线条,python,numpy,perlin-noise,Python,Numpy,Perlin Noise,我一直在用python实现perlin noice生成器。 除了结果中清晰可见的线条外,它工作得非常好 问题似乎与我在X方向的渐变之间切换的位置有关 代码如下: from random import randint, seed from PIL import Image from numpy import asarray, interp, uint8 seed(1) gradients = [] for x in range(20): gradients.append([])

我一直在用python实现perlin noice生成器。 除了结果中清晰可见的线条外,它工作得非常好

问题似乎与我在X方向的渐变之间切换的位置有关

代码如下:

from random import randint, seed
from PIL import Image
from numpy import asarray, interp, uint8

seed(1)
gradients = []
for x in range(20):
    gradients.append([])
    for y in range(20):
        gradients[x].append([randint(-1,1), randint(-1,1)])

def getInfluenceValue(x,y,Xgrad,Ygrad):
    return ((gradients[Xgrad][Ygrad][0] * (x-Xgrad)) + (gradients[Xgrad][Ygrad][1]*(y-Ygrad)))
    
def lerp(v0,v1,t):
    return (1 - t) * v0 + t * v1;

def fade(t):
    return 3*pow(t,2) - 2*pow(t,3)

def perlin(x, y):
    X0 = int(x) 
    Y0 = int(y)
    X1 = X0+1
    Y1 = Y0+1
    sx = fade(float(x) - float(X0));
    sy = fade(float(y) - float(Y0));
    topLeftDot = getInfluenceValue(x,y,X0,Y1)
    topRightDot = getInfluenceValue(x,y,X1,Y1) 
    bottomLeftDot = getInfluenceValue(x,y,X0,Y0)
    bottomRightDot = getInfluenceValue(x,y,X1,Y0)

    return lerp(lerp(topLeftDot, topRightDot, sx), lerp(bottomLeftDot, bottomRightDot, sx), sy)

tmp_list = []
for x in range(1000):
    tmp_list.append([])    
    for y in range(1000):
        tmp_list[x].append(perlin(x/100.0, y/100.0))

data = asarray(tmp_list)
rescaled = interp(data, (data.min(), data.max()), (0, 255)).astype(uint8)
Image.fromarray(rescaled).save('test.png')
结果如下:

我尝试过更换lerp功能,并使用了其他淡入淡出功能。但问题依然存在。这是怎么回事


另外,我在stackoverflow上看到了关于柏林噪声产生的“块状”结果的其他问题,但由于该结果似乎仅在1个方向/维度上“块状”,我认为该问题与这些问题无关。

回答您的问题,我不确定这是否是整个问题,但我确实看到了一个错误。在X中,沿着sx从X0移动到X1。但在Y中,你可以从Y1到Y0。在topLeftDot bottomRightDot变量中交换Y1/Y0应该可以解决这个问题。或者,切换哪些变量位于lerp返回线的哪些部分。如果这不能解决问题,请尝试反转X0/X1。我想知道为什么你的图像显示的是X轴的不连续性而不是Y轴的不连续性

另外,我看到您正在使用整数转换将x、y转换为X0和Y0。这对正数很有效,但对负数可能不起作用。有关更多信息,请参阅


最后,我的一般建议是:Perlin是一种处理噪声的老方法,它往往会产生非常网格对齐的结果。一旦你的噪音正常工作,或者如果你看到柏林噪音的其他图像,它可能会变得很明显(柏林是第一排)。这可能是一个有益的编程练习,但如果您要比编程练习更深入,那么我建议您编码或使用良好的单纯形或单纯形相关噪声实现。有关在柏林实现二维单纯形噪波的详细信息,或者如果您希望在项目中使用易于导入的单纯形相关噪波,请参阅。

看起来唯一的问题是,在Y插值中,上下颠倒。 这会产生垂直带,因为按照代码的设置方式,Y是水平轴

将return语句切换为先“底部”后“顶部”:

生成以下柏林噪波图像:


您基本上是在请求他人帮助调试代码。如果您至少添加了代码所做(或正在尝试做)的概述,这会很有帮助。谢谢您,正如您所说的,切换Y变量解决了这个问题,似乎我通过将左下角视为(0,0)而犯了一个错误。是的,这只是一个编程练习。我已经实现了用于地形生成的柏林噪声和菱形正方形算法。并且正在考虑下一步实施simplex noice。因此,我们非常感谢与simplex noice的链接。
return lerp(lerp(bottomLeftDot, bottomRightDot, sx), lerp(topLeftDot, topRightDot, sx), sy)