3

I have been trying to draw the following diagram in TikZ:

enter image description here

What I have achieved so far, with the help of the question posed in Drawing cylinder in 3D plane is this:

\documentclass[border=10pt,tikz]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}
\draw [fill=gray, fill opacity=.25]
(180:2.5mm) coordinate (a)
 -- ++(0,-12.5mm) coordinate (b)
 arc (180:360:2.5mm and 0.875mm) coordinate (d)
 -- (a -| d) coordinate (c) arc (0:180:2.5mm and 0.875mm);
 \draw [fill=gray, fill opacity=.25]
 (0,0) coordinate (t) circle (2.5mm and 0.875mm);
 \draw []
 (180:7.5mm) coordinate (A)
 -- ++(0,-12.5mm) coordinate (B) node [midway, right, inner sep=1pt] {}
 arc (180:360:7.5mm and 2.625mm) coordinate (D)
 -- (A -| D) coordinate (C) arc (0:180:7.5mm and 2.625mm);
 \draw []
 (0,0) coordinate (T) circle (7.5mm and 2.625mm);
 \end{tikzpicture}
 \end{document}

I do not understand how to (1) arrange multiple cylinders and (2) hide bits of the cylinders behind the main one, so to end up with the figure shown.

1
  • You can use the axis environment to do 3-d things and then draw cylinders. I don't have an MWE, but it is feasible
    – Someone
    Apr 29, 2020 at 17:42

1 Answer 1

6

Welcome! You can install an orthographic view and then just add these things in an appropriate order. For repeating things like the small cylinders pics are useful.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{perspective,3d,patterns.meta}
\begin{document}
\makeatletter
\tikzset{pics/3d cylinder z/.style={code={%
            \tikzset{3d/cylinder/.cd,#1}%
            \def\pv##1{\pgfkeysvalueof{/tikz/3d/cylinder/##1}}%
            \edef\mylocalaz{\pgf@view@az}%
            \draw[/tikz/3d/cylinder/mantle,pic actions] %[left color=gray!90,right color=gray!60,middle color=gray!20] 
            plot[domain=\pgf@view@az:\pgf@view@az-180,variable=\t,smooth]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},0)
            -- 
            plot[domain=\mylocalaz-180:\mylocalaz,variable=\t,smooth]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},
            \pv{h}) 
            -- cycle;
            \draw[/tikz/3d/cylinder/top,pic actions] %[fill=gray!30] 
            plot[domain=0:360,variable=\t,smooth cycle]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},
            \pv{h}); 
            \pgfkeys{/tikz/3d/cylinder/extra}
    }},
    3d/.cd,cylinder/.cd,r/.initial=0.3,h/.initial=4,extra/.code={},
    top/.style={fill=white,postaction={pattern={Lines[angle=-45,distance={3pt}]}}},
    mantle/.style={fill=white}}
\makeatother    
\begin{tikzpicture}[line cap=round,line join=round,declare function={az=0;R=1.6;}]
 \begin{scope}[3d view={az}{35}]
  \draw plot[smooth,variable=\t,domain=00:180]
   ({R*cos(\t+az)},{R*sin(\t+az)},4);
  \path foreach \Y in {1,2,3,4}
  { foreach \X in {1,-1}
   {({cos(\Y*\X*45-\X*45/2+az+90)},{sin(\Y*\X*45-\X*45/2+az+90)},0)
    pic{3d cylinder z}}
    \ifnum\Y=2
     (0,0,0) pic{3d cylinder z}
    \fi
    };
  \draw[fill=white] plot[smooth,variable=\t,domain=00:-180]
   ({R*cos(\t+az)},{R*sin(\t+az)},4) --
   plot[smooth,variable=\t,domain=-180:00]
   ({R*cos(\t+az)},{R*sin(\t+az)},0) -- cycle;
 \end{scope}
\end{tikzpicture}   
\end{document}

enter image description here

One can change the elevation angle to any reasonable positive value, the azimuth arbitrarily and may introduce a rotation angle that rotates the small cylinders.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{perspective,3d,patterns.meta}
\begin{document}
\makeatletter
\tikzset{pics/3d cylinder z/.style={code={%
            \tikzset{3d/cylinder/.cd,#1}%
            \def\pv##1{\pgfkeysvalueof{/tikz/3d/cylinder/##1}}%
            \edef\mylocalaz{\pgf@view@az}%
            \draw[/tikz/3d/cylinder/mantle,pic actions] %[left color=gray!90,right color=gray!60,middle color=gray!20] 
            plot[domain=\pgf@view@az:\pgf@view@az-180,variable=\t,smooth]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},0)
            -- 
            plot[domain=\mylocalaz-180:\mylocalaz,variable=\t,smooth]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},
            \pv{h}) 
            -- cycle;
            \draw[/tikz/3d/cylinder/top,pic actions] %[fill=gray!30] 
            plot[domain=0:360,variable=\t,smooth cycle]
            ({\pv{r}*cos(\t)},
            {\pv{r}*sin(\t)},
            \pv{h}); 
            \pgfkeys{/tikz/3d/cylinder/extra}
    }},
    3d/.cd,cylinder/.cd,r/.initial=0.3,h/.initial=4,extra/.code={},
    top/.style={fill=white,postaction={pattern={Lines[angle=-45,distance={3pt}]}}},
    mantle/.style={fill=white}}
\makeatother    
\foreach \Rotation in {2.5,5,...,45}
{\begin{tikzpicture}[line cap=round,line join=round,
    declare function={az=0;R=1.6;rot=\Rotation;}]
 \begin{scope}[3d view={az}{35}]
  \draw plot[smooth,variable=\t,domain=00:180]
   ({R*cos(\t+az)},{R*sin(\t+az)},4);
  \path foreach \Y in {1,2,3,4}
  { foreach \X in {1,-1}
   {({cos(\Y*\X*45-\X*45/2+az+90+Mod(rot+45/2,45)-45)},
   {sin(\Y*\X*45-\X*45/2+az+90+Mod(rot+45/2,45)-45)},0)
    pic{3d cylinder z}}
    \ifnum\Y=2
     (0,0,0) pic{3d cylinder z}
    \fi
    };
  \draw[fill=white] plot[smooth,variable=\t,domain=00:-180]
   ({R*cos(\t+az)},{R*sin(\t+az)},4) --
   plot[smooth,variable=\t,domain=-180:00]
   ({R*cos(\t+az)},{R*sin(\t+az)},0) -- cycle;
 \end{scope}
\end{tikzpicture}}   
\end{document}

enter image description here

4
  • Excellent, this is exactly what I need!
    – Trevor3
    Apr 29, 2020 at 16:52
  • Perhaps the mistake is on my side, but I think Lines[angle=-45,distance={3pt}] does not work.
    – Trevor3
    Apr 29, 2020 at 17:05
  • 1
    @david5377 You have probably an older TeX installation. patterns.meta was added only recently. You can load patterns instead of patterns.meta and use top/.style={fill=white,postaction={pattern=north west lines}}. The cleaner solution is to update your TeX installation.
    – user194703
    Apr 29, 2020 at 17:08
  • Thanks, it works!
    – Trevor3
    Apr 29, 2020 at 17:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .