2

I want to show the volume of a surface and for that it would be great to have an outline around my hyperboloid.

How can I do that?

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}
\begin{axis}
[
axis lines = center,
axis line style = thick,
xlabel=$x$, ylabel=$y$, zlabel=$z$,
ylabel style={left},
ymin=-10,
ymax=10,
xmin=-10,
xmax=10,
zmin=-5,
zmax=25,
unit vector ratio=1 1 1,
width=30cm,
xtick=\empty,
ytick=\empty,
ztick=\empty,
clip=false,
view={20}{25},
colormap={cm}{color(0)=(gray!20) color(1)=(gray!20)}
]
\addplot3[surf,z buffer=sort,
shader=interp,opacity=0.7,
samples=12,samples y=61,domain=0:sqrt(3),domain y=0:360]
({x*cos(y)*5},{x*sin(y)*3},{10*sqrt(1+x*x)});

\addplot3 [domain=0:360, samples=50] ({sqrt(75)*cos(x)}, {sqrt(27)*sin(x)}, {20}); 
\end{axis}
\end{tikzpicture}

\end{document}

I'd like to have something like that. P.S Here I draw an inaccurate outline in a photo editor. enter image description here

5
  • I hope I am wrong but it is not a trivial question. Usually one has to compute the contour analytically. It obviously depends on the view angles. For simple plots like this one can compute the contour, but there is to be best of my knowledge no fully automatic solution.
    – user194703
    Commented Apr 29, 2020 at 19:03
  • I was thinking about creating mesh that would be so big that make only the outline, but I don't know how to do that and whether it is possible.
    – antshar
    Commented Apr 29, 2020 at 19:49
  • But then you would still need the parametrization of the outline, wouldn't you?
    – user194703
    Commented Apr 29, 2020 at 19:50
  • I think I found something that could help. But I didn't manage to draw a line on the surface in my case. Could you help? tex.stackexchange.com/a/451003/213149
    – antshar
    Commented Apr 29, 2020 at 22:04
  • This tells you how to embed a curve on the surface, but not what the boundary of the projection on the screen is.
    – user194703
    Commented Apr 29, 2020 at 22:16

1 Answer 1

2

This is not too serious an answer but maybe some of this could be useful for some. We can compute the contour as follows. Given a surface parametrized by

F(u,v) = (fx(u,v),fy(u,v),fz(u,v))

one can compute the tangent vectors

 dF(u,v)/du   and   dF(u,v)/dv

The normal is given by

 n(u,v) =  dF(u,v)/du x dF(u,v)/dv .

The contour of the surface is then given by the solution of

 n(u,v) . n_screeen = 0 ,

where in pgfplots the normal on the screen is given by

 (cos(el)*sin(az), -cos(el)*cos(az), sin(el)) .

The elevation and azimuth angles are stored in the pgf keys of the same name, see below. This equation can be solved for u or v. However, the analytic solution is messy. I solved this with Mathematica and plotted the result with pgfplots.

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}

\begin{document}

\begin{tikzpicture}
\begin{axis}
[
axis lines = center,
axis line style = thick,
xlabel=$x$, ylabel=$y$, zlabel=$z$,
ylabel style={left},
ymin=-10,
ymax=10,
xmin=-10,
xmax=10,
zmin=-5,
zmax=25,
unit vector ratio=1 1 1,
width=30cm,
xtick=\empty,
ytick=\empty,
ztick=\empty,
clip=false,
view={20}{25},
colormap={cm}{color(0)=(gray!20) color(1)=(gray!20)},
declare function={
ucrit1(\a,\b,\c,\r)=-acos((\a*\b*\b*\c*\r*sqrt(1+\r*\r)*sin(\pgfkeysvalueof{/pgfplots/view/az})*
tan(\pgfkeysvalueof{/pgfplots/view/el})-%
(1/pow(cos(\pgfkeysvalueof{/pgfplots/view/el}),2))*%
sqrt(\a*\a*\c*\c*\r*\r*pow(cos(\pgfkeysvalueof{/pgfplots/view/az}),2)*%
pow(cos(\pgfkeysvalueof{/pgfplots/view/el}),4)*%
(\a*\a*\c*\c*\r*\r*pow(cos(\pgfkeysvalueof{/pgfplots/view/az}),2)+%
\b*\b*(\c*\c*\r*\r*pow(sin(\pgfkeysvalueof{/pgfplots/view/az}),2)-%
\a*\a*(1+\r*\r)*pow(tan(\pgfkeysvalueof{/pgfplots/view/el}),2)))))/%
(\c*\c*\r*\r*(\a*\a*pow(cos(\pgfkeysvalueof{/pgfplots/view/az}),2)+%
\b*\b*pow(sin(\pgfkeysvalueof{/pgfplots/view/az}),2))));%
ucrit2(\a,\b,\c,\r)=180+1*\pgfkeysvalueof{/pgfplots/view/az}-ucrit1(5,3,10,x);%
}]
\addplot3[surf,z buffer=sort,
shader=interp,opacity=0.7,
samples=12,samples y=61,domain=0:sqrt(3),domain y=0:360]
({x*cos(y)*5},{x*sin(y)*3},{10*sqrt(1+x*x)});
% 
\addplot3 [domain={0.15}:{sqrt(3)},samples y=0] 
({5*x*cos(ucrit1(5,3,10,x))}, {3*x*sin(ucrit1(5,3,10,x))},{10*sqrt(1+x*x)}); 

\addplot3 [domain={0.15}:{sqrt(3)},samples y=0] 
({5*x*cos(ucrit2(5,3,10,x))}, 
{3*x*sin(ucrit2(5,3,10,x))},
{10*sqrt(1+x*x)}); 


\addplot3 [domain=0:360, samples=50] ({sqrt(75)*cos(x)}, {sqrt(27)*sin(x)}, {20}); 
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

It seems to work (however, I do not understand the coefficient 1 in ucrit2(\a,\b,\c,\r)=180+1*\pgfkeysvalueof{/pgfplots/view/az}-ucrit1(5,3,10,x); in front of \pgfkeysvalueof{/pgfplots/view/az}, I thought it should be a 2).

So the bottom-line is that it is in principle possible to compute and draw these contours.

It might be that pgfplots computes the contour numerically or could at least do it in principle when it constructs the plot. I do not understand the plot handler well enough to be able to claim that it does, let alone to hack them to provide us with this data.

1
  • Perfect! Thank you!
    – antshar
    Commented Apr 30, 2020 at 10:33

You must log in to answer this question.

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