Back to Portfolio

Drawing with harmonics

Shape is a path. Speed is a signal.

A signal-processing studio for gestures

Two identical paths can describe very different motion. Keep the shape, inspect the timing, and see what survives when you change the representation.

↔ Window microscope ↔ Wavelet reconstruction

Timed trefoil ready to explore · draw your own, or change the preset below.

Input motionWindowed targetCurrent STFT curveGlowing tip traceRotating vectors

STFT measures recent motion. The windowed sketch is tapered; choose Match sampled path to recover the original time samples.

The sketch tapers toward its mean. Recovery uses all bins and overlapping windows; its vector budget is fixed.

The same path rushes through one part and lingers through another. Parameter speed varies about 152×; geometric speed also depends on the curve.

Inside this window

The green path supplies timed samples. Windowed sketch tapers motion toward its mean and keeps a limited spectrum. Match sampled path uses inverse STFT to recover the untapered buffer; gold rotors then decompose that buffer and follow its latest sample. In sketch mode the tip freely tours a changing local curve; in recovery mode it follows the input with one sample interval of delay.

—non-DC spectral energy retained
—RMS error against windowed target
—analysis + geometry update

Timing changes the spectrum without changing the path. “Steady parameter speed” advances the curve parameter uniformly; geometric speed can still vary. Endpoint holds preserve pauses. Energy excludes the DC offset. The sketch omits Nyquist; recovery retains it. Samples end one interval before now: a time-local reconstruction is not a prediction of the current pointer. A full match refers to these 128 interpolated samples, not unrecorded detail between mouse events.

01 · Keep the shape

Global Fourier coefficients represent the whole sampled curve. Cosine extends it with a reversed copy.

02 · Keep the timing

Draw quickly, slowly, then pause. STFT measures recent motion at uniform time intervals, so all three leave different signatures.

03 · Change the representation

Compare window sizes below, then use localized wavelets to reconstruct the same kind of timed gesture.

The basis and its drawing are different choices

One rotor. Two oscillations.

A complex exponential rotates: eiθ = cos θ + i sin θ. A scalar cosine and a scalar sine both oscillate along a fixed axis, a quarter-cycle apart. Neither scalar basis intrinsically spins.

Complex Fourier

Each complex coefficient is a rotating vector. Positive and negative frequencies turn in opposite directions; their sum draws a planar curve.

Cosine · even extension

cos θ = (eiθ + e−iθ)/2. This view draws the two counter-rotating parts, whose transverse motion cancels. The reconstructed gesture goes out and back.

Sine · odd extension

sin θ = (eiθ − e−iθ)/(2i). Here we draw the combined fixed-axis contribution directly. Removing and restoring a straight baseline lets the sine residual preserve the two endpoints.

Why increasing the sketch budget cannot undo Hann tapering: more frequencies reproduce the tapered target more faithfully. Recovering the original samples needs an inverse transform with overlapping windows: sum the inverse frames times Hann, then divide by the accumulated Hann squared. Padding covers both ends of the finite buffer. No division by a single window’s zero-valued endpoint is needed.

References: SciPy: inverse STFT and dual windows · FFTW: even/odd cosine and sine transforms.

Interactive schematic · time–frequency resolution

A sharper clock or a sharper spectrum?

Both instruments below observe the same signal. Only the Hann-window duration changes. The colors show amplitude on the same −50 to 0 dB scale; darkness means little energy.

What each reconstruction preserves

DFT · the full path

The input is x + iy. Each complex coefficient supplies one global rotating vector. Presets use uniformly timed samples, so burst-and-linger timing affects their global spectrum too. Custom strokes use event order in this mode.

Cosine basis · an even extension

The curve is followed by its reversed copy and analyzed with a DFT. Opposite frequencies stay paired, so the motion retraces symmetrically. It demonstrates the even-extension relationship behind the DCT.

STFT · recent motion

The last window is interpolated onto 128 evenly spaced time samples. Windowed sketch tapers displacement around its mean; Match sampled path uses overlapping inverse transforms to recover the untapered samples. A stationary pointer remains a stationary offset in both views.

Sampling, timing and what this demo does not claim

A global Fourier transform can also encode speed when its input is sampled uniformly in time. STFT adds time localization: it does not invent timing information missing from a global transform. Here the pointer timestamps are retained specifically for the STFT mode.

