2

I used the following modified code from the answer to this question (which was modified to allow accepting several rotations) to draw the following patterns.

enter image description here

enter image description here

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{verbatim}
\begin{document}
% ====================== begin spirosegment setting with nRotations ======================
\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)*\pv{nRotations}, 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.01,samples/.initial=21,nRotations/.initial=1,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 nRotations ======================
\begin{frame}[t]
\frametitle{1}
\begin{center}
\vskip -.6cm
\begin{tikzpicture}[line width=.2mm]
\path (0,0)  
foreach \X [count=\Y starting from 0] in {blue}
{pic[scale=0.5,draw=\X,ultra thick]{spirosegment={R=9.6,r=-3,p=2,nRotations=5,dx=0.001}}};
\end{tikzpicture} 
\end{center} 
\end{frame}
\begin{frame}[fragile,t]
\frametitle{2}
\begin{tikzpicture}[line width=.4mm]
\path (0,0)
pic[scale=0.3,draw=yellow]{spirosegment={dx=0.03}}
foreach \X [count=\Y starting from 0] in {blue,red,green,orange}
{pic[scale=0.3,draw=\X]{spirosegment={domain={-pi/12+\Y*pi/2}:{pi/12+\Y*pi/2}}}
};
\path[line cap=round] (6,0)  
foreach \ScaleN [evaluate=\ScaleN as \Scale using {pow(0.85,\ScaleN)/0.8}]
in {1}
{foreach \Z in {0,...,3}
{foreach \X [count=\Y starting from 0] in 
{yellow,orange,red,blue,purple,cyan,magenta,green!70!black}
{pic[scale=0.5,draw=\X,fill=\X!40,rotate=\Y*90/8+\Z*90,  scale=\Scale,line width=\Scale*2pt]{spirosegment={domain={-pi/11.4}:{pi/11.4}}}
}}};
\end{tikzpicture}
\end{frame}
\end{document}

I tried to use the code used in the second frame to segment the pattern in the first frame, to produce the following drawing, but I could not figure out how to calculate the needed formula to produce it, or to produce filled spikes.

enter image description here

enter image description here

Hany
  • 4,709
  • I tried to understand the question, and failed. (And I tried hard.) The very first code is a complete, self-contained example, and I can understand it. The second code on spirosegment is a fragment, which contains a definition of a pic. You say it produces some figure. However, it is called spirosegment probably because it produces a segment. So the result should not be surprising, is it? –  Feb 02 '20 at 03:10
  • It would be great if you could provide (1) a complete list of features that you want to achieve and (2) a complete list of keys that you want to use to get these features. Up to coloring the interior of the graph it should be rather easy to provide you with a code that achieves this. My main problem is that I do not have a complete list of requirements (which should not be mutually exclude each other). –  Feb 02 '20 at 03:12
  • Coloring the faces is a tougher task. (Of course I may well be missing something.) The last graph you show is easy, and has been part of at least one of the answers you received. It will always be easy if the cycles do not overlap each other. If they do, the only thing I can think of is protecting older cycles with clips, as outlined in some answers. It may well be that there is another way, but I am not aware of it, unfortunately. (I could imagine some way with layers but this would require additional assumptions.) –  Feb 02 '20 at 03:15
  • @ Schrödinger's cat Thank you for your concern, I edited my post. When I tried to apply your code in the 2nd frame, I failed to figure out how to do it. So, this is what I need. (1) To modify your code, so that it could be used for drawing a whole pattern which might need more than one rotation (I hope my trial is correct). (2) How to calculate the needed formula in your code in the 2nd frame to segment the pattern in the 1st frame. (3) Is it possible to fill it! If it is too complicated, as you mentioned in your comment, ignore the filling part. – Hany Feb 02 '20 at 06:11

2 Answers2

5

I am sorry, this is again something that adds something to your existing code, and not just adjusting some pgf values. I added a closed option, which is initially false to be downwards compatible. I also added an nfill style that cycles through the colors defined in spiro colors.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{verbatim}
\newif\ifspiroclosed
\begin{document}
% ====================== begin spirosegment setting with nRotations ======================
\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)*\pv{nRotations}, 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})}
)
\ifspiroclosed
 -- ({(\pv{xmax}+\pv{xmin})/2}:\pv{rmin}) -- cycle
