Clear plastic parts under load light up with stress fringes between polarizers.
Stressed plastic becomes birefringent, so between crossed circular polarizers every point glows with a color set by its principal stress difference. The stresses come from a real finite element solve: each part is meshed on a grid of bilinear plane-stress elements, cells cut by the outline keep a stiffness scaled by their covered area, and the banded stiffness matrix is Cholesky factored a slice per frame. Because the problem is linear, the program solves once for a unit force in x and once in y and blends them for whatever force you drag. Element stresses are averaged to the nodes, interpolated per pixel, turned into retardation, and colored by integrating sin^2(pi R / wavelength) over the visible spectrum, which reproduces the black, white, yellow, red, violet and blue isochromatic fringes. Switch to a plane polariscope and the black isoclinics appear where the principal directions line up with the polarizer.
Try it. Drag the arrow's handle to change the force, drag its tip along the outline to move the load point, or press and drag anywhere on the part to push it with a finger. Keys 1 to 5 switch parts, P toggles plane and circular polariscope (arrow keys turn the polarizer), L toggles dark and light field, up and down change the load, and space pauses the breathing load.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a photoelasticity simulator with JavaScript and the HTML canvas element: a plastic disk squeezed between two points glows with rainbow stress fringes, as it would between crossed polarizers. 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 on a black background.
- Write a function that turns a retardation R in nanometers into a color. For wavelengths from 380 to 780 nm the light through a dark-field circular polariscope is sin^2(pi * R / wavelength). Weight it with an approximation of the CIE x, y, z color matching functions, convert XYZ to linear sRGB, white balance so a flat spectrum is white, and gamma encode. Precompute a table from 0 to 3000 nm and draw it as a strip to check it: black, gray, white, yellow, red, violet, blue, green, then repeating pinks and greens.
- Use the exact stress field for a disk in diametral compression (two point loads on the vertical diameter, the Flamant-based closed form you can find in any elasticity textbook) to compute sigma_x, sigma_y and tau_xy at every pixel inside the disk.
- Color each pixel with the table at R = k * sqrt((sigma_x - sigma_y)^2 + 4 tau_xy^2), and animate k up and down so fringes bloom out from the contact points and recede.
Once that works, make it beautiful:
- Add a slider or drag gesture for the load, a faint rim around the disk, and a fringe order key.
- Add a plane polariscope mode that multiplies by sin^2(2 (theta - alpha)), where theta is the principal stress direction, to show black isoclinics that sweep as the polarizer turns.
- Add a light-field mode that shows the complementary colors.
Explain the optics and mechanics 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 a small finite element solver for arbitrary shapes like a crane hook or a beam with holes, draggable loads, or stress concentration around a hole in a plate.