Pointer positions are linearly interpolated between events, with the first and last positions held beyond the available event range. Resampling does not recover motion that was never captured. With 128 samples over T seconds, the analyzed Nyquist limit is 64/T Hz.

Fourier’s two selection policies use the same full discrete spectrum and the same coefficient budget. Both keep the mean. “Largest” minimizes sample-space squared error among the remaining coefficients of this fixed orthogonal basis; it does not change the transform. The dotted comparison uses the other policy. The error is measured against uniformly indexed samples, before display interpolation.

The microscope uses a radix-2 FFT and a periodic Hann window. Its Δf = 1/T is the bin spacing; practical peak separation also depends on window width, signal variation and noise. The live STFT, static Fourier modes and sine transform reuse FFT plans. Static reconstructions change only with the input or controls.

Change the boundary, change the basis

The runnable Sine · anchored endpoints mode removes the straight line between the gesture’s endpoints, decomposes the remaining motion with a DST-I, and adds the line back. Every sine mode vanishes at both ends. With all 255 interior modes, the 257 sampled positions reconstruct exactly; a small budget smooths the interior while preserving both anchors.

Fourier
periodic continuation
Cosine
even reflection
Sine
fixed endpoints
Haar
local intervals

Cosine · reflect without flipping

An even extension keeps the same value on either side of a boundary: f(−t) = f(t). Here the sample order is mirrored, so the rotating vectors go out along the curve, then retrace it. The reflection planes sit halfway beyond the first and last samples, as in a DCT-II. Keeping fewer modes can move the endpoint values; they are not pinned.

Sine · reflect and change sign

An odd extension flips the residual: r(−t) = −r(t). A continuous residual must therefore be zero at the reflection boundary. We first subtract the line between the two endpoints, leaving exactly that condition. Each sin(kπt) contribution vanishes at both ends, so even one retained mode preserves both anchors.

These are different boundary assumptions for reconstructing each coordinate; they do not require the drawn shape itself to be mirror-symmetric. In sine mode the gold segments oscillate along fixed directions, like standing waves, instead of rotating around circles. The tip travels out and back because of the playback clock; the sine basis does not require that motion.

Try Open flourish with a small budget, then compare Cosine and Sine. Watch which endpoints move as you remove detail. Transform conventions: FFTW · even and odd extensions ↗

This is also a useful bridge to modal analysis. A uniform spring chain with pinned ends has discrete sine-shaped eigenvectors. Here, the coefficients reconstruct a drawn path; they are not simulated sound amplitudes. Modal2D goes further: geometry, material and boundary conditions determine the eigenproblem, and excitation and damping determine the sound.

↔ Continue to Modal2D · geometry becomes an instrument

The Mathematics

Fourier Series Decomposition:

$$f(t) = \sum_{n=-\infty}^{\infty} c_n e^{2\pi i n t}$$

Each coefficient $c_n$ represents a rotating circle with radius $|c_n|$ and frequency $n$

Discrete Fourier Transform:

$$X_k = \sum_{n=0}^{N-1} x_n e^{-2\pi i k n / N}$$

Converts discrete time-domain points to frequency components (complex coefficients)

Discrete Cosine Transform (Type-II):

$$X_k = \sum_{n=0}^{N-1} x_n \cos\left[\frac{\pi k (n + 0.5)}{N}\right]$$

Real-valued transform using only cosine basis. Popular in compression (JPEG uses 8×8 DCT blocks)

Discrete Sine Transform (Type-I):

$$b_k = \frac{2}{N+1}\sum_{j=1}^{N} r_j\sin\left(\frac{\pi kj}{N+1}\right),\qquad r_j=\sum_{k=1}^{N} b_k\sin\left(\frac{\pi kj}{N+1}\right)$$

Here N = 255 interior samples. The endpoint baseline is removed before analysis and restored after synthesis; x and y are transformed independently.

Complex Exponential as Rotation:

$$e^{i\theta} = \cos\theta + i\sin\theta$$

Euler's formula shows why Fourier naturally creates rotating circles—complex exponentials trace circular paths!

Short-Time Fourier Transform (STFT):

$$\text{STFT}(t, \omega) = \int_{-\infty}^{\infty} f(\tau) w(\tau - t) e^{-i\omega\tau} d\tau$$

Applies Fourier transform to windowed segments $w(t)$ (e.g., Hann window) sliding through time