Walldye

Eclipse contours

Inside a heavy ring, noise contours bunch where a disc’s surface drops away. A faint ring sits outside.

Made with Claude Opus 5.5

Technique
flow fields and contours
Shape
Any screen
Added
27 September 2026

Colours

  • #1C1B1Abackground
  • #DAD8CEforeground
  • #CF6A4Caccent

Export

Format
Shape
Size

Sources

  1. Marching squares.
  2. Inigo Quilez, FBM.

Source code

wallpapers/eclipse-contours/design.py, 46 lines

"""Noise contour lines confined to a disc inside two rings: an fBm field traced by marching squares and clipped."""

import numpy as np
from numpy.typing import NDArray

from walldye import ACCENT, ACCENT_4, BG, UI, Canvas, P, design, ladder
from walldye.field import iso_lines, sample_field

R, CELL = 330, 6  # disc radius; field sample spacing
SPAN = 420  # px per noise unit
AT = (1240 / SPAN, 540 / SPAN)  # the noise-plane point under the disc centre
LEVELS = [-0.3 + k * 0.035 for k in range(18)]
# one tone per level, skipping the near-background end of the ladder so every line reads
TONES = ladder((BG, ACCENT_4, ACCENT), len(LEVELS) + 4)[4:]


@design(aspects="any")
def draw(s: Canvas) -> None:
    # about 0.65 along the long axis (clear of the left-side windows on a desktop, below the
    # clock on a phone), centred on the short axis
    c = s.pick(landscape=(0.646, 0.5), portrait=(0.5, 0.6))
    noise = s.noise(7)
    # Sample only the disc's bounding box, relative to its centre, so every aspect shows the
    # same planet.
    half = int(np.ceil((R + 2 * CELL) / CELL))

    def height(i: NDArray[np.int64], j: NDArray[np.int64]) -> NDArray[np.float64]:
        dx, dy = (i - half) * CELL, (j - half) * CELL
        d = np.hypot(dx, dy) / R
        # the negative falloff past 0.85 R bunches the lines against the rim, like a limb
        return noise.fbm(AT[0] + dx / SPAN, AT[1] + dy / SPAN, 4) - 0.9 * np.maximum(0.0, d - 0.85)

    field = sample_field(height, 2 * half, 2 * half)
    origin = c - (half * CELL, half * CELL)
    with s.clip() as disc:
        disc.add(P().circle(c, R))
    with (
        s.group(clip_path=disc.ref),
        s.buckets(TONES, "stroke", stroke_width=1.6, stroke_linejoin="round") as lines,
    ):
        for k, level in enumerate(LEVELS):
            for line in iso_lines(field, level, cell=CELL, origin=origin):
                if len(line) > 3:
                    lines[k].poly(line)
    s.stroke(P().circle(c, R + 18), UI, 2)
    s.stroke(P().circle(c, R), ACCENT, 3)

Run it yourself

$ git clone https://github.com/nickolaj-jepsen/walldye && cd walldye$ uv run walldye render eclipse-contours --theme fireproof -o eclipse-contours-fireproof-16x9.svg