You can use the predefined cylinder shape and then draw an ellipse with a solid fill on top. With the following code, you can supply all the options to the cylinder
shape as before, the let
code in the ellipse takes care of the position, size and rotation of the ellipse. You only need to adjust the colour.
The operation let \p<number> = (<coordinate>) in ...
is described on p. 150 (section 14.15) in the pgf manual: It assigns a point described by (<coordinate>)
to the local variable \p<number>
, where <number>
can be arbitrarily chosen. The variables \x<number>
and \y<number>
then contain the x and y values of the point. The registers \n<number>
can be used to store results from mathematical operations.
The construct <coordinate>!<number>!<second coordinate>
is described on p. 135 (section 13.5.5) in the manual: It describes a point along the line from <first coordinate>
to <second coordinate>
, where the value 0 would be at the first point, 1 at the second, and 0.5 halfway in between.
The points (cyl.before top)
, (cyl.after top)
and (cyl.top)
are defined by the cylinder shape (see p. 434, section 48.3 in the pgf manual).
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,calc}
\begin{document}
\begin{tikzpicture}
\node [draw,
shape=cylinder,
name=nodename, % Can be defined arbitrarily
alias=cyl, % Will be used by the ellipse to reference the cylinder
aspect=1.5,
minimum height=3cm,
minimum width=2cm,
left color=blue!30,
right color=blue!60,
middle color=red!20, % Has to be called after left color and middle color
outer sep=-0.5\pgflinewidth, % to make sure the ellipse does not draw over the lines
shape border rotate=90
] at (1,2) {A};
\fill [red!20] let
\p1 = ($(cyl.before top)!0.5!(cyl.after top)$),
\p2 = (cyl.top),
\p3 = (cyl.before top),
\n1={veclen(\x3-\x1,\y3-\y1)},
\n2={veclen(\x2-\x1,\y2-\y1)},
\n3={atan2((\y2-\y1),(\x2-\x1))}
in
(\p1) ellipse [x radius=\n1, y radius = \n2, rotate=\n3];
\end{tikzpicture}
\end{document}

Version for PGF 2.0
For PGF 2.0, the code needs to be adapted slightly, because the mathematical function atan2
is missing in the old version and the syntax for an ellipse is different.
The operation let \p = () in ...
is described on p. 127 (section 13.14) in the pgf 2.0 manual ('The Let Operation').
The construct <coordinate>!<number>!<coordinate>
is described on p. 116, section 12.4.3 in the pgf 2.0 manual.
The points (cyl.before top), (cyl.after top) and (cyl.top) are defined by the cylinder shape (see p. 326, section 39.3 ('Geometric Shapes') in the pgf 2.0 manual).
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,calc}
\begin{document}
\begin{tikzpicture}
\node [draw,
shape=cylinder,
name=nodename, % Can be defined arbitrarily
alias=cyl, % Will be used by the ellipse to reference the cylinder
aspect=1.5,
minimum height=3cm,
minimum width=2cm,
left color=blue!30,
right color=blue!60,
middle color=red!20, % Has to be called after left color and middle color
outer sep=-0.5\pgflinewidth, % to make sure the ellipse does not draw over the lines
shape border rotate=90
] at (1,2) {A};
\fill [red!20] let
\p1 = ($(cyl.before top)!0.5!(cyl.after top)$),
\p2 = (cyl.top),
\p3 = (cyl.before top),
\n1={veclen(\x3-\x1,\y3-\y1)},
\n2={veclen(\x2-\x1,\y2-\y1)}
in
(\p1) ellipse (\n1 and \n2);
\end{tikzpicture}
\end{document}
pgflibraryshapes.geometric.code.tex
and add keys and code for shading, but I don't have time to do that right now. Give me few days, I will try something, unless someone else comes up with a better solution.