Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

__version__ = "1.2.3"

from . import _perlin, _simplex

from . import _perlin, _simplex, _cellular
snoise2 = _simplex.noise2
snoise3 = _simplex.noise3
snoise4 = _simplex.noise4
pnoise1 = _perlin.noise1
pnoise2 = _perlin.noise2
pnoise3 = _perlin.noise3
cnoise2 = _cellular.noise2
100 changes: 100 additions & 0 deletions _cellular.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) 2008, Casey Duncan (casey dot duncan at gmail dot com)
// see LICENSE.txt for details
// $Id$

#include "Python.h"
#include "_noise.h"
#include <math.h>

#define PERM_SIZE 256
#define PERM_MASK (PERM_SIZE - 1)
#define OFFSET_INV 0.0625f /* 1.0 / 16.0 */

static inline float sqr_dist(float x1, float y1, float x2, float y2) {
return ((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2));
}

// cellular noise implementation
// https://en.wikipedia.org/wiki/Worley_noise
// https://sangillee.com/2025-04-18-cellular-noises/
float noise2_cellular(float x, float y) {
int ix = fastfloor(x);
int iy = fastfloor(y);

float xf = x - (float)ix;
float yf = y - (float)iy;
float min_dist_sq = 8.0f;

int i_wrapped[3], j_wrapped[3];
for (int n = 0; n < 3; n++) {
i_wrapped[n] = (ix + (n - 1) + 1024) & PERM_MASK;
j_wrapped[n] = (iy + (n - 1) + 1024) & PERM_MASK;
}

for (int i = 0; i < 3; i++) {
float dx_base = (float)(i - 1) - xf;
int o = PERM[i_wrapped[i]];
for (int j = 0; j < 3; j++) {
int hash = PERM[o + j_wrapped[j]];
float dx = dx_base + (float)(hash & 15) * OFFSET_INV;
float dy = ((float)(j - 1) - yf) + (float)(hash >> 4) * OFFSET_INV;

float d_sq = (dx * dx) + (dy * dy);

if (d_sq < min_dist_sq) {
min_dist_sq = d_sq;
}
}
}
return sqrtf(min_dist_sq);
}

static PyObject *py_noise2_cellular(PyObject *self, PyObject *args) {
float x, y;
if (!PyArg_ParseTuple(args, "ff", &x, &y))
return NULL;
return PyFloat_FromDouble((double)noise2_cellular(x, y));
}

PyDoc_STRVAR(noise2_doc,
"noise2(x, y)\n\n"
"2 dimensional cellular (Worley) noise function.\n"
"Returns the distance to the nearest feature point.");

static PyMethodDef cellular_functions[] = {
{"noise2", (PyCFunction) py_noise2_cellular, METH_VARARGS | METH_KEYWORDS, noise2_doc},
{NULL}
};

PyDoc_STRVAR(module_doc, "Native-code implementation of cellular (Worley) noise functions");


#if PY_MAJOR_VERSION >= 3

static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"_cellular",
module_doc,
-1, /* m_size */
cellular_functions, /* m_methods */
NULL, /* m_reload (unused) */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL /* m_free */
};

PyObject *
PyInit__cellular(void)
{
return PyModule_Create(&moduledef);
}

#else

void
init_cellular(void)
{
Py_InitModule3("_cellular", cellular_functions, module_doc);
}

#endif
33 changes: 33 additions & 0 deletions examples/cellnoise.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Writes a 256x256 grayscale cell noise texture to a file in pgm format
(see http://netpbm.sourceforge.net/doc/pgm.html)
"""
# $Id: cellnoise.py $

import sys
from noise import _cellular

if len(sys.argv) not in (2, 3) or '--help' in sys.argv or '-h' in sys.argv:
print()
print(__doc__)
raise SystemExit

if len(sys.argv) < 2:
print('Usage: python cellular_texture.py OUTPUT_FILE.pgm')
sys.exit(1)

filename = sys.argv[1]
size = 256
scale = 16.0

with open(filename, 'wt') as f:
f.write('P2\n')
f.write(f'{size} {size}\n')
f.write('255\n')

for y in range(size):
for x in range(size):
val = _cellular.noise2(x / scale, y / scale)
brightness = int((1.0 - min(val, 1.0)) * 255)
f.write(f"{brightness}\n")

print(f"Texture saved to {filename}")
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
),
Extension('noise._perlin', ['_perlin.c'],
extra_compile_args=compile_args,
),
Extension('noise._cellular', ['_cellular.c'],
extra_compile_args=compile_args,
)
],
)