Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am new to tikz and am using it to draw cylinders. I understand how to invoke cylinder body fill to completely fill one, but I also need some cylinders that are only shaded to a certain height. Is there a built in parameter for cylinder that automates this? Looking at p433 of the documentation and searching this forum, I don't see one. If so, I'd like to learn it.

If not, I was thinking I'd just overlay two cylinders---one "body filled" with blue, the other, shorter one filled with white---to achieve the desired effect. I can do that, so I'm not asking for code. I'm more wondering if this is how veteran tikz users think about this problem.

Edit: Adding my (admittedly inelegant) code.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,shapes,decorations.markings}

% Syntax: \Cylinder{<x-coordinate>}{<y-coordinate>}{<name>}
\newcommand\whitebodyCylinder[3]{%
\tikzset{Cylin/.style={cylinder, shape border rotate = 90, draw, cylinder uses custom fill,
  cylinder end fill = white, cylinder body fill = white, minimum height = 4cm,
  minimum width = 3cm, opacity = 1, aspect = 2.5}}
  \node[Cylin] (#3) at (#1,#2) {};
}

\newcommand\bluebottomCylinder[3]{%
\tikzset{Cylin/.style={cylinder, shape border rotate = 90, draw, cylinder uses custom fill,
  cylinder end fill = blue!20, cylinder body fill = blue!20, minimum height =2cm,
  minimum width = 3cm, opacity = 1, aspect = 2.5}}
  \node[Cylin] (#3) at (#1,#2) {};
  \draw[dashed] (#1+1.5,-.5+#2) arc [start angle=0, end angle=180,
    x radius=1.5cm, y radius=3mm];
}

\begin{document}


\begin{tikzpicture}
  \whitebodyCylinder{0}{0}{}
  \bluebottomCylinder{0}{-1}{}
\end{tikzpicture}

\end{document}

enter image description here

share|improve this question
3  
Real men, like Andrew Stacey, do stuff like this. –  Jake May 10 '12 at 21:32
    
Ha! I saw that one while searching. It's on my "things to figure out how to do" list. ;-) –  JohnD May 10 '12 at 21:44
1  
Andrew hasn't told us how he did that, but he did post a really nice explanation for getting (unfilled) 3D cylinders at Drawing simple 3D cylinders in TikZ –  Jake May 10 '12 at 21:45
1  
The code in the question that Jake links to first really, really was horrible. It was a quick hack to make a joke and many things were done by eye. Thinking about what the final output would have to involve, I can't think of a way to do this that isn't, deep down, two cylinders with one filled and one drawn. To make it look as good as possible, I'd probably decompose it further to ensure that the fills and draws take place in the right order. Of course, one could wrap it up in a macro (as TB has done) but deep down that's what would be happening. –  Loop Space May 11 '12 at 7:11

1 Answer 1

up vote 12 down vote accepted

I don't know about cylinder patricians like Andrew Stacey, but if you don't neccesarily need the filled cylinders in any perspectivce, a cylinder pleb like me might do something like this:

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

\newcommand{\paficy}[5]{%
\pgfmathsetmacro{\cylinderradius}{#1}
\pgfmathsetmacro{\cylinderheight}{#2}
\pgfmathsetmacro{\fillpercentage}{#3}
\pgfmathsetmacro{\aspectratio}{#4}
\providecommand{\fillcolor}{#5}
\fill[\fillcolor] (0,0) ellipse (\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\fill[\fillcolor] (0,\cylinderheight*\fillpercentage) ellipse (\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\fill[\fillcolor] (-\cylinderradius,0) rectangle (\cylinderradius,\cylinderheight*\fillpercentage);
\draw (-\cylinderradius,0) arc (180:360:\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\draw[dashed] (-\cylinderradius,0) arc (180:0:\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\draw (0,\cylinderheight*\fillpercentage) ellipse (\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\draw (0,\cylinderheight) ellipse (\cylinderradius*1cm and \cylinderradius*\aspectratio*1cm);
\draw (-\cylinderradius,0) -- (-\cylinderradius,\cylinderheight);
\draw (\cylinderradius,0) -- (\cylinderradius,\cylinderheight);
}

\begin{document}

\begin{tikzpicture}
    \paficy{2}{7}{0.37}{0.35}{red!50!orange}
\end{tikzpicture}
\begin{tikzpicture}
    \paficy{2}{7}{0.89}{0.35}{green!50!orange}
\end{tikzpicture}

\begin{tikzpicture}
    \paficy{4}{5}{0.25}{0.15}{blue!70!gray}
\end{tikzpicture}
\begin{tikzpicture}
    \paficy{4}{5}{0.75}{0.15}{red!70!gray}
\end{tikzpicture}

\end{document}

enter image description here

If however you need them in other perspectives, I really can recommend Andrew Stacey's answer linked by Jake, it came in very handy when I had to do a exploded view drawing a while back.

share|improve this answer
2  
Looks good to me. The only thing I can see that I would have done differently would be to make the options pgf keys. Not only can they then be set as defaults, but also it makes it easier to remember which one is which. –  Loop Space May 11 '12 at 7:14
    
Yes, I thought about that. But that would have required to look up exactly how that was done again, and this I could do out of the box. But feel free to edit it ;) –  Tom Bombadil May 11 '12 at 8:07
    
Great, highly flexible solution with those 5 control parameters. This helps me greatly. Thanks! –  JohnD May 11 '12 at 13:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.