Is AffineTransform a reasonable way to draw "spirograph" patterns?

45 Views Asked by At

For context, I'm not a math person. I'm a software person trying to do something that is pushing me to the limit. I did ok with unit-circle trig in school, but that's about as far as I got. Please "dumb down" any explanations.

I'm trying to write some code to make "spirograph" patterns, like the red line in the pic. A cycloid inscribed on the blue circle, I think? If that's the right terminology.

Spirograph

I thought I could use AffineTransforms to rotate, scale, and translate, but it's not working out. Is this a misguided use of AffineTransforms? I'm using them because they're available in the graphics library I'm using (Apple Swift language).

Making the outer ring is easy: I start with a point at (1, 0) and rotate it repeatedly. I get the blue ring in the pic, radius = 1. Even drawing the spindle path is easy: start with a point at (x, 0) and apply the same rotations as to the other point. I get the orange ring in the pic, radius = x.

But somehow I can't get anything to work for the red ring. It seemed to me that I could treat the red ring as a unit circle, and transform (1, 0) with the same rotation as the blue ring, then add scaling and translating. No joy whatsoever. I'm told that matrix multiplication isn't commutative, so I've tried all six permutations of rotate, scale, translate, but still with no joy.

I'm thinking I could show some pseudocode here, but it seems sufficient to say that I'm scaling the inner circle by "x" (this much seems to work), and rotating it through a full circle while translating by "x" (this sounds wrong given that I'm scaling by the same amount, but also seems like the only sensible translation).

I guess the main question is, is this a reasonable use of AffineTransform? Is there a much easier way? Is there a common mistake that AffineTransform noobs make? Any advice appreciated.