Drag a galaxy cluster and its gravity bends a deep field into giant arcs.
Every pixel is a light ray traced backward through the lens equation, beta = theta - alpha(theta), into a procedurally painted deep field of spirals, ellipticals and star-forming knots. The deflection alpha comes from a softened isothermal ellipsoid halo, using Keeton's closed-form solution, plus isothermal spheres for 16 member galaxies and any clumps you add; it is evaluated on a coarse grid and interpolated per pixel. Because lensing conserves surface brightness, that one lookup produces the giant arcs, multiple images and near rings. Critical curves, where the Jacobian determinant of the lens mapping vanishes, are traced by marching squares, and mapped through the lens equation into caustics on the source-plane inset: sources that straddle a caustic become the brightest arcs.
Try it. Drag the cluster center or any clump; click empty sky to add a mass clump and right-click or Shift-click to remove one. The wheel or up and down arrows change the halo mass, left and right rotate it, E changes its ellipticity, C toggles the critical curves, S the source-plane inset, N paints a new background field, R resets, and holding Space shows the unlensed sky.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a gravitational lensing simulator with JavaScript and the HTML canvas element: a galaxy cluster that bends a background field into arcs. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window and stays sharp on high-DPI screens.
- Paint a background "source" image into an offscreen canvas: black space with a few hundred small soft galaxies in blue, white and orange, and a few bigger spirals made of soft dots along logarithmic spiral arms. Read its pixels once with getImageData.
- Render the lensed view at a reduced resolution (for example 320 x 200) into its own ImageData. For each pixel at angle theta, compute the deflection of a point mass or singular isothermal sphere at the cluster center, alpha = b * (theta - center) / |theta - center|, then look up the source image at beta = theta - alpha and copy that color.
- Draw the result scaled up to the full canvas and draw a soft yellow glow for the cluster's central galaxy on top.
- Let me drag the cluster around and watch the arcs and Einstein rings form.
Once that works, make it beautiful:
- Make the halo elliptical (a softened isothermal ellipsoid has a closed-form deflection with atan and atanh) and add a dozen smaller member galaxies with their own deflections.
- Use bilinear interpolation when sampling the source so stretched arcs look smooth.
- Compute the deflection on a coarse grid, find where det(I - d alpha / d theta) changes sign, and draw those critical curves as glowing lines.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as clicking to add dark matter clumps, an inset showing the caustics in the source plane, or a key that shows the unlensed sky.