From 40c239b1fffb7fa1035e2de34a83182af67da5ad Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 07:13:54 -0800 Subject: [PATCH 1/9] Include SNoise --- vnoise/__init__.py | 1 + vnoise/_tables.py | 25 ++++ vnoise/vsnoise.py | 366 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 392 insertions(+) create mode 100644 vnoise/vsnoise.py diff --git a/vnoise/__init__.py b/vnoise/__init__.py index e4d5239..82327c3 100644 --- a/vnoise/__init__.py +++ b/vnoise/__init__.py @@ -1,4 +1,5 @@ from .vnoise import Noise +from .vsnoise import SNoise def _get_version() -> str: diff --git a/vnoise/_tables.py b/vnoise/_tables.py index d4fe7a4..fae4f60 100644 --- a/vnoise/_tables.py +++ b/vnoise/_tables.py @@ -280,3 +280,28 @@ 156, 180, ) + +M_1_PI = 0.31830988618379067154 + + +GRAD4 = ( + (0, 1, 1, 1), (0, 1, 1, -1), (0, 1, -1, 1), (0, 1, -1, -1), + (0, -1, 1, 1), (0, -1, 1, -1), (0, -1, -1, 1), (0, -1, -1, -1), + (1, 0, 1, 1), (1, 0, 1, -1), (1, 0, -1, 1), (1, 0, -1, -1), + (-1, 0, 1, 1), (-1, 0, 1, -1), (-1, 0, -1, 1), (-1, 0, -1, -1), + (1, 1, 0, 1), (1, 1, 0, -1), (1, -1, 0, 1), (1, -1, 0, -1), + (-1, 1, 0, 1), (-1, 1, 0, -1), (-1, -1, 0, 1), (-1, -1, 0, -1), + (1, 1, 1, 0), (1, 1, -1, 0), (1, -1, 1, 0), (1, -1, -1, 0), + (-1, 1, 1, 0), (-1, 1, -1, 0), (-1, -1, 1, 0), (-1, -1, -1, 0)) + +SIMPLEX = ( + (0, 1, 2, 3), (0, 1, 3, 2), (0, 0, 0, 0), (0, 2, 3, 1), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), + (1, 2, 3, 0), (0, 2, 1, 3), (0, 0, 0, 0), (0, 3, 1, 2), (0, 3, 2, 1), (0, 0, 0, 0), (0, 0, 0, 0), + (0, 0, 0, 0), (1, 3, 2, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), + (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (1, 2, 0, 3), (0, 0, 0, 0), (1, 3, 0, 2), (0, 0, 0, 0), + (0, 0, 0, 0), (0, 0, 0, 0), (2, 3, 0, 1), (2, 3, 1, 0), (1, 0, 2, 3), (1, 0, 3, 2), (0, 0, 0, 0), + (0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 3, 1), (0, 0, 0, 0), (2, 1, 3, 0), (0, 0, 0, 0), (0, 0, 0, 0), + (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 1, 3), + (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 0, 1, 2), (3, 0, 2, 1), (0, 0, 0, 0), (3, 1, 2, 0), + (2, 1, 0, 3), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 1, 0, 2), (0, 0, 0, 0), (3, 2, 0, 1), + (3, 2, 1, 0)) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py new file mode 100644 index 0000000..dee5aa3 --- /dev/null +++ b/vnoise/vsnoise.py @@ -0,0 +1,366 @@ +""" +// Copyright (c) 2008, Casey Duncan (casey dot duncan at gmail dot com) +// see LICENSE.txt for details +// $Id$ +""" + +import numpy as np + +from ._tables import PERM, GRAD4, GRAD3, M_1_PI, SIMPLEX + + +"Native-code simplex noise functions" + +# 2D simplex skew factors +F2 = 0.3660254037844386 # 0.5 * (sqrt(3.0) - 1.0) +G2 = 0.21132486540518713 # (3.0 - sqrt(3.0)) / 6.0 + +from math import floor + + +def _snoise2_impl(x: float, y: float) -> float: + s = (x + y) * F2 + i = floor(x + s) + j = floor(y + s) + t = (i + j) * G2 + + xx = [0.0, 0.0, 0.0] + yy = [0.0, 0.0, 0.0] + f = [0.0, 0.0, 0.0] + + noise = [0.0, 0.0, 0.0] + g = [0, 0, 0] + + xx[0] = x - (i - t) + yy[0] = y - (j - t) + + i1 = xx[0] > yy[0] + j1 = xx[0] <= yy[0] + + xx[2] = xx[0] + G2 * 2.0 - 1.0 + yy[2] = yy[0] + G2 * 2.0 - 1.0 + xx[1] = xx[0] - i1 + G2 + yy[1] = yy[0] - j1 + G2 + + I = int(i & 255) + J = int(j & 255) + g[0] = PERM[I + PERM[J]] % 12 + g[1] = PERM[I + i1 + PERM[J + j1]] % 12 + g[2] = PERM[I + 1 + PERM[J + 1]] % 12 + + for c in range(0, 3): + f[c] = 0.5 - xx[c] * xx[c] - yy[c] * yy[c] + + for c in range(0, 3): + if f[c] > 0: + noise[c] = f[c] * f[c] * f[c] * f[c] * (GRAD3[g[c]][0] * xx[c] + GRAD3[g[c]][1] * yy[c]) + + return (noise[0] + noise[1] + noise[2]) * 70.0 + + +def dot3(v1, v2): + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + + +def ASSIGN(a, v0, v1, v2): + a[0] = v0 + a[1] = v1 + a[2] = v2 + + +F3 = 1.0 / 3.0 +G3 = 1.0 / 6.0 + + +def _snoise3_impl(x: float, y: float, z: float) -> float: + # int c, o1[3], o2[3], g[4], I, J, K; + o1 = [0, 0, 0] + o2 = [0, 0, 0] + g = [0, 0, 0, 0] + + f = [0.0] * 4 + noise = [0.0] * 4 + s = (x + y + z) * F3 + i = np.floor(x + s) + j = np.floor(y + s) + k = np.floor(z + s) + t = (i + j + k) * G3 + + pos = np.zeros((4, 3), dtype='float') + # float pos[4][3]; + + pos[0][0] = x - (i - t) + pos[0][1] = y - (j - t) + pos[0][2] = z - (k - t) + + if pos[0][0] >= pos[0][1]: + if pos[0][1] >= pos[0][2]: + ASSIGN(o1, 1, 0, 0) + ASSIGN(o2, 1, 1, 0) + elif pos[0][0] >= pos[0][2]: + ASSIGN(o1, 1, 0, 0) + ASSIGN(o2, 1, 0, 1) + else: + ASSIGN(o1, 0, 0, 1) + ASSIGN(o2, 1, 0, 1) + else: + if pos[0][1] < pos[0][2]: + ASSIGN(o1, 0, 0, 1) + ASSIGN(o2, 0, 1, 1) + elif pos[0][0] < pos[0][2]: + ASSIGN(o1, 0, 1, 0) + ASSIGN(o2, 0, 1, 1) + else: + ASSIGN(o1, 0, 1, 0) + ASSIGN(o2, 1, 1, 0) + + for c in range(0, 3): + pos[3][c] = pos[0][c] - 1.0 + 3.0 * G3 + pos[2][c] = pos[0][c] - o2[c] + 2.0 * G3 + pos[1][c] = pos[0][c] - o1[c] + G3 + + I = int(i & 255) + J = int(j & 255) + K = int(k & 255) + g[0] = PERM[I + PERM[J + PERM[K]]] % 12 + g[1] = PERM[I + o1[0] + PERM[J + o1[1] + PERM[o1[2] + K]]] % 12 + g[2] = PERM[I + o2[0] + PERM[J + o2[1] + PERM[o2[2] + K]]] % 12 + g[3] = PERM[I + 1 + PERM[J + 1 + PERM[K + 1]]] % 12 + + for c in range(0, 4): + f[c] = 0.6 - pos[c][0] * pos[c][0] - pos[c][1] * pos[c][1] - pos[c][2] * pos[c][2] + + for c in range(0, 4): + if f[c] > 0: + noise[c] = f[c] * f[c] * f[c] * f[c] * dot3(pos[c], GRAD3[g[c]]) + + return (noise[0] + noise[1] + noise[2] + noise[3]) * 32.0 + + +def _fbm_noise3_impl(x: float, y: float, z: float, octaves: int, persistence: float, lacunarity: float) -> float: + freq = 1.0 + amp = 1.0 + max = 1.0 + total = _snoise3_impl(x, y, z) + for i in range(1, octaves): + freq *= lacunarity + amp *= persistence + max += amp + total += _snoise3_impl(x * freq, y * freq, z * freq) * amp + return total / max + + +def _dot4(v1, x, y, z, w): + return v1[0] * x + v1[1] * y + v1[2] * z + v1[3] * w + + +F4 = 0.30901699437494745 # /* (sqrt(5.0) - 1.0) / 4.0 */ +G4 = 0.1381966011250105 # /* (5.0 - sqrt(5.0)) / 20.0 */ + + +def _noise4_impl(x: float, y: float, z: float, w: float) -> float: + noise = [0.0] * 5 + + s = (x + y + z + w) * F4 + i = np.floor(x + s) + j = np.floor(y + s) + k = np.floor(z + s) + l = np.floor(w + s) + t = (i + j + k + l) * G4 + + x0 = x - (i - t) + y0 = y - (j - t) + z0 = z - (k - t) + w0 = w - (l - t) + + c = (x0 > y0) * 32 + (x0 > z0) * 16 + (y0 > z0) * 8 + (x0 > w0) * 4 + (y0 > w0) * 2 + (z0 > w0) + i1 = SIMPLEX[c][0] >= 3 + j1 = SIMPLEX[c][1] >= 3 + k1 = SIMPLEX[c][2] >= 3 + l1 = SIMPLEX[c][3] >= 3 + i2 = SIMPLEX[c][0] >= 2 + j2 = SIMPLEX[c][1] >= 2 + k2 = SIMPLEX[c][2] >= 2 + l2 = SIMPLEX[c][3] >= 2 + i3 = SIMPLEX[c][0] >= 1 + j3 = SIMPLEX[c][1] >= 1 + k3 = SIMPLEX[c][2] >= 1 + l3 = SIMPLEX[c][3] >= 1 + + x1 = x0 - i1 + G4 + y1 = y0 - j1 + G4 + z1 = z0 - k1 + G4 + w1 = w0 - l1 + G4 + x2 = x0 - i2 + 2.0 * G4 + y2 = y0 - j2 + 2.0 * G4 + z2 = z0 - k2 + 2.0 * G4 + w2 = w0 - l2 + 2.0 * G4 + x3 = x0 - i3 + 3.0 * G4 + y3 = y0 - j3 + 3.0 * G4 + z3 = z0 - k3 + 3.0 * G4 + w3 = w0 - l3 + 3.0 * G4 + x4 = x0 - 1.0 + 4.0 * G4 + y4 = y0 - 1.0 + 4.0 * G4 + z4 = z0 - 1.0 + 4.0 * G4 + w4 = w0 - 1.0 + 4.0 * G4 + + I = int(i & 255) + J = int(j & 255) + K = int(k & 255) + L = int(l & 255) + gi0 = PERM[I + PERM[J + PERM[K + PERM[L]]]] & 0x1f + gi1 = PERM[I + i1 + PERM[J + j1 + PERM[K + k1 + PERM[L + l1]]]] & 0x1f + gi2 = PERM[I + i2 + PERM[J + j2 + PERM[K + k2 + PERM[L + l2]]]] & 0x1f + gi3 = PERM[I + i3 + PERM[J + j3 + PERM[K + k3 + PERM[L + l3]]]] & 0x1f + gi4 = PERM[I + 1 + PERM[J + 1 + PERM[K + 1 + PERM[L + 1]]]] & 0x1f + # float t0, t1, t2, t3, t4; + + t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0 + if t0 >= 0.0: + t0 *= t0 + noise[0] = t0 * t0 * _dot4(GRAD4[gi0], x0, y0, z0, w0) + + t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1 + if t1 >= 0.0: + t1 *= t1 + noise[1] = t1 * t1 * _dot4(GRAD4[gi1], x1, y1, z1, w1) + + t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2 + if t2 >= 0.0: + t2 *= t2 + noise[2] = t2 * t2 * _dot4(GRAD4[gi2], x2, y2, z2, w2) + + t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3 + if t3 >= 0.0: + t3 *= t3 + noise[3] = t3 * t3 * _dot4(GRAD4[gi3], x3, y3, z3, w3) + + t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4 + if t4 >= 0.0: + t4 *= t4 + noise[4] = t4 * t4 * _dot4(GRAD4[gi4], x4, y4, z4, w4) + + return 27.0 * (noise[0] + noise[1] + noise[2] + noise[3] + noise[4]) + + +def _fbm_noise4_impl(x: float, y: float, z: float, w: float, octaves: int, persistence: float, lacunarity: float) -> float: + freq = 1.0 + amp = 1.0 + max = 1.0 + total = _noise4_impl(x, y, z, w) + + for i in range(1, octaves): + freq *= lacunarity + amp *= persistence + max += amp + total += _noise4_impl(x * freq, y * freq, z * freq, w * freq) * amp + return total / max + + +def py_noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0): + """ + noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) + return simplex noise value for specified 2D coordinate. + + octaves -- specifies the number of passes, defaults to 1 (simple noise). + + persistence -- specifies the amplitude of each successive octave relative + to the one below it. Defaults to 0.5 (each higher octave's amplitude + is halved). Note the amplitude of the first pass is always 1.0. + + lacunarity -- specifies the frequency of each successive octave relative + "to the one below it, similar to persistence. Defaults to 2.0. + + repeatx, repeaty -- specifies the interval along each axis when + "the noise values repeat. This can be used as the tile size for creating + "tileable textures + + base -- specifies a fixed offset for the noise coordinates. Useful for + generating different noise textures with the same repeat interval + """ + z = 0.0 + + if octaves <= 0: + raise ValueError("Expected octaves value > 0") + + if repeatx is None and repeaty is None: + # Flat noise, no tiling + freq = 1.0 + amp = 1.0 + max = 1.0 + total = _snoise2_impl(x + z, y + z) + + for i in range(1, octaves): + freq *= lacunarity + amp *= persistence + max += amp + total += _snoise2_impl(x * freq + z, y * freq + z) * amp + + return total / max + else: # Tiled noise + w = z + if repeaty is not None: + yf = y * 2.0 / repeaty + yr = repeaty * M_1_PI * 0.5 + vy = np.sin(yf) # originally fast_sin + vyz = np.cos(yf) # originally fast_cos + y = vy * yr + w += vyz * yr + if repeatx is None: + return _fbm_noise3_impl(x, y, w, octaves, persistence, lacunarity) + if repeatx is not None: + xf = x * 2.0 / repeatx + xr = repeatx * M_1_PI * 0.5 + vx = np.sin(xf) + vxz = np.cos(xf) + x = vx * xr + z += vxz * xr + if repeaty is None: + return _fbm_noise3_impl(x, y, z, octaves, persistence, lacunarity) + return _fbm_noise4_impl(x, y, z, w, octaves, persistence, lacunarity) + + +class SNoise: + def noise3(self, x: float, y: float, z: float, octaves=1, persistence=0.5, lacunarity=2.0): + """ + noise3(x, y, z, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for + specified 3D coordinate + + octaves -- specifies the number of passes, defaults to 1 (simple noise). + + persistence -- specifies the amplitude of each successive octave relative + to the one below it. Defaults to 0.5 (each higher octave's amplitude + is halved). Note the amplitude of the first pass is always 1.0. + + lacunarity -- specifies the frequency of each successive octave relative + to the one below it, similar to persistence. Defaults to 2.0. + """ + if octaves == 1: + # Single octave, return simple noise + return _snoise3_impl(x, y, z) + elif octaves > 1: + return _fbm_noise3_impl(x, y, z, octaves, persistence, lacunarity) + else: + raise ValueError("Expected octaves value > 0") + + def noise4(self, x: float, y: float, z: float, w: float, octaves=1, persistence=0.5, lacunarity=2.0): + """ + noise4(x, y, z, w, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for + specified 4D coordinate + + octaves -- specifies the number of passes, defaults to 1 (simple noise). + + persistence -- specifies the amplitude of each successive octave relative + to the one below it. Defaults to 0.5 (each higher octave's amplitude + is halved). Note the amplitude of the first pass is always 1.0. + + lacunarity -- specifies the frequency of each successive octave relative + to the one below it, similar to persistence. Defaults to 2.0. + """ + if octaves == 1: + # Single octave, return simple noise + return _noise4_impl(x, y, z, w) + elif octaves > 1: + return _fbm_noise4_impl(x, y, z, w, octaves, persistence, lacunarity) + else: + raise ValueError("Expected octaves value > 0") From dd51e59ee7202dca6cbac345167a32676c76fc48 Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 07:21:33 -0800 Subject: [PATCH 2/9] SNoise include noise2 --- vnoise/vsnoise.py | 140 ++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 62 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index dee5aa3..4f52745 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -3,6 +3,8 @@ // see LICENSE.txt for details // $Id$ """ +import random +from typing import Optional, Sequence import numpy as np @@ -257,70 +259,84 @@ def _fbm_noise4_impl(x: float, y: float, z: float, w: float, octaves: int, persi return total / max -def py_noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0): - """ - noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) - return simplex noise value for specified 2D coordinate. - - octaves -- specifies the number of passes, defaults to 1 (simple noise). - - persistence -- specifies the amplitude of each successive octave relative - to the one below it. Defaults to 0.5 (each higher octave's amplitude - is halved). Note the amplitude of the first pass is always 1.0. - - lacunarity -- specifies the frequency of each successive octave relative - "to the one below it, similar to persistence. Defaults to 2.0. - - repeatx, repeaty -- specifies the interval along each axis when - "the noise values repeat. This can be used as the tile size for creating - "tileable textures - - base -- specifies a fixed offset for the noise coordinates. Useful for - generating different noise textures with the same repeat interval - """ - z = 0.0 - - if octaves <= 0: - raise ValueError("Expected octaves value > 0") - - if repeatx is None and repeaty is None: - # Flat noise, no tiling - freq = 1.0 - amp = 1.0 - max = 1.0 - total = _snoise2_impl(x + z, y + z) - - for i in range(1, octaves): - freq *= lacunarity - amp *= persistence - max += amp - total += _snoise2_impl(x * freq + z, y * freq + z) * amp - - return total / max - else: # Tiled noise - w = z - if repeaty is not None: - yf = y * 2.0 / repeaty - yr = repeaty * M_1_PI * 0.5 - vy = np.sin(yf) # originally fast_sin - vyz = np.cos(yf) # originally fast_cos - y = vy * yr - w += vyz * yr - if repeatx is None: - return _fbm_noise3_impl(x, y, w, octaves, persistence, lacunarity) - if repeatx is not None: - xf = x * 2.0 / repeatx - xr = repeatx * M_1_PI * 0.5 - vx = np.sin(xf) - vxz = np.cos(xf) - x = vx * xr - z += vxz * xr - if repeaty is None: - return _fbm_noise3_impl(x, y, z, octaves, persistence, lacunarity) - return _fbm_noise4_impl(x, y, z, w, octaves, persistence, lacunarity) +class SNoise: + def __init__(self, seed: Optional[int] = None): + if seed is not None: + self.seed(seed) + else: + self._set_perm(PERM) + + def seed(self, s: int) -> None: + perm = list(PERM) + random.Random(s).shuffle(perm) + self._set_perm(perm) + + def _set_perm(self, perm: Sequence[int]) -> None: + self._perm = np.array(list(perm) * 2, dtype=np.uint8) + + def noise2(self, x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0): + """ + noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) + return simplex noise value for specified 2D coordinate. + + octaves -- specifies the number of passes, defaults to 1 (simple noise). + + persistence -- specifies the amplitude of each successive octave relative + to the one below it. Defaults to 0.5 (each higher octave's amplitude + is halved). Note the amplitude of the first pass is always 1.0. + + lacunarity -- specifies the frequency of each successive octave relative + "to the one below it, similar to persistence. Defaults to 2.0. + + repeatx, repeaty -- specifies the interval along each axis when + "the noise values repeat. This can be used as the tile size for creating + "tileable textures + + base -- specifies a fixed offset for the noise coordinates. Useful for + generating different noise textures with the same repeat interval + """ + z = 0.0 + + if octaves <= 0: + raise ValueError("Expected octaves value > 0") + + if repeatx is None and repeaty is None: + # Flat noise, no tiling + freq = 1.0 + amp = 1.0 + max = 1.0 + total = _snoise2_impl(x + z, y + z) + + for i in range(1, octaves): + freq *= lacunarity + amp *= persistence + max += amp + total += _snoise2_impl(x * freq + z, y * freq + z) * amp + + return total / max + else: # Tiled noise + w = z + if repeaty is not None: + yf = y * 2.0 / repeaty + yr = repeaty * M_1_PI * 0.5 + vy = np.sin(yf) # originally fast_sin + vyz = np.cos(yf) # originally fast_cos + y = vy * yr + w += vyz * yr + if repeatx is None: + return _fbm_noise3_impl(x, y, w, octaves, persistence, lacunarity) + if repeatx is not None: + xf = x * 2.0 / repeatx + xr = repeatx * M_1_PI * 0.5 + vx = np.sin(xf) + vxz = np.cos(xf) + x = vx * xr + z += vxz * xr + if repeaty is None: + return _fbm_noise3_impl(x, y, z, octaves, persistence, lacunarity) + return _fbm_noise4_impl(x, y, z, w, octaves, persistence, lacunarity) -class SNoise: def noise3(self, x: float, y: float, z: float, octaves=1, persistence=0.5, lacunarity=2.0): """ noise3(x, y, z, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for From c66856378ff76bb2739f2278e6b22751fdb124c3 Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 18:47:25 -0800 Subject: [PATCH 3/9] Apply Black --- vnoise/vsnoise.py | 56 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index 4f52745..64c8679 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -55,7 +55,9 @@ def _snoise2_impl(x: float, y: float) -> float: for c in range(0, 3): if f[c] > 0: - noise[c] = f[c] * f[c] * f[c] * f[c] * (GRAD3[g[c]][0] * xx[c] + GRAD3[g[c]][1] * yy[c]) + noise[c] = ( + f[c] * f[c] * f[c] * f[c] * (GRAD3[g[c]][0] * xx[c] + GRAD3[g[c]][1] * yy[c]) + ) return (noise[0] + noise[1] + noise[2]) * 70.0 @@ -88,7 +90,7 @@ def _snoise3_impl(x: float, y: float, z: float) -> float: k = np.floor(z + s) t = (i + j + k) * G3 - pos = np.zeros((4, 3), dtype='float') + pos = np.zeros((4, 3), dtype="float") # float pos[4][3]; pos[0][0] = x - (i - t) @@ -139,7 +141,9 @@ def _snoise3_impl(x: float, y: float, z: float) -> float: return (noise[0] + noise[1] + noise[2] + noise[3]) * 32.0 -def _fbm_noise3_impl(x: float, y: float, z: float, octaves: int, persistence: float, lacunarity: float) -> float: +def _fbm_noise3_impl( + x: float, y: float, z: float, octaves: int, persistence: float, lacunarity: float +) -> float: freq = 1.0 amp = 1.0 max = 1.0 @@ -175,7 +179,14 @@ def _noise4_impl(x: float, y: float, z: float, w: float) -> float: z0 = z - (k - t) w0 = w - (l - t) - c = (x0 > y0) * 32 + (x0 > z0) * 16 + (y0 > z0) * 8 + (x0 > w0) * 4 + (y0 > w0) * 2 + (z0 > w0) + c = ( + (x0 > y0) * 32 + + (x0 > z0) * 16 + + (y0 > z0) * 8 + + (x0 > w0) * 4 + + (y0 > w0) * 2 + + (z0 > w0) + ) i1 = SIMPLEX[c][0] >= 3 j1 = SIMPLEX[c][1] >= 3 k1 = SIMPLEX[c][2] >= 3 @@ -210,11 +221,11 @@ def _noise4_impl(x: float, y: float, z: float, w: float) -> float: J = int(j & 255) K = int(k & 255) L = int(l & 255) - gi0 = PERM[I + PERM[J + PERM[K + PERM[L]]]] & 0x1f - gi1 = PERM[I + i1 + PERM[J + j1 + PERM[K + k1 + PERM[L + l1]]]] & 0x1f - gi2 = PERM[I + i2 + PERM[J + j2 + PERM[K + k2 + PERM[L + l2]]]] & 0x1f - gi3 = PERM[I + i3 + PERM[J + j3 + PERM[K + k3 + PERM[L + l3]]]] & 0x1f - gi4 = PERM[I + 1 + PERM[J + 1 + PERM[K + 1 + PERM[L + 1]]]] & 0x1f + gi0 = PERM[I + PERM[J + PERM[K + PERM[L]]]] & 0x1F + gi1 = PERM[I + i1 + PERM[J + j1 + PERM[K + k1 + PERM[L + l1]]]] & 0x1F + gi2 = PERM[I + i2 + PERM[J + j2 + PERM[K + k2 + PERM[L + l2]]]] & 0x1F + gi3 = PERM[I + i3 + PERM[J + j3 + PERM[K + k3 + PERM[L + l3]]]] & 0x1F + gi4 = PERM[I + 1 + PERM[J + 1 + PERM[K + 1 + PERM[L + 1]]]] & 0x1F # float t0, t1, t2, t3, t4; t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0 @@ -245,7 +256,9 @@ def _noise4_impl(x: float, y: float, z: float, w: float) -> float: return 27.0 * (noise[0] + noise[1] + noise[2] + noise[3] + noise[4]) -def _fbm_noise4_impl(x: float, y: float, z: float, w: float, octaves: int, persistence: float, lacunarity: float) -> float: +def _fbm_noise4_impl( + x: float, y: float, z: float, w: float, octaves: int, persistence: float, lacunarity: float +) -> float: freq = 1.0 amp = 1.0 max = 1.0 @@ -275,7 +288,17 @@ def seed(self, s: int) -> None: def _set_perm(self, perm: Sequence[int]) -> None: self._perm = np.array(list(perm) * 2, dtype=np.uint8) - def noise2(self, x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0): + def noise2( + self, + x, + y, + octaves=1, + persistence=0.5, + lacunarity=2.0, + repeatx=None, + repeaty=None, + base=0, + ): """ noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) return simplex noise value for specified 2D coordinate. @@ -359,7 +382,16 @@ def noise3(self, x: float, y: float, z: float, octaves=1, persistence=0.5, lacun else: raise ValueError("Expected octaves value > 0") - def noise4(self, x: float, y: float, z: float, w: float, octaves=1, persistence=0.5, lacunarity=2.0): + def noise4( + self, + x: float, + y: float, + z: float, + w: float, + octaves=1, + persistence=0.5, + lacunarity=2.0, + ): """ noise4(x, y, z, w, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for specified 4D coordinate From 9dd9bc6fd85a6b4aec622716152f9c35e39a56a3 Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 18:58:14 -0800 Subject: [PATCH 4/9] Apply Black --- vnoise/_tables.py | 116 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/vnoise/_tables.py b/vnoise/_tables.py index fae4f60..510aaeb 100644 --- a/vnoise/_tables.py +++ b/vnoise/_tables.py @@ -285,23 +285,103 @@ GRAD4 = ( - (0, 1, 1, 1), (0, 1, 1, -1), (0, 1, -1, 1), (0, 1, -1, -1), - (0, -1, 1, 1), (0, -1, 1, -1), (0, -1, -1, 1), (0, -1, -1, -1), - (1, 0, 1, 1), (1, 0, 1, -1), (1, 0, -1, 1), (1, 0, -1, -1), - (-1, 0, 1, 1), (-1, 0, 1, -1), (-1, 0, -1, 1), (-1, 0, -1, -1), - (1, 1, 0, 1), (1, 1, 0, -1), (1, -1, 0, 1), (1, -1, 0, -1), - (-1, 1, 0, 1), (-1, 1, 0, -1), (-1, -1, 0, 1), (-1, -1, 0, -1), - (1, 1, 1, 0), (1, 1, -1, 0), (1, -1, 1, 0), (1, -1, -1, 0), - (-1, 1, 1, 0), (-1, 1, -1, 0), (-1, -1, 1, 0), (-1, -1, -1, 0)) + (0, 1, 1, 1), + (0, 1, 1, -1), + (0, 1, -1, 1), + (0, 1, -1, -1), + (0, -1, 1, 1), + (0, -1, 1, -1), + (0, -1, -1, 1), + (0, -1, -1, -1), + (1, 0, 1, 1), + (1, 0, 1, -1), + (1, 0, -1, 1), + (1, 0, -1, -1), + (-1, 0, 1, 1), + (-1, 0, 1, -1), + (-1, 0, -1, 1), + (-1, 0, -1, -1), + (1, 1, 0, 1), + (1, 1, 0, -1), + (1, -1, 0, 1), + (1, -1, 0, -1), + (-1, 1, 0, 1), + (-1, 1, 0, -1), + (-1, -1, 0, 1), + (-1, -1, 0, -1), + (1, 1, 1, 0), + (1, 1, -1, 0), + (1, -1, 1, 0), + (1, -1, -1, 0), + (-1, 1, 1, 0), + (-1, 1, -1, 0), + (-1, -1, 1, 0), + (-1, -1, -1, 0), +) SIMPLEX = ( - (0, 1, 2, 3), (0, 1, 3, 2), (0, 0, 0, 0), (0, 2, 3, 1), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), - (1, 2, 3, 0), (0, 2, 1, 3), (0, 0, 0, 0), (0, 3, 1, 2), (0, 3, 2, 1), (0, 0, 0, 0), (0, 0, 0, 0), - (0, 0, 0, 0), (1, 3, 2, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), - (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (1, 2, 0, 3), (0, 0, 0, 0), (1, 3, 0, 2), (0, 0, 0, 0), - (0, 0, 0, 0), (0, 0, 0, 0), (2, 3, 0, 1), (2, 3, 1, 0), (1, 0, 2, 3), (1, 0, 3, 2), (0, 0, 0, 0), - (0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 3, 1), (0, 0, 0, 0), (2, 1, 3, 0), (0, 0, 0, 0), (0, 0, 0, 0), - (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 1, 3), - (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 0, 1, 2), (3, 0, 2, 1), (0, 0, 0, 0), (3, 1, 2, 0), - (2, 1, 0, 3), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 1, 0, 2), (0, 0, 0, 0), (3, 2, 0, 1), - (3, 2, 1, 0)) + (0, 1, 2, 3), + (0, 1, 3, 2), + (0, 0, 0, 0), + (0, 2, 3, 1), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (1, 2, 3, 0), + (0, 2, 1, 3), + (0, 0, 0, 0), + (0, 3, 1, 2), + (0, 3, 2, 1), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (1, 3, 2, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (1, 2, 0, 3), + (0, 0, 0, 0), + (1, 3, 0, 2), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (2, 3, 0, 1), + (2, 3, 1, 0), + (1, 0, 2, 3), + (1, 0, 3, 2), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (2, 0, 3, 1), + (0, 0, 0, 0), + (2, 1, 3, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (2, 0, 1, 3), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (3, 0, 1, 2), + (3, 0, 2, 1), + (0, 0, 0, 0), + (3, 1, 2, 0), + (2, 1, 0, 3), + (0, 0, 0, 0), + (0, 0, 0, 0), + (0, 0, 0, 0), + (3, 1, 0, 2), + (0, 0, 0, 0), + (3, 2, 0, 1), + (3, 2, 1, 0), +) From 89f3b11dc3ecf880393c7b7c9d725df00a36a3ba Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 19:14:20 -0800 Subject: [PATCH 5/9] Annotation. --- vnoise/vsnoise.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index 64c8679..db8995b 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -298,7 +298,7 @@ def noise2( repeatx=None, repeaty=None, base=0, - ): + ) -> float: """ noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) return simplex noise value for specified 2D coordinate. @@ -360,7 +360,15 @@ def noise2( return _fbm_noise3_impl(x, y, z, octaves, persistence, lacunarity) return _fbm_noise4_impl(x, y, z, w, octaves, persistence, lacunarity) - def noise3(self, x: float, y: float, z: float, octaves=1, persistence=0.5, lacunarity=2.0): + def noise3( + self, + x: float, + y: float, + z: float, + octaves: int = 1, + persistence: float = 0.5, + lacunarity: float = 2.0, + ) -> float: """ noise3(x, y, z, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for specified 3D coordinate @@ -388,10 +396,10 @@ def noise4( y: float, z: float, w: float, - octaves=1, - persistence=0.5, - lacunarity=2.0, - ): + octaves: int = 1, + persistence: float = 0.5, + lacunarity: float = 2.0, + ) -> float: """ noise4(x, y, z, w, octaves=1, persistence=0.5, lacunarity=2.0) return simplex noise value for specified 4D coordinate From 4415719b61751eb713f4a49203bc9b690fd1796a Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 19:40:13 -0800 Subject: [PATCH 6/9] Annotation. --- vnoise/vsnoise.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index db8995b..2f5082a 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -290,8 +290,8 @@ def _set_perm(self, perm: Sequence[int]) -> None: def noise2( self, - x, - y, + x: float, + y: float, octaves=1, persistence=0.5, lacunarity=2.0, From bcb91d3d9b6ed3169fdffad2a2233424fe0b1965 Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 19:44:58 -0800 Subject: [PATCH 7/9] Annotation. --- vnoise/vsnoise.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index 2f5082a..c385e1b 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -292,12 +292,12 @@ def noise2( self, x: float, y: float, - octaves=1, - persistence=0.5, - lacunarity=2.0, - repeatx=None, - repeaty=None, - base=0, + octaves: int = 1, + persistence: float = 0.5, + lacunarity: float = 2.0, + repeatx: Optional[int] = None, + repeaty: Optional[int] = None, + base: int = 0, ) -> float: """ noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=None, repeaty=None, base=0.0) From cd99a9d3c5e73745ec2252d1df1366932277fe84 Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 19:54:31 -0800 Subject: [PATCH 8/9] isort --- vnoise/vsnoise.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index c385e1b..fe94481 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -4,12 +4,12 @@ // $Id$ """ import random +from math import floor from typing import Optional, Sequence import numpy as np -from ._tables import PERM, GRAD4, GRAD3, M_1_PI, SIMPLEX - +from ._tables import GRAD3, GRAD4, M_1_PI, PERM, SIMPLEX "Native-code simplex noise functions" @@ -17,9 +17,6 @@ F2 = 0.3660254037844386 # 0.5 * (sqrt(3.0) - 1.0) G2 = 0.21132486540518713 # (3.0 - sqrt(3.0)) / 6.0 -from math import floor - - def _snoise2_impl(x: float, y: float) -> float: s = (x + y) * F2 i = floor(x + s) From de7a60b7599df733b2c449420554ef93dacbd03b Mon Sep 17 00:00:00 2001 From: tatarize Date: Thu, 25 Feb 2021 19:54:47 -0800 Subject: [PATCH 9/9] black --- vnoise/vsnoise.py | 1 + 1 file changed, 1 insertion(+) diff --git a/vnoise/vsnoise.py b/vnoise/vsnoise.py index fe94481..d11c820 100644 --- a/vnoise/vsnoise.py +++ b/vnoise/vsnoise.py @@ -17,6 +17,7 @@ F2 = 0.3660254037844386 # 0.5 * (sqrt(3.0) - 1.0) G2 = 0.21132486540518713 # (3.0 - sqrt(3.0)) / 6.0 + def _snoise2_impl(x: float, y: float) -> float: s = (x + y) * F2 i = floor(x + s)