6

I used the following code from the answer to this question, to draw a Spirograph pattern

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\begin{document}
\tikzset{pics/spiro/.style={code={
\tikzset{spiro/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}} 
\draw[trig format=rad,pic actions]
 plot[variable=\t,domain=0:2*pi*\pv{nRotations}, samples=90*\pv{nRotations}+1, smooth cycle]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
);
}},
spiro/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1,nRotations/.initial=1}
\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm]
\foreach \i/\clr in {5/blue,10/blue,15/blue,20/blue,25/blue,30/blue,35/blue,40/blue,45/blue,50/green,55/green,60/green,65/green,70/green,75/green,80/green,85/green,90/green,95/orange,100/orange,105/orange,110/orange,115/orange,120/orange,125/orange,130/orange,135/orange,140/purple,145/purple,150/purple,155/purple,160/purple,165/purple,170/purple,175/purple,180/purple}
{
(0,0) \pic[draw=\clr,rotate=\i,scale=.4]{spiro={R=10.5,r=-5.25,p=3,nRotations=1}};
}
\end{tikzpicture} 
\end{center} 
\end{frame}
\end{document}

enter image description here

I tried using the following code to simplify repeating each rotation angle, but something is not right!

\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm]
\foreach \b in {5,10,...,45}
\foreach \g in {50,55,...,90}
\foreach \o in {95,100,...,135}
\foreach \p in {140,145,...,180}
\foreach \i/\clr in {\b/blue,\g/green,\o/orange,\p/purple}
{
(0,0) \pic[draw=\clr,rotate=\i,scale=.4]{spiro={R=10.5,r=-5.25,p=3,nRotations=1}};
}
\end{tikzpicture} 
\end{center} 
\end{frame}

I also tried to apply the code from the answer to this question to avoid overlapping tha last pattern over the older ones to produce the following drawing (using the option fill=\clr!40) but I could not figure out how to apply it.

enter image description here

Hany
  • 4,709

1 Answers1

10

You may want something like this:

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\begin{document}
\tikzset{pics/spiro/.style={code={
\tikzset{spiro/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}} 
\draw[trig format=rad,pic actions]
 plot[variable=\t,domain=0:2*pi*\pv{nRotations}, samples=90*\pv{nRotations}+1, smooth cycle]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
);
}},
spiro/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1,nRotations/.initial=1}
\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm]
\path foreach \clr [count=\X starting from 0] in {blue,green,orange,purple}
{foreach \Y in {1,...,9}
{(0,0) pic[draw=\clr,rotate=45*\X+5*\Y,scale=.4]{spiro={R=10.5,r=-5.25,p=3,nRotations=1}}
}};
\end{tikzpicture} 
\end{center} 
\end{frame}
\end{document}

enter image description here

This loops over the colors and draws for each color the graph in 9 versions, relatively rotated by 5 degrees each. Please also notice that (0,0) in your code had no effect, and that I slightly change the foreachs to be in the path.

One may also want to interpolate between the colors.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\begin{document}
\tikzset{pics/spiro/.style={code={
\tikzset{spiro/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}} 
\draw[trig format=rad,pic actions]
 plot[variable=\t,domain=0:2*pi*\pv{nRotations}, samples=90*\pv{nRotations}+1, smooth cycle]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
);
}},
spiro/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1,nRotations/.initial=1}
\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm]
\path foreach \clr [count=\X starting from 0,
    remember=\clr as \lastclr (initially purple)] in {blue,green,orange,purple}
{foreach \Y [evaluate=\Y as \mycf using {int(100*\Y/9)}] in {1,...,9}
{(0,0) pic[draw=\clr!\mycf!\lastclr,rotate=45*\X+5*\Y-22.5,scale=.4]{spiro={R=10.5,r=-5.25,p=3,nRotations=1}}
}};
\end{tikzpicture} 
\end{center} 
\end{frame}
\end{document}

enter image description here

