% 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 FriCAS Images}
\newcommand{\ugAppGraphicsNumber}{G.}
%
% =====================================================================
\begin{page}{ugAppGraphicsPage}{G. Programs for FriCAS 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\ :=\ (high(uRange)\ -\ low(uRange))/uSteps}\newline
{\tt 24.\ \ \ \ delV\ :=\ (high(vRange)\ -\ low(vRange))/vSteps}\newline
{\tt 25.\ \ \ \ uSteps\ :=\ uSteps\ +\ 1;\ vSteps\ :=\ vSteps\ +\ 1}\newline
{\tt 26.\ \ \ \ u\ :=\ low\ 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\ :=\ low\ 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\ :=\ (high(uRange)\ -\ low(uRange))/uSteps}\newline
{\tt 85.\ \ \ \ delV\ :=\ (high(vRange)\ -\ low(vRange))/vSteps}\newline
{\tt 86.\ \ \ \ uSteps\ :=\ uSteps\ +\ 1;\ vSteps\ :=\ vSteps\ +\ 1}\newline
{\tt 87.\ \ \ \ u\ :=\ low\ uRange}\newline
{\tt 88.\ \ \ \ for\ i\ in\ 1..uSteps\ repeat}\newline
{\tt 89.\ \ \ \ \ \ v\ :=\ low\ 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\ :=\ (high(tRange)\ -\ low(tRange))/10000}\newline
{\tt 11.\ \ \ \ oldT:DFLOAT\ :=\ low(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 \spadfun{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 \spadtype{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)$}{\spad{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}
%
