aboutsummaryrefslogtreecommitdiff
path: root/src/hyper/pages/ug21.ht
diff options
context:
space:
mode:
Diffstat (limited to 'src/hyper/pages/ug21.ht')
-rw-r--r--src/hyper/pages/ug21.ht939
1 files changed, 939 insertions, 0 deletions
diff --git a/src/hyper/pages/ug21.ht b/src/hyper/pages/ug21.ht
new file mode 100644
index 00000000..e17c9cf4
--- /dev/null
+++ b/src/hyper/pages/ug21.ht
@@ -0,0 +1,939 @@
+% Copyright The Numerical Algorithms Group Limited 1992-94. All rights reserved.
+% !! DO NOT MODIFY THIS FILE BY HAND !! Created by ht.awk.
+\setcounter{chapter}{5} % Appendix F
+%% use \begin{xmpLines} etc, not \begin{figXmpLines}
+%% see use of \labelSpace below when heading crashes into text
+%% you've repeat one of the section labels (ugFknot)
+
+%
+\newcommand{\ugAppGraphicsTitle}{Programs for AXIOM Images}
+\newcommand{\ugAppGraphicsNumber}{G.}
+%
+% =====================================================================
+\begin{page}{ugAppGraphicsPage}{G. Programs for AXIOM Images}
+% =====================================================================
+\beginscroll
+%
+This appendix contains the \Language{} programs used to generate
+the images in the \Gallery{} color insert of this book.
+All these input files are included
+with the \Language{} system.
+To produce the images
+on page 6 of the \Gallery{} insert, for example, issue the command:
+\begin{verbatim}
+)read images6
+\end{verbatim}
+
+These images were produced on an IBM RS/6000 model 530 with a
+standard color graphics adapter. The smooth shaded images
+were made from X Window System screen dumps.
+The remaining images were produced with \Language{}-generated
+PostScript output. The images were reproduced from slides made on an Agfa
+ChromaScript PostScript interpreter with a Matrix Instruments QCR camera.
+
+\beginmenu
+ \menudownlink{{F.1. images1.input}}{ugFimagesOnePage}
+ \menudownlink{{F.2. images2.input}}{ugFimagesTwoPage}
+ \menudownlink{{F.3. images3.input}}{ugFimagesThreePage}
+ \menudownlink{{F.4. images5.input}}{ugFimagesFivePage}
+ \menudownlink{{F.5. images6.input}}{ugFimagesSixPage}
+ \menudownlink{{F.6. images7.input}}{ugFimagesSevenPage}
+ \menudownlink{{F.7. images8.input}}{ugFimagesEightPage}
+ \menudownlink{{F.8. conformal.input}}{ugFconformalPage}
+ \menudownlink{{F.9. tknot.input}}{ugFtknotPage}
+ \menudownlink{{F.10. ntube.input}}{ugFntubePage}
+ \menudownlink{{F.11. dhtri.input}}{ugFdhtriPage}
+ \menudownlink{{F.12. tetra.input}}{ugFtetraPage}
+ \menudownlink{{F.13. antoine.input}}{ugFantoinePage}
+ \menudownlink{{F.14. scherk.input}}{ugFscherkPage}
+\endmenu
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesOneTitle}{images1.input}
+\newcommand{\ugFimagesOneNumber}{G.1.}
+%
+% =====================================================================
+\begin{page}{ugFimagesOnePage}{G.1. images1.input}
+% =====================================================================
+\beginscroll
+
+\labelSpace{3pc}
+
+
+\noindent
+{\tt 1.\ \ \ )read\ tknot}\newline
+{\tt 2.\ \ \ }\newline
+{\tt 3.\ \ \ torusKnot(15,17,\ 0.1,\ 6,\ 700)}\newline
+
+\noindent
+%-% \HDindex{torus knot}{ugFimagesOnePage}{G.1.}{images1.input}
+
+\newpage
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesTwoTitle}{images2.input}
+\newcommand{\ugFimagesTwoNumber}{G.2.}
+%
+% =====================================================================
+\begin{page}{ugFimagesTwoPage}{G.2. images2.input}
+% =====================================================================
+\beginscroll
+
+These images illustrate how Newton's method converges when computing the
+%-% \HDindex{Newton iteration}{ugFimagesTwoPage}{G.2.}{images2.input}
+complex cube roots of 2. Each point in the \smath{(x,y)}-plane represents the
+complex number \smath{x + iy,} which is given as a starting point for Newton's
+method. The poles in these images represent bad starting values.
+The flat areas are the regions of convergence to the three roots.
+
+
+\noindent
+{\tt 1.\ \ \ )read\ newton}\newline
+{\tt 2.\ \ \ )read\ vectors}\newline
+{\tt 3.\ \ \ f\ :=\ newtonStep(x**3\ -\ 2)}\newline
+{\tt 4.\ \ \ }\newline
+
+\noindent
+
+The function \texht{$f^n$}{f**n} computes $n$ steps of Newton's method.
+
+
+\noindent
+{\tt 1.\ \ \ clipValue\ :=\ 4}\newline
+{\tt 2.\ \ \ drawComplexVectorField(f**3,\ -3..3,\ -3..3)}\newline
+{\tt 3.\ \ \ drawComplex(f**3,\ -3..3,\ -3..3)}\newline
+{\tt 4.\ \ \ drawComplex(f**4,\ -3..3,\ -3..3)}\newline
+
+\noindent
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesThreeTitle}{images3.input}
+\newcommand{\ugFimagesThreeNumber}{G.3.}
+%
+% =====================================================================
+\begin{page}{ugFimagesThreePage}{G.3. images3.input}
+% =====================================================================
+\beginscroll
+
+
+\noindent
+{\tt 1.\ \ \ )r\ tknot}\newline
+{\tt 2.\ \ \ for\ i\ in\ 0..4\ repeat\ torusKnot(2,\ 2\ +\ i/4,\ 0.5,\ 25,\ 250)}\newline
+
+\noindent
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesFiveTitle}{images5.input}
+\newcommand{\ugFimagesFiveNumber}{G.4.}
+%
+% =====================================================================
+\begin{page}{ugFimagesFivePage}{G.4. images5.input}
+% =====================================================================
+\beginscroll
+
+The parameterization of the Etruscan Venus is due to George Frances.
+%-% \HDindex{Etruscan Venus}{ugFimagesFivePage}{G.4.}{images5.input}
+
+
+\noindent
+{\tt 1.\ \ \ venus(a,r,steps)\ ==}\newline
+{\tt 2.\ \ \ \ \ surf\ :=\ (u:DFLOAT,\ v:DFLOAT):\ Point\ DFLOAT\ +->}\newline
+{\tt 3.\ \ \ \ \ \ \ cv\ :=\ cos(v)}\newline
+{\tt 4.\ \ \ \ \ \ \ sv\ :=\ sin(v)}\newline
+{\tt 5.\ \ \ \ \ \ \ cu\ :=\ cos(u)}\newline
+{\tt 6.\ \ \ \ \ \ \ su\ :=\ sin(u)}\newline
+{\tt 7.\ \ \ \ \ \ \ x\ :=\ r\ *\ cos(2*u)\ *\ cv\ +\ sv\ *\ cu}\newline
+{\tt 8.\ \ \ \ \ \ \ y\ :=\ r\ *\ sin(2*u)\ *\ cv\ -\ sv\ *\ su}\newline
+{\tt 9.\ \ \ \ \ \ \ z\ :=\ a\ *\ cv}\newline
+{\tt 10.\ \ \ \ \ \ point\ [x,y,z]}\newline
+{\tt 11.\ \ \ \ draw(surf,\ 0..\%pi,\ -\%pi..\%pi,\ var1Steps==steps,}\newline
+{\tt 12.\ \ \ \ \ \ \ \ \ var2Steps==steps,\ title\ ==\ "Etruscan\ Venus")}\newline
+{\tt 13.\ \ }\newline
+{\tt 14.\ \ venus(5/2,\ 13/10,\ 50)}\newline
+
+\noindent
+
+The Figure-8 Klein Bottle
+%-% \HDindex{Klein bottle}{ugFimagesFivePage}{G.4.}{images5.input}
+parameterization is from
+``Differential Geometry and Computer Graphics'' by Thomas Banchoff,
+in {\it Perspectives in Mathematics,} Anniversary of Oberwolfasch 1984,
+Birkh\"{a}user-Verlag, Basel, pp. 43-60.
+
+
+\noindent
+{\tt 1.\ \ \ klein(x,y)\ ==}\newline
+{\tt 2.\ \ \ \ \ cx\ :=\ cos(x)}\newline
+{\tt 3.\ \ \ \ \ cy\ :=\ cos(y)}\newline
+{\tt 4.\ \ \ \ \ sx\ :=\ sin(x)}\newline
+{\tt 5.\ \ \ \ \ sy\ :=\ sin(y)}\newline
+{\tt 6.\ \ \ \ \ sx2\ :=\ sin(x/2)}\newline
+{\tt 7.\ \ \ \ \ cx2\ :=\ cos(x/2)}\newline
+{\tt 8.\ \ \ \ \ sq2\ :=\ sqrt(2.0@DFLOAT)}\newline
+{\tt 9.\ \ \ \ \ point\ [cx\ *\ (cx2\ *\ (sq2\ +\ cy)\ +\ (sx2\ *\ sy\ *\ cy)),\ \_}\newline
+{\tt 10.\ \ \ \ \ \ \ \ \ \ \ sx\ *\ (cx2\ *\ (sq2\ +\ cy)\ +\ (sx2\ *\ sy\ *\ cy)),\ \_}\newline
+{\tt 11.\ \ \ \ \ \ \ \ \ \ \ -sx2\ *\ (sq2\ +\ cy)\ +\ cx2\ *\ sy\ *\ cy]}\newline
+{\tt 12.\ \ }\newline
+{\tt 13.\ \ draw(klein,\ 0..4*\%pi,\ 0..2*\%pi,\ var1Steps==50,}\newline
+{\tt 14.\ \ \ \ \ \ \ var2Steps==50,title=="Figure\ Eight\ Klein\ Bottle")}\newline
+
+\noindent
+
+The next two images are examples of generalized tubes.
+
+
+\noindent
+{\tt 15.\ \ )read\ ntube}\newline
+{\tt 16.\ \ rotateBy(p,\ theta)\ ==}\newline
+{\tt 17.\ \ \ \ c\ :=\ cos(theta)}\newline
+{\tt 18.\ \ \ \ s\ :=\ sin(theta)}\newline
+{\tt 19.\ \ \ \ point\ [p.1*c\ -\ p.2*s,\ p.1*s\ +\ p.2*c]}\newline
+{\tt 20.\ \ }\newline
+{\tt 21.\ \ bcircle\ t\ ==\ }\newline
+{\tt 22.\ \ \ \ point\ [3*cos\ t,\ 3*sin\ t,\ 0]}\newline
+{\tt 23.\ \ \ }\newline
+{\tt 24.\ \ twist(u,\ t)\ ==}\newline
+{\tt 25.\ \ \ \ theta\ :=\ 4*t}\newline
+{\tt 26.\ \ \ \ p\ :=\ point\ [sin\ u,\ cos(u)/2]}\newline
+{\tt 27.\ \ \ \ rotateBy(p,\ theta)}\newline
+{\tt 28.\ \ \ }\newline
+{\tt 29.\ \ ntubeDrawOpt(bcircle,\ twist,\ 0..2*\%pi,\ 0..2*\%pi,}\newline
+{\tt 30.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ 70,\ var2Steps\ ==\ 250)}\newline
+{\tt 31.\ \ }\newline
+{\tt 32.\ \ twist2(u,\ t)\ ==}\newline
+{\tt 33.\ \ \ \ theta\ :=\ t}\newline
+{\tt 34.\ \ \ \ p\ :=\ point\ [sin\ u,\ cos(u)]}\newline
+{\tt 35.\ \ \ \ rotateBy(p,\ theta)}\newline
+{\tt 36.\ \ }\newline
+{\tt 37.\ \ cf(u,v)\ ==\ sin(21*u)}\newline
+{\tt 38.\ \ }\newline
+{\tt 39.\ \ ntubeDrawOpt(bcircle,\ twist2,\ 0..2*\%pi,\ 0..2*\%pi,}\newline
+{\tt 40.\ \ \ \ colorFunction\ ==\ cf,\ var1Steps\ ==\ 168,}\newline
+{\tt 41.\ \ \ \ var2Steps\ ==\ 126)}\newline
+
+\noindent
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesSixTitle}{images6.input}
+\newcommand{\ugFimagesSixNumber}{G.5.}
+%
+% =====================================================================
+\begin{page}{ugFimagesSixPage}{G.5. images6.input}
+% =====================================================================
+\beginscroll
+
+\labelSpace{3pc}
+
+\noindent
+{\tt 1.\ \ \ gam(x,y)\ ==\ }\newline
+{\tt 2.\ \ \ \ \ g\ :=\ Gamma\ complex(x,y)}\newline
+{\tt 3.\ \ \ \ \ point\ [x,y,max(min(real\ g,\ 4),\ -4),\ argument\ g]}\newline
+{\tt 4.\ \ \ }\newline
+{\tt 5.\ \ \ }\newline
+{\tt 6.\ \ \ draw(gam,\ -\%pi..\%pi,\ -\%pi..\%pi,\ }\newline
+{\tt 7.\ \ \ \ \ \ \ \ title\ ==\ "Gamma(x\ +\ \%i*y)",\ \_}\newline
+{\tt 8.\ \ \ \ \ \ \ \ var1Steps\ ==\ 100,\ var2Steps\ ==\ 100)}\newline
+{\tt 9.\ \ \ }\newline
+{\tt 10.\ \ b(x,y)\ ==\ Beta(x,y)}\newline
+{\tt 11.\ \ }\newline
+{\tt 12.\ \ draw(b,\ -3.1..3,\ -3.1\ ..\ 3,\ title\ ==\ "Beta(x,y)")}\newline
+{\tt 13.\ \ }\newline
+{\tt 14.\ \ atf(x,y)\ ==\ }\newline
+{\tt 15.\ \ \ \ a\ :=\ atan\ complex(x,y)}\newline
+{\tt 16.\ \ \ \ point\ [x,y,real\ a,\ argument\ a]}\newline
+{\tt 17.\ \ }\newline
+{\tt 18.\ \ draw(atf,\ -3.0..\%pi,\ -3.0..\%pi)}\newline
+
+\noindent
+%-% \HDindex{function!Gamma}{ugFimagesSixPage}{G.5.}{images6.input}
+%-% \HDindex{function!Euler Beta}{ugFimagesSixPage}{G.5.}{images6.input}
+%-% \HDindex{Euler!Beta function}{ugFimagesSixPage}{G.5.}{images6.input}
+
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesSevenTitle}{images7.input}
+\newcommand{\ugFimagesSevenNumber}{G.6.}
+%
+% =====================================================================
+\begin{page}{ugFimagesSevenPage}{G.6. images7.input}
+% =====================================================================
+\beginscroll
+
+First we look at the conformal
+%-% \HDindex{conformal map}{ugFimagesSevenPage}{G.6.}{images7.input}
+map \texht{$z \mapsto z + 1/z$}{z +-> z + 1/z}.
+\labelSpace{2pc}
+
+\noindent
+{\tt 1.\ \ \ )read\ conformal}\newline
+{\tt 2.\ \ \ }\newline
+{\tt 3.\ \ \ }\newline
+{\tt 4.\ \ \ f\ z\ ==\ z}\newline
+{\tt 5.\ \ \ }\newline
+{\tt 6.\ \ \ conformalDraw(f,\ -2..2,\ -2..2,\ 9,\ 9,\ "cartesian")}\newline
+{\tt 7.\ \ \ }\newline
+{\tt 8.\ \ \ f\ z\ ==\ z\ +\ 1/z}\newline
+{\tt 9.\ \ \ \ }\newline
+{\tt 10.\ \ conformalDraw(f,\ -2..2,\ -2..2,\ 9,\ 9,\ "cartesian")}\newline
+
+\noindent
+
+The map \texht{$z \mapsto -(z+1)/(z-1)$}{z +-> -(z+1)/(z-1)} maps
+the unit disk to the right half-plane, as shown
+%-% \HDindex{Riemann!sphere}{ugFimagesSevenPage}{G.6.}{images7.input}
+on the Riemann sphere.
+
+
+\noindent
+{\tt 1.\ \ \ f\ z\ ==\ z}\newline
+{\tt 2.\ \ \ }\newline
+{\tt 3.\ \ \ riemannConformalDraw(f,0.1..0.99,0..2*\%pi,7,11,"polar")}\newline
+{\tt 4.\ \ \ }\newline
+{\tt 5.\ \ \ f\ z\ ==\ -(z+1)/(z-1)}\newline
+{\tt 6.\ \ \ }\newline
+{\tt 7.\ \ \ riemannConformalDraw(f,0.1..0.99,0..2*\%pi,7,11,"polar")}\newline
+{\tt 8.\ \ \ }\newline
+{\tt 9.\ \ \ riemannSphereDraw(-4..4,\ -4..4,\ 7,\ 7,\ "cartesian")}\newline
+
+\noindent
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFimagesEightTitle}{images8.input}
+\newcommand{\ugFimagesEightNumber}{G.7.}
+%
+% =====================================================================
+\begin{page}{ugFimagesEightPage}{G.7. images8.input}
+% =====================================================================
+\beginscroll
+
+\labelSpace{1pc}
+
+\noindent
+{\tt 1.\ \ \ )read\ dhtri}\newline
+{\tt 2.\ \ \ )read\ tetra}\newline
+{\tt 3.\ \ \ drawPyramid\ 4}\newline
+{\tt 4.\ \ \ }\newline
+%-% \HDindex{Sierpinsky's Tetrahedron}{ugFimagesEightPage}{G.7.}{images8.input}
+{\tt 5.\ \ \ )read\ antoine}\newline
+{\tt 6.\ \ \ drawRings\ 2}\newline
+{\tt 7.\ \ \ }\newline
+%-% \HDindex{Antoine's Necklace}{ugFimagesEightPage}{G.7.}{images8.input}
+{\tt 8.\ \ \ )read\ scherk}\newline
+{\tt 9.\ \ \ drawScherk(3,3)}\newline
+{\tt 10.\ \ }\newline
+%-% \HDindex{Scherk's minimal surface}{ugFimagesEightPage}{G.7.}{images8.input}
+{\tt 11.\ \ )read\ ribbonsNew}\newline
+{\tt 12.\ \ drawRibbons([x**i\ for\ i\ in\ 1..5],\ x=-1..1,\ y=0..2)}\newline
+
+\noindent
+
+
+%\input{gallery/conformal.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFconformalTitle}{conformal.input}
+\newcommand{\ugFconformalNumber}{G.8.}
+%
+% =====================================================================
+\begin{page}{ugFconformalPage}{G.8. conformal.input}
+% =====================================================================
+\beginscroll
+%
+The functions in this section draw conformal maps both on the
+%-% \HDindex{conformal map}{ugFconformalPage}{G.8.}{conformal.input}
+plane and on the Riemann sphere.
+%-% \HDindex{Riemann!sphere}{ugFconformalPage}{G.8.}{conformal.input}
+
+%-- Compile, don't interpret functions.
+%\xmpLine{)set fun comp on}{}
+
+\noindent
+{\tt 1.\ \ \ C\ :=\ Complex\ DoubleFloat}\newline
+{\tt 2.\ \ \ S\ :=\ Segment\ DoubleFloat}\newline
+{\tt 3.\ \ \ R3\ :=\ Point\ DFLOAT}\newline
+{\tt 4.\ \ \ \ }\newline
+
+\noindent
+
+\userfun{conformalDraw}{\it (f, rRange, tRange, rSteps, tSteps, coord)}
+draws the image of the coordinate grid under {\it f} in the complex plane.
+The grid may be given in either polar or Cartesian coordinates.
+Argument {\it f} is the function to draw;
+{\it rRange} is the range of the radius (in polar) or real (in Cartesian);
+{\it tRange} is the range of \texht{$\theta$}{\theta} (in polar) or imaginary (in Cartesian);
+{\it tSteps, rSteps}, are the number of intervals in the {\it r} and
+\texht{$\theta$}{\theta} directions; and
+{\it coord} is the coordinate system to use (either {\tt "polar"} or
+{\tt "cartesian"}).
+
+
+\noindent
+{\tt 1.\ \ \ conformalDraw:\ (C\ ->\ C,\ S,\ S,\ PI,\ PI,\ String)\ ->\ VIEW3D}\newline
+{\tt 2.\ \ \ conformalDraw(f,rRange,tRange,rSteps,tSteps,coord)\ ==}\newline
+{\tt 3.\ \ \ \ \ transformC\ :=}\newline
+{\tt 4.\ \ \ \ \ \ \ coord\ =\ "polar"\ =>\ polar2Complex}\newline
+{\tt 5.\ \ \ \ \ \ \ cartesian2Complex}\newline
+{\tt 6.\ \ \ \ \ cm\ :=\ makeConformalMap(f,\ transformC)}\newline
+{\tt 7.\ \ \ \ \ sp\ :=\ createThreeSpace()}\newline
+{\tt 8.\ \ \ \ \ adaptGrid(sp,\ cm,\ rRange,\ tRange,\ rSteps,\ tSteps)}\newline
+{\tt 9.\ \ \ \ \ makeViewport3D(sp,\ "Conformal\ Map")}\newline
+
+\noindent
+
+\userfun{riemannConformalDraw}{\it (f, rRange, tRange, rSteps, tSteps, coord)}
+draws the image of the coordinate grid under {\it f} on the Riemann sphere.
+The grid may be given in either polar or Cartesian coordinates.
+Its arguments are the same as those for \userfun{conformalDraw}.
+
+\noindent
+{\tt 10.\ \ riemannConformalDraw:(C->C,S,S,PI,PI,String)->VIEW3D}\newline
+{\tt 11.\ \ riemannConformalDraw(f,\ rRange,\ tRange,}\newline
+{\tt 12.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ rSteps,\ tSteps,\ coord)\ ==}\newline
+{\tt 13.\ \ \ \ transformC\ :=}\newline
+{\tt 14.\ \ \ \ \ \ coord\ =\ "polar"\ =>\ polar2Complex}\newline
+{\tt 15.\ \ \ \ \ \ cartesian2Complex}\newline
+{\tt 16.\ \ \ \ sp\ :=\ createThreeSpace()}\newline
+{\tt 17.\ \ \ \ cm\ :=\ makeRiemannConformalMap(f,\ transformC)}\newline
+{\tt 18.\ \ \ \ adaptGrid(sp,\ cm,\ rRange,\ tRange,\ rSteps,\ tSteps)}\newline
+{\tt 19.\ \ \ \ curve(sp,[point\ [0,0,2.0@DFLOAT,0],point\ [0,0,2.0@DFLOAT,0]])}\newline
+{\tt 20.\ \ \ \ makeViewport3D(sp,"Map\ on\ the\ Riemann\ Sphere")}\newline
+{\tt 21.\ \ }\newline
+{\tt 22.\ \ adaptGrid(sp,\ f,\ uRange,\ vRange,\ \ uSteps,\ vSteps)\ ==}\newline
+{\tt 23.\ \ \ \ delU\ :=\ (hi(uRange)\ -\ lo(uRange))/uSteps}\newline
+{\tt 24.\ \ \ \ delV\ :=\ (hi(vRange)\ -\ lo(vRange))/vSteps}\newline
+{\tt 25.\ \ \ \ uSteps\ :=\ uSteps\ +\ 1;\ vSteps\ :=\ vSteps\ +\ 1}\newline
+{\tt 26.\ \ \ \ u\ :=\ lo\ uRange}\newline
+{\tt 27.\ \ \ \ for\ i\ in\ 1..uSteps\ repeat}\newline
+{\tt 28.\ \ \ \ \ \ c\ :=\ curryLeft(f,u)}\newline
+{\tt 29.\ \ \ \ \ \ cf\ :=\ (t:DFLOAT):DFLOAT\ +->\ 0}\newline
+{\tt 30.\ \ \ \ \ \ makeObject(c,vRange::SEG\ Float,colorFunction==cf,}\newline
+{\tt 31.\ \ \ \ \ \ \ \ space\ ==\ sp,\ tubeRadius\ ==\ .02,\ tubePoints\ ==\ 6)}\newline
+{\tt 32.\ \ \ \ \ \ u\ :=\ u\ +\ delU}\newline
+{\tt 33.\ \ \ \ v\ :=\ lo\ vRange}\newline
+{\tt 34.\ \ \ \ for\ i\ in\ 1..vSteps\ repeat}\newline
+{\tt 35.\ \ \ \ \ \ c\ :=\ curryRight(f,v)}\newline
+{\tt 36.\ \ \ \ \ \ cf\ :=\ (t:DFLOAT):DFLOAT\ +->\ 1}\newline
+{\tt 37.\ \ \ \ \ \ makeObject(c,uRange::SEG\ Float,colorFunction==cf,}\newline
+{\tt 38.\ \ \ \ \ \ \ \ space\ ==\ sp,\ tubeRadius\ ==\ .02,\ tubePoints\ ==\ 6)}\newline
+{\tt 39.\ \ \ \ \ \ v\ :=\ v\ +\ delV}\newline
+{\tt 40.\ \ \ \ void()}\newline
+{\tt 41.\ \ }\newline
+{\tt 42.\ \ riemannTransform(z)\ ==}\newline
+{\tt 43.\ \ \ \ r\ :=\ sqrt\ norm\ z}\newline
+{\tt 44.\ \ \ \ cosTheta\ :=\ (real\ z)/r}\newline
+{\tt 45.\ \ \ \ sinTheta\ :=\ (imag\ z)/r}\newline
+{\tt 46.\ \ \ \ cp\ :=\ 4*r/(4+r**2)}\newline
+{\tt 47.\ \ \ \ sp\ :=\ sqrt(1-cp*cp)}\newline
+{\tt 48.\ \ \ \ if\ r>2\ then\ sp\ :=\ -sp}\newline
+{\tt 49.\ \ \ \ point\ [cosTheta*cp,\ sinTheta*cp,\ -sp\ +\ 1]}\newline
+{\tt 50.\ \ \ }\newline
+{\tt 51.\ \ cartesian2Complex(r:DFLOAT,\ i:DFLOAT):C\ ==}\newline
+{\tt 52.\ \ \ \ complex(r,\ i)}\newline
+{\tt 53.\ \ }\newline
+{\tt 54.\ \ polar2Complex(r:DFLOAT,\ th:DFLOAT):C\ ==\ }\newline
+{\tt 55.\ \ \ \ complex(r*cos(th),\ r*sin(th))}\newline
+{\tt 56.\ \ }\newline
+{\tt 57.\ \ makeConformalMap(f,\ transformC)\ ==}\newline
+{\tt 58.\ \ \ \ (u:DFLOAT,v:DFLOAT):R3\ +->\ }\newline
+{\tt 59.\ \ \ \ \ \ z\ :=\ f\ transformC(u,\ v)}\newline
+{\tt 60.\ \ \ \ \ \ point\ [real\ z,\ imag\ z,\ 0.0@DFLOAT]}\newline
+{\tt 61.\ \ \ }\newline
+{\tt 62.\ \ makeRiemannConformalMap(f,\ transformC)\ ==}\newline
+{\tt 63.\ \ \ \ (u:DFLOAT,\ v:DFLOAT):R3\ +->}\newline
+{\tt 64.\ \ \ \ \ \ riemannTransform\ f\ transformC(u,\ v)}\newline
+{\tt 65.\ \ }\newline
+{\tt 66.\ \ riemannSphereDraw:\ (S,\ S,\ PI,\ PI,\ String)\ ->\ VIEW3D}\newline
+{\tt 67.\ \ riemannSphereDraw(rRange,tRange,rSteps,tSteps,coord)\ ==}\newline
+{\tt 68.\ \ \ \ transformC\ :=}\newline
+{\tt 69.\ \ \ \ \ \ coord\ =\ "polar"\ =>\ polar2Complex}\newline
+{\tt 70.\ \ \ \ \ \ cartesian2Complex}\newline
+{\tt 71.\ \ \ \ grid\ :=\ (u:DFLOAT,\ v:DFLOAT):\ R3\ +->\ }\newline
+{\tt 72.\ \ \ \ \ \ z1\ :=\ transformC(u,\ v)}\newline
+{\tt 73.\ \ \ \ \ \ point\ [real\ z1,\ imag\ z1,\ 0]}\newline
+{\tt 74.\ \ \ \ sp\ :=\ createThreeSpace()}\newline
+{\tt 75.\ \ \ \ adaptGrid(sp,\ grid,\ rRange,\ tRange,\ rSteps,\ tSteps)}\newline
+{\tt 76.\ \ \ \ connectingLines(sp,grid,rRange,tRange,rSteps,tSteps)}\newline
+{\tt 77.\ \ \ \ makeObject(riemannSphere,0..2*\%pi,0..\%pi,space==sp)}\newline
+{\tt 78.\ \ \ \ f\ :=\ (z:C):C\ +->\ z}\newline
+{\tt 79.\ \ \ \ cm\ :=\ makeRiemannConformalMap(f,\ transformC)}\newline
+{\tt 80.\ \ \ \ adaptGrid(sp,\ cm,\ rRange,\ tRange,\ rSteps,\ tSteps)}\newline
+{\tt 81.\ \ \ \ makeViewport3D(sp,\ "Riemann\ Sphere")}\newline
+{\tt 82.\ \ \ }\newline
+{\tt 83.\ \ connectingLines(sp,f,uRange,vRange,uSteps,vSteps)\ ==}\newline
+{\tt 84.\ \ \ \ delU\ :=\ (hi(uRange)\ -\ lo(uRange))/uSteps}\newline
+{\tt 85.\ \ \ \ delV\ :=\ (hi(vRange)\ -\ lo(vRange))/vSteps}\newline
+{\tt 86.\ \ \ \ uSteps\ :=\ uSteps\ +\ 1;\ vSteps\ :=\ vSteps\ +\ 1}\newline
+{\tt 87.\ \ \ \ u\ :=\ lo\ uRange}\newline
+{\tt 88.\ \ \ \ for\ i\ in\ 1..uSteps\ repeat}\newline
+{\tt 89.\ \ \ \ \ \ v\ :=\ lo\ vRange}\newline
+{\tt 90.\ \ \ \ \ \ for\ j\ in\ 1..vSteps\ repeat}\newline
+{\tt 91.\ \ \ \ \ \ \ \ p1\ :=\ f(u,v)}\newline
+{\tt 92.\ \ \ \ \ \ \ \ p2\ :=\ riemannTransform\ complex(p1.1,\ p1.2)}\newline
+{\tt 93.\ \ \ \ \ \ \ \ fun\ :=\ lineFromTo(p1,p2)}\newline
+{\tt 94.\ \ \ \ \ \ \ \ cf\ :=\ (t:DFLOAT):DFLOAT\ +->\ 3}\newline
+{\tt 95.\ \ \ \ \ \ \ \ makeObject(fun,\ 0..1,space==sp,tubePoints==4,}\newline
+{\tt 96.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ tubeRadius==0.01,colorFunction==cf)}\newline
+{\tt 97.\ \ \ \ \ \ \ \ v\ :=\ v\ +\ delV}\newline
+{\tt 98.\ \ \ \ \ \ u\ :=\ u\ +\ delU}\newline
+{\tt 99.\ \ \ \ void()}\newline
+{\tt 100.\ \ }\newline
+{\tt 101.\ riemannSphere(u,v)\ ==\ }\newline
+{\tt 102.\ \ \ sv\ :=\ sin(v)}\newline
+{\tt 103.\ \ \ 0.99@DFLOAT*(point\ [cos(u)*sv,sin(u)*sv,cos(v),0.0@DFLOAT])+}\newline
+{\tt 104.\ \ \ \ \ point\ [0.0@DFLOAT,\ 0.0@DFLOAT,\ 1.0@DFLOAT,\ 4.0@DFLOAT]}\newline
+{\tt 105.\ \ }\newline
+{\tt 106.\ lineFromTo(p1,\ p2)\ ==}\newline
+{\tt 107.\ \ \ d\ :=\ p2\ -\ p1}\newline
+{\tt 108.\ \ \ (t:DFLOAT):Point\ DFLOAT\ +->}\newline
+{\tt 109.\ \ \ \ \ p1\ +\ t*d}\newline
+
+\noindent
+
+%\input{gallery/tknot.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFtknotTitle}{tknot.input}
+\newcommand{\ugFtknotNumber}{G.9.}
+%
+% =====================================================================
+\begin{page}{ugFtknotPage}{G.9. tknot.input}
+% =====================================================================
+\beginscroll
+%
+Create a $(p,q)$ torus-knot with radius $r$ around the curve.
+The formula was derived by Larry Lambe.
+
+
+\noindent
+{\tt 1.\ \ \ )read\ ntube}\newline
+{\tt 2.\ \ \ torusKnot:\ (DFLOAT,\ DFLOAT,\ DFLOAT,\ PI,\ PI)\ ->\ VIEW3D}\newline
+{\tt 3.\ \ \ torusKnot(p,\ q\ ,r,\ uSteps,\ tSteps)\ ==}\newline
+{\tt 4.\ \ \ \ \ knot\ :=\ (t:DFLOAT):Point\ DFLOAT\ +->\ }\newline
+{\tt 5.\ \ \ \ \ \ \ fac\ :=\ 4/(2.2@DFLOAT-sin(q*t))}\newline
+{\tt 6.\ \ \ \ \ \ \ fac\ *\ point\ [cos(p*t),\ sin(p*t),\ cos(q*t)]}\newline
+{\tt 7.\ \ \ \ \ circle\ :=\ (u:DFLOAT,\ t:DFLOAT):\ Point\ DFLOAT\ +->}\newline
+{\tt 8.\ \ \ \ \ \ \ r\ *\ point\ [cos\ u,\ sin\ u]}\newline
+{\tt 9.\ \ \ \ \ ntubeDrawOpt(knot,\ circle,\ 0..2*\%pi,\ 0..2*\%pi,}\newline
+{\tt 10.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ uSteps,\ var2Steps\ ==\ tSteps)}\newline
+{\tt 11.\ \ }\newline
+
+\noindent
+
+%\input{gallery/ntube.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFntubeTitle}{ntube.input}
+\newcommand{\ugFntubeNumber}{G.10.}
+%
+% =====================================================================
+\begin{page}{ugFntubePage}{G.10. ntube.input}
+% =====================================================================
+\beginscroll
+%
+The functions in this file create generalized tubes (also known as generalized
+cylinders).
+These functions draw a 2-d curve in the normal
+planes around a 3-d curve.
+
+
+\noindent
+{\tt 1.\ \ \ R3\ :=\ Point\ DFLOAT}\newline
+{\tt 2.\ \ \ R2\ :=\ Point\ DFLOAT}\newline
+{\tt 3.\ \ \ S\ :=\ Segment\ Float}\newline
+{\tt 4.\ \ \ }\newline
+{\tt 5.\ \ \ ThreeCurve\ :=\ DFLOAT\ ->\ R3}\newline
+{\tt 6.\ \ \ TwoCurve\ :=\ (DFLOAT,\ DFLOAT)\ ->\ R2}\newline
+{\tt 7.\ \ \ Surface\ :=\ (DFLOAT,\ DFLOAT)\ ->\ R3}\newline
+{\tt 8.\ \ \ }\newline
+{\tt 9.\ \ \ FrenetFrame\ :=\ }\newline
+{\tt 10.\ \ \ \ \ Record(value:R3,tangent:R3,normal:R3,binormal:R3)}\newline
+{\tt 11.\ \ frame:\ FrenetFrame}\newline
+{\tt 12.\ \ }\newline
+
+\noindent
+
+\userfun{ntubeDraw}{\it (spaceCurve, planeCurve,}
+$u_0 .. u_1,$ $t_0 .. t_1)$
+draws {\it planeCurve} in the normal planes of {\it spaceCurve.}
+The parameter $u_0 .. u_1$ specifies
+the parameter range for {\it planeCurve}
+and $t_0 .. t_1$ specifies the parameter range for {\it spaceCurve}.
+Additionally, the plane curve function takes
+a second parameter: the current parameter of {\it spaceCurve}.
+This allows the plane curve to change shape
+as it goes around the space curve.
+See \downlink{``\ugFimagesFiveTitle''}{ugFimagesFivePage} in Section \ugFimagesFiveNumber\ignore{ugFimagesFive} for an example of this.
+%
+
+\noindent
+{\tt 1.\ \ \ ntubeDraw:\ (ThreeCurve,TwoCurve,S,S)\ ->\ VIEW3D}\newline
+{\tt 2.\ \ \ ntubeDraw(spaceCurve,planeCurve,uRange,tRange)\ ==}\newline
+{\tt 3.\ \ \ \ \ ntubeDrawOpt(spaceCurve,\ planeCurve,\ uRange,\ \_}\newline
+{\tt 4.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ tRange,\ []\$List\ DROPT)}\newline
+{\tt 5.\ \ \ \ }\newline
+{\tt 6.\ \ \ ntubeDrawOpt:\ (ThreeCurve,TwoCurve,S,S,List\ DROPT)}\newline
+{\tt 7.\ \ \ \ \ \ \ ->\ VIEW3D}\newline
+{\tt 8.\ \ \ ntubeDrawOpt(spaceCurve,planeCurve,uRange,tRange,l)\ ==}\newline
+{\tt 9.\ \ \ \ \ \ \ \ \ \ \ \ \ }\newline
+{\tt 10.\ \ \ \ delT:DFLOAT\ :=\ (hi(tRange)\ -\ lo(tRange))/10000}\newline
+{\tt 11.\ \ \ \ oldT:DFLOAT\ :=\ lo(tRange)\ -\ 1}\newline
+{\tt 12.\ \ \ \ fun\ :=\ ngeneralTube(spaceCurve,planeCurve,delT,oldT)}\newline
+{\tt 13.\ \ \ \ draw(fun,\ uRange,\ tRange,\ l)}\newline
+{\tt 14.\ \ }\newline
+
+\noindent
+
+\userfun{nfrenetFrame}{\it (c, t, delT)}
+numerically computes the Frenet frame
+about the curve {\it c} at {\it t}.
+Parameter {\it delT} is a small number used to
+compute derivatives.
+
+\noindent
+{\tt 15.\ \ nfrenetFrame(c,\ t,\ delT)\ ==}\newline
+{\tt 16.\ \ \ \ f0\ :=\ c(t)}\newline
+{\tt 17.\ \ \ \ f1\ :=\ c(t+delT)}\newline
+{\tt 18.\ \ \ \ t0\ :=\ f1\ -\ f0}\newline
+{\tt 19.\ \ \ \ n0\ :=\ f1\ +\ f0\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\newline
+{\tt 20.\ \ \ \ b\ :=\ cross(t0,\ n0)}\newline
+{\tt 21.\ \ \ \ n\ :=\ cross(b,t0)}\newline
+{\tt 22.\ \ \ \ ln\ :=\ length\ n}\newline
+{\tt 23.\ \ \ \ lb\ :=\ length\ b}\newline
+{\tt 24.\ \ \ \ ln\ =\ 0\ or\ lb\ =\ 0\ =>}\newline
+{\tt 25.\ \ \ \ \ \ \ \ error\ "Frenet\ Frame\ not\ well\ defined"}\newline
+{\tt 26.\ \ \ \ n\ :=\ (1/ln)*n}\newline
+{\tt 27.\ \ \ \ b\ :=\ (1/lb)*b}\newline
+{\tt 28.\ \ \ \ [f0,\ t0,\ n,\ b]\$FrenetFrame}\newline
+
+\noindent
+
+\userfun{ngeneralTube}{\it (spaceCurve, planeCurve,}{\it delT, oltT)}
+creates a function that can be passed to the system axiomFun{draw} command.
+The function is a parameterized surface for the general tube
+around {\it spaceCurve}. {\it delT} is a small number used to compute
+derivatives. {\it oldT} is used to hold the current value of the
+{\it t} parameter for {\it spaceCurve.} This is an efficiency measure
+to ensure that frames are only computed once for each value of {\it t}.
+
+\noindent
+{\tt 29.\ \ ngeneralTube:\ (ThreeCurve,\ TwoCurve,\ DFLOAT,\ DFLOAT)\ ->\ Surface}\newline
+{\tt 30.\ \ ngeneralTube(spaceCurve,\ planeCurve,\ delT,\ oldT)\ ==}\newline
+{\tt 31.\ \ \ \ free\ frame}\newline
+{\tt 32.\ \ \ \ (v:DFLOAT,\ t:\ DFLOAT):\ R3\ +->}\newline
+{\tt 33.\ \ \ \ \ \ if\ (t\ \texht{$\sim$}{~}=\ oldT)\ then}\newline
+{\tt 34.\ \ \ \ \ \ \ \ frame\ :=\ nfrenetFrame(spaceCurve,\ t,\ delT)}\newline
+{\tt 35.\ \ \ \ \ \ \ \ oldT\ :=\ t}\newline
+{\tt 36.\ \ \ \ \ \ p\ :=\ planeCurve(v,\ t)}\newline
+{\tt 37.\ \ \ \ \ \ frame.value\ +\ p.1*frame.normal\ +\ p.2*frame.binormal}\newline
+
+\noindent
+
+%\input{gallery/dhtri.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFdhtriTitle}{dhtri.input}
+\newcommand{\ugFdhtriNumber}{G.11.}
+%
+% =====================================================================
+\begin{page}{ugFdhtriPage}{G.11. dhtri.input}
+% =====================================================================
+\beginscroll
+%
+Create affine transformations (DH matrices) that transform
+a given triangle into another.
+
+
+\noindent
+{\tt 1.\ \ \ tri2tri:\ (List\ Point\ DFLOAT,\ List\ Point\ DFLOAT)\ ->\ DHMATRIX(DFLOAT)}\newline
+{\tt 2.\ \ \ tri2tri(t1,\ t2)\ ==}\newline
+{\tt 3.\ \ \ \ \ n1\ :=\ triangleNormal(t1)}\newline
+{\tt 4.\ \ \ \ \ n2\ :=\ triangleNormal(t2)}\newline
+{\tt 5.\ \ \ \ \ tet2tet(concat(t1,\ n1),\ concat(t2,\ n2))}\newline
+{\tt 6.\ \ \ \ }\newline
+{\tt 7.\ \ \ tet2tet:\ (List\ Point\ DFLOAT,\ List\ Point\ DFLOAT)\ ->\ DHMATRIX(DFLOAT)}\newline
+{\tt 8.\ \ \ tet2tet(t1,\ t2)\ ==}\newline
+{\tt 9.\ \ \ \ \ m1\ :=\ makeColumnMatrix\ t1}\newline
+{\tt 10.\ \ \ \ m2\ :=\ makeColumnMatrix\ t2}\newline
+{\tt 11.\ \ \ \ m2\ *\ inverse(m1)}\newline
+{\tt 12.\ \ \ }\newline
+{\tt 13.\ \ makeColumnMatrix(t)\ ==}\newline
+{\tt 14.\ \ \ \ m\ :=\ new(4,4,0)\$DHMATRIX(DFLOAT)}\newline
+{\tt 15.\ \ \ \ for\ x\ in\ t\ for\ i\ in\ 1..repeat}\newline
+{\tt 16.\ \ \ \ \ \ for\ j\ in\ 1..3\ repeat}\newline
+{\tt 17.\ \ \ \ \ \ \ \ m(j,i)\ :=\ x.j}\newline
+{\tt 18.\ \ \ \ \ \ m(4,i)\ :=\ 1}\newline
+{\tt 19.\ \ \ \ m}\newline
+{\tt 20.\ \ \ }\newline
+{\tt 21.\ \ triangleNormal(t)\ ==}\newline
+{\tt 22.\ \ \ \ a\ :=\ triangleArea\ t}\newline
+{\tt 23.\ \ \ \ p1\ :=\ t.2\ -\ t.1}\newline
+{\tt 24.\ \ \ \ p2\ :=\ t.3\ -\ t.2}\newline
+{\tt 25.\ \ \ \ c\ :=\ cross(p1,\ p2)}\newline
+{\tt 26.\ \ \ \ len\ :=\ length(c)}\newline
+{\tt 27.\ \ \ \ len\ =\ 0\ =>\ error\ "degenerate\ triangle!"}\newline
+{\tt 28.\ \ \ \ c\ :=\ (1/len)*c}\newline
+{\tt 29.\ \ \ \ t.1\ +\ sqrt(a)\ *\ c}\newline
+{\tt 30.\ \ \ }\newline
+{\tt 31.\ \ triangleArea\ t\ ==}\newline
+{\tt 32.\ \ \ \ a\ :=\ length(t.2\ -\ t.1)}\newline
+{\tt 33.\ \ \ \ b\ :=\ length(t.3\ -\ t.2)}\newline
+{\tt 34.\ \ \ \ c\ :=\ length(t.1\ -\ t.3)}\newline
+{\tt 35.\ \ \ \ s\ :=\ (a+b+c)/2}\newline
+{\tt 36.\ \ \ \ sqrt(s*(s-a)*(s-b)*(s-c))}\newline
+
+\noindent
+
+
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFtetraTitle}{tetra.input}
+\newcommand{\ugFtetraNumber}{G.12.}
+%
+% =====================================================================
+\begin{page}{ugFtetraPage}{G.12. tetra.input}
+% =====================================================================
+\beginscroll
+%
+%\input{gallery/tetra.htex}
+%\outdent{Sierpinsky's Tetrahedron}
+
+\labelSpace{3pc}
+
+
+\noindent
+{\tt 1.\ \ \ )set\ expose\ add\ con\ DenavitHartenbergMatrix}\newline
+{\tt 2.\ \ \ }\newline
+{\tt 3.\ \ \ x1:DFLOAT\ :=\ sqrt(2.0@DFLOAT/3.0@DFLOAT)}\newline
+{\tt 4.\ \ \ x2:DFLOAT\ :=\ sqrt(3.0@DFLOAT)/6}\newline
+{\tt 5.\ \ \ }\newline
+{\tt 6.\ \ \ p1\ :=\ point\ [-0.5@DFLOAT,\ -x2,\ 0.0@DFLOAT]}\newline
+{\tt 7.\ \ \ p2\ :=\ point\ [0.5@DFLOAT,\ -x2,\ 0.0@DFLOAT]}\newline
+{\tt 8.\ \ \ p3\ :=\ point\ [0.0@DFLOAT,\ 2*x2,\ 0.0@DFLOAT]}\newline
+{\tt 9.\ \ \ p4\ :=\ point\ [0.0@DFLOAT,\ 0.0@DFLOAT,\ x1]}\newline
+{\tt 10.\ \ \ }\newline
+{\tt 11.\ \ baseTriangle\ \ :=\ [p2,\ p1,\ p3]}\newline
+{\tt 12.\ \ }\newline
+{\tt 13.\ \ mt\ \ :=\ [0.5@DFLOAT*(p2+p1),\ 0.5@DFLOAT*(p1+p3),\ 0.5@DFLOAT*(p3+p2)]}\newline
+{\tt 14.\ \ }\newline
+{\tt 15.\ \ bt1\ :=\ [mt.1,\ p1,\ mt.2]}\newline
+{\tt 16.\ \ bt2\ :=\ [p2,\ mt.1,\ mt.3]}\newline
+{\tt 17.\ \ bt3\ :=\ [mt.2,\ p3,\ mt.3]}\newline
+{\tt 18.\ \ bt4\ :=\ [0.5@DFLOAT*(p2+p4),\ 0.5@DFLOAT*(p1+p4),\ 0.5@DFLOAT*(p3+p4)]}\newline
+{\tt 19.\ \ }\newline
+{\tt 20.\ \ tt1\ :=\ tri2tri(baseTriangle,\ bt1)}\newline
+{\tt 21.\ \ tt2\ :=\ tri2tri(baseTriangle,\ bt2)}\newline
+{\tt 22.\ \ tt3\ :=\ tri2tri(baseTriangle,\ bt3)}\newline
+{\tt 23.\ \ tt4\ :=\ tri2tri(baseTriangle,\ bt4)}\newline
+{\tt 24.\ \ }\newline
+{\tt 25.\ \ drawPyramid(n)\ ==}\newline
+{\tt 26.\ \ \ \ s\ :=\ createThreeSpace()}\newline
+{\tt 27.\ \ \ \ dh\ :=\ rotatex(0.0@DFLOAT)}\newline
+{\tt 28.\ \ \ \ drawPyramidInner(s,\ n,\ dh)}\newline
+{\tt 29.\ \ \ \ makeViewport3D(s,\ "Sierpinsky\ Tetrahedron")}\newline
+{\tt 30.\ \ }\newline
+{\tt 31.\ \ drawPyramidInner(s,\ n,\ dh)\ ==}\newline
+{\tt 32.\ \ \ \ n\ =\ 0\ =>\ makeTetrahedron(s,\ dh,\ n)}\newline
+{\tt 33.\ \ \ \ drawPyramidInner(s,\ n-1,\ dh\ *\ tt1)}\newline
+{\tt 34.\ \ \ \ drawPyramidInner(s,\ n-1,\ dh\ *\ tt2)}\newline
+{\tt 35.\ \ \ \ drawPyramidInner(s,\ n-1,\ dh\ *\ tt3)}\newline
+{\tt 36.\ \ \ \ drawPyramidInner(s,\ n-1,\ dh\ *\ tt4)}\newline
+{\tt 37.\ \ }\newline
+{\tt 38.\ \ makeTetrahedron(sp,\ dh,\ color)\ ==}\newline
+{\tt 39.\ \ \ \ w1\ :=\ dh*p1}\newline
+{\tt 40.\ \ \ \ w2\ :=\ dh*p2}\newline
+{\tt 41.\ \ \ \ w3\ :=\ dh*p3}\newline
+{\tt 42.\ \ \ \ w4\ :=\ dh*p4}\newline
+{\tt 43.\ \ \ \ polygon(sp,\ [w1,\ w2,\ w4])}\newline
+{\tt 44.\ \ \ \ polygon(sp,\ [w1,\ w3,\ w4])}\newline
+{\tt 45.\ \ \ \ polygon(sp,\ [w2,\ w3,\ w4])}\newline
+{\tt 46.\ \ \ \ void()}\newline
+
+\noindent
+%-% \HDindex{Sierpinsky's Tetrahedron}{ugFtetraPage}{G.12.}{tetra.input}
+
+
+%\input{gallery/antoine.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFantoineTitle}{antoine.input}
+\newcommand{\ugFantoineNumber}{G.13.}
+%
+% =====================================================================
+\begin{page}{ugFantoinePage}{G.13. antoine.input}
+% =====================================================================
+\beginscroll
+%
+Draw Antoine's Necklace.
+%-% \HDindex{Antoine's Necklace}{ugFantoinePage}{G.13.}{antoine.input}
+Thank you to Matthew Grayson at IBM's T.J Watson Research Center for the idea.
+
+
+\noindent
+{\tt 1.\ \ \ )set\ expose\ add\ con\ DenavitHartenbergMatrix}\newline
+{\tt 2.\ \ \ }\newline
+{\tt 3.\ \ \ torusRot:\ DHMATRIX(DFLOAT)}\newline
+{\tt 4.\ \ \ }\newline
+{\tt 5.\ \ \ }\newline
+{\tt 6.\ \ \ drawRings(n)\ ==}\newline
+{\tt 7.\ \ \ \ \ s\ :=\ createThreeSpace()}\newline
+{\tt 8.\ \ \ \ \ dh:DHMATRIX(DFLOAT)\ :=\ identity()}\newline
+{\tt 9.\ \ \ \ \ drawRingsInner(s,\ n,\ dh)}\newline
+{\tt 10.\ \ \ \ makeViewport3D(s,\ "Antoine's\ Necklace")}\newline
+{\tt 11.\ \ }\newline
+
+\noindent
+
+In order to draw Antoine rings, we take one ring, scale it down to
+a smaller size, rotate it around its central axis, translate it
+to the edge of the larger ring and rotate it around the edge to
+a point corresponding to its count (there are 10 positions around
+the edge of the larger ring). For each of these new rings we
+recursively perform the operations, each ring becoming 10 smaller
+rings. Notice how the \axiomType{DHMATRIX} operations are used to build up
+the proper matrix composing all these transformations.
+
+
+\noindent
+{\tt 1.\ \ \ drawRingsInner(s,\ n,\ dh)\ ==}\newline
+{\tt 2.\ \ \ \ \ n\ =\ 0\ =>}\newline
+{\tt 3.\ \ \ \ \ \ \ drawRing(s,\ dh)}\newline
+{\tt 4.\ \ \ \ \ \ \ void()}\newline
+{\tt 5.\ \ \ \ \ t\ :=\ 0.0@DFLOAT}\newline
+{\tt 6.\ \ \ \ \ p\ :=\ 0.0@DFLOAT}\newline
+{\tt 7.\ \ \ \ \ tr\ :=\ 1.0@DFLOAT}\newline
+{\tt 8.\ \ \ \ \ inc\ :=\ 0.1@DFLOAT}\newline
+{\tt 9.\ \ \ \ \ for\ i\ in\ 1..10\ repeat}\newline
+{\tt 10.\ \ \ \ \ \ tr\ :=\ tr\ +\ inc}\newline
+{\tt 11.\ \ \ \ \ \ inc\ :=\ -inc}\newline
+{\tt 12.\ \ \ \ \ \ dh'\ :=\ dh*rotatez(t)*translate(tr,0.0@DFLOAT,0.0@DFLOAT)*}\newline
+{\tt 13.\ \ \ \ \ \ \ \ \ \ \ \ \ rotatey(p)*scale(0.35@DFLOAT,\ 0.48@DFLOAT,\ 0.4@DFLOAT)}\newline
+{\tt 14.\ \ \ \ \ \ drawRingsInner(s,\ n-1,\ dh')}\newline
+{\tt 15.\ \ \ \ \ \ t\ :=\ t\ +\ 36.0@DFLOAT}\newline
+{\tt 16.\ \ \ \ \ \ p\ :=\ p\ +\ 90.0@DFLOAT}\newline
+{\tt 17.\ \ \ \ void()}\newline
+{\tt 18.\ \ }\newline
+{\tt 19.\ \ drawRing(s,\ dh)\ ==}\newline
+{\tt 20.\ \ \ \ free\ torusRot}\newline
+{\tt 21.\ \ \ \ torusRot\ :=\ dh}\newline
+{\tt 22.\ \ \ \ makeObject(torus,\ 0..2*\%pi,\ 0..2*\%pi,\ var1Steps\ ==\ 6,}\newline
+{\tt 23.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ space\ ==\ s,\ var2Steps\ ==\ 15)}\newline
+{\tt 24.\ \ }\newline
+{\tt 25.\ \ torus(u\ ,v)\ ==}\newline
+{\tt 26.\ \ \ \ cu\ :=\ cos(u)/6}\newline
+{\tt 27.\ \ \ \ torusRot*point\ [(1+cu)*cos(v),(1+cu)*sin(v),(sin\ u)/6]}\newline
+
+\noindent
+
+%\input{gallery/scherk.htex}
+\endscroll
+\autobuttons
+\end{page}
+%
+%
+\newcommand{\ugFscherkTitle}{scherk.input}
+\newcommand{\ugFscherkNumber}{G.14.}
+%
+% =====================================================================
+\begin{page}{ugFscherkPage}{G.14. scherk.input}
+% =====================================================================
+\beginscroll
+%
+
+Scherk's minimal surface, defined by:
+%-% \HDindex{Scherk's minimal surface}{ugFscherkPage}{G.14.}{scherk.input}
+\texht{$e^z \cos(x) = \cos(y)$}{\axiom{exp(z) * cos(x) = cos(y)}}.
+See: {\it A Comprehensive Introduction to Differential Geometry,} Vol. 3,
+by Michael Spivak, Publish Or Perish, Berkeley, 1979, pp. 249-252.
+
+
+\noindent
+{\tt 1.\ \ \ (xOffset,\ yOffset):DFLOAT}\newline
+{\tt 2.\ \ \ \ }\newline
+{\tt 3.\ \ \ }\newline
+{\tt 4.\ \ \ drawScherk(m,n)\ ==}\newline
+{\tt 5.\ \ \ \ \ free\ xOffset,\ yOffset}\newline
+{\tt 6.\ \ \ \ \ space\ :=\ createThreeSpace()}\newline
+{\tt 7.\ \ \ \ \ for\ i\ in\ 0..m-1\ repeat}\newline
+{\tt 8.\ \ \ \ \ \ \ xOffset\ :=\ i*\%pi}\newline
+{\tt 9.\ \ \ \ \ \ \ for\ j\ in\ 0\ ..\ n-1\ repeat}\newline
+{\tt 10.\ \ \ \ \ \ \ \ rem(i+j,\ 2)\ =\ 0\ =>\ 'iter}\newline
+{\tt 11.\ \ \ \ \ \ \ \ yOffset\ :=\ j*\%pi}\newline
+{\tt 12.\ \ \ \ \ \ \ \ drawOneScherk(space)}\newline
+{\tt 13.\ \ \ \ makeViewport3D(space,\ "Scherk's\ Minimal\ Surface")}\newline
+{\tt 14.\ \ }\newline
+{\tt 15.\ \ scherk1(u,v)\ ==}\newline
+{\tt 16.\ \ \ \ x\ :=\ cos(u)/exp(v)}\newline
+{\tt 17.\ \ \ \ point\ [xOffset\ +\ acos(x),\ yOffset\ +\ u,\ v,\ abs(v)]}\newline
+{\tt 18.\ \ \ }\newline
+{\tt 19.\ \ scherk2(u,v)\ ==}\newline
+{\tt 20.\ \ \ \ x\ :=\ cos(u)/exp(v)}\newline
+{\tt 21.\ \ \ \ point\ [xOffset\ -\ acos(x),\ yOffset\ +\ u,\ v,\ abs(v)]}\newline
+{\tt 22.\ \ \ }\newline
+{\tt 23.\ \ scherk3(u,v)\ ==\ }\newline
+{\tt 24.\ \ \ \ x\ :=\ exp(v)\ *\ cos(u)}\newline
+{\tt 25.\ \ \ \ point\ [xOffset\ +\ u,\ yOffset\ +\ acos(x),\ v,\ abs(v)]}\newline
+{\tt 26.\ \ \ }\newline
+{\tt 27.\ \ scherk4(u,v)\ ==\ }\newline
+{\tt 28.\ \ \ \ x\ :=\ exp(v)\ *\ cos(u)}\newline
+{\tt 29.\ \ \ \ point\ [xOffset\ +\ u,\ yOffset\ -\ acos(x),\ v,\ abs(v)]}\newline
+{\tt 30.\ \ \ }\newline
+{\tt 31.\ \ drawOneScherk(s)\ ==}\newline
+{\tt 32.\ \ \ \ makeObject(scherk1,-\%pi/2..\%pi/2,0..\%pi/2,space==s,}\newline
+{\tt 33.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ 28,\ var2Steps\ ==\ 28)}\newline
+{\tt 34.\ \ \ \ makeObject(scherk2,-\%pi/2..\%pi/2,0..\%pi/2,space==s,}\newline
+{\tt 35.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ 28,\ var2Steps\ ==\ 28)}\newline
+{\tt 36.\ \ \ \ makeObject(scherk3,-\%pi/2..\%pi/2,-\%pi/2..0,space==s,}\newline
+{\tt 37.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ 28,\ var2Steps\ ==\ 28)}\newline
+{\tt 38.\ \ \ \ makeObject(scherk4,-\%pi/2..\%pi/2,-\%pi/2..0,space==s,}\newline
+{\tt 39.\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ var1Steps\ ==\ 28,\ var2Steps\ ==\ 28)}\newline
+{\tt 40.\ \ \ \ void()}\newline
+
+\noindent
+\endscroll
+\autobuttons
+\end{page}
+%