ADDENDUM: You can also produce filled graphs. However, in this case your definition may not be optimal. So I changed that.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\begin{document}
\tikzset{pics/spiro/.style={code={
\tikzset{spiro/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}} 
\draw[trig format=rad,pic actions]
 plot[variable=\t,domain=pi/2:3*pi/2, samples=31, smooth]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
);
}},
spiro path/.code={\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}}
\tikzset{insert path={
plot[trig format=rad,variable=\t,domain=pi/2:3*pi/2, samples=31,
smooth,domain=pi:pi/2]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
) 
|- (\pv{R}+\pv{r}+\pv{p},-\pv{R}-\pv{r}-\pv{p})
-- 
(\pv{R}+\pv{r}+\pv{p},\pv{R}+\pv{r}+\pv{p})  --
(-\pv{R}-\pv{r}-\pv{p},\pv{R}+\pv{r}+\pv{p})
--  cycle
}}},
spiro/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1}
\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm,spiro/.cd,R=10.5,r=-5.25,p=3]
\begin{scope}
\foreach\Z in {0,1}
{\foreach \clr [count=\X starting from 0] in {blue,green,orange,purple}
{\foreach \Y in {1,...,9}
{\ifnum\Z\X\Y=102
 \clip[scale=.4,rotate=5,spiro path];
\fi
\pic[draw=\clr,rotate=45*\X+5*\Y+\Z*180,scale=.4,fill=\clr!40]{spiro};
}}}
\end{scope}
\fill[white] circle[radius={0.4*(\pgfkeysvalueof{/tikz/spiro/R}+
\pgfkeysvalueof{/tikz/spiro/r}-\pgfkeysvalueof{/tikz/spiro/p})}];
\end{tikzpicture} 
\end{center} 
\end{frame}
\end{document}

enter image description here

With color interpolation it does not look too bad IMHO.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\begin{document}
\tikzset{pics/spiro/.style={code={
\tikzset{spiro/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}} 
\draw[trig format=rad,pic actions]
 plot[variable=\t,domain=pi/2:3*pi/2, samples=31, smooth]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
);
}},
spiro path/.code={\def\pv##1{\pgfkeysvalueof{/tikz/spiro/##1}}
\tikzset{insert path={
plot[trig format=rad,variable=\t,domain=pi/2:3*pi/2, samples=31,
smooth,domain=pi:pi/2]
(
{(\pv{R}+\pv{r})*cos(\t)+\pv{p}*cos((\pv{R}+\pv{r})*\t/\pv{r})},
{(\pv{R}+\pv{r})*sin(\t)+\pv{p}*sin((\pv{R}+\pv{r})*\t/\pv{r})}
) 
|- (\pv{R}+\pv{r}+\pv{p},-\pv{R}-\pv{r}-\pv{p})
-- 
(\pv{R}+\pv{r}+\pv{p},\pv{R}+\pv{r}+\pv{p})  --
(-\pv{R}-\pv{r}-\pv{p},\pv{R}+\pv{r}+\pv{p})
--  cycle
}}},
spiro/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1}
\begin{frame}[t]
\frametitle{}
\begin{center}
\begin{tikzpicture}[line width=.2mm,spiro/.cd,R=10.5,r=-5.25,p=3]
\foreach\Z in {0,1}
{\foreach \clr [count=\X starting from 0,
    remember=\clr as \lastclr (initially purple)] in {blue,green,orange,purple}
{\foreach \Y [evaluate=\Y as \mycf using {int(100*\Y/9)}] in {1,...,9}
{\ifnum\Z\X\Y=102
 \clip[scale=.4,rotate=5,spiro path];
\fi
\pic[draw=\clr!\mycf!\lastclr,rotate=45*\X+5*\Y+\Z*180,scale=.4,fill=\clr!\mycf!\lastclr!40]{spiro};
}}}
\end{tikzpicture} 
\end{center} 
\end{frame}
\end{document}

enter image description here

  • Thank you for your answer. What about solving the filling issue by applying your code in the answer to https://tex.stackexchange.com/questions/521165/modifying-foreach-loop-to-make-first-loop-overlaps-last-one to avoid overlapping the last pattern over the previous ones! I could not figure out how to apply it. – Hany Jan 18 '20 at 16:03
  • @Hany Sorry, I did not read this part of the question in that way, also because there is no code. However, I also do not understand how the target output should look like. What would you like to do with the inner circle? –  Jan 18 '20 at 18:01
  • @ Schrödinger's cat Thank you very much for your answers. This is what I had in mind. https://i.stack.imgur.com/Tmved.png Your answers are as close as possible. – Hany Jan 19 '20 at 05:11
  • @Hany You're welcome! You can just add a white disk to achieve this. –  Jan 19 '20 at 05:20
  • @ Schrödinger's cat Thank you very very much for your concern. I appreciate very much your answers. Just one comment; how to add a disk! – Hany Jan 19 '20 at 05:23
  • 1
    @Hany Added it. –  Jan 19 '20 at 05:30
  • @ Schrödinger's cat Thank you very much. – Hany Jan 19 '20 at 05:59