<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://nanisaac.github.io/notes/feed.xml" rel="self" type="application/atom+xml" /><link href="https://nanisaac.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-17T20:55:38+00:00</updated><id>https://nanisaac.github.io/notes/feed.xml</id><title type="html">Isaac Yong</title><subtitle>Notes on X-ray physics, scientific software, and the tools in between.</subtitle><author><name>Isaac Yong</name></author><entry><title type="html">How the homepage wave works</title><link href="https://nanisaac.github.io/notes/2026/10/how-the-hero-wave-works/" rel="alternate" type="text/html" title="How the homepage wave works" /><published>2026-10-13T00:00:00+00:00</published><updated>2026-10-13T00:00:00+00:00</updated><id>https://nanisaac.github.io/notes/2026/10/how-the-hero-wave-works</id><content type="html" xml:base="https://nanisaac.github.io/notes/2026/10/how-the-hero-wave-works/"><![CDATA[<p>The ripple field on the front page is not an animation loop. It is a small solver
for the 2D scalar wave equation, stepped about 120 times per second in your browser.</p>

<h2 id="model">Model</h2>

\[\frac{\partial^2 u}{\partial t^2} = c^2 \left( \frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} \right) + s(x, y, t)\]

<p>discretized with the explicit leapfrog scheme and a five-point Laplacian on square cells:</p>

\[u^{n+1}_{ij} = 2u^n_{ij} - u^{n-1}_{ij} + r^2 \left( u^n_{i+1,j} + u^n_{i-1,j} + u^n_{i,j+1} + u^n_{i,j-1} - 4u^n_{ij} \right)\]

<p>with \(r = c\,\Delta t / \Delta x = 0.5\), inside the 2D stability limit \(r \le 1/\sqrt{2}\).
Units are grid cells and time steps — there is no mapping to SI and none is implied.</p>

<ul>
  <li><strong>No continuous source</strong> on the home page: the field rests until something taps it. Until
you do, a ghost hand left of the slits alternates a tap and a swipe, feeding the field
exactly what a real tap or mouse move would. The slit itself is fixed here; moving it is the <a href="/lab/">lab</a>’s job. (The lab keeps two coherent oscillators
with \(T = 24\) steps by default, so the wavelength is \(cT = 12\) cells; a slider changes it.)</li>
  <li><strong>Moving the mouse</strong> leaves a faint wake of Gaussian bumps whose amplitude scales with
pointer speed (scrolling with the mouse resting on the film counts as moving); <strong>click</strong> adds one strong bump; <strong>dragging</strong> adds a rate-limited trail.</li>
  <li><strong>The barrier</strong> is two cells of Dirichlet wall, \(u = 0\), with a six-cell graded damping
layer on its upstream face, so the jaws mostly soak up what hits them, like tungsten
X-ray slit blades. This is an approximation, not a perfect absorber: some reflection
remains. (The lab can switch the jaws to ideal reflectors.) Each slit is 7 cells wide,
narrower than the 12-cell wavelength, so diffraction is strong.</li>
  <li><strong>Edges</strong> use a quadratic sponge layer,
\(u^{n+1} = \left[ 2u^n - (1-\sigma)u^{n-1} + r^2 \nabla^2 u^n \right] / (1+\sigma)\),
to suppress border reflections. It is an approximation, not a perfectly matched layer.</li>
</ul>

<h2 id="the-detector-line">The detector line</h2>

<p>The curve on the right is an exponential moving average of \(u^2\) along one column,
with a time constant of about six periods, normalized to its own maximum. It is a
<em>relative</em> intensity from the solver arrays only — the glow and bloom are drawn on top
and never feed into it. In the lab, drag a slit and the fringes on the detector respond after a short lag.</p>

<p>One honest caveat: this is an in-plane 2D field. A real double slit lit in 3D produces a
2D pattern on a screen; here the slit is a gap in a line, and the detector sees a 1D profile.
The fringe physics — spacing shrinks as the slits move apart — is the same.</p>

<h2 id="colors">Colors</h2>

<p>The field is drawn like exposed film on a grey panel: crests develop toward the ink colour,
troughs toward the opposite tone. The shading is a visual encoding of the sign of \(u\),
not the colour of any real wavelength.</p>

<p>The solver is about 100 lines of plain JavaScript (<code class="language-plaintext highlighter-rouge">wave.js</code>), with a regression test that
checks stability, absorption at the edges, that a closed barrier blocks transmission, and
that the absorbing jaws send back less than a quarter of the energy reflecting ones do.</p>]]></content><author><name>Isaac Yong</name></author><category term="simulation" /><category term="waves" /><summary type="html"><![CDATA[The model behind the interactive hero — a 2D scalar wave equation on a grid, a double slit with absorbing jaws, and what the detector line does and does not measure.]]></summary></entry></feed>