Monday, January 2, 2017

The Way to the Stars

Just before the holidays I was working on a Christmas tree sketch with a student at The Coder School and we needed a star for the top of the tree, because it's easier to draw than an angel. I could probably eyeball the points but as a math guy I should probably get it more or less exact.


The proportions of the pentagram and pentagon have been well researched, and it's cool how the magic number Phi comes up everywhere. But it's only the diagonals, not the x- and y-coordinates of the vertices, see?



 Would I have to use right triangles and dissect the star piece by piece?

Rotations to the Rescue


There's usually a math tool that will help, and this time it's rotation. The vertices (the "points") of a five-sided star can be seen as a set of five rotations from the center, like this:

Each rotation is 360 degrees divided by 5, which is 72 degrees. The Processing graphics package has a "vertex" function, so I just made a segment ("sz" units long, since "size" is already a keyword) and rotated it.

Radians


Most graphics packages and programming languages measure their angles in radians, not degrees, so I can still use degrees, but I just have to convert the number to radians by using the "radians" function.

def star(sz):
    fill(255,255,0) #yellow
    beginShape() #remember the vertices
    for i in range(5): #"do this 5 times"
        vertex(0,100) #make a vertex at the point(0,100)
        rotate(radians(72)) #then rotate 72 degrees
    endShape() 


Unfortunately, all I got was a blank screen. Since the "rotate" function rotates the coordinate system, it makes it impossible to save the coordinates of the vertices that way.


Polar Coordinates to the Rescue


There's another math tool which might help: polar coordinates. Instead of defining a point by its horizontal (x) and vertical (y) location, it's defined by a rotation and then a "radius" from the center of rotation, like this:



So I could define a vertex as a point that has a radius "sz" and the angle keeps going up by 72. A loop is in order!

def star3(sz):
    fill(255,255,0) #yellow
    beginShape()
    for x in range(5):
        vertex(sz*cos(radians(72*x)),sz*sin(radians(72*x)))
    endShape(CLOSE)

I was hoping the loop wouldn't mess with the vertex functionality, and here's the output:


Oops! I have to rotate twice as many degrees every vertex. Let's change the vertex line to this:

vertex(sz*cos(radians(144*x)),sz*sin(radians(144*x)))

And there's my star. Perfect!


Want to add ornaments to my tree? Click anywhere!

See the Pen Christmas Tree by Peter Farrell (@peterfarrell66) on CodePen.