用Perlin噪声使Voronoi失真

时间:2020-10-23 16:21:44

标签: python voronoi perlin-noise

根据this blog post,有几种方法可以使voronoi细胞更具动感。我感兴趣的是他们提到的第一个:

上面的图示与上面的图示是相同的Voronoi图,只是现在,Perlin噪声已用于扭曲哪些点属于哪个单元格。这在单元格之间创建了一些更有趣的边界。 只要您使用最接近的voronoi原点的逐像素(或逐区块)分配,这就很容易实现,因为您可以非常简单地用Perlin噪声抵消像素的实际坐标-与失真的Perlin噪声密切相关。

我见过其他地方提到过类似的想法,但是没有实际的代码显示Perlin噪声是如何“扭曲”或“添加”到voronoi图的。我已经尝试通过猜测来应用它,但是没有运气。我的代码的编写方式是,点之间的距离为数百,而perlin噪声值仅为0到1,因此添加或减去噪声实际上并没有多大作用。乘法似乎破坏了voronoi。我曾尝试将voronoi距离值缩放到0到1或-1到1之间,然后应用于噪声,但这也不起作用。

下面是我正在生成的voronoi图和perlin噪声的示例。我将不胜感激任何反馈或有能力为我指出正确的方向。

from PIL import Image
import random
import math
import numpy as np
import noise
wid = 500
hei = 250
image = Image.new("RGB",(wid,hei))
world_test = np.zeros(image.size)
scale       = 100 # Number that determines at what distance to view the noisemap
octaves     = 6 # the number of levels of detail you want you perlin noise to have
persistence = 0.5 # number that determines how much detail is added or removed at each octave (adjusts frequency)
lacunarity  = 2.0 # number that determines how much each octave contributes to the overall shape (adjusts amplitude)
# Creates perlin noise
for x in range(wid):
    for y in range(hei):
        world_test[x][y] = ((noise.pnoise2(x/100, 
                                    y/100, 
                                    octaves     = octaves, 
                                    persistence = persistence, 
                                    lacunarity  = lacunarity, 
                                    repeatx     = wid, 
                                    repeaty     = hei, 
                                    base        = 0)))
def generate_voronoi_diagram(width, height, num_cells):
    image = Image.new("RGB", (width, height))
    putpixel = image.putpixel
    imgx, imgy = image.size
    nx = []
    ny = []
    nr = []
    ng = []
    nb = []
    #Go through number of cells
    for i in range(num_cells):
        #creat a point (x,y) and give it a specific color value
        nx.append(random.randrange(imgx))
        ny.append(random.randrange(imgy))
        nr.append(random.randrange(256))
        ng.append(random.randrange(256))
        nb.append(random.randrange(256))
    #go through each pixel in the image
    for y in range(int(imgy)):
        for x in range(int(imgx)):
            dmin = math.hypot(imgx-1, imgy-1)
            j = -1
            #go through each cell
            for i in range(num_cells):
                # d is distance from each voronoi starting point
                d = math.hypot((nx[i]-x), (ny[i]-y))
                # apply perlin distort to d
                d +=  world_test[x][y]
                #if distance is less than the current min distance,
                #set that point as the owner of this pixel and the new dmin
                if d < dmin:
                    dmin = d
                    j = i
            putpixel((x, y), (nr[j], ng[j], nb[j]))
    image.save("Voronoi_example.png", "PNG")
    image.show()
generate_voronoi_diagram(wid, hei, 30)

0 个答案:

没有答案
相关问题