【发布时间】:2020-10-23 16:21:44
【问题描述】:
根据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)
【问题讨论】:
标签: python voronoi perlin-noise