Solución:
Creo que la mejor manera de abordar el problema del “sólido de revolución” sería utilizar un sistema de coordenadas adecuado, uno en el que pueda ingresar el radio, el ángulo y la protuberancia a lo largo del eje.
Aquí hay un intento de reproducir su primera imagen:
documentclass{standalone}
usepackage{pgfplots}
pgfplotsset{compat=1.9}
% usetikzlibrary{}
% usepgfplotslibrary{}
% defines a new value for 'data cs'.
%
% On input, this "data coordinate system" consists of
% x=generatrix (=radius)
% y=<angle>
% z=distance along axis
%
% On output, it will show the z value on the X axis and the radius on
% the Y axis.
pgfplotsdefinecstransform{polarrad along x}{cart}{%
% First, swap axis such that we can apply polarrad->cart.
% Note that polarrad expects (<angle>,<radius>,Z):
pgfkeysgetvalue{/data point/x}X% copy value of /data point/x into X
pgfkeysgetvalue{/data point/y}Y
pgfkeyslet{/data point/y}X% copy value of X into /data point/y
pgfkeyslet{/data point/x}Y
pgfplotsaxistransformcs
{polarrad}
{cart}%
%
% Ok, now we have cartesian. Swap axes such that we have them
% along X:
pgfkeysgetvalue{/data point/x}X
pgfkeysgetvalue{/data point/y}Y
pgfkeysgetvalue{/data point/z}Z
pgfkeyslet{/data point/y}X
pgfkeyslet{/data point/z}Y
pgfkeyslet{/data point/x}Z
}%
begin{document}
begin{tikzpicture}
begin{axis}[
title={Rotation um die x-Achse},
colormap/greenyellow,
view={15}{30}]
defgeneratrix{(((2*x^4)/27) - ((4*x^3)/9))}
addplot3[
surf,
shader=faceted,
samples=25,
domain=0:6,
domain y=0:3*pi/2,
z buffer=sort,
data cs=polarrad along x]
({generatrix},y,x);
addplot3[
blue,
fill,
fill opacity=0.5,
samples=25,
samples y=1,
domain=0:6,
data cs=polarrad along x]
({generatrix},0,x) --cycle;
addplot3[
orange,
fill,
fill opacity=0.5,
samples=25,
samples y=1,
domain=0:6,
data cs=polarrad along x]
({generatrix},3*pi/2,x) --cycle;
end{axis}
end{tikzpicture}
end{document}
He hecho uso de data cs
, la característica de pgfplots
lo que permite proporcionar los datos en un sistema de coordenadas diferente al del eje. La función pgfplotsdefinecstransform
sólo está documentado en el código fuente de pgfplots
en el momento de escribir este artículo; define una transformación de algún sistema de entrada a algún sistema de salida. Pgfplots intenta usar las transformaciones disponibles cada vez que encuentra algo como data cs=polarrad along x
.
También definí una macro que contiene su generatriz. El código restante dibuja la superficie de la revolución como un gráfico de superficie que se parece al suyo.
Los dos segundos addplot3
las instrucciones son paramétricas 3d línea parcelas (debido a samples y=1
); utilizan la misma secuencia de entrada excepto que fijan y (que es el ángulo en nuestro data cs
).
En cuanto a su segunda imagen, puede hacer uso de la fillbetween
biblioteca que se envía con pgfplots
(a partir de la versión 1.10). Su propósito es llenar el área entre otras dos parcelas (de línea), comparar Rellenar el área entre dos curvas calculadas por pgfplots o Rellenar entre dos curvas en pgfplots. para aplicaciones sencillas.
Si lo entiendo correctamente, tiene alguna función generadora interna y alguna función generadora externa y la interna define el agujero.
Mi idea sería “trazar” tanto con draw=none, name path=<some name>
para etiquetar las rutas resultantes. Entonces podemos llenar el área entre ellos.
Aquí está ese enfoque:
documentclass{standalone}
usepackage{pgfplots}
pgfplotsset{compat=1.10}
% usetikzlibrary{}
usepgfplotslibrary{fillbetween}
% defines a new value for 'data cs'.
%
% On input, this "data coordinate system" consists of
% x=generatrix (=radius)
% y=<angle>
% z=distance along axis
%
% On output, it will show the z value on the X axis and the radius on
% the Y axis.
pgfplotsdefinecstransform{polarrad along x}{cart}{%
% First, swap axis such that we can apply polarrad->cart.
% Note that polarrad expects (<angle>,<radius>,Z):
pgfkeysgetvalue{/data point/x}X% copy value of /data point/x into X
pgfkeysgetvalue{/data point/y}Y
pgfkeyslet{/data point/y}X% copy value of X into /data point/y
pgfkeyslet{/data point/x}Y
pgfplotsaxistransformcs
{polarrad}
{cart}%
%
% Ok, now we have cartesian. Swap axes such that we have them
% along X:
pgfkeysgetvalue{/data point/x}X
pgfkeysgetvalue{/data point/y}Y
pgfkeysgetvalue{/data point/z}Z
pgfkeyslet{/data point/y}X
pgfkeyslet{/data point/z}Y
pgfkeyslet{/data point/x}Z
}%
begin{document}
begin{tikzpicture}
begin{axis}[
title={Rotation um die x-Achse},
colormap/greenyellow,
view={15}{30}]
defgeneratrix{(((2*x^4)/27) - ((4*x^3)/9))}
addplot3[
surf,
shader=faceted,
samples=25,
domain=0:6,
domain y=0:3*pi/2,
z buffer=sort,
data cs=polarrad along x]
({generatrix},y,x);
% A Helper macro such that we do not need to repeat outselfes.
%
% It can be invoked with
% generatrix[<draw/fill options>]{<angle which defines slice>}{some unique text label}
newcommandgenerateSlice[3][]{%
addplot3[
draw=none,
%blue, fill, fill opacity=0.5,
name path=outline_y#3,
samples=25,
samples y=1,
domain=0:6,
data cs=polarrad along x]
({generatrix},#2,x);
addplot3[
smooth,
draw=none,
%red, fill, fill opacity=0.5,
name path=inner_y#3,
samples=25,
samples y=1,
domain=0:6,
data cs=polarrad along x]
coordinates {
(0,#2,2) (-2,#2,3)
(-2.5,#2,4.2) (0,#2,5.2)
};
addplot[#1] fill between[
% typically, the 'fill between' library tries to draw
% its paths in a background layer. Avoid that:
on layer=main,
of=outline_y#3 and inner_y#3];
}
generateSlice[draw,blue,fill opacity=0.5]{0}{first}
generateSlice[draw,orange,fill opacity=0.5]{3*pi/2}{second}
end{axis}
end{tikzpicture}
end{document}
Para evitar repeticiones, utilicé una macro de ayuda para los dos cortes. Solo proporciono el ángulo que define el corte, las opciones de dibujo y la etiqueta única en la entrada.
Tenga en cuenta que proporcioné la función interna por medio de addplot3 coordinates {<list>}
que es perfectamente válido en este contexto (al igual que cualquier otra entrada 3d).
Tenga en cuenta que esto fillbetween
Esencialmente, las cosas no están relacionadas con los sólidos de revolución como se indica en los enlaces anteriores, pero funciona a la perfección.
Podría haber una modificación más útil para visualizar el agujero: podríamos agregar un segundo sólido de revolución en el medio. Con este fin, tomé mi última solución, reemplacé addplot3 coordinates
por alguna generatriz interior aleatoria y llegó a
documentclass{standalone}
usepackage{pgfplots}
pgfplotsset{compat=1.9}
% usetikzlibrary{}
usepgfplotslibrary{fillbetween}
% defines a new value for 'data cs'.
%
% On input, this "data coordinate system" consists of
% x=generatrix (=radius)
% y=<angle>
% z=distance along axis
%
% On output, it will show the z value on the X axis and the radius on
% the Y axis.
pgfplotsdefinecstransform{polarrad along x}{cart}{%
% First, swap axis such that we can apply polarrad->cart.
% Note that polarrad expects (<angle>,<radius>,Z):
pgfkeysgetvalue{/data point/x}X
pgfkeysgetvalue{/data point/y}Y
pgfkeyslet{/data point/y}X
pgfkeyslet{/data point/x}Y
pgfplotsaxistransformcs
{polarrad}
{cart}%
%
% Ok, now we have cartesian. Swap axes such that we have them
% along X:
pgfkeysgetvalue{/data point/x}X
pgfkeysgetvalue{/data point/y}Y
pgfkeysgetvalue{/data point/z}Z
pgfkeyslet{/data point/y}X
pgfkeyslet{/data point/z}Y
pgfkeyslet{/data point/x}Z
}%
begin{document}
begin{tikzpicture}
begin{axis}[
title={Rotation um die x-Achse},
colormap/greenyellow,
view={15}{30}]
defgeneratrix{(((2*x^4)/27) - ((4*x^3)/9))}
addplot3[
surf,
shader=faceted,
samples=25,
domain=0:6,
domain y=0:3*pi/2,
z buffer=sort,
data cs=polarrad along x]
({generatrix},y,x);
definnergeneratrix{-10*(x-2)/2*(1-(x-2)/2)}
addplot3[
surf,
colormap/violet,
shader=faceted,
samples=7,
domain=2:4,
domain y=0:3*pi/2,
z buffer=sort,
data cs=polarrad along x]
({innergeneratrix},y,x);
% A Helper macro such that we do not need to repeat outselfes.
%
% It can be invoked with
% generatrix[<draw/fill options>]{<angle which defines slice>}{some unique text label}
newcommandgenerateSlice[3][]{%
addplot3[
draw=none,
%blue, fill, fill opacity=0.5,
name path=outline_y#3,
samples=25,
samples y=1,
domain=0:6,
data cs=polarrad along x]
({generatrix},#2,x);
addplot3[
draw=none,
%red, fill, fill opacity=0.5,
name path=inner_y#3,
samples=7,
samples y=1,
domain=2:4,
data cs=polarrad along x]
({innergeneratrix},#2,x);
addplot[#1] fill between[
% typically, the 'fill between' library tries to draw
% its paths in a background layer. Avoid that:
on layer=main,
of=outline_y#3 and inner_y#3];
}
generateSlice[draw,blue,fill opacity=0.5]{0}{first}
generateSlice[draw,orange,fill opacity=0.5]{3*pi/2}{second}
end{axis}
end{tikzpicture}
end{document}
Con PSTricks y pst-solides3d
. Ejecutarlo con xelatex
o la secuencia latex->dvips->ps2pdf
(es más rápido)
documentclass{article}
usepackage{pst-solides3d}
begin{document}
psset{linewidth=0.5pslinewidth,viewpoint=80 -75 0 rtp2xyz,lightsrc=viewpoint,Decran=30}
begin{pspicture}(-1,-5)(5,5)
defFunction[algebraic]{func}(x,y)
{ x }
{ (x^4 * 2/27 - x^3 * 4/9) * cos(y)}
{ (x^4 * 2/27 - x^3 * 4/9) * sin(y)}
psSolid[
object=surfaceparametree,
base=0 6 0 Pi 1.5 mul,
hue=0 1,
incolor=yellow,
ngrid=0.2 0.2,
function=func]
gridIIID[Zmin=-10,Zmax=10,stepX=2,stepY=4,stepZ=2](0,10)(-10,10)
end{pspicture}
%
psset{viewpoint=80 -60 0 rtp2xyz}
begin{pspicture}(-1,-5)(5,5)
defFunction[algebraic]{func}(x,y)
{ x }
{ (x^4 * 2/27 - x^3 * 4/9) * cos(y)}
{ (x^4 * 2/27 - x^3 * 4/9) * sin(y)}
psSolid[
object=surfaceparametree,
base=0 6 0 Pi 1.5 mul,
hue=0 1,
incolor=yellow,
ngrid=0.2 0.2,
function=func]
% gridIIID[Zmin=-10,Zmax=10,stepX=2,stepY=4,stepZ=4](0,10)(-10,10)
end{pspicture}
end{document}