6

I realize there are a couple of questions about cylinders in Tikz, but I haven't figured out how to add them to my image.

I have something like:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc,3d,arrows,shapes}
\usepackage{tikz-3dplot}

\begin{document}
\tdplotsetmaincoords{70}{46+90} % rotate 60 degrees around x axis, then 105 degrees about z
\begin{tikzpicture}[>=stealth',           % arrow tip
                    tdplot_main_coords,   % 
                    scale=0.5               % scale
                    ]  
   % XYZ axis
   \draw[thick,->] (0,0,0) -- (6,0,0) node[anchor=north east]{\textbf{x}};
   \draw[thick,->] (0,0,0) -- (0,6,0) node[anchor=north]{\textbf{y}};
   \draw[thick,->] (0,0,0) -- (0,0,6) node[anchor=south]{\textbf{z}};
    \draw[dotted] (0,0,0) circle (15);
    \draw plot [mark=*, mark size=3] coordinates{(15,0,0)} node[anchor=south east]{S}; 

% my lousy attempt
 \node [cylinder,draw=black,thick,aspect=0.5,minimum height=1cm,minimum width=0.25cm,shape border      
   rotate=0,cylinder uses custom fill, cylinder body fill=red!30,cylinder end fill=red!5] at (15,0,0){S};
\end{tikzpicture}

\end{document}

enter image description here

Where there is a 3D coordinate system, and a big circle with an specific coordinate "S" on where I want a cylinder, oriented towards (0,0,0). However I can't seem to achieve this orientation.

If the only way to approach this is to manually draw the cylinder, then I have a problem with joining the "lids". I can draw 2 filled circles in another orientation than XY plane (as @john Kormylo shows in the comments) but I have no idea how to "attach" those circles

  • I think you need a \documentclass... ;. The best option might be to draw the cylinder rather than using a node. That way, you can use the tikz-3dplot stuff for the rotation and calculations? – cfr Feb 26 '16 at 12:57
  • @cfr oh yeah, this was supposed to mean just a MVCE (ofc my figure its way more complex), and i forgot it! It could be, but, I have no idea how to approach that case then! – Ander Biguri Feb 26 '16 at 13:00
  • Sorry, but the acronyms elude me.... – cfr Feb 26 '16 at 13:23
  • I think you can probably just draw the outline in the normal way but you need to use x-y-z rather than the x-y coordinates which I'm guessing the node is using. (At least, effectively using.) – cfr Feb 26 '16 at 13:25
  • 1
    Do you just want a cylinder, or do you want to write curved text on the sides? BTW, with tikz-3d circles can only be drawn in the x-y plane, so you will probably need a rotated coordinate system. See tex.stackexchange.com/questions/254820/… – John Kormylo Feb 26 '16 at 17:19
3
+50

As far as I know, this is not easily achieved. Because node shapes are always drawn on the canvas, but you need a three-dimensional one, we need to draw the cylinder by hand. This is easily done in the rotated reference frame tikz-3dplot has ready. I set this frame in such a way that the face of the cylinder is in this plane. The circular face is easily drawn then. The only problem is drawing the side lines at the right position. For this we need to find the right angle in this plane, for which I created a macro a while back here, which I call \rotatedtangentangle here.

Putting everything together yields:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc,3d,arrows,shapes}
\usepackage{tikz-3dplot}

\begin{document}
\tdplotsetmaincoords{70}{46+90} % rotate 60 degrees around x axis, then 105 degrees about z
\begin{tikzpicture}[>=stealth',           % arrow tip
                    tdplot_main_coords,   % 
                    scale=0.5               % scale
                    ]

\newcommand{\rotatedtangentangle}[1]{%
    % find directions of projection
    \path[tdplot_rotated_coords] (1,0,0);
    \pgfgetlastxy{\axisxx}{\axisxy}
    \path[tdplot_rotated_coords] (0,1,0);
    \pgfgetlastxy{\axisyx}{\axisyy}
    \path[tdplot_rotated_coords] (0,0,1);
    \pgfgetlastxy{\axiszx}{\axiszy}
    % angle of tangent
    \pgfmathsetmacro{\rtang}{atan(-\axiszy/\axiszx)+180}
    \pgfmathsetmacro{\angkorr}{atan(\axisyy/\axisyx)/2}

    \pgfmathsetmacro{#1}{\rtang+\angkorr}
}%

   % XYZ axis
    \draw[thick,->] (0,0,0) -- (6,0,0) node[anchor=north east]{\textbf{x}};
    \draw[thick,->] (0,0,0) -- (0,6,0) node[anchor=north]{\textbf{y}};
    \draw[thick,->] (0,0,0) -- (0,0,6) node[anchor=south]{\textbf{z}};
    \draw[dotted] (0,0,0) circle (15);

    \tdplotsetthetaplanecoords{90} % create rotated frame
    \rotatedtangentangle{\tangent} % compute tanget angle
    % shift rotated frame to center of cylinder
    \coordinate (shift) at (15,0,0);
    \tdplotsetrotatedcoordsorigin{(shift)}
    % draw cylinder
    \begin{scope}[tdplot_rotated_coords]
        % draw the side lines and arc of the cylinder (here length 1, radius 0.5)
        \draw[fill=red!30]
            (0,0,-1) ++(\tangent:0.5) -- ++(0,0,1) arc (\tangent:\tangent-180:0.5) -- ++(0,0,-1);
        % draw the circular face (radius 0.5)
        \draw[fill=red!30] (0,0,-1) circle [radius=0.5];
        \node at (0,0,0) {S};
    \end{scope}

\end{tikzpicture}

\end{document}

enter image description here

| improve this answer | |
  • Fantastic. Could you please give a hint on how to change the cylinder diymensions? – Ander Biguri Mar 8 '16 at 9:03
  • Since the cylinder is drawn in the last scope, you may simply change the appropriate values. The radius of the circle is used as radius as well as in the arc (its start angle:end angle:radius). The length of the cylinder is drawn in absolute coordinates, here 1cm. Just change the value e.g. to -- ++(0,0,2) to get twice the length. – Dux Mar 8 '16 at 9:08
  • I am sure one could wrap this up in a nice makro though... – Dux Mar 8 '16 at 9:08

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.