我正在尝试使用Perlin噪声发生器来制作地图的瓷砖,但我注意到我的噪音太尖锐了,我的意思是,它有太多的高度,没有平坦的地方,而且它们看起来不像山,岛屿,湖泊或任何东西;它们似乎太随意而且有很多峰值.

在问题的最后,需要进行修改才能修复它.

该问题的重要代码是:

1D:

def Noise(self,x):     # I wrote this noise function but it seems too random
    random.seed(x)
    number = random.random()
    if number < 0.5:
        final = 0 - number * 2
    elif number > 0.5:
        final = number * 2
    return final

 def Noise(self,x):     # I found this noise function on the internet
    x = (x<<13) ^ x
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)

2D:

def Noise(self,x,y):     # I wrote this noise function but it seems too random
    n = x + y
    random.seed(n)
    number = random.random()
    if number < 0.5:
        final = 0 - number * 2
    elif number > 0.5:
        final = number * 2
    return final

def Noise(self,y):     # I found this noise function on the internet
    n = x + y * 57
    n = (n<<13) ^ n
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)

我在代码中留下了1D和2D Perlin噪音,因为可能有人对此感兴趣:
(我花了很长时间才找到一些代码,所以我觉得有人会很高兴在这里找到一个例子).
你不需要Matplotlib或NumPy来制造噪音;我只是使用它们制作图表并更好地查看结果.

import random
import matplotlib.pyplot as plt              # To make graphs
from mpl_toolkits.mplot3d import Axes3D      # To make 3D graphs
import numpy as np                           # To make graphs

class D():     # Base of classes D1 and D2
    def Cubic_Interpolate(self,v0,v1,v2,v3,x):
        P = (v3 - v2) - (v0 - v1)
        Q = (v0 - v1) - P
        R = v2 - v0
        S = v1
        return P * x**3 + Q * x**2 + R * x + S

class D1(D):
    def __init__(self,lenght,octaves):
        self.result = self.Perlin(lenght,octaves)

    def Noise(self,x):     # I wrote this noise function but it seems too random
        random.seed(x)
        number = random.random()
        if number < 0.5:
            final = 0 - number * 2
        elif number > 0.5:
            final = number * 2
        return final

    def Noise(self,x):     # I found this noise function on the internet
        x = (x<<13) ^ x
        return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)

    def Perlin(self,octaves):
        result = []
        for x in range(lenght):
            value = 0
            for y in range(octaves):
                frequency = 2 ** y
                amplitude = 0.25 ** y            
                value += self.Interpolate_Noise(x * frequency) * amplitude
            result.append(value)
            print(f"{x} / {lenght} ({x/lenght*100:.2f}%): {round(x/lenght*10) * '#'} {(10-round(x/lenght*10)) * ' '}. Remaining {lenght-x}.")     # I don't use `os.system('cls')` because it slow down the code.
        return result

    def Smooth_Noise(self,x):
        return self.Noise(x) / 2 + self.Noise(x-1) / 4 + self.Noise(x+1) / 4

    def Interpolate_Noise(self,x):
        round_x = round(x)
        frac_x  = x - round_x
        v0 = self.Smooth_Noise(round_x - 1)
        v1 = self.Smooth_Noise(round_x)
        v2 = self.Smooth_Noise(round_x + 1)
        v3 = self.Smooth_Noise(round_x + 2)
        return self.Cubic_Interpolate(v0,frac_x)

    def graph(self,*args):
        plt.plot(np.array(self.result),'-',label = "Line")
        for x in args:
            plt.axhline(y=x,color='r',linestyle='-')    
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.title("Simple Plot")
        plt.legend()
        plt.show()

