I would like to draw the diagram below using either pgfplots
or tikz
.
I am able to draw a cylinder, using the pgfplots
manual, but I don't know how to draw a fraction of a cylinder.
-
Easiest would be to use tikz3d instead. – John Kormylo Aug 17 '18 at 23:55
-
This is not a plot, so you should not use PGFPlots, but pure TikZ. There are many sources on how to draw an arc, a line and add text(nodes). See e.g. the introduction in the TikZ manual. Anyway, for a question here you need to show what you have, and describe what is causing you problems. – hpekristiansen Aug 17 '18 at 23:58
-
I think you found how to draw a cylinder in the TikZ manual and not in the PGFPlots manual, right? And as another side note, if you really want to use this as a diagram: Have a look at section 7.6 p. 94f in the TikZ/pgf manual (v3.0.1a) on why you shouldn't use 3D pie charts. – Stefan Pinnow Aug 18 '18 at 5:01
TikZ and 3D means in my experience always a bit of improvisation. One can change the view angle with some restrictions. If you want to lift these restrictions, you may have to change the drawing order and/or add or subtract certain contours. UPDATE: Fixed a bug pointed out by Friendly Ghost: the projection of the arrow on top of the cheese was incorrect. This was due to a bug in the 3d library. Some time ago I knew about it but forgot it.
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d}
\usepackage{tikz-3dplot}
\makeatletter % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\begin{document}
\foreach \X in {0,5,...,355}
{\tdplotsetmaincoords{120+20*sin(\X)}{-135+45*cos(2*\X)}
\begin{tikzpicture}
\path[use as bounding box] (-6,-3) rectangle (6,5);
\begin{scope}[tdplot_main_coords]
\draw plot[variable=\x,domain=\tdplotmainphi+180:0,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},0) -- (0,0,0) -- (0,-4,0)
plot[variable=\x,domain=-90:\tdplotmainphi,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},0);
\draw plot[variable=\x,domain=0:270,samples=90,smooth]
({4*cos(\x)},{4*sin(\x)},2);
\draw (0,-4,0) -- (0,-4,2) (4,0,0) -- (4,0,2) (0,0,0) -- (0,0,2)
(0,-4,2) -- (0,0,2) -- (4,0,2)
({4*cos(\tdplotmainphi+180)},{4*sin(\tdplotmainphi+180)},0) --
({4*cos(\tdplotmainphi+180)},{4*sin(\tdplotmainphi+180)},2)
({4*cos(\tdplotmainphi)},{4*sin(\tdplotmainphi)},0) --
({4*cos(\tdplotmainphi)},{4*sin(\tdplotmainphi)},2);
\path ({5*cos(\tdplotmainphi+180)},{5*sin(\tdplotmainphi+180)},0) coordinate(B)
({5*cos(\tdplotmainphi+180)},{5*sin(\tdplotmainphi+180)},2) coordinate(T)
(0,0,3) coordinate (A);
\begin{scope}[x={(1,0,0)},y={(0,1,0)},z={(0,0,1)}]
\begin{scope}[canvas is xy plane at z=2,transform shape]
\fill (0,0) -- (0:0.1) arc(0:270:.1) -- cycle;
\path (-0.3,0) -- (-0.3,-4) node[sloped,yscale=-1,midway] {4cm};
\node[xscale=-1,rotate=-45] at (-0.6,0.6) {$270^\circ$};
\pgflowlevelsynccm
\draw[latex-latex] (0:0.4) arc(00:270:.4);
\end{scope}
\end{scope}
\end{scope}
\draw[latex-latex] (T) -- (B) node[midway,left] {2cm};
\end{tikzpicture}}
\end{document}
ADDENDUM: A version for J Leon V. ;-)
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d}
\usepackage{tikz-3dplot}
\makeatletter % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\begin{document}
\foreach \X in {0,5,...,355}
{\tdplotsetmaincoords{120+20*sin(\X)}{-135+45*cos(2*\X)}
\begin{tikzpicture}
\path[use as bounding box] (-6,-3) rectangle (6,5);
\begin{scope}[tdplot_main_coords]
% face on the left
\draw[fill=yellow!30!orange]
plot[variable=\x,domain=\tdplotmainphi+180:0,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},0) -- ++(0,0,2) --
plot[variable=\x,domain=0:\tdplotmainphi+180,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},2) --cycle;
% face on the right
\draw[fill=yellow!30!orange] plot[variable=\x,domain=-90:\tdplotmainphi,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},0) -- ++(0,0,2) --
plot[variable=\x,domain=\tdplotmainphi:-90,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},2) -- cycle;
\draw[fill=yellow!30!orange] plot[variable=\x,domain=0:270,samples=90,smooth]
({4*cos(\x)},{4*sin(\x)},2) -- (0,-4,2) -- (0,0,2) -- (4,0,2) ;
\begin{scope}[canvas is xz plane at y=0,transform shape]
\filldraw[fill=yellow!80!orange] (4,2) -- (4,0) --(0,0) -- (0,2) -- cycle;
\foreach \x/\y/\r in {0.4/0.6/0.3,
0.5/1.3/0.2,
1.5/0.5/0.4,
1.5/0.5/0.4,
2.1/1.5/0.3,
2.5/0.8/0.2,
3.3/1.1/0.3}
{\shade[ball color=yellow!80!orange,opacity=0.2] (\x,\y) circle (\r);}
\end{scope}
\begin{scope}[canvas is yz plane at x=0,transform shape]
\filldraw[fill=yellow!80!orange] (-4,2) -- (-4,0) --(0,0) -- (0,2) -- cycle;
\foreach \x/\y/\r in {-0.4/0.6/0.3,
-0.5/1.3/0.2,
-1.5/0.5/0.4,
-1.5/0.5/0.4,
-2.1/1.5/0.3,
-2.5/0.8/0.2,
-3.3/1.1/0.3}
{\shade[ball color=yellow!80!orange,opacity=0.2] (\x,\y) circle (\r);}
\end{scope}
\path ({5*cos(\tdplotmainphi+180)},{5*sin(\tdplotmainphi+180)},0) coordinate(B)
({5*cos(\tdplotmainphi+180)},{5*sin(\tdplotmainphi+180)},2) coordinate(T)
(0,0,3) coordinate (A);
\begin{scope}[x={(1,0,0)},y={(0,1,0)},z={(0,0,1)}]
\begin{scope}[canvas is xy plane at z=2,transform shape]
\fill (0,0) -- (0:0.1) arc(0:270:.1) -- cycle;
\path (-0.3,0) -- (-0.3,-4) node[sloped,yscale=-1,midway] {4cm};
\node[xscale=-1,rotate=-45] at (-0.6,0.6) {$270^\circ$};
\pgflowlevelsynccm
\draw[latex-latex] (0:0.4) arc(00:270:.4);
\end{scope}
\end{scope}
\end{scope}
\draw[latex-latex] (T) -- (B) node[midway,left] {2cm};
\end{tikzpicture}}
\end{document}
2nd ADDENDUM: A version that works for all angles. This exploits the fact that the missing piece has an arc of 90 degrees. Therefore one can cook it down to 8 orderings of the elements.
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{3d}
\usepackage{tikz-3dplot}
\makeatletter % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\newcommand{\DrawVerticalPart}[3][]{%
\draw[fill=yellow!30!orange,#1]
plot[variable=\x,domain=#2:#3,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},0) -- ++(0,0,2) --
plot[variable=\x,domain=#3:#2,samples=30,smooth]
({4*cos(\x)},{4*sin(\x)},2) --cycle;
}
\newcommand{\CheesePiece}[1]{\ifcase#1
\or% 1: xz face
\begin{scope}[canvas is xz plane at y=0,transform shape]
\filldraw[fill=yellow!80!orange] (4,2) -- (4,0) --(0,0) -- (0,2) -- cycle;
\foreach \x/\y/\r in {0.4/0.6/0.3,
0.5/1.3/0.2,
1.5/0.5/0.4,
1.5/0.5/0.4,
2.1/1.5/0.3,
2.5/0.8/0.2,
3.3/1.1/0.3}
{\shade[ball color=yellow!80!orange,opacity=0.2] (\x,\y) circle (\r);}
\end{scope}
\or% 2: yz face
\begin{scope}[canvas is yz plane at x=0,transform shape]
\filldraw[fill=yellow!80!orange] (-4,2) -- (-4,0) --(0,0) -- (0,2) -- cycle;
\foreach \x/\y/\r in {-0.4/0.6/0.3,
-0.5/1.3/0.2,
-1.5/0.5/0.4,
-1.5/0.5/0.4,
-2.1/1.5/0.3,
-2.5/0.8/0.2,
-3.3/1.1/0.3}
{\shade[ball color=yellow!80!orange,opacity=0.2] (\x,\y) circle (\r);}
\end{scope}
\or% 3: top
\draw[fill=yellow!30!orange] plot[variable=\x,domain=0:270,samples=90,smooth]
({4*cos(\x)},{4*sin(\x)},2) -- (0,-4,2) -- (0,0,2) -- (4,0,2);
\or% 4: bottom
\draw[fill=yellow!30!orange] plot[variable=\x,domain=0:270,samples=90,smooth]
({4*cos(\x)},{4*sin(\x)},0) -- (0,-4,0) -- (0,0,0) -- (4,0,0);
\fi}
\begin{document}
\foreach \X in {0,5,...,355}%{45,135,225,315}
{%\tdplotsetmaincoords{120+20*sin(\X)}{-135+45*cos(2*\X)}
\tdplotsetmaincoords{90+30*sin(\X)}{\X}
\begin{tikzpicture}
\path[use as bounding box] (-6,-3) rectangle (6,5);
\pgfmathtruncatemacro{\xtest}{sign(cos(\tdplotmainphi+90))}
\pgfmathtruncatemacro{\ytest}{sign(-cos(\tdplotmainphi))}
\pgfmathtruncatemacro{\ztest}{sign(cos(\tdplotmaintheta))}
%\node[anchor=north west] at (-6,5) {\X,\xtest,\ytest,\ztest};
\begin{scope}[tdplot_main_coords]
\ifnum\xtest=1
\CheesePiece{2}
\ifnum\ytest=1
\CheesePiece{1}
\DrawVerticalPart{0}{\tdplotmainphi-180}
\DrawVerticalPart{\tdplotmainphi}{270}
\else
\DrawVerticalPart{0}{\tdplotmainphi-180}
\fi
\else
\ifnum\ytest=1
\CheesePiece{1}
\DrawVerticalPart{\tdplotmainphi}{270}
\else
\DrawVerticalPart{\tdplotmainphi}{\tdplotmainphi+180}
\fi
\fi
\ifnum\ztest=1
\CheesePiece{4}
\else
\CheesePiece{3}
\fi
\end{scope}
\end{tikzpicture}}
\end{document}
-
3
-
2At some points in space and time there are conditions in which the arrow heads look a bit weird. – Friendly Ghost Aug 18 '18 at 2:29
-
2@FriendlyGhost Very good observation! Thanks! I fixed it, I believe. (One should always look at the output before uploading... ;-) – marmot Aug 18 '18 at 2:54
-
2
-
2+1 Excellent, as always exceeding expectations, but what about the internal lines of the cut ... – J Leon V. Aug 18 '18 at 6:17