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'])
path.append((x,y))
coord_paths.append(path)
coord_paths = shift(coord_paths, (950//2, 650//2))
prototype(coord_paths)
Coupled with the preview generator, we can see the outputs quickly for various values of radius and step sizes:



