1

I would like to fill the peaks and troughs of a circle vibrating with respect to its static configuration using alternating colors. I tried using the fillbetween package (with pgfplots 1.15) and it almost works. What should I do in order to obtain the desired result?

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
    hide axis,
    trig format plots=rad,
    view={60}{120}
]

\addplot3 [name path=vibrating, variable=t, domain=-pi:pi, samples=1000, samples y=0] ({cos(t)},{sin(t)},{cos(4*t)});

\addplot3 [name path=flat, variable=t, domain=-pi:pi, samples=100, samples y=0] ({cos(t)},{sin(t)},0);

\addplot3 [fill=gray!5] fill between [
of=vibrating and flat, 
split,
every even segment/.style = {red!20!white}];

\tikzfillbetween[
of=vibrating and flat,
on layer=,
split,
every even segment/.style = {fill=none, draw=none}]{blue,opacity=50}

\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

4

Welcome to TeX.SE! The issue is that intersections are always intersections of 2D paths, i.e. paths on the screen, and not 3D intersections. Therefore, the intersection segments used in your picture do not match the expectations.

Therefore, it might be worthwhile to slightly switch gears and compute the intersections analytically, which is simple enough in the given setting. And it suffices to use tikz-3dplot here.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\begin{tikzpicture}[scale=4]
 \tdplotsetmaincoords{70}{110}
 \pgfmathsetmacro{\Amplitude}{0.3}
 \begin{scope}[tdplot_main_coords,samples=101]
 \draw plot[variable=\x,domain=0:360] ({cos(\x)},{sin(\x)},{0});
 \foreach \X in {1,...,4}
 {\draw[fill=red] plot[variable=\x,domain=90*\X+360/16:90*\X+3*360/16,samples=51]
 ({cos(\x)},{sin(\x)},{\Amplitude*cos(4*\x)}) 
 --plot[variable=\x,domain=90*\X+3*360/16:90*\X+360/16,samples=51]
 ({cos(\x)},{sin(\x)},{0});
 \draw[fill=blue] plot[variable=\x,domain=90*\X-360/16:90*\X+360/16,samples=51]
 ({cos(\x)},{sin(\x)},{\Amplitude*cos(4*\x)}) 
 --plot[variable=\x,domain=90*\X+360/16:90*\X-360/16,samples=51]
 ({cos(\x)},{sin(\x)},{0});}
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Of course, you could use pgfplots as well.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    hide axis,
    trig format plots=rad,
    view={60}{120}
]

\addplot3 [name path=vibrating, variable=t, domain=-pi:pi, samples=1000, samples y=0] ({cos(t)},{sin(t)},{cos(4*t)});
\pgfmathsetmacro{\Amplitude}{1}
\pgfplotsinvokeforeach{1,...,4}{%
\draw[fill=red,fill opacity=0.5] plot[variable=\x,domain=90*#1+360/16:90*#1+3*360/16,samples=51]
 ({cos(\x)},{sin(\x)},{\Amplitude*cos(4*\x)}) 
 --plot[variable=\x,domain=90*#1+3*360/16:90*#1+360/16,samples=51]
 ({cos(\x)},{sin(\x)},{0});
 \draw[fill=blue,fill opacity=0.5] plot[variable=\x,domain=90*#1-360/16:90*#1+360/16,samples=51]
 ({cos(\x)},{sin(\x)},{\Amplitude*cos(4*\x)}) 
 --plot[variable=\x,domain=90*#1+360/16:90*#1-360/16,samples=51]
 ({cos(\x)},{sin(\x)},{0});}

\addplot3 [name path=flat, variable=t, domain=-pi:pi, samples=100, samples y=0] ({cos(t)},{sin(t)},0);
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Please note also that for much more complex images it might be worthwhile to switch to asymptote, which comes with a true 3D engine.

|improve this answer|||||
  • Thank you so much for such a thorough answer! – Marduk Nov 27 '18 at 9:48

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.