particles_paths · sandstroke
Sand Stroke
The Sand Stroke is applied here in it's most basic form. Each image is composed of approximately 42 sand strokes. Each instance of the sand stroke lays down grains of colored sand (pixel exposures) growing horizontally from left to right. For every layer of growth, the sand stroke deposits precisely the same number of sand grains despite the magnitude of the wave. This produces a very interesting density modulation across an even mass of sand.
Original: https://complexification.net
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
k horizontal sweep agents walk rightward at vx pixels per frame; each step the head paints a leading column and a tapered fan of wd grain samples modulated by gage*sin(i*w). On crossing the right edge a sweep self-reinitialises with a fresh palette colour and y-position.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 500 | 200–1000 | Square canvas side length in pixels. |
k | int | 22 | 4–64 | Number of horizontal sweeps. |
wd | int | 200 | 40–400 | Number of grain samples laid down per sweep step (density of fan). |
vx | float | 1 | 0.25–4 | Horizontal sweep speed (pixels per step). |
stroke_alpha | float | 0.07 | 0.01–0.3 | Alpha of the leading edge column. |
fan_alpha | float | 0.1 | 0.05–0.4 | Base alpha of the tapered fan grains. |
gauge_walk | float | 0.042 | 0–0.1 | Per-step random walk amplitude on the fan angular frequency. |
gauge_max | float | 0.3 | 0.05–1 | Clamp on the fan wave amplitude. |
Reference
First 60 lines of reference.py. Full source:
library/sandstroke/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
_PALETTE = np.array(
[
(0, 0, 0),
(15, 15, 15),
(32, 32, 32),
(54, 54, 54),
(76, 60, 38),
(96, 75, 50),
(118, 92, 64),
(140, 110, 80),
(162, 130, 96),
(184, 150, 112),
(200, 170, 128),
(212, 188, 144),
(224, 204, 160),
(236, 220, 176),
(244, 232, 192),
(252, 244, 208),
(255, 240, 200),
(220, 100, 80),
(180, 70, 60),
(140, 50, 45),
(100, 40, 35),
(60, 80, 60),
(80, 110, 90),
(140, 170, 140),
(80, 100, 140),
(110, 140, 180),
(160, 200, 220),
(220, 220, 200),
(245, 240, 230),
(255, 250, 235),
],
dtype=np.float32,
)
class SandStroke:
"""Sand Stroke — j.tarbell, January 2004.
k horizontal sweeps grow left-to-right across a square canvas. Each
sweep carries a stochastic vertical wave whose amplitude ``gage`` is
slowly modulated. Every step the sweep paints a column of pixels at
its head and a tapered fan above/below the head whose width is
``gage * sin(i*w)`` for ``wd`` samples. When the sweep leaves the
canvas on the right it ``selfinit``s with a fresh color and starts
back at the left edge.
This is the canonical sand-stroke painter: it lays down a coloured
column at the leading edge and a fading fan of the same color up and
down to produce the dense, granulated strokes Tarbell is known for.
"""
Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library/sandstroke/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from core library
Binary Ring
particles_paths · binaryRing
A system of path tracing particles evolves continually from an initial creation.
Bit 10001
networks_fractals · bit10001
(no description available) — Bit 10001 is a 3D particle system of 10,001 mutually-interacting points rendered to 2D via a rotating perspective camera.
Box Fitting
growth_aggregation · boxFitting
Box Fitting (source code)
Box Fitting Img
growth_aggregation · boxFittingImg
The classic box fitting algorithm (see Box Fitting) modified with an image substrate, allowing new boxes to draw color from an invisible background.
Bubble Chamber
physics_chamber · bubblechamber
The Bubble Chamber is a generative painting system of imaginary colliding particles.
Buddhabrot
networks_fractals · buddhabrot
(no description available) — Buddhabrot is the rendering of escape-time trajectories of the Mandelbrot iteration.