See the Pen Harmonic Pendulum on CodePen.

Harmonic Pendulum: A Mathematical Exploration in CSS

My dad sent me a YouTube video, fascinated by the motion and patterns made with a harmonic pendulum. I was deep in some CSS animation work on another project, and immediately thought: "I could make that in CSS." Down the rabbit hole we go!

 

Materials & Tools:

- Math
- CSS / Javascript
- Codepen or JSFiddle

 

Step 1: A CSS only approach

My first attempts were to make the app solely in CSS. Before diving into the math of things, let's see how far we can go with just some basic transitions & keyframe animation. 

To get a basic back and forth, repeating swinging motion, we can add a simple keyframe animation: (Note: for brevity, I have not included all of the browser prefixes or the entire snippet of HTML & CSS code required. We'll put everything together in the last step)

@-webkit-keyframes swing {
from {
-webkit-transform: rotate(-25deg);
}
to {
-webkit-transform: rotate(25deg);
}
}

We can add a few more strings, adjusting their heights and animation times. We can add as many strings as we'd like. It's starting to look pretty cool!

.no1 .string { height: 200px; }
.no2 .string { height: 250px; }
.no3 .string { height: 300px; }

.no1 { -webkit-animation: swing 1.0s alternate infinite ease-in-out; }
.no2 { -webkit-animation: swing 1.25s alternate infinite ease-in-out; }
.no3 { -webkit-animation: swing 1.5s alternate infinite ease-in-out; }

This works well up to a certain point, and we can even attempt to match the string heights & timing to more exact calculations. But these numbers are imprecise, so even a more complex animation still doesn't line up quite right for an entire cycle. Notice how the circles aren't completely lined up throughout the animation here. For our final pendulum, we'll continue to use this animation, but we will be calculating the string heights and animation timing with javascript.

This is a really great place to begin having fun with the design and speed of our animation. Experiment: what happens if you change the heights? The speeds? What do different animation timing functions look like? 

 

Step 2: What is harmonic motion?

Let's step back to high school physics class. At some point, while you were napping, pendulums & harmonic motion were probably introduced. According to Wikipedia, a simple gravity pendulum depends on the length of string, strength of gravity, and the amplitude or angle of the swing. Knowing these variables will give you the "period" of the swing, or the amount of time it takes for the bob to make one complete oscillation back and forth.

This is represented by an equation that looks like this, where T is period, L is length, and g is gravity. 

Now we have to solve for T. We know gravity is generally represented by 9.8 m/s. Next, we have to figure out what our string lengths are. I attempted to calculate these numbers manually, but that took a while and my numbers seemed to be consistently wrong. So I found a site with the first 9 lengths to get me started, and filled in the blanks for the rest of my 15 strings. To represent this equation and these lengths as variables in javascript:

var height = [2.11, 2.18, 2.25, 2.32, 2.40, 2.48, 2.56, 2.65, 2.75, 2.85, 2.95, 3.06, 3.18, 3.30, 3.43]

var period = (2 * Math.PI) * (Math.sqrt(height[index] / 9.8));

We'll loop through each element, mapping the corresponding height for each string to get the animation time. Again, since our manual height calculations only go out a couple decimal places, this gets us only so far. To get more accurate numbers, we'll have to actually calculate these. We'll use the period equation in the final code, but let's find a way to generate those heights.

 

Step 3: Calculating string lengths

The Internet is a magical place. It has removed the necessity of needing to memorize equations or solve for y to get another variable. After beating my head against a broken TI-86 for a while, I found another blog that so kindly provided me with an equation to calculate string lengths. In this equation,  g is gravityΓ is the duration of one entire cycle, N is the number of oscillations the longest string has in the cycle (I use 15 in my final version), and n is the pendulum index (starting at 0).

To represent this in javascript: 

var gravity= 9.8; // g
var maxOsc = 15;// N
var duration = 240; // Γ
var height = [];// l(n)

for (var j = 0; j < 15; j++) {
var length = g * duration / Math.pow((2 * Math.PI * (maxOsc + j)), 2);
height.push(length);
}
height.reverse();

 

Step 4: Putting it all together

We have our timing function, our string lengths calculated, and our animation down. I added a few fancy things, like injecting the DOM elements with JS, and decreasing the size of the circles as the strings get shorter (to make them appear further away in space). For the purpose of this demo, I'm going to assume that you have some basic understanding of CSS and Javascript, so we'll save the stylistic details for another day.

Here's all of our final code:

Step 5: Fun stuff

Javascript is a fun way to make math look beautiful. While making the initial design, I fiddled around with many of the variables. Here are a few interesting outtakes from the blooper reel:

Photo Jan 19, 1 56 55 PM.gif
Photo Jan 19, 2 28 53 PM.gif
Photo Jan 19, 2 43 14 PM.gif