12

I want to draw a clyinder between two planes. I want to specify the distance between the planes and position and radius of the cylinder.

Result

I would like to use tikz-3dplot, because it allows a free rotation of the Viewpoint if everything is implemented with it.

There are a few Threads in which the creation of 3D bodies in TikZ, Drawing simple 3D cylinders in TikZ and Drawing 3D cylinder have been discussed.

Unfortunately those solution seem not to work with tikz-3dplot, because they all manipulate the 'Viewpoint' themself. This leads to the Problem, that a manipulation of the viewpoint with \tdplotsetmaincoords only rotates all Objects except the Cylinders.

Result at the moment with tikz Result at the moment with Tikz - front view

Another User had a very similar question which yielded no answer yet. How to draw a 3d cylinder using TikZ-3dplot?

To summarize: I want to draw a cylinder in 3d using tikz-3dplot. At the Moment i can draw the circle at the end of the cylinder and a line from border to border, which only recognizes rotation around the x-axis. The Question is how can i put the lines correctly at the side of the cylinder. Solution at the moment

Example of Code:

\documentclass[convert = false, tikz]{standalone}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{textcomp}

\usepackage{amsmath}
\usepackage{tikz-3dplot}

\begin{document}

%Configure here Rotation around x and y axis
\pgfmathsetmacro{\x}{60}
\pgfmathsetmacro{\y}{100}

\tdplotsetmaincoords{\x}{\y}

\begin{tikzpicture}[ tdplot_main_coords]

  \coordinate (O) at (0, 0, 0);

    \draw[-latex] (O) -- (-8, 0, 0) node[font = \small, pos = 1.1] {\(x\)};
    \draw[-latex] (O) -- (0, 6, 0) node[font = \small, pos = 1.1] {\(y\)};
    \draw[-latex] (O) -- (0, 0, 6) node[font = \small, pos = 1.1] {\(z\)};

    % define size of planes
    \pgfmathsetmacro{\planesize}{4}

    %plane1
    \filldraw[blue, opacity = .2]
         (0, 0, 0)
          -- (0, \planesize, 0)
          -- (0, \planesize, \planesize)
          -- (0, 0, \planesize)
          -- cycle;


    %Define Plane in which the circles of the cylinder are drawn.
    \tdplotgetpolarcoords{0}{1}{0}
    \tdplotsetthetaplanecoords{\tdplotresphi}

    %\tdplotdrawarc[coordinate system, draw styles]{center}{r}{angle start}{angle end}{label options}{label}
    %circle on first plane
    \pgfmathsetmacro{\radius}{0.5}
    \tdplotdrawarc[tdplot_rotated_coords]{(1,1,0)}{\radius}{0}%
    {360}{}{}

    %circle on second plane  
    \tdplotdrawarc[tdplot_rotated_coords]{(1,1,4)}{\radius}{0}%
    {360}{}{}

    %line from middle to middle
    \draw[tdplot_rotated_coords] (1,1,0) -- (1, 1, 4) node[font = \small, pos = 1.1] {};

    %First Edge of cylinder
     \draw[tdplot_rotated_coords] 
     ({1+sin(\x)*\radius},
      {1+cos(\x)*\radius},0)
       -- 
     ({1+sin(\x)*\radius},
      {1+cos(\x)*\radius},
       4) 
     node[font = \small, pos = 1.1] {};


    %plane2
    \filldraw[blue, opacity = .2]
             (-4, 0, 0)
              -- (-4, \planesize, 0)
              -- (-4, \planesize, \planesize)
              -- (-4, 0, \planesize)
              -- cycle;