class D2(D):
    def __init__(self,octaves = 1):

        self.lenght_axes = round(lenght ** 0.5)
        self.lenght = self.lenght_axes ** 2

        self.result = self.Perlin(self.lenght,y):     # I wrote this noise function but it seems too random
        n = x + y
        random.seed(n)
        number = random.random()
        if number < 0.5:
            final = 0 - number * 2
        elif number > 0.5:
            final = number * 2
        return final

    def Noise(self,y):     # I found this noise function on the internet
        n = x + y * 57
        n = (n<<13) ^ n
        return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)

    def Smooth_Noise(self,y):
        corners = (self.Noise(x - 1,y - 1) + self.Noise(x + 1,y - 1) + self.Noise(x - 1,y + 1) + self.Noise(x + 1,y + 1) ) / 16
        sides   = (self.Noise(x - 1,y) + self.Noise(x + 1,y) + self.Noise(x,y - 1)  + self.Noise(x,y + 1) ) /  8
        center  =  self.Noise(x,y) / 4
        return corners + sides + center

    def Interpolate_Noise(self,y):

        round_x = round(x)
        frac_x  = x - round_x

        round_y = round(y)
        frac_y  = y - round_y

        v11 = self.Smooth_Noise(round_x - 1,round_y - 1)
        v12 = self.Smooth_Noise(round_x,round_y - 1)
        v13 = self.Smooth_Noise(round_x + 1,round_y - 1)
        v14 = self.Smooth_Noise(round_x + 2,round_y - 1)
        i1 = self.Cubic_Interpolate(v11,v12,v13,v14,frac_x)

        v21 = self.Smooth_Noise(round_x - 1,round_y)
        v22 = self.Smooth_Noise(round_x,round_y)
        v23 = self.Smooth_Noise(round_x + 1,round_y)
        v24 = self.Smooth_Noise(round_x + 2,round_y)
        i2 = self.Cubic_Interpolate(v21,v22,v23,v24,frac_x)

        v31 = self.Smooth_Noise(round_x - 1,round_y + 1)
        v32 = self.Smooth_Noise(round_x,round_y + 1)
        v33 = self.Smooth_Noise(round_x + 1,round_y + 1)
        v34 = self.Smooth_Noise(round_x + 2,round_y + 1)
        i3 = self.Cubic_Interpolate(v31,v32,v33,v34,frac_x)

        v41 = self.Smooth_Noise(round_x - 1,round_y + 2)
        v42 = self.Smooth_Noise(round_x,round_y + 2)
        v43 = self.Smooth_Noise(round_x + 1,round_y + 2)
        v44 = self.Smooth_Noise(round_x + 2,round_y + 2)
        i4 = self.Cubic_Interpolate(v41,v42,v43,v44,frac_x)

        return self.Cubic_Interpolate(i1,i2,i3,i4,frac_y)

    def Perlin(self,octaves):
        result = []
        for x in range(lenght):
            value = 0
            for y in range(octaves):
                frequency = 2 ** y
                amplitude = 0.25 ** y            
                value += self.Interpolate_Noise(x * frequency,x * frequency) * amplitude
            result.append(value)
            print(f"{x} / {lenght} ({x/lenght*100:.2f}%): {round(x/lenght*10) * '#'} {(10-round(x/lenght*10)) * ' '}. Remaining {lenght-x}.")     # I don't use `os.system('cls')` because it slow down the code.
        return result

    def graph(self,color = 'viridis'):
        # Other colors: https://matplotlib.org/examples/color/colormaps_reference.html
        fig = plt.figure()
        Z = np.array(self.result).reshape(self.lenght_axes,self.lenght_axes)

        ax = fig.add_subplot(1,2,1,projection='3d')
        X = np.arange(self.lenght_axes)
        Y = np.arange(self.lenght_axes)
        X,Y = np.meshgrid(X,Y)        
        d3 = ax.plot_surface(X,Y,Z,rstride=1,cstride=1,cmap=color,linewidth=0,antialiased=False)
        fig.colorbar(d3)

        ax = fig.add_subplot(1,2)
        d2 = ax.imshow(Z,interpolation='none')
        fig.colorbar(d2)

        plt.show()

问题是输出似乎不适合地图.

使用以下命令查看此输出:

test = D2(1000,3)
test.graph()

我正在寻找更顺畅的东西.

也许在二维噪音中很难注意到我在说什么,但在一维中它更容易:

test = D1(1000,3)
test.graph()

来自互联网的噪音功能稍微小一点,频率较低,但它仍然有太多.我正在寻找更顺畅的东西.

这样的事情可能是:

或这个:

P.S:我是根据this pseudocode制作的.

编辑:

pikalek:

即使值较低,它也有峰值,没有曲线或平滑/平坦的线条.

geza:解决方案

