Project Scribble - Spirographs

Project Scribble - Spirographs

I recently uploaded a longer video about this, but here is the code (and maths) that relates:

The main bit of maths is working out the (x,y) coordinate for a location for a point on the circle, based upon an angle. From our high school maths, that's done by some basic right-angle triangles theory.

As previously shown (vector maths of fractals), we can represent a location on a chart by one of two methods - either an (x,y) system (called Cartesian) or a system using an angle and a distance (also called the Polar notation). Different tasks are easier or harder in different coordinate systems.

When we're modelling the spirograph, we break it down as a point moving around a circle, which in turn is moving around a circle. Because we're moving around the circle, it's easier for us to keep track of where we are in the Polar (angle and radius) then it is in the x-y. For these circles, the radius is fixed for the drawing, but the angle increases slightly on each step.

So to work out the location of a point, its the sum of the x of both circles, and then the sum of the y for both circles (or more circles if we're being adventurous).

For the maths, the X coordinate is radius * cos(angle) and the Y parameter is radius * sin(angle), and therefore we can do the following code to generate the paths:

coord_paths = []

circles = [
    { "radius": 100, "angle":0, "step": 0.1}, 
    { "radius": 50, "angle":0, "step": 0.4}, 

coord_paths = []
path = []

for i in range(500):
    x = 0
    y = 0
    for circle in circles:
        circle['angle'] += circle['step']
        while circle['angle'] > random.TWOPI:
            circle['angle'] -= random.TWOPI
        x += circle['radius'] * math.cos(circle['angle']) 
        y += circle['radius'] * math.sin(circle['angle']) 


coord_paths = shift(coord_paths, (950//2, 650//2))


Coupled with the preview generator, we can see the outputs quickly for various values of radius and step sizes: