Drawing a bundle of cylinders inside a cylinder in 3D

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

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.

• 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 Apr 29, 2020 at 17:42

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}

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}

• Excellent, this is exactly what I need! Apr 29, 2020 at 16:52
• Perhaps the mistake is on my side, but I think Lines[angle=-45,distance={3pt}] does not work. Apr 29, 2020 at 17:05
• @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! Apr 29, 2020 at 17:22