# The Digital Harmonograph

## A fun JavaScript animation inspired by a Victorian contraption

Recently I learned about the harmonograph, a nineteenth-century device that uses a system of pendulums to draw intricate designs on paper. It is an elegant idea that comes in many varieties. A common type of harmonograph involves three pendulums: one that moves a sheet of paper around in an ellipse, and two others that move a pen around onto the paper. Here is an example by Karl Sims, a digital media artist who provides wonderful instructions for building it:

I thought it would be fun to create a computer simulation of this kind of harmonograph. Here I present JavaScript code that runs in a web browser to draw images based on the behavior of three mutually interacting pendulums. Along with the math and physics, we will cover a few helpful tricks about animation in the browser environment.

## The Behavior of a Single Pendulum

Before discussing the interaction of multiple pendulums, it is important to understand how a single pendulum behaves. The algorithm presented here models a pendulum using simple formulas. The model is a good approximation of the behavior of a real pendulum. There are two underlying ideas in the model:

- If there is no friction, a pendulum traces a repeated elliptical path.
- When there is friction, the radius of the path
*decays*(gets smaller) over time. After enough time, the pendulum’s movement becomes insignificant.

## A Frictionless Pendulum

The following diagram shows how we can model the first idea, that of a point **P** moving along a perfect ellipse:

The position vector **P** represents the location of the pendulum bob at a given moment in time. In this frictionless model, **P** travels around the same elliptical path indefinitely. The shape of the ellipse is defined by the constants *a* (the semi-major axis) and *b* (the semi-minor axis). At a time *t*, the location of **P** is indicated by the following pair of coordinates:

Here, *F* is the frequency of rotation in radians/second, and *K* is the starting angle (or *phase*) in radians. To be clear, these angles are conceptual. They are not literally measured on the depicted plane, because the general ellipse is not a perfect circle. The important idea is that each time the value (*Ft*+*K*) increases by 2π, the point **P** has traveled another revolution around the ellipse.

## Adding Friction to the Model

We make a small change in the formulas to simulate how friction will gradually slow down the pendulum and make it come to rest. We multiply by an exponential decay factor to gradually reduce the magnitude of *x* and *y* over time:

Here, *R* is a non-negative real number called the *decay constant*. If *R*=0, there is no friction, because *e*⁰=1. If *R*>0, then as the time *t* increases, the exponential factor decreases asymptotically to zero. A small positive value of *R* emulates a small amount of friction, causing the curve to spiral in very slowly. A larger value of *R* causes higher friction, so that the inward spiral happens faster.

So now we have a mathematical model for a single pendulum. We have at our command five tunable parameters, *a*, *b*, *F*, *K*, and *R*, to make a variety of spiraling shapes.

## Combining Multiple Pendulums

We have talked about the model for a single pendulum. But the harmonograph simulation includes three pendulums. How do we adapt the formulas to handle the behavior of three interacting pendulums? The approach I took is fairly straightforward. Each pendulum has its own set of five parameters *a*, *b*, *F*, *K*, *R*. The five parameters are independent for each of the three pendulums, for a total of 15 adjustable parameters.

To trace the harmonograph shape, we calculate the three (*x*, *y*) vectors for the three pendulums, then add them together. That is, add the three *x* coordinates for the three pendulums to produce a net *x* coordinate, and do the same thing with the three pendulums’ respective *y* coordinates. The resulting (*x*, *y*) pair indicates the location of the imaginary pen on the imaginary paper at the time *t*.

## The Animation Algorithm

I wanted something fun to watch and interact with, so a single static harmonograph shape wasn’t going to be good enough. As you can see, the demo above changes with time, and also has some sliders that let you interactively adjust the resulting pattern. (I’ll explain the sliders below.)

For each animation frame, I follow the approach outlined above to iterate over a series of time values *t*. Thus in each frame of the animation, the code draws an entire harmonograph doodle, starting with *t*=0 and increasing *t* by a small amount, and connecting the consecutive dots with line segments on the HTML canvas. The drawing stops when the exponential decay has made the graph spiral in smaller than an arbitrary threshold.

In each subsequent animation frame, I change the three phase angles (the *K* constants) at different linear rates, so that the three pendulums start at different mutual phases. This causes the harmonograph shape to morph gradually over time. See the function `MakeHarmonograph`

in the code listing below.

The sliders beneath the animation allow you to adjust the three frequencies (the *F* constants) for the pendulums. You will notice that the shapes look more “smooth” when the the ratios of frequencies are close to integers, and more “crazy” when the frequency ratios deviate away from integers.

Real, physical harmonographs share this integer-ratio tendency. Their pendulum frequencies are adjusted by moving the weights up and down on their suspension rods, and they require adjustment to make pleasing patterns.

## Summary of the Simulator Code

The code requires no external JavaScript packages or frameworks, and will run in any reasonably modern browser. I tested it on Chrome, Safari, and Edge.

The animation proceeds by using the requestAnimationFrame function to repeatedly schedule a callback every time the browser is ready to render another frame of animation. My callback is the function `timerTick`

, which draws one frame via the function `Render`

, and then schedules itself to be called again in the next animation frame.

In each animation frame, the code creates a `Harmonograph`

object whose constructor accepts an arbitrary list of `Pendulum`

objects. The code is flexible. You can change it to use any number of pendulums, not just three. It proceeds to calculate a series of pen positions for incremental values of *t*, until friction slows down the pen to a certain small radius.

To make the colors more interesting, I render the spiral shape using a radial gradient that transitions from red gradually to blue. I tried drawing each line segment with its own calculated color, but this dramatically hurts performance. Gradients are much faster because they allow me to draw the entire shape with a single call to `context.stroke()`

.

## Code Listings

The HTML part of the code is very simple. It consists of a single canvas and three sliders:

The stylesheet is important for making the canvas fit the browser’s client area. It also prevents annoying flashes when the user taps the canvas on a touch-screen device. Here it is:

Most of the interesting stuff is in the JavaScript file `harmonograph.js`

:

So there it is. I hope you enjoy playing around with the harmonograph simulator, and also, I hope you can learn from and adapt the code for your own fun projects. Feel free to ask questions, and I’ll do my best to answer.

## References

- The simulation’s complete source code on GitHub.
- The harmonograph simulation running live in its own web page.
- Karl Sims’ instructions for how to build your own physical harmonograph.