At the risk of asking YET ANOTHER TIKZ question on a general TeX forum :), I was wondering if there was any easy way to draw a ruled surface like a hyperbolic paraboloid in TikZ? I'm not particular about the surface per se: I just need some eye candy for a nontrivial looking surface, and the hyperbolic paraboloid is a good example because of the negative curvature. I checked texample.net and google, and while I found a PSTricks package that can do this, it doesn't fit my workflow with pdflatex and Beamer.
3 Answers
PGFplots can do a reasonably good job with not too complex 3D plots. Here's an example of a hyperbolic paraboloid:
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot3 [surf,shader=flat,draw=black] {x^2-y^2};
\end{axis}
\end{tikzpicture}
\end{document}
-
ah ! I forgot pgfplots! :( perhaps pgfplots combines with gnuplot is a good solution ? Jun 5, 2011 at 9:19
-
ah very nice. and I see from the manual that I can even get rid of axes etc.– SureshJun 5, 2011 at 20:42
-
accepted this one because this is what I ended up using. But other answers are excellent too.– SureshJun 6, 2011 at 6:15
Using class beamer
and running it with xelatex
to get directly a pdf. It shows a 2D view of 3D curves in the x-y plane.
\documentclass{beamer}
\usetheme{Warsaw}
\usepackage{pst-solides3d}
\begin{document}
\begin{frame}{Title}
\psset{arrowlength=3,arrowinset=0,unit=0.6,
viewpoint=50 30 25 rtp2xyz,Decran=50,lightsrc=viewpoint}
\begin{center}
\begin{pspicture}(-2,-4)(7,8)
\axesIIID[linecolor=gray](0,0,0)(7,7,7)
\psSolid[ngrid=.3 .3,object=grille,base=1.5 6.5 1.5 6.5,
linewidth=0.4pt,linecolor=gray!50,action=draw]%
\psPoint(4,4,4 5 sub 2 exp 4 5 sub 2 exp sub 6 div 5 add){P}
\psPoint(4,4,0){Po}
\pcline[linecolor=red,linestyle=dashed](P)(Po)\Aput{$z=f(x,y)$}
\psSurface[ngrid=.3 .3,fillcolor=green!30,incolor=gray!30,intersectiontype=0,
intersectionplan={
[0 0 1 -6.5]
[0 0 1 -6.1]
[0 0 1 -5.7]
[0 0 1 -5.3]
[0 0 1 -4.9]},intersectioncolor=(bleu),intersectionlinewidth=1,
linewidth=0.4pt,algebraic](1.5,1.5)(6.5,6.5){ ((y-5)^2-(x-5)^2)/6+5 }
\psdot[linecolor=red,dotscale=0.7](P)
\psdot[dotscale=0.7](Po)
\psPoint(1.5,6.5,0){D}\uput[90](D){$D$}
\psPoint(2,6.5,6.5 5 sub 2 exp 2 5 sub 2 exp sub 6 div 5 add){S}\uput[0](S){$S$}
%% Contouring on xy plane for z=6.5 6.1 5.7 5.3 4.9
%% Explicit representation: z=((y-5)2-(x-5)2)/6+5
%% Parametric representation of z=f(x,y)
%% x=x(x)=x
%% y=y(x)=sqrt((x-5)^2+6*(z-5))+5
%% z=z(x)=0
\psset{object=courbe,r=0,linecolor=blue,resolution=360,function=Fxy,algebraic}
\defFunction{Fxy}(x){x}{-sqrt((x-5)^2+6*(6.5-5))+5}{0}
\psSolid[range=3.155 6.5]
\defFunction{Fxy}(x){x}{-sqrt((x-5)^2+6*(6.1-5))+5}{0}
\psSolid[range=2.6 6.5]
\defFunction{Fxy}(x){x}{-sqrt((x-5)^2+6*(5.7-5))+5}{0}
\psSolid[range=2.15 6.5]
\defFunction{Fxy}(x){x}{-sqrt((x-5)^2+6*(5.3-5))+5}{0}
\psSolid[range=1.75 6.5]
\defFunction{Fxy}(x){x}{sqrt((x-5)^2+6*(5.3-5))+5}{0}
\psSolid[range=4.35 5.7]
\defFunction{Fxy}(x){-sqrt((x-5)^2+6*(5-4.9))+5}{x}{0}
\psSolid[range=1.6 6.5]
\defFunction{Fxy}(x){sqrt((x-5)^2+6*(5-4.9))+5}{x}{0}
\psSolid[range=3.7 6.3]
\end{pspicture}
\end{center}
\end{frame}
\end{document}
-
@Herbert xelatex takes the same way that latex : dvi ps and pdf ?because if you can run pstricks directly, i think its because xelatex uses dvi and then ps? isn't it ? Jun 5, 2011 at 9:24
-
I have tried it, apparently xelatex runs slower than latex->dvips->ps2pdf. Jun 5, 2011 at 12:51
-
xelatex
is always slower ... same forlualatex
. The new features are not available for free ...– user2478Jun 5, 2011 at 12:55 -
-
Nice picture: I could use xelatex on my file and then this would be usable.– SureshJun 5, 2011 at 20:42
Just because it is fun (I don't claim that this is a good way to draw this), using the fact that the surface is ruled):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\definecolor{startcolor}{named}{red}
\definecolor{endcolor}{named}{blue}
\newcommand\steps{250}
\newcommand\lineAstart{0,0,0}
\newcommand\lineAend{1,0,1}
\newcommand\lineBstart{0,1,1}
\newcommand\lineBend{1,1,0}
\begin{tikzpicture}[x={(-3.5cm,-2cm)},y={(10cm,-1cm)},z={(0,7cm)}]
\draw[->] (0,0) -- (1,0,0);
\draw[->] (0,0) -- (0,1,0);
\draw[->] (0,0) -- (0,0,1);
\foreach \n in {0,1,...,\steps} {
\pgfmathparse{\n/\steps*100}
\let\i\pgfmathresult
\draw[ultra thick,color={startcolor!\i!endcolor}]
($(\lineAstart)!{\n/\steps}!(\lineAend)$) --
($(\lineBstart)!{\n/\steps}!(\lineBend)$);
}
\end{tikzpicture}
\end{document}
More interestingly, one can draw the two families of lines:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
\begin{document}
\tikzset{f1/.style={red}}
\tikzset{f2/.style={blue}}
\newcommand\steps{40}
\begin{tikzpicture}[x={(-3.5cm,-2cm)},y={(10cm,-1cm)},z={(0,7cm)}]
\coordinate (lineAstart) at (1,0,1);
\coordinate (lineAend) at (0,0,0);
\coordinate (lineBstart) at (1,1,0);
\coordinate (lineBend) at (0,1,1);
\draw[->] (0,0) -- (1,0,0);
\draw[->] (0,0) -- (0,1,0);
\draw[->] (0,0) -- (0,0,1);
%
% Draw the first family of lines
%
\draw[name path global={f1l0},name path global={f1l0-short},f1] (lineAstart) -- (lineBstart);
\foreach \n in {1,...,\steps} {
\pgfmathparse{\n/\steps*100}
\let\i\pgfmathresult
\pgfmathtruncatemacro\p{\n-1}
% Create the path of the lines
\edef\optname{name path global={f1l\n}}
\expandafter\path\expandafter[\optname]
($(lineAstart)!{\n/\steps}!(lineAend)$) --
($(lineBstart)!{\n/\steps}!(lineBend)$);
% Draw the correct bits of the lines
\edef\optname{name intersections={of={f1l\n} and f1l\p},name path global={f1l\n-short}}
\expandafter\draw\expandafter[\optname,f1]
(intersection-1) -- ($(lineBstart)!{\n/\steps}!(lineBend)$);
\edef\optname{name intersections={of={f1l\n} and f1l0}}
\expandafter\draw\expandafter[\optname,f1]
($(lineAstart)!{\n/\steps}!(lineAend)$) -- (intersection-1);
}
%
% Draw the second family of lines
%
\foreach \n in {\steps,...,0} {
\pgfmathparse{\n/\steps*100}
\let\i\pgfmathresult
\pgfmathtruncatemacro\p{\n+1}
% Create the paths
\edef\optname{name path global={f2l\n}}
\expandafter\path\expandafter[\optname,shorten <=4pt]
($(lineAstart)!{\n/\steps}!(lineBstart)$) --
($(lineAend)!{\n/\steps}!(lineBend)$);
% Draw the correct bits
\ifnum\n=\steps % handle the first line separately
\draw[f2] (lineBstart) -- (lineBend);
\else
% Note: one should actually find the intersection with the correct line of the first family.
% However, this is rather complicated. The following gives a good approximation when the
% number of lines is high enough.
\edef\optname{name intersections={of={f2l\n} and f2l\p,total=\noexpand\total}}
\expandafter\draw\expandafter[\optname,f2]
\ifnum\total=1
($(lineAstart)!{\n/\steps}!(lineBstart)$) -- (intersection-1);
\else
($(lineAstart)!{\n/\steps}!(lineBstart)$) -- ($(lineAend)!{\n/\steps}!(lineBend)$);
\fi;
\fi
}
\end{tikzpicture}
-
2+1! You're right, that is fun! And it's quite a bit faster than PGFplots (if much less flexible).– JakeJun 5, 2011 at 17:56
-
pdftricks
and you can give a look at the packagepst-pdf