Spirograph-like curves arise from simple sums of rotating vectors; a tiny tweak in frequency or phase yields striking patterns.
Download original notebookCompact parametric form:
where (k) is the frequency ratio. Rational (k) β closed patterns; irrational (k) β long, nonrepeating traces. β numbers allow to write such expressions much shorter, for instance:
ParametricPlot[ReIm[(*SpB[*)Power[I(*|*),(*|*)-t](*]SpB*) + 3 (*SpB[*)Power[I(*|*),(*|*)t/3](*]SpB*)], {t, 0, 4Pi}]
(*VB[*)(FrontEndRef["0b2a2ce6-db3b-46a8-9cfb-03bf3f69a7f7"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGyQZJRolp5rppiQZJ+mamCVa6FompyXpGhgnpRmnmVkmmqeZAwCSjhZi"*)(*]VB*)
We can nicely decompose it back into 2 components and animate it using Animate expression and bunch of arrows:
a = Animate[ ParametricPlot[ReIm[(*SpB[*)Power[I(*|*),(*|*)-t](*]SpB*) + 3 (*SpB[*)Power[I(*|*),(*|*)t/3](*]SpB*)], {t,0,u}, Epilog->{ Arrow[{{0,0}, ReIm[(*SpB[*)Power[I(*|*),(*|*)-u](*]SpB*)]}], Arrow[{ ReIm[(*SpB[*)Power[I(*|*),(*|*)-u](*]SpB*)], ReIm[(*SpB[*)Power[I(*|*),(*|*)-u](*]SpB*) + 3 (*SpB[*)Power[I(*|*),(*|*)u/3](*]SpB*)]}] }, PlotRange->{{-4,4}, {-4,4}}, GridLines->Automatic, PlotStyle->(*VB[*)(RGBColor[1, 0, 0])(*,*)(*"1:eJxTTMoPSmNiYGAo5gUSYZmp5S6pyflFiSX5RcEsQBHn4PCQNGaQPAeQCHJ3cs7PyS8qYgCDD/ZQBgMDnAEA4iUPRg=="*)(*]VB*) ] , {u, 0.001, 4Pi}, RefreshRate->30, Appearance->None]
(*VB[*)(FrontEndRef["60aea15c-c5d8-46da-8eb0-20cb3188dba7"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxkkpiYamibrJpumWOiamKUk6lqkJhnoGhkkJxkbWlikJCWaAwCOGxYk"*)(*]VB*)
note
Here we start from 0.001 to avoid zeros in ParametricPlot, otherwize it will throw a warning message
Now we can export it to GIF animation by rasterizing it into AnimatedImage
Export["animation.gif", AnimatedImage @ a]