# Perlin 雜訊

``````...搭配〈建立網格面〉中的 surface

# Perlin noise 實作
def blending(t):
return 6 * (t ** 5) - 15 * (t ** 4) + 10 * (t ** 3)

def lerp(g1, g2, t):
return g1 + t * (g2 - g1)

return [dy, dx + dy, dx, dx - dy, -dy, -dx - dy, -dx, -dx + dy][hashvalue % 8];

rand_table = np.random.randint(255, size = 256).tolist()
# 增加一個 zScale 參數
def _perlin2(x, y, zScale):
xi = floor(x)
yi = floor(y)

aa = rand_table[
(rand_table[xi % 256] + yi) % 256
]
ba = rand_table[
(rand_table[(xi + 1) % 256] + yi) % 256
]
ab = rand_table[
(rand_table[xi % 256] + yi + 1) % 256
]
bb = rand_table[
(rand_table[(xi + 1) % 256] + yi + 1) % 256
]

dx = x - xi
dy = y - yi

u = blending(dx)
v = blending(dy)

g2 = lerp(grad2(ab, dx, dy - 1), grad2(bb, dx - 1, dy - 1), u)

# 傳回座標，其中雜訊值是 z
return (x, y, lerp(g1, g2, v) * zScale)
_perlin2 = np.frompyfunc(_perlin2, 3, 1)

def perlin2(x, y, zScale):
cx, cy = np.meshgrid(x, y)
return _perlin2(cx, cy, zScale)

width = 25
step = 1.1
zScale = 2
thickness = 0.1

x = np.arange(0, width, step)
y = np.arange(0, width, step)

points = perlin2(x, y, zScale)

show_object(surface(points, thickness))
``````

CadQuery 本身採用 BREP，並不鼓勵這種自行建立多面體的做法，這跟 OpenSCAD 是相對的，多面體的做法比較適合在 OpenSCAD 中做，例如，對應的做法並將 `step` 縮小後，OpenSCAD 可以做出以下模型：

``````from math import floor
import numpy as np

from cadquery import Workplane, Face, Vector

# Perlin noise 實作
def blending(t):
return 6 * (t ** 5) - 15 * (t ** 4) + 10 * (t ** 3)

def lerp(g1, g2, t):
return g1 + t * (g2 - g1)

return [dy, dx + dy, dx, dx - dy, -dy, -dx - dy, -dx, -dx + dy][hashvalue % 8];

rand_table = np.random.randint(255, size = 256).tolist()
def _perlin2(x, y, zScale):
xi = floor(x)
yi = floor(y)

aa = rand_table[
(rand_table[xi % 256] + yi) % 256
]
ba = rand_table[
(rand_table[(xi + 1) % 256] + yi) % 256
]
ab = rand_table[
(rand_table[xi % 256] + yi + 1) % 256
]
bb = rand_table[
(rand_table[(xi + 1) % 256] + yi + 1) % 256
]

dx = x - xi
dy = y - yi

u = blending(dx)
v = blending(dy)

g2 = lerp(grad2(ab, dx, dy - 1), grad2(bb, dx - 1, dy - 1), u)

# 傳回座標的 Vector 實例，其中雜訊值是 z
return Vector(x, y, lerp(g1, g2, v) * zScale)
_perlin2 = np.frompyfunc(_perlin2, 3, 1)

def perlin2(x, y, zScale):
cx, cy = np.meshgrid(x, y)
return _perlin2(cx, cy, zScale)

width = 200
step = 20.1
zScale = 10

x = np.arange(0, width, step)
y = np.arange(0, width, step)

points = perlin2(x, y, zScale)

show_object(Face.makeSplineApprox(points))
``````