8

I need to draw a lot of 3D cylinders with different dimensions. Has anyone maybe already defined a command like \3Dcylinder{x}{y}{z}?

I found 3D bodies in TikZ and tried the third answer. But I don't understand how the parameters work.

Also I found Drawing simple 3D cylinders in TikZ. But I don't know how to use it to easily draw a bunch of different cylinders.

5

I also once had that problem when I had to draw an explded view drawing. Andrew Stacey's answer in the second link you mentioned was the way to go, so I adapted the following macro:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\pgfmathsetmacro{\xdeg}{30}
\pgfmathsetmacro{\xx}{cos(\xdeg)}
\pgfmathsetmacro{\xy}{sin(\xdeg)}

\pgfmathsetmacro{\ydeg}{120}
\pgfmathsetmacro{\yx}{cos(\ydeg)}
\pgfmathsetmacro{\yy}{sin(\ydeg)}

\pgfmathsetmacro{\zdeg}{80}
\pgfmathsetmacro{\zx}{cos(\zdeg)}
\pgfmathsetmacro{\zy}{sin(\zdeg)}

\newcommand{\tdcyl}[5]{% origin x, origin y, origin z, radius, height
    \path (1,0,0);
    \pgfgetlastxy{\cylxx}{\cylxy}
    \path (0,1,0);
    \pgfgetlastxy{\cylyx}{\cylyy}
    \path (0,0,1);
    \pgfgetlastxy{\cylzx}{\cylzy}
    \pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
    \pgfmathsetmacro{\ang}{atan(\cylt)}
    \pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
    \pgfmathsetmacro{\st}{\cylt * \ct}
    \filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=-180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
    \filldraw[fill=white] (#1,#2,#3+#5) circle[radius=#4];
}

\begin{document}

\begin{tikzpicture}[x={(\xx*1cm,\xy*1cm)},y={(\yx*1cm,\yy*1cm)},z={(\zx*1cm,\zy*1cm)}]
    \tdcyl{0}{0}{0}{1}{3}
    \draw (-3,0,0) -- (3,0,0) node[circle,fill=white] {x};
    \draw (0,-3,0) -- (0,3,0) node[circle,fill=white] {y};
    \draw (0,0,-3) -- (0,0,3) node[circle,fill=white] {z};
\end{tikzpicture}

\end{document}

enter image description here

Note however that this only works for cylinders growing in z-direction and "right handed" coordinate systems, e.g. when in a clockwise fashion the vectors are yzx, zxy or xyz, but not yxz, zxy or xzy.


Edit 1: As I remembered that I also had to draw y-growing cylinders, I looked it up. Being too lazy to generalize the macro, I then just redefined the coordinate axes locally thus changling the order of th input meaning (from xyzrh for z-growing to xzyrh for y-growing and yzxrh for x-growing), and I also had to modify the original macro. Probably one could unify these (probably involving something like ifthenelse from xifthen package). For now, here's the ugly hackish version, I recommaned not using it or documenting very well what you did:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\pgfmathsetmacro{\xdeg}{30}
\pgfmathsetmacro{\xx}{cos(\xdeg)}
\pgfmathsetmacro{\xy}{sin(\xdeg)}

\pgfmathsetmacro{\ydeg}{150}
\pgfmathsetmacro{\yx}{cos(\ydeg)}
\pgfmathsetmacro{\yy}{sin(\ydeg)}

\pgfmathsetmacro{\zdeg}{90}
\pgfmathsetmacro{\zx}{cos(\zdeg)}
\pgfmathsetmacro{\zy}{sin(\zdeg)}

\newcommand{\tdcyl}[5]{% origin x, origin y, origin z, radius, height
    \path (1,0,0);
    \pgfgetlastxy{\cylxx}{\cylxy}
    \path (0,1,0);
    \pgfgetlastxy{\cylyx}{\cylyy}
    \path (0,0,1);
    \pgfgetlastxy{\cylzx}{\cylzy}
    \pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
    \pgfmathsetmacro{\ang}{atan(\cylt)}
    \pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
    \pgfmathsetmacro{\st}{\cylt * \ct}
    \filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=-180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
    \filldraw[fill=white] (#1,#2,#3+#5) circle[radius=#4];
}

\newcommand{\tdcylxy}[5]{% origin x, origin y, origin z, radius, height
    \path (1,0,0);
    \pgfgetlastxy{\cylxx}{\cylxy}
    \path (0,1,0);
    \pgfgetlastxy{\cylyx}{\cylyy}
    \path (0,0,1);
    \pgfgetlastxy{\cylzx}{\cylzy}
    \pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
    \pgfmathsetmacro{\ang}{atan(\cylt)}
    \pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
    \pgfmathsetmacro{\st}{\cylt * \ct}
    \filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
    \filldraw[fill=white] (#1,#2,#3) circle[radius=#4];
}

\begin{document}

\begin{tikzpicture}[x={(\xx*1cm,\xy*1cm)},y={(\yx*1cm,\yy*1cm)},z={(\zx*1cm,\zy*1cm)}]
    \tdcyl{0}{0}{3}{1}{3} % x y z   r h
    \begin{scope}[x={(\xx*1cm,\xy*1cm)},z={(\yx*1cm,\yy*1cm)},y={(\zx*1cm,\zy*1cm)}]
        % This is a y-growing cylinder
        \tdcylxy{0}{0}{3}{1.5}{3} % x z y r h
    \end{scope}
    \begin{scope}[z={(\xx*1cm,\xy*1cm)},x={(\yx*1cm,\yy*1cm)},y={(\zx*1cm,\zy*1cm)}]
        % This is a x-growing cylinder
        \tdcylxy{0}{0}{3}{0.5}{3} % y z x  r h
    \end{scope}
    \draw (-3,0,0) -- (3,0,0) node[circle,fill=white] {x};
    \draw (0,-3,0) -- (0,3,0) node[circle,fill=white] {y};
    \draw (0,0,-3) -- (0,0,3) node[circle,fill=white] {z};
\end{tikzpicture}

\end{document}

enter image description here

11

You may also use the cylinder shape. Here are two examples, taken directly from the tikz manual.

\documentclass[border=5pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\begin{document}

\begin{tikzpicture}
\node[cylinder, draw, shape aspect=.5] {ABC};
\end{tikzpicture}

\begin{tikzpicture}
  \node [cylinder, gray!50, rotate=30, draw,
    minimum height=2cm, minimum width=1cm] (c) {Cylinder};
  \draw[red, <->] (c.top)   -- (c.bottom)
    node [at end, below, black]   {height};
  \draw[red, <->] (c.north) -- (c.south)
    node [at start, above, black] {width};
\end{tikzpicture}

\end{document}

The result is:

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.