# Worley 雜訊

March 29, 2022

``````width = 100;

point = [width, width] / 2;
range = [0:width];
for(x = range, y = range) {
p = [x, y];
dist = norm(p - point);

gray = dist / (width * 0.8); // 調整寬度，只是為了亮一點

color([gray, gray, gray])
translate(p)
square(1);
}
``````

## 點的勢力範圍

``````width = 100;

p1 = [width, width] / 4;
p2 = p1 * 3;

range = [0:width];
for(x = range, y = range) {
p = [x, y];
dist1 = norm(p - p1);
dist2 = norm(p - p2);

gray = min(dist1, dist2) / (width * 0.8); // 調整寬度，只是為了亮一點

color([gray, gray, gray])
translate(p)
square(1);
}
``````

``````width = 100;
n = 5;

cell_points = [for(i = [0:n - 1]) rands(0, width, 2)];

range = [0:width];
for(x = range, y = range) {
p = [x, y];
dists = [for(pt = cell_points) norm(p - pt)];

gray = min(dists) / (width * 0.8); // 調整寬度，只是為了亮一點

color([gray, gray, gray])
translate(p)
square(1);
}
``````

Voronoi 是勢力均衡下產生的圖案，就方才的範例而言，是以距離作為勢力衡量的依據，也就是範圍中每個座標比較靠近哪個點，就選擇該點勢力作為灰階值計算依據。

## nz_cell 函式

dotSCAD 的 `nz_cell`，可以指定作為細胞核的隨機點，傳回特定點的 Worley 雜訊，例如：

``````use <noise/nz_cell.scad>;

width = 100;
n = 10;

cell_points = [for(i = [0:n - 1]) rands(0, width, 2)];

range = [0:width];
for(x = range, y = range) {
p = [x, y];
noise = nz_cell(cell_points, p);

translate(p)
linear_extrude(noise / 2)
square(1);
}
``````

## Worley 雜訊的變化

Worley 雜訊不見得是要比較點與點間的直線距離，也可以是其他的距離計算方式，例如，`nz_cell``dist` 還可以使用 `"manhattan"` 指定〈曼哈頓距離〉、`"chebyshev"` 指定〈切比雪夫距離〉等，來看看指定了 `"manhattan"` 時的樣子：

``````use <noise/nz_cell.scad>;

width = 100;
n = 10;

cell_points = [for(i = [0:n - 1]) rands(0, width, 2)];

range = [0:width];
for(x = range, y = range) {
p = [x, y];
noise = nz_cell(cell_points, p, dist = "manhattan");
gray = noise / (width * 0.75);

color([gray, gray, gray])
translate(p)
linear_extrude(noise / 2)
square(1);
}
``````

``````use <noise/nz_cell.scad>;
use <golden_spiral.scad>;

size = [100, 50];
half_size = size / 2;
pts_angles = golden_spiral(
from = 3,
to = 10,
point_distance = 3
);

cell_points = [for(pt_angle = pts_angles) pt_angle[0] + half_size];

for(x = [0:size.x], y = [0:size.y]) {
p = [x, y];
noise = nz_cell(cell_points, p);
gray = noise / size.y;

color([gray, gray, gray])
translate(p)
linear_extrude(noise + 1)
square(1);
}
``````