Deck the halls with trigonometry! We're using the sine function to create a holiday scene.
In this tutorial we’re going to create this holiday scene using the sine function, Math.sin()
in JavaScript. Using only sine we can create the effect of hanging holiday lights. Take a look at the final result below!
To start, we’ll look at how you can graph a function in JavaScript Graphics.
To draw the function, we’ll make a lot of tiny Circle
objects across the canvas, where their y
position corresponds to the result of Math.sin()
.
We create a for loop that loops the x
variable horizontally across the canvas by increments of 0.5 and calculates a y
value using Math.sin()
. The y
value is equal to Math.sin(x / 10) * amplitude
.
x
is divided by 10 to make sure the sine curve is smooth—remember that sine repeats every 2 pi, so we want to make sure we’re putting small values into Math.sin
to get a smooth curve.
The period of a curve is the length of one cycle. For a sine wave, the period is the amount of time it takes to go from 0 to 1 to -1 and back to 0.
For a sine curve, the period is 2 pi, 2 * Math.PI
in JavaScript. That means that if we draw a Circle
at every pixel, we’ll have a sine curve that completes its period every 6.28 pixels, which is going to be too small to see!
In order to stretch our sine curve out, we can make sure the x
values we’re graphing are distributed so that we complete a single period across a larger horizontal distance.
We’re going to create a new variable, theta
, which is the angle we’re graphing, and increment it separately from x
. We’ll then want to increment theta
by an amount which creates a smooth sine curve over our desire period. That amount, called dTheta
, will be equal to 2 * Math.PI / period
.
Here are a few sine curves with different period graphed on top of eachother.
In order to create the effect of hanging lights, we’re going to need to limit sine to the range [Math.PI, 2 * Math.PI]
. Within this range, the sine function is between 0 and negative 1, which gives the appearance of lights hanging down:
We can use the modulus operator (%
) to make sure that theta
is always between Math.PI
and 2 * Math.PI
We now have a black wire, which isn’t very festive. In order to add lights to it, we’re going to create a larger, colored Circle
every time the x
value is equal to 0, 10, 20, 30, etc. We’ll use the modulus operator again, checking if x % lightDistance === 0
and creating a colored light if it is.
Let’s close this out by making the lights blink every 500 milliseconds using setTimer
!
We’ll create an array of colors that we want to use called colors
, and every time we create a light we’ll also use setTimer
to create a function that will change that light’s color every 500 milliseconds.
We also use setBackgroundColor
to make the lights show up a little better!
And we’re done! You can experiment with different colors, a different period
, a different lightSpacing
, or any other number of changes. Share what you create with CodeHS on Twitter and we might feature your program.
Check out part two, where we use the sine function to create snow!
https://codehs.com/tutorial/andy/seasonal-geometry-part-two
Prefer a video? I walk through the program step by step below.