\fi;
}},
spirosegment/.cd,R/.initial=6,r/.initial=-1.5,p/.initial=1, dx/.initial=0.01,samples/.initial=21,nRotations/.initial=1,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,closed/.is if=spiroclosed,closed=false,
rmin/.initial=1}
% ====================== end spirosegment setting nRotations ======================
\tikzset{nfill/.code={%
\pgfmathtruncatemacro{\myind}{Mod(#1,dim({\pgfkeysvalueof{/tikz/spiro colors}}))}%
\pgfmathsetmacro{\mycolor}{{\pgfkeysvalueof{/tikz/spiro colors}}[\myind]}%
\tikzset{fill=\mycolor,fill opacity=0.5,draw=\mycolor}%
},spiro colors/.initial={"green","cyan","orange","gray!50"}}

\begin{frame}[fragile,t]
\frametitle{2}
\begin{tikzpicture}[line width=.4mm]
\path[blue] (0,0)
foreach \Y in {1,...,16}
{pic[scale=0.3,rotate=\Y*360/16]{spirosegment={%
    domain={-pi/7.5}:{pi/7.5},closed,rmin=3.75}}
};
\path[line cap=round,line width=.2mm] (6,0) 
foreach \Y in {1,...,16}
{pic[scale=0.3,rotate=\Y*360/16,nfill=\Y]{spirosegment={%
    domain={-pi/7.5}:{pi/7.5},closed,rmin=3.75}}
}; 
\end{tikzpicture}
\end{frame}
\end{document}

enter image description here

  • @ Schrödinger's cat Thank you very much for your time and efforts. Would you please insert some comments in your answer for me to understand how did you decide to use (the basis for using) these specific numbers pi/7.5,rmin=3.75). I would like to apply your code for other patterns using other R:r relation and nRotations more than 1. I noticed that you used my initial R:r relation for nRotations=1. – Hany Feb 03 '20 at 05:22
2

The wheelchart package, which I wrote, can be used.

The gap between the slices is obtained with the key gap.

The shape of the slices is determined by the keys slices inner arrow and slices outer arrow.

The colors are specified with a list using the key WClistcolors. These colors can be used with the macro \WClistcolors.

The number of slices is determined by the key total count.

enter image description here

\documentclass[border=6pt]{standalone}
\usepackage{wheelchart}
\begin{document}
\begin{tikzpicture}
\wheelchart[
  gap,
  radius={2.5}{2.5},
  slices inner arrow={1}{0},
  slices outer arrow={1.5}{0},
%  slices={(-0.5,0)--(0,{2.5*tan(360/32)})--(0.8,0)--(0,{-2.5*tan(360/32)})--cycle;},
  slices style={
    fill=\WClistcolors!10,%none
    draw=\WClistcolors,
    %rounded corners
  },
  start half,
  total count=16,
  WClistcolors={green,cyan,orange,gray}
]{}
\end{tikzpicture}
\end{document}
matexmatics
  • 4,819
  • 1
    Thank you for your suggestion. Unfortunately I got the following error message ! Undefined control sequence. \pgfkeys@code #1\pgfeov ->\tl_gset:Ne \g__wheelchart_name_tl {#1} l.2178 } – Hany Dec 22 '23 at 07:45
  • @Hany In that case, the version of expl3 is not up to date enough. It is probably sufficient to put the following before \usepackage{wheelchart}:

    \ExplSyntaxOn \cs_generate_variant:Nn \tl_gset:Nn { Ne } \cs_generate_variant:Nn \str_case:nnF { enF } \cs_generate_variant:Nn \tl_set:Nn { Ne } \cs_generate_variant:Nn \regex_match:nnTF { nVTF } \cs_generate_variant:Nn \str_case:nn { en } \cs_set_eq:NN \cs_set:Npe \cs_set:Npx \cs_set_eq:NN \cs_set:cpe \cs_set:cpx \ExplSyntaxOff

    – matexmatics Dec 22 '23 at 16:30
  • Thank you. It works now. – Hany Dec 24 '23 at 05:47