感谢geza’s suggestions,我找到了解决问题的方法:

def Perlin(self,lenght_axes,octaves,zoom = 0.01,amplitude_base = 0.5):
    result = []

    for y in range(lenght_axes):
        line = []
        for x in range(lenght_axes):
            value = 0
            for o in range(octaves):
                frequency = 2 ** o
                amplitude = amplitude_base ** o
                value += self.Interpolate_Noise(x * frequency * zoom,y * frequency * zoom) * amplitude
            line.append(value)
        result.append(line)
        print(f"{y} / {lenght_axes} ({y/lenght_axes*100:.2f}%): {round(y/lenght_axes*20) * '#'} {(20-round(y/lenght_axes*20)) * ' '}. Remaining {lenght_axes-y}.")
    return result

其他修改包括:

> Z = np.array(self.result)而不是图函数中的Z = np.array(self.result).reshape(self.lenght_axes,self.lenght_axes).
>在round_x和round_y变量的Interpolate_Noise函数中使用math.floor()(记住导入数学)而不是round().
>修改Noise(第二个)返回行返回(1.0 – ((n *(n * n * 15731 789221)1376312589)& 0x7fffffff)/ 1073741824.0).
D2(10000,10)

现在唯一奇怪的是山(黄色)总是在同一个地方,但我认为这是改变噪音功能中的数字的问题.

解决方法

我在你的代码中发现了这些错误:

>您需要将Interpolate_Noise参数乘以“缩放”到地图中(例如,将x乘以0.01).如果你在1D情况下这样做,你会发现生成的函数已经好多了
>将八度计数从3增加到更大(3个八度音程不会产生太多细节)
>使用振幅0.5 ^八度音程,而不是0.25 ^八度音程(但你可以使用这个参数,所以0.25本身并不坏,但它没有给出太多细节)
>对于2D情况,你需要有2个外环(一个用于水平,一个用于垂直.当然,你仍然需要有八度环).因此,您需要使用水平和垂直位置正确“索引”噪声,而不仅仅是x和x.
>完全去除平滑.柏林噪音不需要它.
> 2D噪声函数有一个错误:它在返回表达式中使用x而不是n
>在三次插值中,使用round而不是math.floor.

这是我的答案,简单的(C)实现Perlin-like(它不是正确的perlin)噪音:https://stackoverflow.com/a/45121786/8157187

