skip to content

26 Oct 2026 · numerics · 2 min

Why the pond uses Δy = 2Δx

The pond on the home page is a numerical solution of the damped wave equation, drawn one character per grid cell:

∂2u∂t2=c2∇2u−γ∂u∂t\frac{\partial^2 u}{\partial t^2} = c^2 \nabla^2 u - \gamma \frac{\partial u}{\partial t}

The catch is that a character cell is not square. A monospaced glyph advances about 0.6 em0.6\,\mathrm{em}, and with a line height of 1.2 em1.2\,\mathrm{em} every cell is twice as tall as it is wide. A grid that pretends the two spacings are equal stretches every ripple into a 2:12:1 ellipse.

fig. 1 — the same radial wave sampled with Δy = Δx (left) and Δy = 2Δx (right)

Discretising

Central differences in time and in both space directions give the explicit leapfrog update

ui,jn+1=2ui,jn−ui,jn−1+rx(ui+1,jn−2ui,jn+ui−1,jn)+ry(ui,j+1n−2ui,jn+ui,j−1n)\begin{aligned} u^{n+1}_{i,j} = {} & 2u^{n}_{i,j} - u^{n-1}_{i,j} \\ & + r_x\left(u^{n}_{i+1,j} - 2u^{n}_{i,j} + u^{n}_{i-1,j}\right) \\ & + r_y\left(u^{n}_{i,j+1} - 2u^{n}_{i,j} + u^{n}_{i,j-1}\right) \end{aligned}

with rx=c2Δt2/Δx2r_x = c^2\Delta t^2/\Delta x^2 and ry=c2Δt2/Δy2r_y = c^2\Delta t^2/\Delta y^2. Setting Δy=2Δx\Delta y = 2\Delta x gives ry=rx/4r_y = r_x/4, so the shape of the screen is absorbed into the coefficients rather than distorting the geometry.

Stability

An explicit scheme is only stable if its numerical domain of dependence contains the physical one. For this scheme in two dimensions, the Courant–Friedrichs–Lewy condition reads

c2Δt2(1Δx2+1Δy2)≤1⟺rx+ry≤1.c^2\Delta t^2\left(\frac{1}{\Delta x^2} + \frac{1}{\Delta y^2}\right) \le 1 \quad\Longleftrightarrow\quad r_x + r_y \le 1 .

The pond uses rx=0.5r_x = 0.5 and ry=0.125r_y = 0.125, so rx+ry=0.625r_x + r_y = 0.625: comfortably stable, with headroom to make the waves faster.

Damping and drawing

Instead of differencing the γ ∂u/∂t\gamma\,\partial u/\partial t term, each update is multiplied by (1−ε)(1-\varepsilon) with ε=0.004\varepsilon = 0.004. For a single mode, the two roots of the resulting recurrence are complex conjugates whose product is 1−ε1-\varepsilon, so a free ripple decays as (1−ε)n/2≈e−εn/2(1-\varepsilon)^{n/2} \approx e^{-\varepsilon n/2} after nn steps.

Each cell then picks a glyph from the density ramp . · : - = + * # % according to ∣u∣|u|, and crests above u=0.3u = 0.3 are drawn in the accent colour, so peaks and troughs stay distinguishable.