Wednesday, February 12, 2014

Playing with Moiré Patterns and HTML5 Canvas


A few days ago I was programatically creating some Polar + Cartesian dual coordinate graph paper as a teaching aide for a lesson on coordinate systems.  While doing so I accidentally created a pretty cool Moiré pattern.  I encountered enough fun math, physics, and biology concepts while playing with the pattern that I decided to code up what I saw in an animation to share.  It was also good practice for transferring my JavaFX canvas experience to HTML5.

The main Moiré pattern has a few interesting properties in addition to being quite pretty.  All of the phenomena I'll be describing can be seen by clicking the Start button on the animation below, or by manipulating the image yourself.  It is fun to attempt to discern which patterns are caused by the mathematical limitations of discrete rectangular pixel grids, the limits imposed by the materials/technology used in your screen's pixels (how long it takes a pixel to change color), and limitations of your eyes and brain.

Moiré Patterns

The pattern I'll be discussing was created by drawing 800 evenly spaced radials extending from the center of an image.  For best viewing it is important to have your browser set to 100% zoom (700x700 px).  Attempting to scale the image will result in some interesting artifacts which I'll discuss later.

WARNING! If you're sensitive to rapidly flashing lights or flickering graphics it may be best to avoid viewing the animation.  It is a bit of an optical migraine simulator.


Light & Dark Banding
The bright and dark bands in the image are the result of interference caused by trying to display radial components using a rectangular (pixel) sampling grid.  The light portions of the image are locations at which the diagonals match up nicely with the pixel grid, the dark bands are a result of the opposite.  The effect is a visual manifestation of the same circumstances responsible for the creation of acoustic beat frequencies.

The means by which this phenomenon arises can be seen clearly in the image below.  To emphasize what's happening I've taken a radial pattern and overlaid it with a square grid.  If you look closely you can see that the lighter portions of the image are locations in which the radials and the grid line up cleanly.  From a distance the pattern begins to resemble that of the original, without the added grid.

Movement Interference
Moving the main image around on a computer screen creates a series of circular patterns reminiscent of magnetic field lines.  The effect is caused by a common limitation of computer screens, the time it takes a pixel to change colors.  The pixels don't respond immediately when the image is moved.  Instead, a ghosted image from the previous position remains on the screen for a few milliseconds.  The interference between the current image and the ghost image creates a secondary Moiré pattern.  The appearance of the pattern will vary depending on the response rate of the screen's pixels and the movement speed.  In the image below I've spaced two radial patterns a few pixels apart to show how the light and dark inference bands are formed.

Flicker Colors
While moving the main image around you may see flickers of color in parts of the image.  I think these are a manifestation of Fechner colors rather than a result of the individual RGB pixels having different response rates.  If I had a fast enough camera I'd take a picture of it just to be sure.

Fechner colors are an illusion created by the human visual system's reaction to rapidly shifting black and white patterns.  Why they occur is not entirely understood.  A likely explanation is that certain parts of the neuronal network or certain cone cells respond to intensity changes at different rates than others.  The end result is a brief colored afterimage.

Resizing Interference
Some very cool effects are created if you take a snapshot of the radial Moiré pattern and then attempt to resize it.  The computer does its best to create a scaled version of the Moiré pattern.  However, the same underlying structure of radially expanding lines is still there (albeit with thinner lines).  This means that in addition to the scaled image, we also still see a portion of the original Moiré pattern!  More Moiré!

Again we have two Moiré patterns and again they can interfere to create a third!  When the image scaling nears the major fractions (¾, ⅔, ⅗, ½, ⅓, ¼, ⅕, ect.) beat frequencies build up between the two Moiré patterns.  The beat frequencies manifest as a grid pattern with spacing equal to the inverse of the misalignment between the natural and artificial (scaled) pixel grids.

It is amazing how much is going on in such a simple image!  Thinking of all the additional trigonometric and frequency domain stuff that is going on is quite fun too.  Math is beautiful.