Skip to content
Sample of Wave Interference

akten_quayola · WaveInterference

Wave Interference

N drifting point sources emit circular sinusoidal waves whose superposition is tone-mapped into a stormy ocean-like field. Inspired by Akten's Waves series, which draws on the history of ocean painting from Hokusai and Turner to Aivazovsky and uses computational simulations to dramatise water. Frequency ratios are quantized to small integers so the interference fringes form visible moire and constructive-band structures as sources drift around the canvas.

Original: https://www.memo.tv/works/waves-2-0-terra/

▶ 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.

Family
akten_quayola
Source
akten × quayola
Evolution
wave
Render
wave_field_palette
Complexity
medium
Agents
6
Year
2014
Author
Memo Akten (memo.tv)

Math essence

For each source i with normalized position p_i and frequency f_i, the wave contribution at pixel (x, y) is exp(-d/(w*0.45)) * sin(f_i*d - wave_speed*100*t + phase_i), where d = ||(x,y) - p_i||. Field = sum_i / num_sources; render reads tanh(field * 1.4) into a swell-trough-crest palette.

Parameters

Name Type Default Range Description
num_sources int 6 3–12 Number of point wave sources.
dim int 512 256–1024 Output canvas side length.
wave_speed float 0.06 0.01–0.2 Time evolution rate of the wave phases.
frequency_base float 0.12 0.04–0.3 Base spatial frequency of the smallest source.
drift float 0.004 0–0.02 Per-step Gaussian drift of each source position.

Reference

First 60 lines of reference.py. Full source: library_external/akten_quayola/WaveInterference/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


class WaveInterference:
    """Wave Interference — Memo Akten, *Waves* (2014–).

    Akten's Waves series renders the surface of an imagined ocean by
    simulating multiple radial wave sources and summing their
    contributions.  Here the kernel is reduced to its purest form:  N
    point sources at random positions emit circular sinusoidal waves;
    the field at each pixel is the sum of those contributions and is
    tone-mapped through a perceptual palette that evokes Akten's Hokusai-
    and Turner-inspired ocean abstractions.

    Sources slowly drift across the domain (Akten's "complex signal
    broken down into its basic elements at different frequencies") and
    their frequencies are quantized ratios so the resulting pattern
    exhibits clear constructive and destructive interference fringes.
    """

    family: ClassVar[str] = "akten_quayola"
    sketch: ClassVar[str] = "WaveInterference"

    def __init__(
        self,
        num_sources: int = 6,
        dim: int = 512,
        wave_speed: float = 0.06,
        frequency_base: float = 0.12,
        drift: float = 0.004,
        seed: int | None = None,
        background: tuple[int, int, int] = (8, 14, 28),
        **_,
    ) -> None:
        self.num_sources = int(num_sources)
        self.dim = int(dim)
        self.wave_speed = float(wave_speed)
        self.frequency_base = float(frequency_base)
        self.drift = float(drift)
        self.bg_color = np.array(background, dtype=np.float32)
        self.reset(seed=seed)

    def reset(self, seed: int | None = None) -> None:
        self.rng = np.random.default_rng(seed)
        self.t = 0
        self.positions = self.rng.uniform(0.0, 1.0, size=(self.num_sources, 2)).astype(np.float32)
        self.phases = self.rng.uniform(0.0, np.pi * 2.0, size=self.num_sources).astype(np.float32)
        ratios = np.array([1.0, 1.5, 2.0, 2.5, 3.0], dtype=np.float32)
        ratio_idx = self.rng.integers(0, len(ratios), size=self.num_sources)
        self.freqs = (self.frequency_base * ratios[ratio_idx]).astype(np.float32)
        ys, xs = np.mgrid[0:self.dim, 0:self.dim].astype(np.float32)
        self.grid_x = xs
        self.grid_y = ys

    def step(self, n: int = 1) -> None:
        for _ in range(n):

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/akten_quayola/WaveInterference/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from akten × quayola

Sample of Gesture Driven Field

Gesture Driven Field

akten_quayola · GestureDrivenField

Particles advected through a vector field whose structure is driven by a synthetic gesture signal: a chain of sinusoids at integer-related frequencies.

View →
Sample of Lissajous 3D

Lissajous 3D

akten_quayola · Lissajous3D

A three-dimensional Lissajous figure rendered as a single precision line drawing on a deep field.

View →
Sample of Mechanical Flower Spline

Mechanical Flower Spline

akten_quayola · MechanicalFlowerSpline

A 2D petal-radius spline r(θ) = r0 + A*cos(p*θ + δ) + B*cos(q*θ) swept 360° around a vertical Y axis to form a procedural flower-like 3D surface, then orthographically projected and depth-shaded.

View →
Sample of Pleated Fabric

Pleated Fabric

akten_quayola · PleatedFabric

A textile grid whose vertical coordinate follows z = A * envelope(y) * sin(2π f x + phase(t)), projected obliquely onto a 2D canvas so the folds read as parallel ridges of light.

View →
Sample of Simple Harmonic Motion

Simple Harmonic Motion

akten_quayola · SimpleHarmonicMotion

A 100x100 grid of damped harmonic oscillators driven by a periodic central impulse.

View →
Sample of Strata Landscape

Strata Landscape

akten_quayola · StrataLandscape

A geological landscape rendered as N horizontal strata stacked vertically, each band displaced by a slowly growing sinusoid and shaded with its own hue.

View →

See all akten_quayola artworks →