\end{tikzpicture}
\end{document}
4
  • Sebastian, you're welcome, but that comment should be a comment and not part of the question. Secondly, could you please explain why you included my solution in your question? I'm having a hard time trying to figure out the problem here. :P (You can comment below here.)
    – Alenanno
    Oct 16, 2013 at 20:08
  • @Alemanno i basically want a way to draw the first picture and be able to expand it to three planes and multiple cylinders. I thought that Tikz-3dplot would be the best way to do something like that. Unfortunately there seems to be no support for cylinders. That's the reason why I am trying to construct them myself and why i am asking for help. I will abandon tikz in a blink if you know a better tool to do the job. I only know Blender, but that would be overkill i guess. Oct 17, 2013 at 9:08
  • Showing a mock-up of your desired final result would be helpful. Your first image looks like the one I've been doing so I'm not sure what you want exactly. :D
    – Alenanno
    Oct 17, 2013 at 9:15
  • @Alenanno i reformulated everything. The Problem is, that it's just a coincidence, that the Picture in your Answer looks correct. The Coordinates of the circle and of the plane are completly different. Oct 17, 2013 at 9:49

4 Answers 4

6

Attempted with pgfplots:

\documentclass[tikz]{standalone}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[
    view={45}{30},
    axis equal image,
    axis lines=center,
    xtick=\empty,ytick=\empty,ztick=\empty,
    colormap={white}{color=(white)color=(white)},
    mesh/interior colormap={blue}{color=(blue!20)color=(blue!20)},
    z buffer=sort]
    \addplot3 [domain=0:8,y domain=0:8,surf,opacity=0.6,shader=flat,samples=2] (x,8,y);
    \addplot3 [domain=0:8,y domain=0:2*pi,mesh,black,samples=25] ({4+1*cos(deg(y))},{8},{4+1*sin(deg(y))});
    \addplot3 [domain=0:8,y domain=0:2*pi,surf,shader=interp,samples=25] ({4+1*cos(deg(y))},{x},{4+1*sin(deg(y))});
    \addplot3 [domain=0:8,y domain=0:8,surf,opacity=0.6,shader=flat,samples=2] (x,0,y); 
    \addplot3 [domain=0:8,y domain=0:2*pi,mesh,black,samples=25] ({4+1*cos(deg(y))},{0},{4+1*sin(deg(y))});
    \end{axis}
\end{tikzpicture}

\end{document}

Result:

enter image description here

Remark:

Commands

\addplot3 [domain=0:8,y domain=0:8,surf,opacity=0.6,shader=flat,samples=2] (x,0,y); 

and

\addplot3 [domain=0:8,y domain=0:8,surf,opacity=0.6,shader=flat,samples=2] (x,8,y); 

draw planes y=0 and y=8. While command

\addplot3 [domain=0:8,y domain=0:2*pi,surf,shader=interp,samples=25] ({4+1*cos(deg(y))},{x},{4+1*sin(deg(y))});{x},{4+1*sin(deg(y))});

drawing a cylinder (a+bcos(y),x,a+bsin(y)), where a=4 and b=1. I also added:

\addplot3 [domain=0:8,y domain=0:2*pi,mesh,black,samples=25] ({4+1*cos(deg(y))},{0},{4+1*sin(deg(y))});
\addplot3 [domain=0:8,y domain=0:2*pi,mesh,black,samples=25] ({4+1*cos(deg(y))},{8},{4+1*sin(deg(y))});

to mark where the cylinder and plane intercept, as pgfplots couldn't handle that automatically.

You can rotate the view point freely by changing the view={...}{...} option. For example, view={60}{30} will give you:

enter image description here

Most of the options of pgfplots are quite self-explanatory, refer to the package document for further detail.

2
  • Is it possible to blacken the "edge" of the cylinder? So that the tube is transparent and only two lines connect both circles of the cylinder? Oct 18, 2013 at 17:13
  • 1
    @SebastianSchmitz: You can use options such as mesh or shader=faceted to emphasize the edges. But unfortunately that will mark all the line that are sampled. As far as I know there is no way to remove all the edges except two.
    – Francis
    Oct 18, 2013 at 17:39
6

