2

I need to fill the area between a few curves with tikzfillbetween, but I don't want the inner circle to be filled.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}
\begin{document}

\begin{tikzpicture}[scale=1]
\def\R{1}
\def\s{0.2}

\draw [black, line width=1pt,samples=100,domain=0:2*pi, name path=A] 
plot ({\R*cos(\x r)}, {\R*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=-pi/6:pi/6, name path=B] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=pi/6:pi/2, name path=C] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=pi/2:5/6*pi, name path=D] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=5*pi/6:7*pi/6, name path=E] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=7*pi/6:3*pi/2, name path=F]
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=3*pi/2:11*pi/6, name path=G] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\tikzfillbetween[of=A and B]{blue};
\tikzfillbetween[of=A and C]{red};
\tikzfillbetween[of=A and D]{blue};
\tikzfillbetween[of=A and E]{red};
\tikzfillbetween[of=A and F]{blue};
\tikzfillbetween[of=A and G]{red};

\end{tikzpicture}

\end{document}
4

I have never used pgfplots before and I notice that your code consists in making 6 times the same curve by rotating it around the origin. So I used two foreach loops: one to color in blue, the other to color in red with the same code as you.

This results in:

plots

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}
\begin{document}

\begin{tikzpicture}[scale=1]
\def\R{1}
\def\s{0.2}

\foreach \d in {-pi/6:pi/6,pi/2:5/6*pi,-pi/2:-5*pi/6
}{
\draw [black, line width=1pt,samples=100,domain=\d, name path=B] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});
\draw [black, line width=1pt,samples=100,domain=\d, name path=A] 
plot ({\R*cos(\x r)}, {\R*sin(\x r)});
\tikzfillbetween[of=B and A]{blue};
}

\foreach \d [count=\c] in {pi/2:pi/6,5*pi/6:7*pi/6,3*pi/2:11*pi/6
}{
\draw [black, line width=1pt,samples=100,domain=\d, name path=C] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});
\draw [black, line width=1pt,samples=100,domain=\d, name path=A] 
plot ({\R*cos(\x r)}, {\R*sin(\x r)});
\tikzfillbetween[of=A and C]{red};
}

\end{tikzpicture}

\end{document}
  • The pgfplots library fillbetween can be used without doing pgfplots stuff, i.e. without using an axis environment. It allows you to fill intersection segments of long paths. (If the task here is just to produce the picture, you only need to fill the inner circle white at the end of the OP's code. I thought the task was to make use of the pgfplots library fillbetween because the OP is loading it. However, who knows. +1) – marmot Oct 7 '18 at 16:48
  • @marmot I didn't quite understand your comment. The only thing I did was to trace each of the six lunula separately with the fillbetween library. I didn't try to do what the OP said, I coded the same construction differently to get around its problem. I could have done 120° rotations, it would have resulted in the same result. +1 too :) – AndréC Oct 7 '18 at 17:17
  • What I want to say is that with fillbetween you can decompose a long path into small segments for the fills, and you do not have to create a whole lot of additional paths. In this case, this can be done because we know the parametrizations of the segments, in general, however, we do not, and then this library is really useful. – marmot Oct 7 '18 at 17:21
3

I am a bit confused about the purpose of the question. If you want to make use of the fillbetween library, which you are loading, please switch to the lower code. If you just want to fill the different bits with different colors, just do

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\def\R{1}
\def\s{0.2}
\foreach \X in {0,...,5}
{\ifodd\X
\draw [fill=red, line width=1pt,samples=100,domain={-pi/6+\X*pi/3}:{pi/6+\X*pi/3}] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x
r)});
\else
\draw [fill=blue, line width=1pt,samples=100,domain={-pi/6+\X*pi/3}:{pi/6+\X*pi/3}] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x
r)});
\fi}
\draw[fill=white,line width=1pt] (0,0) circle (\R);
\end{tikzpicture}
\end{document}

On the other hand, this is a special answer to this special situation, and will fail at the very moment in which you switch to more different shapes. Something that always works can be set up with the pgfplots library fillbetween, which you are loading. In order to achieve what you want, consider filling intersection sequences rather than the full paths. A is very long, and if you fill the full thing, the circle will be filled.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}
\begin{document}

\begin{tikzpicture}[scale=1]
\def\R{1}
\def\s{0.2}

\draw [black, line width=1pt,samples=100,domain=0:2*pi, name path=A] 
plot ({\R*cos(\x r)}, {\R*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=-pi/6:pi/6, name path=B] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=pi/6:pi/2, name path=C] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=pi/2:5/6*pi, name path=D] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=5*pi/6:7*pi/6, name path=E] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=7*pi/6:3*pi/2, name path=F]
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\draw [black, line width=1pt,samples=100,domain=3*pi/2:11*pi/6, name path=G] 
plot ({(\R + abs(\s*cos(3*\x r)))*cos(\x r)}, {(\R + abs(\s*cos(3*\x r)))*sin(\x r)});

\fill [blue,intersection segments={of=A and B,
                sequence={A0 -- B1[reverse]}}];
\fill [red,intersection segments={of=A and C,
                sequence={A1 -- B1[reverse]}}];
\fill [blue,intersection segments={of=A and D,
                sequence={A1 -- B1[reverse]}}];
\fill [red,intersection segments={of=A and E,
                sequence={A1 -- B1[reverse]}}];
\fill [blue,intersection segments={of=A and F,
                sequence={A1 -- B1[reverse]}}];
\fill [red,intersection segments={of=A and G,
                sequence={A1 -- B1[reverse]}}];

\end{tikzpicture}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.