Solución:
Puede usar la forma de cilindro predefinida y luego dibujar una elipse con un relleno sólido en la parte superior. Con el siguiente código, puede proporcionar todas las opciones al cylinder
forma como antes, el let
el código en la elipse se encarga de la posición, el tamaño y la rotación de la elipse. Solo necesitas ajustar el color.
La operacion let p<number> = (<coordinate>) in ...
se describe en la p. 150 (apartado 14.15) del manual pgf: Asigna un punto descrito por (<coordinate>)
a la variable local p<number>
, dónde <number>
se puede elegir arbitrariamente. Las variables x<number>
y y<number>
luego contiene los valores xey del punto. Los registros n<number>
se puede utilizar para almacenar resultados de operaciones matemáticas.
El constructo <coordinate>!<number>!<second coordinate>
se describe en la p. 135 (sección 13.5.5) del manual: describe un punto a lo largo de la línea desde <first coordinate>
para <second coordinate>
, donde el valor 0 estaría en el primer punto, 1 en el segundo y 0,5 en el medio.
Los puntos (cyl.before top)
, (cyl.after top)
y (cyl.top)
se definen por la forma del cilindro (ver p. 434, sección 48.3 en el manual pgf).
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.5pgflinewidth, % 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}
Versión para PGF 2.0
Para PGF 2.0, el código debe adaptarse ligeramente, porque la función matemática atan2
falta en la versión anterior y la sintaxis de una elipse es diferente.
La operacion let p = () in ...
se describe en la p. 127 (sección 13.14) en el manual pgf 2.0 (‘La operación Let’).
El constructo <coordinate>!<number>!<coordinate>
se describe en la p. 116, sección 12.4.3 del manual pgf 2.0.
Los puntos (cilindro antes de la parte superior), (cilindro después de la parte superior) y (parte superior del cilindro) están definidos por la forma del cilindro (consulte la p. 326, sección 39.3 (‘Formas geométricas’) en el manual pgf 2.0).
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.5pgflinewidth, % 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}
Para crear un cilindro independiente, sin usar las formas TikZ predefinidas, puede hacer algo como esto:
documentclass{article}
usepackage{tikz}
usetikzlibrary{calc}
begin{document}
pagestyle{empty}
begin{tikzpicture}
coordinate (ll) at (-3,-2);
coordinate (lr) at (3,-2);
coordinate (ul) at (-3,2);
coordinate (ur) at (3,2);
shade [shading angle=90] (ll) arc (-180:-60:3cm and .75cm) -- +(0,4) arc (-60:-180:3cm and .75cm) -- cycle;
shade [shading angle=270] (lr) arc (0:-60:3cm and .75cm) -- +(0,4) arc (-60:0:3cm and .75cm) -- cycle;
draw [thick] (ll) arc (-180:0:3cm and .75cm) -- (ur) arc (0:-180:3cm and .75cm) -- cycle;
draw [thick, shade, shading angle=30] (ul) arc (-180:180:3cm and .75cm);
node at (0,-.75){Huge A};
end{tikzpicture}
end{document}
Solo por diversión. Las respuestas anteriores son geniales. Sin embargo, la respuesta de Jan no crea un nodo. La fantástica respuesta de Jake construye la elipse en dos pasos. Esto no es nada malo, pero es posible que desee construirlo de una vez. He aquí una forma de hacerlo en un solo paso. No se me ocurrió el camino del final, sino que se copió del shapes.geometric
Biblioteca. Parece posible (ab) usar imágenes de ruta para “alojar” algún código pgf que uno encuentra en otros lugares. No sé si eso se ha mencionado antes en este sitio, si lo fue, estaré feliz de dar el crédito adecuado, ni sé si hay problemas importantes. Solo hice pruebas muy limitadas, así que utilícelo con cuidado.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{shapes.geometric}
begin{document}
tikzset{cylinder end fill/.style={path picture={
pgftransformshift{centerpoint}%
pgftransformrotate{rotate}%
pgfpathmoveto{beforetop}%
pgfpatharc{90}{-270}{xradius and yradius}%
pgfpathclose
pgfsetfillcolor{#1}%
pgfusepath{fill}}
}}
begin{tikzpicture}
pgfmathsetmacro{myaspect}{pi/4}
node [draw,
shape=cylinder,
aspect=myaspect,
minimum height=3cm,
minimum width=2cm,
rotate=20,
cylinder end fill=blue,
left color=blue!30,
right color=black,
middle color=blue!80,
shading angle=20,
font=sffamily,
text width=pi*1cm,
text=white] {Hello world, ducks, koalas and marmots!};
end{tikzpicture}
end{document}
RESPUESTA ANTIGUA: (innecesariamente complicado) En esta respuesta, se declara una forma “nueva” basada en el cilindro estándar. No lo probé extensamente, simplemente lo hice para aprender algo nuevo. Lo nuevo que aprendí está en la parte superior de la respuesta.
documentclass{beamer}
setbeamertemplate{navigation symbols}{}
usepackage{tikz}
usetikzlibrary{shapes.geometric}
makeatletter
% Additional keys for shape "shaded cylinder"
%
% /pgf/cylinder body top shade : Custom shading color for the cylinderbody.
% /pgf/cylinder body middle shade: Custom shading color for the cylinderbody.
% /pgf/cylinder body bottom shade : Custom shading color for the cylinderbody.
%
newififpgfcylinderusescustomshade
pgfkeys{/pgf/.cd,
cylinder uses custom shade/.is if=pgfcylinderusescustomshade,
cylinder end fill/.initial=white,
cylinder body top shade/.initial=white,
cylinder body middle shade/.initial=white,
cylinder body bottom shade/.initial=white,
cylinder body shade angle/.initial=0,
}
pgfdeclareshape{shaded cylinder}{%
savedmacrogetcylinderpoints{%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/inner xsep}}%
[email protected][email protected]%
advance[email protected]wdpgfnodeparttextbox%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/inner ysep}}%
[email protected][email protected]%
advance[email protected]htpgfnodeparttextbox%
advance[email protected]dppgfnodeparttextbox%
ifpgfshapeborderusesincircle%
pgfmathsetmacrorotate{pgfkeysvalueof{/pgf/shape border rotate}}%
ifdim[email protected]<[email protected]%
[email protected][email protected]%
else%
[email protected][email protected]%
fi%
[email protected][email protected]%
[email protected][email protected]%
else%
pgfmathmod{pgfkeysvalueof{/pgf/shape border rotate}}{360}%
ifdimpgfmathresult pt<0ptrelax%
[email protected]{pgfmathresult}{360}%
fi%
pgfmathsetcount[email protected]@counta{+pgfmathresult}%
advance[email protected]@counta45relax%
divide[email protected]@counta90relax%
multiply[email protected]@counta90relax%
edefrotate{the[email protected]@counta}%
ifnum[email protected]@counta=90relax%
[email protected][email protected]%
[email protected][email protected]%
[email protected][email protected]%
[email protected][email protected]%
else%
ifnum[email protected]@counta=270relax%
[email protected][email protected]%
[email protected][email protected]%
[email protected][email protected]%
[email protected][email protected]%
fi%
fi%
fi%
addtosavedmacrorotate%
[email protected][email protected]%
[email protected][email protected]%
[email protected]pgfshapeaspect[email protected]%
[email protected][email protected]%
%
% Adjust for minimum height.
%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/minimum width}}%
ifdim[email protected]<.5[email protected]relax%
[email protected][email protected]%
[email protected][email protected]%
fi%
%
% Calculate how far the node contents can extend into the cylinder bottom.
%
[email protected][email protected]%
advance[email protected][email protected]%
[email protected]{[email protected]{[email protected]}}{[email protected]{[email protected]}}%
[email protected]{pgfmathresult}%
[email protected]{pgfmathresult}%
letanglepgfmathresult%
[email protected]pgfmathresult[email protected]%
%
% Adjust for minimum width.
%
[email protected]pgflinewidth%
advance[email protected][email protected]%
advance[email protected][email protected]%
advance[email protected][email protected]%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/minimum height}}%
ifdim[email protected]<[email protected]%
advance[email protected][email protected]%
advance[email protected][email protected]%
fi%
%
% Add the larger of the outer sep to the radii.
%
[email protected][email protected]relax%
[email protected][email protected]relax%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/outer xsep}}%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/outer ysep}}%
ifdim[email protected]>[email protected]%
advance[email protected][email protected]%
advance[email protected][email protected]%
edefoutersep{the[email protected]}%
else%
advance[email protected][email protected]%
advance[email protected][email protected]%
edefoutersep{the[email protected]}%
fi%
edefxradius{the[email protected]}%
edefyradius{the[email protected]}%
addtosavedmacroxradius%
addtosavedmacroyradius%
addtosavedmacrooutersep%
%
[email protected]cylindercenter{%
[email protected][email protected]%
advance[email protected]pgflinewidth%
advance[email protected][email protected]%
[email protected][email protected]%
[email protected]%
}%
addtosavedmacrocylindercenter%
%
[email protected]beforetop{%
[email protected][email protected]%
advance[email protected][email protected]%
advance[email protected]pgflinewidth%
[email protected][email protected]%
}%
[email protected]afterbottom{%
[email protected][email protected]%
advance[email protected][email protected]%
[email protected][email protected]%
}%
addtosavedmacrobeforetop%
addtosavedmacroafterbottom%
pgfmathsetlength[email protected]{pgfkeysvalueof{/pgf/outer ysep}}%
[email protected]beforetopanchor{%
beforetop%
advance[email protected][email protected]%
}%
[email protected]afterbottomanchor{%
afterbottom%
advance[email protected][email protected]%
}%
addtosavedmacrobeforetopanchor%
addtosavedmacroafterbottomanchor%
%
beforetopanchor%
advance[email protected]xradiusrelax%
ifdim[email protected]>[email protected]%
edefexternalradius{the[email protected]}%
else%
edefexternalradius{the[email protected]}%
fi%
addtosavedmacroexternalradius%
}
savedanchorcenterpoint{%
[email protected]wdpgfnodeparttextbox%
[email protected]htpgfnodeparttextbox%
advance[email protected]dppgfnodeparttextbox%
}%
savedanchormidpoint{%
[email protected]wdpgfnodeparttextbox%
pgfmathsetlength[email protected]{+0.5ex}%
}%
savedanchorbasepoint{%
[email protected]wdpgfnodeparttextbox%
[email protected]%
}%
anchor{center}{centerpoint}
anchor{shape center}{%
getcylinderpoints%
pgfmathrotatepointaround{pgfpointadd{cylindercenter}{centerpoint}}%
{centerpoint}{rotate}%
}%
anchor{mid}{midpoint}%
anchor{mid east}{%
getcylinderpoints%
let[email protected]@referencepointmidpoint%
[email protected]@[email protected]{pgfqpoint{externalradius}{0pt}}%
}%
anchor{mid west}{%
getcylinderpoints%
let[email protected]@referencepointmidpoint%
[email protected]@[email protected]{pgfqpoint{-externalradius}{0pt}}%
}%
anchor{base}{basepoint}%
anchor{base east}{%
getcylinderpoints%
let[email protected]@referencepointbasepoint%
[email protected]@[email protected]{pgfqpoint{externalradius}{0pt}}%
}%
anchor{base west}{%
getcylinderpoints%
let[email protected]@referencepointbasepoint%
[email protected]@[email protected]{pgfqpoint{-externalradius}{0pt}}%
}%
anchor{north}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{0pt}{externalradius}}%
}%
anchor{south}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{0pt}{-externalradius}}%
}%
anchor{east}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{externalradius}{0pt}}%
}%
anchor{west}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{-externalradius}{0pt}}%
}%
anchor{north east}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{externalradius}{externalradius}}%
}%
anchor{south west}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{-externalradius}{-externalradius}}%
}%
anchor{south east}{%
getcylinderpoints%
[email protected]@[email protected]{pgfqpoint{externalradius}{-externalradius}}%
}%
anchor{north west}{%
getcylinderpoints%
[email protected][email protected]@border{pgfqpoint{-externalradius}{externalradius}}%
}%
anchor{before top}{%
getcylinderpoints%
pgfmathrotatepointaround{pgfpointadd{beforetopanchor}{centerpoint}}{centerpoint}{rotate}%
}
anchor{top}{%
getcylinderpoints%
pgfmathrotatepointaround{%
pgfpointadd{%
beforetop%
[email protected]relax%
advance[email protected]xradiusrelax%
}{centerpoint}}{centerpoint}{rotate}%
}
anchor{after top}{%
getcylinderpoints%
pgfmathrotatepointaround{pgfpointadd{beforetopanchor[email protected][email protected]}{centerpoint}}{centerpoint}{rotate}%
}
anchor{before bottom}{%
getcylinderpoints%
pgfmathrotatepointaround{pgfpointadd{afterbottomanchor[email protected][email protected]}{centerpoint}}{centerpoint}{rotate}%
}
anchor{bottom}{%
getcylinderpoints%
pgfmathrotatepointaround{%
pgfpointadd{%
afterbottom%
[email protected]relax%
advance[email protected]xradiusrelax%
}{centerpoint}}{centerpoint}{rotate}%
}
anchor{after bottom}{%
getcylinderpoints%
pgfmathrotatepointaround{pgfpointadd{afterbottomanchor}{centerpoint}}{centerpoint}{rotate}%
}
backgroundpath{%
getcylinderpoints%
{%
[email protected]xradiusrelax%
advance[email protected]outerseprelax%
edefxradius{the[email protected]}%
[email protected]yradiusrelax%
advance[email protected]outerseprelax%
edefyradius{the[email protected]}%
pgftransformshift{centerpoint}%
pgftransformrotate{rotate}%
pgfpathmoveto{afterbottom}%
pgfpatharc{90}{270}{xradius and yradius}%
pgfpathlineto{beforetop[email protected][email protected]}%
pgfpatharc{-90}{90}{xradius and yradius}%
pgfpathclose%
pgfpathmoveto{beforetop}%
pgfpatharc{90}{270}{xradius and yradius}%
}%
}%
behindbackgroundpath{%
ifpgfcylinderusescustomfill%
getcylinderpoints%
[email protected]xradiusrelax%
advance[email protected]outerseprelax%
edefxradius{the[email protected]}%
[email protected]yradiusrelax%
advance[email protected]outerseprelax%
edefyradius{the[email protected]}%
{%
pgftransformshift{centerpoint}%
pgftransformrotate{rotate}%
pgfpathmoveto{afterbottom}%
pgfpatharc{90}{270}{xradius and yradius}%
pgfpathlineto{beforetop[email protected][email protected]}%
pgfpatharc{270}{90}{xradius and yradius}%
pgfpathclose%
expandafterpgfsetfillcolorexpandafter{pgfkeysvalueof{/pgf/cylinder body fill}}%
pgfusepath{fill}%
%
pgfpathmoveto{beforetop}%
pgfpatharc{90}{-270}{xradius and yradius}%
pgfpathclose
expandafterpgfsetfillcolorexpandafter{pgfkeysvalueof{/pgf/cylinder end fill}}%
pgfusepath{fill}%
}%
fi%
ifpgfcylinderusescustomshade%
getcylinderpoints%
[email protected]xradiusrelax%
advance[email protected]outerseprelax%
edefxradius{the[email protected]}%
[email protected]yradiusrelax%
advance[email protected]outerseprelax%
edefyradius{the[email protected]}%
{%
%
expandafterpgfdeclareverticalshading{cylindershade}{yradius}
{color(0bp)=(expandafter{pgfkeysvalueof{/pgf/cylinder body top shade}});
color(0.5*yradius)=(expandafter{pgfkeysvalueof{/pgf/cylinder body middle shade}});
color(yradius)=(expandafter{pgfkeysvalueof{/pgf/cylinder body bottom shade}})}
pgftransformshift{centerpoint}%
pgftransformrotate{rotate}%
begin{pgfscope}%
pgfpathmoveto{afterbottom}%
pgfpatharc{90}{270}{xradius and yradius}%
pgfpathlineto{beforetop[email protected][email protected]}%
pgfpatharc{270}{90}{xradius and yradius}%
pgfpathclose%
typeout{pgfkeysvalueof{/pgf/cylinder body shade angle}}
expandafterpgfshadepath{cylindershade}{pgfkeysvalueof{/pgf/cylinder body shade angle}}%
pgfsetfillcolor{white}%
pgfsetfillopacity{0}%
pgfusepath{fill}%
end{pgfscope}
%
pgfpathmoveto{beforetop}%
pgfpatharc{90}{-270}{xradius and yradius}%
pgfpathclose
expandafterpgfsetfillcolorexpandafter{pgfkeysvalueof{/pgf/cylinder end fill}}%
pgfusepath{fill}%
}%
fi%
}%
anchorborder{%
[email protected]externalpoint{}%
getcylinderpoints%
[email protected]{[email protected]@referencepoint}{letreferencepointcenterpoint}{%
letreferencepoint[email protected]@referencepoint}%
[email protected]externalpoint{%
externalpoint%
[email protected][email protected]%
[email protected][email protected]%
referencepoint%
advance[email protected][email protected]%
advance[email protected][email protected]%
}%
pgfmathanglebetweenpoints{centerpoint}{externalpoint}%
[email protected]{pgfmathresult}{rotate}%
ifdimpgfmathresult pt<0ptrelax%
[email protected]{pgfmathresult}{360}%
fi%
letexternalanglepgfmathresult%
%
pgfmathanglebetweenpoints{referencepoint}{pgfpointadd{afterbottomanchor}{centerpoint}}%
ifdimexternalangle pt<pgfmathresult ptrelax%
pgfmathanglebetweenpoints{referencepoint}{pgfpointadd{beforetopanchor}{centerpoint}}%
ifdimexternalangle pt<pgfmathresult ptrelax%
pgfmathrotatepointaround{%
pgfmathpointintersectionoflineandarc%
{pgfmathrotatepointaround{externalpoint}{centerpoint}{-rotate}}%
{pgfmathrotatepointaround{referencepoint}{centerpoint}{-rotate}}%
{%
beforetop%
[email protected][email protected]%
centerpoint%
advance[email protected][email protected]%
}%
{0}{90}{xradius and yradius}%
}{centerpoint}{rotate}%
else%
pgfpointintersectionoflines{%
pgfmathrotatepointaround{pgfpointadd{afterbottomanchor}{centerpoint}}%
{centerpoint}{rotate}}{%
pgfmathrotatepointaround{pgfpointadd{beforetopanchor}{centerpoint}}%
{centerpoint}{rotate}}%
{referencepoint}{externalpoint}%
fi%
else%
pgfmathanglebetweenpoints{referencepoint}{pgfpointadd{afterbottomanchor[email protected][email protected]}{centerpoint}}%
ifdimexternalangle pt>pgfmathresult ptrelax%
pgfmathanglebetweenpoints{referencepoint}{pgfpointadd{beforetopanchor[email protected][email protected]}{centerpoint}}%
ifdimexternalangle pt>pgfmathresult ptrelax%
pgfmathrotatepointaround{%
pgfmathpointintersectionoflineandarc%
{pgfmathrotatepointaround{externalpoint}{centerpoint}{-rotate}}%
{pgfmathrotatepointaround{referencepoint}{centerpoint}{-rotate}}%
{%
beforetop%
[email protected][email protected]%
centerpoint
advance[email protected][email protected]%
}%
{270}{360}{xradius and yradius}%
}{centerpoint}{rotate}%
else%
pgfpointintersectionoflines{%
pgfmathrotatepointaround{pgfpointadd{afterbottomanchor[email protected][email protected]}{centerpoint}}%
{centerpoint}{rotate}}{%
pgfmathrotatepointaround{pgfpointadd{beforetopanchor[email protected][email protected]}{centerpoint}}%
{centerpoint}{rotate}}%
{referencepoint}{externalpoint}%
fi%
else%
pgfmathrotatepointaround{%
pgfmathpointintersectionoflineandarc%
{pgfmathrotatepointaround{externalpoint}{centerpoint}{-rotate}}%
{pgfmathrotatepointaround{referencepoint}{centerpoint}{-rotate}}%
{%
afterbottom%
[email protected][email protected]%
centerpoint
advance[email protected][email protected]%
}%
{90}{270}{xradius and yradius}%
}{centerpoint}{rotate}%
fi%
fi%
}
}
makeatother
begin{document}
begin{frame}[t]
frametitle{}
begin{tikzpicture}[scale=1., transform shape]
node [rotate=30,shaded cylinder,draw,thick,aspect=2.,minimum height=5cm,
minimum width=4cm,shape border rotate=30,cylinder uses custom shade,
cylinder body top shade=black,
cylinder body middle shade=blue,
cylinder body bottom shade=blue!30,
cylinder body shade angle=30,
cylinder end fill=blue,text=white,font=large
] at (0,0){Hello world, how are you doing!};
end{tikzpicture}
end{frame}
end{document}