如何制作更平滑的Perlin噪音发生器?的更多相关文章

  1. 如何制作更平滑的Perlin噪音发生器?

    我正在尝试使用Perlin噪声发生器来制作地图的瓷砖,但我注意到我的噪音太尖锐了,我的意思是,它有太多的高度,没有平坦的地方,而且它们看起来不像山,岛屿,湖泊或任何东西;它们似乎太随意而且有很多峰值.在问题的最后,需要进行修改才能修复它.该问题的重要代码是:1D:2D:我在代码中留下了1D和2DPerlin噪音,因为可能有人对此感兴趣:(我花了很长时间才找到一些代码,所以我觉得有人会很高兴在这里找

  2. 如何更好地光栅化绘图而不会模糊matplotlib中的标签?

    我通常使用ax.set_rasterized来栅格化图形,以便在以eps格式保存时可以处理透明度,但光栅化也会模糊轴标签和刻度标签,所以有没有办法仅在轴内光栅化贴片而不是比整个数字?或者是否更好地导出具有透明度的eps格式?

  3. 使用Python库绘制共享相同y轴的两个水平条形图

    我想绘制两个共享相同y轴的水平条形图.例如,以下问题显示了如何在R中实现此目的:Twohorizontalbarchartswithsharedaxisinggplot2(similartopopulationpyramid)如何用Python创建类似的情节?上面问题的情节如下:以下是上图中使用的状态列表(y轴):以下是每个州的销售人员数量列表:销售数字可以是随机的.解决方法一般来说,如果您显示的

  4. Python Matplotlib线图与轮廓/ imshow对齐

    如何使用Python和Matplotlib设置一个子图的视觉宽度等于另一个子图的宽度?

随机推荐

  1. 数组 – Perl中有什么神奇的数组?

    在Perldocumentationforreverse中,我发现:“请注意,将数组反转到自身(如@a=reverse@a)将尽可能保留不存在的元素;即对于非魔法数组或具有EXISTS和DELETE方法的绑定数组.什么属性区分神奇和非魔法阵列?解决方法一个神奇的阵列是一个执行它的操作不仅仅是改变内容.只有内置的魔术阵列是@ISA,而且这是非常不明显的.正如句子所暗示的,魔术阵列主要是一个绑定的阵列

  2. perl – 使用“isa”方法的最佳方式?

    什么是“最好的”使用方式“isa()”可靠?解决方法Scalar::Util实现明确更好.它避免了eval{}的开销,它总是导致设置一个附加变量.Scalar::Util实现更容易阅读.如果eval也失败了,我相信发生的是你在树之前向后走到eval之前的状态–这是如何实现复位状态.这带来了额外的故障开销.基准根本不是一个对象对象传递isa检查对象出现故障现象检查测试代码:我使用这是为i486-linux-gnu-thread-multi建立的perl,v5.10.1(*),以及Scalar::Util,1

  3. 在CORE :: GLOBAL中哪些Perl内置函数不能被覆盖?

    解决方法toke.c中任何值为负的值都可以被覆盖;所有其他人可能不会.你可以看源码here.例如,我们来看看第10,396行的waitpid:由于waitpid为负数,因此可能会被覆盖.grep怎么样?这是积极的,所以不能被覆盖.这意味着以下关键字不能被覆盖:chop,defined,delete,do,dump,each,else,elsif,eval,exists,for,foreach,format,glob,goto,grep,if,keys,last,local,m,map,my,next,no

  4. 如何在Perl中打印由换行符分隔的列表元素?

    什么是最简单的打印所有列表的元素以Perl中的换行符分隔的元素?解决方法在Perl5.10中:其他方式:或:或者怎么样?

  5. 使用Perl如何获取文件大小(以兆字节为单位)?

    我想以磁盘的形式获取磁盘上的文件大小.使用-s运算符给出了以字节为单位的大小,但是我将假设,然后将其除以魔术数字是一个坏主意:我应该使用只读变量来定义1024,还是有一种编程方式来获取一千字节的字节数?

  6. perl – 如何测试/分类CPAN模块的utf8正确性

    例如:File::Slurp,如果你将读取该文件您将根据命令行开关获得不同的结果,并且perl-CSDA将无法正常工作.伤心.(是的,我知道比Encode::decode(“utf8”,read_file($file,binmode=>’:raw’));将帮助,但是SAD.我的问题:>在这里任何首选方式,如何测试/分类什么CPAN模块是utf8安全/准备/正确?>这里是像Perl::Criticforutf8这样的东西–什么将检查模块源可能的utf8不正确?总结以上是DEVMAX为你收集整理的perl–如

  7. 如何删除Perl字符串中的空格?

    如果我声明一个值为’3’的变量$myString.是否有任何功能来删除返回值的空格.有点像SomeFun然后返回’3′.输出:你可以注意到’vid’=>‘0’,上面的代码从theanswer.我正在研究它.总结以上是DEVMAX为你收集整理的如何删除Perl字符串中的空格?如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  8. 如何在mod_perl2下运行Devel :: Cover?

    Unfortunately,Devel::Coverdoesnotyetworkwiththreads.它也不适用于prefork.在startup.pl中使用,Devel::Cover问题perl5.8.9,Apache2.2.13.我的操作系统是FreeBSD,如果重要.同样的问题是reportedforwin32.更新:PerlTrace全部输出解决方法邪恶之源似乎是Apache::DBI.

  9. 如何使用Perl中的C类?

    我有一套用C写的课.从Perl脚本中调用它们的最佳方法是什么?

  10. perl – 在Emacs中以双模式更好的缩进

    我正在使用Emacs来修改Perl和Verilog交织的代码.我正在使用two-mode-mode在两者之间切换,这样可以预期.问题是perl代码与//一行一行地表示;如下图所示:而双模式则认识到它是Perl,它是逐行的,所以缩进等在线上无意义.我想做的是使Perl代码像往常一样格式化,但忽略//;字符.有什么想法吗?我刚刚开始偷看模式文件,它们是可以理解的复杂的,所以任何提示都不会感激!

返回
顶部