The following answer uses Asymptote rather than TikZ-3dplot, but otherwise does (I think) everything you ask.

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}
\begin{asy}
defaultpen(fontsize(10pt));
settings.render=0;
settings.prc=false;
size(8cm);

import solids;

//currentprojection = obliqueX(angle=55);
currentprojection = orthographic(2X+Y+Z);

path3 xaxis = O -- -6X;
draw(xaxis, arrow=Arrow3);
label(Label("$x$", position=EndPoint), xaxis);

path3 yaxis = O -- 6Y;
draw(yaxis, arrow=Arrow3);
label(Label("$y$", position=EndPoint), yaxis);

path3 zaxis = O -- 6Z;
draw(zaxis, arrow=Arrow3);
label(Label("$z$", position=EndPoint), zaxis);


triple circlecenter = Y+Z;
real radius = 0.5;
triple normal = -X;
// center = Y+Z, radius=0.5, height=4, normal=-X
revolution cylinder = cylinder(circlecenter, radius, 4, normal);

surface plane = surface(O -- 4Y -- 4Y+4Z -- 4Z -- cycle);
material planecolor = material(lightblue+opacity(0.5), emissivepen=lightblue);
draw(shift(-4X) * plane, planecolor);

//Block out everything behind the cylinder.
draw(surface(cylinder), emissive(white));

draw(plane, planecolor);

draw(surface(circle(circlecenter, radius, normal)), emissive(white));

draw(cylinder.silhouette());

\end{asy}
\end{document}

The result:

enter image description here

If you change the projection (by changing which of the two lines starting currentprojection = is commented out), you get the following:

enter image description here

4

Not sure how to answer the "theoretical" part of your question because I'm not really an expert on this subject. But if you simply wanted a solution to make your cylinder look good, then maybe I found one.

It's not the best and it's actually just a sort of "hack/trick" but it works.

cylinder image

What I changed was to move the cylinder code (the one below) to before the filldraw commands:

\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}{2}{0.5}{3} % y z x  r h
\end{scope}

And then repost the same code after the filldraw commands, but this time changing the H value to 0, so that the circle appears in front.

0
1

It is important to avoid manual or sophisticated calculation of boundaries when drawing the projected cylinder. To this end, let me show a robust way with tikz-3dplot library (adapted from my other post):

\documentclass{standalone}
\usepackage{tikz,tikz-3dplot}
\begin{document}

\def\rotx{70}
\def\rotz{110}
\tdplotsetmaincoords{\rotx}{\rotz}
\begin{tikzpicture}[tdplot_main_coords][scale=0.75]
\tikzstyle{every node}=[font=\small]
\draw[dashed,-latex] (0,0,0) -- (6,0,0) node[anchor=north east]{$x$};
\draw[dashed,-latex] (0,0,0) -- (0,6,0) node[anchor=north west]{$y$};
\draw[dashed,-latex] (0,0,0) -- (0,0,6) node[anchor=south]{$z$};
\draw [thick](0,0,0) circle (3);
\draw [thick](0,0,4) circle (3);
% manual edges
\draw [dotted](1.9,-2.34,0) -- (1.9,-2.34,4) node[midway, left]{};
\draw [dotted](-1.9,2.35,0) -- (-1.9,2.35,4);
% automatic edges !
\pgfcoordinate{edge1_top}{ \pgfpointcylindrical{\rotz}{3}{4} };
\pgfcoordinate{edge1_bottom}{ \pgfpointcylindrical{\rotz}{3}{0} };
\draw[thick] (edge1_top) -- (edge1_bottom);
\pgfcoordinate{edge2_top}{ \pgfpointcylindrical{\rotz+180}{3}{4} };
\pgfcoordinate{edge2_bottom}{ \pgfpointcylindrical{\rotz+180}{3}{0} };
\draw[thick] (edge2_top) -- (edge2_bottom);
\end{tikzpicture}

\end{document}

This gives us enter image description here

You must log in to answer this question.

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