|The red parts of this image are a hypocycloid.|
The blue parts of this image are an epicycloid.
The gap on the right side is an unsolved problem.
Years ago, as a child, I knew people with Spirographs, and I loved playing with them, making these crazy patterns with just pen, paper and geared plastic circles.
Until I started looking into laser cutters. Essentially, they're high-contrast printers, and they love vector graphics, using a thin red vector as an indication to cut rather than etch. So, when I saw Gabor write about the SVG module on Perl Maven, I knew what I must do.
Right now, I have three functions that generate these images, corresponding to epicycloid, hypocycloid and hypotrochoid curves, with two functions each providing the X and Y coordinates. In each, take a circle, rotate another circle around it (outside for epicycloids, inside for the others). If the point you're using is along the circumference, it's a cycloid, and if it's beyond that, it's an hypotrochoid, which, strictly speaking, could not be done with a Spirograph because the rings would get in the way. With math, Perl and SVG, this is not a problem.
SVG has the capability of drawing curves, but I assure you that the number of curves in the SVGs that created the images here are zero. If you draw lines between points, and those points are close enough, the lines look like curves, and the file sizes explode. On the other end, if you have the distance between points long enough, they are clearly lines, and it takes a large number of loops over to disguise the straight lines and get a thick curve. My code currently cycles through at 1/400ths of a degree at a time, which is fine for epicycloids and hypocycloids, but overkill for hypotrochoids.
Getting this code to handle Bézier curves and the like requires more math than I currently know, and might not actually be possible, but would certainly be good for reducing file sizes.
|This is a number of hypotrochoids stacked on top of each other, |
cut into balsa wood. I love the 21st century.
And, having an offset, to rotate these things as desired, would also be good. Code below, and also on Github.