Back to Blog

Animating Hypotrochoids

Spirograph-like curves arise from simple sums of rotating vectors; a tiny tweak in frequency or phase yields striking patterns

RefrigiratorOctober 11, 2025
animationmath

Compact parametric form is :

x(t)=Rcost+rcos(kt+φ),y(t)=Rsint+rsin(kt+φ),x(t)=R\cos t+r\cos(kt+\varphi),\\ y(t)=R\sin t+r\sin(kt+\varphi),

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["2e93dc89-05e1-4882-a8cd-ec0bfeedc741"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG6VaGqckW1jqGpimGuqaWFgY6SZaJKfopiYbJKWlpqYkm5sYAgCHyxY8"*)(*]VB*)

We can nicely decompose it back into 2 components and animate it using Animate expression and bunch of arrows:

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["54067362-f5ed-424b-a94a-b0ac40f13ea1"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKm5oYmJkbmxnpppmmpuiaGJkk6SZamiTqJhkkJpsYpBkapyYaAgB6ZRWO"*)(*]VB*)

Here we start from 0.001 to avoid zeros in ParametricPlot, othwersize it will throw a warning message

Now we can export it to GIF animation by rasterizing it into AnimatedImage:

Export["animation.gif", AnimatedImage @ a]