是否可以将 3 个版本的 Spirograph 代码合并起来:
简单的包括控制 nRotations、颜色和比例;
控制分段绘图的(添加的\pv{dx}
);
以及控制图纸填充的部分;
将其转换为一个统一的代码,在需要时,在所有这些不同情况下,可以用来控制所有这些变量。
\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{verbatim}
\begin{document}
% ====================== begin spiro setting ======================
\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}
% ====================== end spiro setting ======================
% ============== begin spirofill setting ===================
\tikzset{pics/spirofill/.style={code={
\tikzset{spirofill/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spirofill/##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})}
);
}},
spirofill path/.code={\def\pv##1{\pgfkeysvalueof{/tikz/spirofill/##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
}}},
spirofill/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1}
% ============== end spirofill setting ===================
% ====================== begin spirosegment setting ======================
\tikzset{pics/spirosegment/.style={code={
\tikzset{spirosegment/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/spirosegment/##1}}
\pgfmathparse{(int(1/\pv{dx}+1)}
\tikzset{spirosegment/samples=\pgfmathresult}
\draw[trig format=rad,pic actions]
plot[variable=\t,domain=\pv{xmin}-0.002:\pv{xmax}+0.002, samples=\pv{samples}, 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})}
);
}},
spirosegment/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1, dx/.initial=0.05,samples/.initial=21,domain/.code args={#1:#2}{%
\pgfmathparse{#1}\tikzset{spirosegment/xmin/.expanded=\pgfmathresult}
\pgfmathparse{#2}\tikzset{spirosegment/xmax/.expanded=\pgfmathresult}},
xmin/.initial=0,xmax/.initial=2*pi}
% ====================== end spirosegment setting ======================
\begin{frame}[t]
\frametitle{Spiro,nRot5}
\begin{center}
\vskip -.6cm
\begin{tikzpicture}[line width=.2mm]
\foreach \scl/\clr/\p in
{.8/blue/3.0,.4/purple/7.0}
{
(0,0) \pic[draw=\clr,rotate=360/4/2*1,scale=\scl]{spiro={R=9.6,r=-12,p=\p,nRotations=5}};
}
\end{tikzpicture}
\end{center}
\end{frame}
\begin{frame}[fragile,t]%this frame needs fragile
\frametitle{spirosegment}
\begin{tikzpicture}[line width=.8mm]
\path (0,0)
foreach \X [count=\Y starting from 0] in {blue,red,green,orange}
{pic[scale=0.5,draw=\X]{spirosegment={domain={-pi/4+\Y*pi/2}:{pi/4+\Y*pi/2}}}};%,dx=0.005
\end{tikzpicture}
\end{frame}
\begin{frame}[t]
\frametitle{spirofill with color interpolation}
\begin{center}
\begin{tikzpicture}[line width=.2mm,spirofill/.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,spirofill path];
\fi
\pic[draw=\clr!\mycf!\lastclr,rotate=45*\X+5*\Y+\Z*180,scale=.4,fill=\clr!\mycf!\lastclr!40]{spirofill};
}}}
\end{tikzpicture}
\end{center}
\end{frame}
\end{document}