<!doctype linuxdoc system>
<!-- macroMan.sgml
     L. Nobre G.
     2004
  -->
<linuxdoc>
  <article>
    <titlepag>
      <title>FEATPOST macros</title>
      <author>L. Nobre G., <tt>http://matagalatlante.org</tt></name>
      <date>December 2004</date>
      <abstract>
	This document intends to be an explanation of the MetaPost macros
	defined in the <tt>FEATPOST</tt> package. Its purpose is to draw
	two or three-dimensional physics diagrams.

	The <tt>FEATPOST</tt> package is supposed to help you draw figures
	containing 3D dots, vectors, flat arrows, angles, parametric
	lines, circles, ellipses,
	cones, cylinders, spheres,
	globes, hemispheres, toruses,
	elliptical frusta,
	polygons, polyhedra, functional and parametric surfaces,
	direction fields, field lines
	and trajectories in vector fields,
	schematic automobiles, electric charges,
	etc.

	The fact that it is a programming language instead of
	Computer Aided Design (CAD)
	helps the user to experiment different
	figure layouts without changing specified geometric relationships
	among figure elements.

	Two of the intrinsic MetaPost features which may be important 
	for physics diagrams are: (i) the typesetting power of
	TeX is easily called when needed and (ii) besides a sufficient
	number of mathematical operators, geometric relationships may
	be expressed by linear equations, without explicit assignements.
      </abstract>
    </titlepag>
    <sect>
      <heading>Introduction</heading>
      <p>
	3D in MetaPost is not a new idea. Denis Roegel
	contributed related packages to CTAN some years ago. It was the
	subject of a 1997 TUGboat article (V18, N4, 274-283). Recently
	he developed <url
	url="http://www.loria.fr/~roegel/TeX/mousson2005.pdf" 
	name="MP2GL">. Anthony
	Phan has been developing a very elegant package
	called <url url="http://www-math.univ-poitiers.fr/~phan/m3Dplain.html" name="m3D">. Due to his skilled coding, <tt>m3D</tt> can
	handle larger objects and can produce more realistic renderings than
	<tt>FEATPOST</tt>. Other possibilities include <url
	  url="http://directory.fsf.org/GNU/3DLDF.html" name="GNU
	  3DLDF">, <url
	  url="http://robert.silve.free.fr/latex/metapost3D/"
	  name="Bob's Info"> or <url
	  url="http://asymptote.sourceforge.net/"
	  name="Asymptote">.
	In any case we are talking about vector-based abstract diagrams,
	so the functionality of
	these packages is nearer to <tt>GNUPLOT</tt> than to <tt>OpenGL</tt>.
	We could also talk about <tt><url url="http://www.povray.org/" name="POV-ray"></tt> or
	<tt><url url="http://www.blender3d.org/" name="blender"></tt> but these
	are focused on ray-traced images, a completely different thing.
      </p>
      <p>
	Regarding software <tt>FEATPOST</tt> requires only MetaPost but
	recommends <tt>LaTeX, bash, ImageMagick, ghostscript,
	Linuxdoc, Textutils, dvips, epstopdf, sed, gv, plaympeg, <url url="http://jl.photodex.com/dog/" name="dog">, <url url="http://www.flexer.it/galrey/" name="galrey"></tt> and <tt><url url="http://lince.cii.fc.ul.pt/xcmd/xcmd.html" name="xcmd"></tt>. Also, it is highly beneficial to
	be able to understand and cope with MetaPost error messages as
	<tt>FEATPOST</tt> has no protection against mistaken inputs. One
	probable cause of errors is the use of variables with the name of
	procedures, like
	<tscreen><verb>X, Y, Z, N, rp, cb, ps</verb>
	</tscreen>All other procedure names have six or more characters.
      </p>
      <p>
	The user must be aware that MetaPost has a limited arithmetic power
	and that the author has limited programming skills,
	which may lead to unperfect 3D figures, very long processing
	time or shear bugs.
	It's advisable not to try very complex diagrams at first 
	and it's recommended to
	keep 3D coordinates near order 1 (default MetaPost units).
      </p>
      <p>
	All <tt>FEATPOST</tt> macros are build apon the MetaPost
	<tt>color</tt> variable type. It looks like this:
	<tscreen><verb>(red,green,blue)</verb>
	</tscreen>Its components may, nevertheless,
	be arbtitrary numbers, like:
	<tscreen><verb>(X,Y,Z)</verb></tscreen>So, the
	<tt>color</tt> type is adequate to define not only colors but
	also 3D points and vectors.
      </p>
    </sect>
    <sect>
      <heading>Small Tutorial</heading>
	<p>
	  One very minimalistic example program could be:
	  <tscreen><verb>
beginfig(1);
  cartaxes(1,1,1);
endfig;
end;</verb></tscreen>where <tt>cartaxes</tt> is a
	  <tt>FEATPOST</tt> macro that produces
	  the Cartesian referential.
	</p>
	<p>
	  One small example program may be:
	  <tscreen><verb>
f := 5.4*(1.5,0.5,1);
Spread := 30;
beginfig(1);
  numeric gridstep, sidenumber, i, j, coord, aa, ab, ac;
  color pa;
  gridstep = 0.9;
  sidenumber = 10;
  coord = 0.5*sidenumber*gridstep;
  for i=0 upto sidenumber:
    for j=0 upto sidenumber:
      pa := (-coord+j*gridstep,-coord+i*gridstep,0);
      aa := uniformdeviate(360);
      ab := uniformdeviate(180);
      ac := uniformdeviate(90);
      kindofcube( false, false, pa, aa, ab, ac, 0.4, 0.4, 0.9 );
    endfor;
  endfor;
endfig;
end.</verb></tscreen>where <tt>kindofcube</tt>
	  is a <tt>FEATPOST</tt> macro that produces
	  a rectangular prism (cuboid).
	</p>
	<p>
	  <figure>
	    <eps file="../allps/kindofcube.1">
	    <img src="../allpng/kindofcube.1.gs.png">
	    <caption>Example that uses <tt>kindofcube</tt>.</caption>
	  </figure><label id="figkindofcube1">
	</p>
	<p>
	  The main variable of any three-dimensional figure is the
	  point of view. <tt>FEATPOST</tt> uses the variable <tt>f</tt>
	  as the point of view. <tt>Spread</tt> is another global
	  variable that controls the size of the projection.
	</p>
	<p>
	  Another example may be:
	  <tscreen>
	    <verb>
f := (13,7,3.5);
Spread := 35;
beginfig(1);
	numeric i, len, wang, reflen, frac, coordg;
	numeric fws, NumLines, inray, outay;
	path conepath, cira, cirb, ella, ellb, tuba, tubb, tubc;
	color axe, aroc, cubevertex, conecenter, conevertex;
	color allellaxe, ellaaxe, ellbaxe, pca, pea, pcb, peb;
	frac := 0.5;
	len := 0.6;
	wang := 60;
	axe := (0,cosd(90-wang),sind(90-wang));
	fws := 4;
	reflen := 0.2*fws;
	outay := 0.45*fws;
	inray := 0.7*outay;
	coordg := frac*fws;
	NumLines := 30;
	HoriZon := -0.5*fws;
	setthestage( 0.5*NumLines, 2*fws );
	cubevertex = (0.12*fws,-0.5*fws,-0.5*fws);
	kindofcube(false,true,cubevertex,180,0,0,0.65*fws,0.2*fws,fws);
	aroc := outay*(0,cosd(wang),sind(wang))-0.5*(0,fws,fws);
	rigorousdisc( inray, true, aroc, outay, axe*len );
	allellaxe := reflen*( 0.707, 0.707, 0 );
	ellaaxe := reflen*( 0.707, -0.707, 1.0 );
	ellbaxe := reflen*( -0.707, 0.707, 1.0 );
	conecenter = ( coordg, coordg, -0.5*fws );
	pca := ( coordg, -coordg, -0.5*fws );
	pcb := ( -coordg, coordg, -0.5*fws );
	pea := ( coordg, -coordg, 0.9*fws );
	peb := ( -coordg, coordg, 0.9*fws );
	cira := goodcirclepath( pca, blue, reflen );
	cirb := goodcirclepath( pcb, blue, reflen );
	ella := ellipticpath( pea, allellaxe, ellaaxe );
	ellb := ellipticpath( peb, allellaxe, ellbaxe );
	tuba := twocyclestogether( cira, ella );
	tubb := twocyclestogether( cirb, ellb );
	tubc := twocyclestogether( ella, ellb );
	unfill tubb; draw tubb;
	unfill tubc; draw tubc;
	unfill tuba; draw tuba;
	conevertex = conecenter + ( -3.5*reflen, 0, 0.8*fws );
	verygoodcone(false,conecenter,blue,reflen,conevertex);
endfig;
end.</verb></tscreen>where we find a <tt>rigorousdisc</tt>
	  and a <tt>verygoodcone</tt>
	  (the nicest <tt>FEATPOST</tt> macros) in addition to
	  <tt>setthestage</tt>, <tt>twocyclestogether</tt> and
	  <tt>kindofcube</tt>.
	</p>
	<p>
	  <figure>
	    <eps file="../allps/stageforthree.1">
	    <img src="../allpng/stageforthree.1.gs.png">
	    <caption>Example that uses <tt>rigorousdisc</tt> and
	      <tt>verygoodcone</tt>.</caption>
	  </figure><label id="figstageforthree">
	</p>
      <sect1>
	<heading>Mechanics</heading>
	<p>
	  The following is the sequence of steps necessary to produce
	  the diagrams.
	  <enum>
	    <item>There are two methods that one can use to instruct 
	      MetaPost to process the TeX parts of the input file with 
	      LaTeX instead of plain TeX.  One is to put a first
	      line containing just <code>%&latex</code> in 
	      the file.  This is the simplest method, but it doesn't
	      work on all systems.  Alternately, you can set the 
	      environment variable <tt>TEX</tt> to "<tt>latex</tt>",
	      like: <code>export TEX=latex</code> or run
	      <tt>mpost</tt> with a command-line option, like:
	      <code>mpost --tex=latex myfile.mp</code> (this text was
	      originally written by Brooks Moses) 
	      </item>
	    <item>
	      Make your MetaPost program know <tt>FEATPOST</tt> macros.
	      This may be accomplished in two ways:
	      <itemize>
		<item>
		  Insert the line:
		  <tscreen><verb>input featpost3Dplus2D;</verb></tscreen>at
		  the beginning
		  of your program and
		  then enter the shell command
		  <code>mpost yourprogram.mp</code> or
		</item>
		<item>
		  Pre-compile the macros into a <tt>mem</tt> file,
		  for instance:
		  <code>mpost -ini featpost</code> and then run your
		  program with
		  <code>mpost -mem featpost yourprogram.mp</code>
		</item>
	      </itemize>
	    </item>
	    <item>
	      If your program contains LaTeX text you may insert, at the
	      beginning, the lines
	      <tscreen><verb>
verbatimtex
\documentclass{article}
\begin{document}
etex</verb></tscreen>and at the end
	      <tscreen><verb>
verbatimtex
\end{document}
etex</verb></tscreen>or make use of the
<url url="http://www.ctan.org/tex-archive/graphics/metapost/contrib/macros/latexmp/" name="latexmp"> package.</item>
	    <item>
	      Pass the produced figure(s) through <tt>dvips</tt>
	      if they contain any text. You may do this with the provided
	      shell script <tt>laproof</tt>.
	      <code>laproof yourprogram N</code> where <tt>N</tt>
	      is the figure number. This
	      script produces an EPS figure that may be viewed with
	      <tt>gv</tt> but that should not be inserted in LaTeX
	      documents. Insert the original figure in LaTeX
	      documents. Instead of <tt>laproof</tt> you may just as
	      well use  <url
		url="http://www.ida.liu.se/~joned/download/mps2eps/"
		name="MPS2EPS"> or <url
		url="http://www.iee.et.tu-dresden.de/~fimmel/metapost.html"                name="metapost.pl">.
	    </item>
	  </enum>
	</p>
      </sect1>
      <sect1>
	<heading>Main Features</heading>
	<sect2>
	  <heading>Perspectives</heading>
	  <p>
	    <tt>FEATPOST</tt> can do three kinds of perspective.
	    <tscreen>
	      <verb>
f := ( 1.2 , 2.0 , 1.6 );
Spread := 75;

V1 := (1,1,1);
V2 := (-1,1,1);
V3 := (-1,-1,1);
V4 := (1,-1,1);
V5 := (1,1,-1);
V6 := (-1,1,-1);
V7 := (-1,-1,-1);
V8 := (1,-1,-1);
makeface1(1,2,3,4);makeface2(5,6,7,8);
makeface3(1,2,6,5);makeface4(2,3,7,6);
makeface5(3,4,8,7);makeface6(4,1,5,8);
makeline1(1,7);makeline2(2,8);
makeline3(3,5);makeline4(4,6);

beginfig(1);
  ParallelProj := true;
  SphericalDistortion := false;
  draw_all_test(red,true);
endfig;

beginfig(2);
  ParallelProj := false;
  SphericalDistortion := false;
  draw_all_test(green,true);
endfig;

beginfig(3);
  ParallelProj := false;
  SphericalDistortion := true;
  PrintStep := 5;
  draw_all_test(blue,true);
endfig;

end;</verb>
	    </tscreen>
	  </p>
	  <p>
	    <figure>
	      <eps file="../allps/cubicfigures.1">
	      <img src="../allpng/cubicfigures.1.gs.png">
	      <caption>Orthogonal perspective.</caption>
	    </figure><label id="figcubicfigures1">
	  </p>
	  <p>
	    <figure>
	      <eps file="../allps/cubicfigures.2">
	      <img src="../allpng/cubicfigures.2.gs.png">
	      <caption>Rigorous perspective.</caption>
	    </figure><label id="figcubicfigures2">
	  </p>
	  <p>
	    <figure>
	      <eps file="../allps/cubicfigures.3">
	      <img src="../allpng/cubicfigures.3.gs.png">
	      <caption>Fish-eye perspective.</caption>
	    </figure><label id="figcubicfigures3">
	  </p>
	</sect2>
	<sect2>
	  <heading>From 3D to 2D</heading>
	  <p>
	    The most important macro is <tt>rp</tt> that converts 3D points
	    to two-dimensional (2D) rigorous, orthogonal
	    or fish-eye projections. To draw a line in
	    3D-space try
	    <tscreen><verb>draw rp(a)--rp(b);</verb></tscreen>where
	    <tt>a</tt> and <tt>b</tt> are points in space
	    (of <tt>color</tt> type).
	    But if you're going for fish-eye it's better to
	    <tscreen><verb>draw pathofstraightline(a,b);</verb></tscreen>If
	    you don't know, leave it as
	    <tscreen><verb>drawsegment(a,b);</verb></tscreen>
	  </p>
	</sect2>
	<sect2>
	  <heading>Angles</heading>
	  <p>
	    When <tt>FEATPOST</tt> was created its main ability was
	    to mark and to calculate angles. This is done with the
	    macros <tt>angline</tt> and <tt>getangle</tt> as in the
	    following program:
	    <tscreen>
	      <verb>
f := (5,3.5,1);
beginfig(2);
  cartaxes(1,1,1);
  color va, vb, vc, vd;
  va = (0.29,0.7,1.0);
  vb = (X(va),Y(va),0);
  vc = N((-Y(va),X(va),0));
  vd = (0,Y(vc),0);
  drawarrow rp(black)--rp(va);
  draw rp(black)--rp(vb)--rp(va) dashed evenly;
  draw rp(vc)--rp(vd) dashed evenly;
  drawarrow rp(black)--rp(vc);
  squareangline( va, vc, black, 0.15 );
  angline(va,red,black,0.75,decimal getangle(va,red),lft);
endfig;</verb>
	    </tscreen><figure>
	      <eps file="../allps/cartaxes.2">
	      <img src="../allpng/cartaxes.2.gs.png">
	      <caption>Example that uses <tt>cartaxes</tt>,
		<tt>angline</tt> and <tt>getangle</tt>.</caption>
	    </figure><label id="figcartaxes2">
	  </p>
	</sect2>
	<sect2>
	  <heading>Intersections</heading>
	  <p>
	    The most advanced feature of <tt>FEATPOST</tt> is the
	    ability to calculate the intersections of planar and
	    convex polygons<footnote>Unfortunately, this is also the
	    most "bugged" feature.</footnote>. It can draw the visible
	    part of arbitrary sets of polygons as in
	    the following program:
	    <tscreen>
	      <verb>
numeric phi;
phi = 0.5*(1+sqrt(5));
V1 := ( 1, phi,0);V2 := (-1, phi,0);
V3 := (-1,-phi,0);V4 := ( 1,-phi,0);
V5 := (0, 1, phi);V6 := (0,-1, phi);
V7 := (0,-1,-phi);V8 := (0, 1,-phi);
V9 := ( phi,0, 1);V10:= ( phi,0,-1);
V11:= (-phi,0,-1);V12:= (-phi,0, 1);
makeface1(1,2,3,4);makeface2(5,6,7,8);
makeface3(9,10,11,12);
beginfig(1);
  sharpraytrace;
endfig;
end</verb></tscreen>
	  </p>
	  <p>
	    <figure>
	      <eps file="../allps/sharpraytrace.1">
	      <img src="../allpng/sharpraytrace.1.gs.png">
	      <caption>Example that uses <tt>sharpraytrace</tt>.</caption>
	    </figure><label id="figsharpraytrace">
	  </p>
	</sect2>
	<sect2>
	  <heading>Coming back to 3D from 2D</heading>
	  <p>
	    It is now possible to do an "automatic perspective tuning"
	    with the aid of macro <tt>photoreverse</tt> which is under
	    development. Please, refer to example
	    <tt>photoreverse.mp</tt> and to <url url="http://matagalatlante.org/nobre/hyt/technicaldrawfromphoto.html" name="FeatPost Deeper Technicalities">.
	  </p>
	  <p>
	    <figure>
	      <eps file="../alleps/photoreverse.1.eps">
	      <img src="../allpng/photoreverse.1.gs.png">
	      <caption>Example that uses <tt>photoreverse</tt>. It may
		not work when vertical lines are not vertical in
		average on the photo.</caption>
	    </figure><label id="figphotoreverse">
	  </p>
	  <sect3>
	    <heading>Coming back to 3D from 1D</heading>
	    <p>
	      Using the same algorithm of <tt>photoreverse</tt>, the
	      macro <tt>improvertex</tt> allows one to approximate a
	      point in 3D-space with given distances from three other
	      points (an initial guess is required).
	    </p>
	  </sect3>
	</sect2>
      </sect1>
    </sect>
    <sect>
      <heading>Reference Manual</heading>
	<p>
	  Some words about notation.
	  The meaning of macro, function, procedure and routine is the same.
	  Global variables are presented like this:
	  <tscreen>
	    <verb>
vartype var, anothervar
anothervartype yetanothervar</verb>
	  </tscreen>Explanation of var, anothervar and
	  yetanothervar. vartype can be any one of
	  MetaPost types but the meaning
	  of <tt>color</tt> is a three-dimensional point or vector, not an
	  actual color like yellow, black or white. If the meaning is
	  an actual color then the type will be <tt>colour</tt>.
	  All global variables have default values.
	</p>
	<p>
	  Functions are presented like this:
	  <itemize>
	    <item>returntype <bf>function()</bf>
	      Explanation of function. returntype can be any one of MetaPost
	      types plus global, draw or drawlabel.
	      global means that the function
	      changes some of the global variables. draw means that
	      the function
	      changes the currentpicture. drawlabel means that the
	      function changes
	      the currentpicture and adds text to it.
	      <enum>
		<item> <tt>type1</tt>
		  Explanation of the first argument. The type of
		  one argument can be any one
		  of MetaPost types plus <tt>suffix</tt> or
		  <tt>text</tt>.</item>
		<item> <tt>type2</tt>
		  Explanation of the second argument.
		  There is the possibility that the
		  function has no arguments. In that case the
		  function is presented like
		  "returntype <bf>function</bf>".</item>
		<item> Etc.</item>
	      </enum>
	    </item>
	  </itemize>
	</p>
      <sect1>
	<heading>Global variables</heading>
	<p>
	  <tscreen>
	    <verb>
boolean ParallelProj
boolean SphericalDistortion</verb>
	  </tscreen>Kind of projection calculated by <tt>rp</tt>.
	  By default projections
	  are rigorous but if <tt>ParallelProj</tt> is set
	  <tt>true</tt> then
	  parallel lines remain parallel in the projection.
	  It is the same as
	  placing the point of view infinitely far without loosing
	  sight.
	  If <tt>SphericalDistortion</tt> is set <tt>true</tt>
	  there will be a
	  distortion coming from: (i) the projection being done
	  on a sphere of
	  center <tt>f</tt> and (ii) this sphere being plaited
	  onto the paper page.
	</p>
	<p>
	  <figure>
	    <eps file="../allps/rigorousdiscSD.1">
	    <img src="../allpng/rigorousdiscSD.1.gs.png">
	    <caption>Figure that uses <tt>SphericalDistortion:=true</tt>
	      and <tt>rigorousdisc</tt>.</caption>
	  </figure><label id="sphericaldisc">
	</p>
	<p>
	  <tscreen>
	    <verb>
color f, viewcentr</verb>
	  </tscreen>The point of view is <tt>f</tt>. The plane or sphere
	  of projection contains
	  the center of view <tt>viewcentr</tt>.
	  The axis parallel to zz that contains the
	  <tt>viewcentr</tt> is projected on a vertical line.
	  <tscreen>
	    <verb>
numeric Spread
pair ShiftV, OriginProjPagePos
numeric PageWidth
numeric PageHeight</verb>
	  </tscreen>These variables control
	  the placement of the projection on the
	  paper. <tt>Spread</tt> is the magnification
	  and <tt>ShiftV</tt> is the position of the
	  <tt>viewcentr</tt> projection on the
	  paper. But, if at some point in your program you introduce
	  <tt>produce_auto_scale</tt> then the
	  <tt>currentpicture</tt> will be
	  centered at <tt>OriginProjPagePos</tt>
	  and scaled to fit inside a rectangle of
	  <tt>PageWidth</tt> by <tt>PageHeight</tt>.
	  <tscreen>
	    <verb>
color V[]
color L[]p[]
color F[]p[]</verb>
	  </tscreen>Vertexes, lines and faces.
	  The idea here is to draw
	  polygons and/or arbitrary lines in 3D space.
	  Defining the polygons and
	  the lines can be a bit tedious as <tt>FEATPOST</tt> is not
	  interactive. First, one defines a list of the
	  vertexes (<tt>V[]</tt>) that define the
	  polygons and/or the lines.
	  There is a list of polygons and a list of
	  lines. Each polygon (<tt>F[]p[]</tt>) or
	  line (<tt>L[]p[]</tt>) is itself a list of vertexes.
	  All vertexes of the same poligon should belong
	  to the same plane.
	  <tscreen>
	    <verb>
numeric NL
numeric npl[]
numeric NF
numeric npf[]</verb>
	  </tscreen>Number of lines, number of vertexes of each line,
	  number of faces, number of vertexes of each face.
	  <tscreen>
	    <verb>
numeric PrintStep</verb>
	  </tscreen>
	  <tt>Printstep</tt> is the size of iterative jumps
	  along lines. Used by
	  <tt>lineraytrace</tt>, <tt>faceraytrace</tt> and
	  <tt>pathofstraightline</tt>.
	  Big <tt>Printstep</tt>s make fast raytracings.
	  <tscreen>
	    <verb>
boolean FCD[]
colour TableC[]
numeric TableColors
numeric FC[]
colour HigColor
colour SubColor
color LightSource</verb>
	  </tscreen><tt>FCD</tt> means "face color defined". The
	  <tt>draw_invisible</tt> macro draws
	  polygons in colour, if it is defined. The colour must be
	  selected from the table of colours <tt>TableC</tt> that has
	  as many as <tt>TableColors</tt>. The colour <tt>FC</tt>
	  of each polygon will depend on its position relatively to
	  <tt>LightSource</tt> where we suppose there is a lamp that
	  emits light coloured <tt>HigColor</tt>. Furthermore the
	  colour of each polygon may be modified if it belongs to a
	  functional or parametric surface. In this case, if we are
	  looking at the polygon from below than <tt>SubColor</tt> is
	  subtracted from its colour.
	  <tscreen>
	    <verb>
numeric RopeColorSeq[]
numeric RopeColors</verb>
	  </tscreen>
	  These are used by <tt>ropepattern</tt>.
	  <tscreen>
	    <verb>
numeric TDAtiplen
numeric TDAhalftipbase
numeric TDAhalfthick</verb>
	  </tscreen>
	  These control the shape of Three-Dimensional Arrows.
	  <tscreen>
	    <verb>
boolean ShadowOn
numeric HoriZon</verb>
	  </tscreen>
	  When <tt>ShadowOn</tt> is set <tt>true</tt>, some objects can
	  cast a black shadow on a horizontal plane of <tt>Z</tt>
	  coordinate equal to <tt>HoriZon</tt> (an area from
	  this plane may be drawn with <tt>setthestage</tt>) as if
	  there is a punctual source of light at
	  <tt>LightSource</tt>.
	  The macros that can produce shadows, in addition to their
	  specific production, are<itemize>
	    <item><tt>emptyline</tt></item>
	    <item><tt>rigorousdisc</tt></item>
	    <item><tt>verygoodcone</tt></item>
	    <item><tt>tropicalglobe</tt></item>
	    <item><tt>whatisthis</tt></item>
	    <item><tt>kindofcube</tt></item>
	    <item><tt>draw_all_test</tt></item>
	    <item><tt>fill_faces</tt></item>
	    <item><tt>positivecharge</tt></item>
	  </itemize>
	  All macros that contain <bf>shadow</bf> in their name
	  calculate the location of shadows (using <tt>cb</tt>).
	  <tscreen>
	    <verb>
path VGAborder</verb>
	  </tscreen>
	  This path and the macro <tt>produce_vga_border</tt> are
	  meant to help you clip the <tt>currentpicture</tt> to a 4:3
	  rectangle as in a movie frame.
	  <tscreen>
	    <verb>
pair PhotoPair[]
color PhotoPoint[]
numeric PhotoMarks</verb>
	  </tscreen>
	  These are used by <tt>photoreverse</tt>.
	  <tscreen>
	    <verb>
pen ForePen, BackPen
path CLPath
numeric NCL</verb>
	  </tscreen>
	  These are used by <tt>closedline</tt>.
	</p>
      </sect1>
      <sect1>
	<heading>Definitions</heading>
	<p>
	  <itemize>
	    <item>global makeline@&num;( text1)</item>
	    <item>global makeface@&num;( text1)</item>
	  </itemize>
	  Both of these functions ease the task of
	  defining lines and polygons. Just
	  provide a list of vertexes in the right
	  sequence for each polygon and/or
	  line. Suppose a tetrahedron
	  <tscreen><verb>
V3:=(+1,-1,-1);V2:=(-1,+1,-1);
V4:=(+1,+1,+1);V1:=(-1,-1,+1);
makeface2(1,2,3);makeface3(1,2,4);
makeface1(3,4,1);makeface4(3,4,2);</verb></tscreen>The
	  number in the last makeface or last
	  makeline procedure name must be the
	  number of polygons or lines. All polygons and lines from 1 upto this
	  number must be defined but the sorting may be any of your liking.
	</p>
      </sect1>
      <sect1>
	<heading>Macros</heading>
	<sect2>
	  <heading>Very Basic Macros</heading>
	  <p>
	    <itemize>
	      <item>numeric <bf>X()</bf>
		Returns the first coordinate of a point or vector (of
		color type). Replaces <tt>redpart</tt>.
	      </item>
	      <item>numeric <bf>Y()</bf>
		Returns the second coordinate of a point or vector.
		Replaces <tt>greenpart</tt>.
	      </item>
	      <item>numeric <bf>Z()</bf>
		Returns the second coordinate of a point or vector.
		Replaces <tt>bluepart</tt>.
	      </item>
	      <item>draw <bf>produce_auto_scale</bf>
		The currentpicture is centered in, and adjusted
		to the size of, an A4
		paper page. This avoids the control of <tt>Spread</tt> and
		<tt>ShiftV</tt>.
	      </item>
	      <item>string <bf>cstr()</bf> Converts a color into its
		string. Usefull in combination with <tt>getready</tt>.
	      </item>
	      <item>string <bf>bstr()</bf> Converts a boolean 
	        expression into its
		string. Usefull in combination with <tt>getready</tt>.
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Vector Calculus</heading>
	  <p>
	    <itemize>
	      <item>color <bf>N()</bf> Unit vector. Returns
		<tt>black</tt> (the null vector) when the argument has
		null norm. The "N" means "normalized".</item>
	      <item>numeric <bf>cdotprod()</bf> Dot product of two
		vectors.</item>
	      <item>color <bf>ccrossprod()</bf> Cross product of two
		vectors.</item>
	      <item>numeric <bf>ndotprod()</bf> Cossine of the angle
		beetween two vectors.</item>
	      <item>color <bf>ncrossprod()</bf> Normalized cross product
		of twovectors.</item>
	      <item>numeric <bf>conorm()</bf> Euclidean norm of a
		vector.</item>
	      <item>numeric <bf>getangle()</bf> Angle beetween two
		vectors.</item>
	      <item>pair <bf>getanglepair()</bf> Orientation angles
		of a vector. The first angle (<tt>xpart</tt>) is
		measured beetween the vector projection on the <tt>XY</tt>
		plane and the <tt>X</tt> axis. The second angle
		(<tt>ypart</tt>)is measured
		beetween the vector and its projection on the <tt>XY</tt>
		plane. This may be usefull to find the arguments of
		<tt>kindofcube</tt></item>
	      <item>color <bf>eulerrotation()</bf> Three-dimensional
		rotation of a vector. See the figure explaining
		<tt>kindofcube</tt> to visualize the following
		movement: (i) grab the <tt>X</tt> component of the
		vector; (ii) rotate it on the <tt>XY</tt> plane as
		much as the first argument; 
		(iii) raise it up as much as the second argument; and
		(iv) turn it around as much as the third argument.
 		<enum>
		  <item><tt>numeric</tt> Angle of rotation around the
		    <tt>Z</tt> component.</item>
		  <item><tt>numeric</tt> Angle of rotation around the
		    rotated <tt>Y</tt> component.</item>
		  <item><tt>numeric</tt> Angle of rotation around the
		    two times rotated <tt>X</tt> component.</item>
		  <item><tt>color</tt> Vector to be rotated.</item>
		</enum>
	      </item>
	      <item>color <bf>randomfear</bf> Generates a randomly
		oriented unit vector.
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Projection Macros</heading>
	  <p>
	    <itemize>
	      <item>pair <bf>rp()</bf> Converts spatial positions into
		planar positions on the paper page. The conversion
		considers the values of the following global
		variables: <tt>viewcentr</tt>,
		<tt>ParallelProj</tt>, <tt>SphericalDistortion</tt>,
		<tt>Spread</tt> and <tt>ShiftV</tt>. When both
		<tt>ParallelProj</tt> and <tt>SphericalDistortion</tt>
		are <tt>false</tt> it won't work if either (i) the
		vectors <tt>f-viewcentr</tt> and <tt>f-R</tt> are
		perpendicular (<tt>R</tt> is the argument) or (ii)
		<tt>f</tt> and <tt>viewcentr</tt> share the same
		<tt>X</tt> and <tt>Y</tt> coordinates. <enum>
		  <item><tt>color</tt> Spatial position.</item>
		</enum>
	      </item>
	      <item>color <bf>cb()</bf> Calculates the position of the
		shadow of a point. Uses <tt>HoriZon</tt> and
		<tt>LightSource</tt>.
		<enum>
		  <item><tt>color</tt> Point position.</item>
		</enum>
	      </item>
	      <item>color <bf>projectpoint()</bf> Calculates the
		intersection beetween a plane and a straight
		line. The plane contains a given point and is
		perpendicular to the line connecting the
		<tt>LightSource</tt> and this same point.
		The line is defined by another given point and the
		<tt>LightSource</tt>. Summary: <tt>projectpoint</tt>
		returns the projection of the second argument on a
		plane that contains the first argument. Can be used to
		draw shadows cast on generic planes.
		<enum>
		  <item><tt>color</tt> Origin of the projection plane.</item>
		  <item><tt>color</tt> Point to be projected.</item>
		</enum>
	      </item>
	      <item>color <bf>lineintersectplan()</bf> Calculates the
		intersection beetween a generic plane and a straight
		line. The plane contains a given point and is
		perpendicular to a given vector.
		The line contains a given point and is parallel to 
		a given vector. 
		<enum>
		  <item><tt>color</tt> Point of the line.</item>
		  <item><tt>color</tt> Vector parallel to the line.</item>
		  <item><tt>color</tt> Point of the projection plane.</item>
		  <item><tt>color</tt> Vector perpendicular to the 
		    projection plane.</item>
		</enum>
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Plain Basic Macros</heading>
	  <p>
	    <itemize>
	      <item>draw <bf>signalvertex()</bf> Draws a dot
		sized inversely proportional to its distance from
		the viewpoint <tt>f</tt>.
		<enum>
		  <item><tt>color</tt> Location.</item>
		  <item><tt>numeric</tt> Factor of proportionality
		  ("size of the dot").</item>
		  <item><tt>colour</tt> Colour of the dot.</item>
		</enum>
		<figure>
		  <eps file="../allps/torus.1">
		  <img src="../allpng/torus.1.gs.png">
		  <caption>Figure that uses <tt>signalvertex</tt>.</caption>
		</figure>
	      </item>
	      <item>path <bf>pathofstraightline()</bf> When using
		<tt>SphericalDistortion:=true</tt>, straight lines
		look like curves. This macro returns the curved path
		of a straight line beetween two points. This path will
		have a greater <tt>length</tt> ("time") when
		<tt>PrintStep</tt> is made smaller.</item>
	      <item>draw <bf>drawsegment()</bf> Alternative 
	        <tt>pathofstraightline</tt> that avoids the
		calculation of all the intermediate points when 
		<tt>SphericalDistortion:=false</tt>.
	      <item>drawlabel <bf>cartaxes()</bf>
		Cartesean axis with prescribed lenghtes and apropriate labels.
		<enum>
		  <item><tt>numeric</tt> Length of the <tt>X</tt> axis.</item>
		  <item><tt>numeric</tt> Length of the <tt>Y</tt> axis.</item>
		  <item><tt>numeric</tt> Length of the <tt>Z</tt> axis.</item>
		</enum>
	      </item>
	      <item>draw <bf>emptyline()</bf> This procedure produces
		a sort of a tube that can cross over itself. It
		facilitates the drawing of, for instance, thick
		helical curves but it won't
		look right if the curves are drawn getting apart from
		the point of view. Please, accept this inconveniance.
		As like many other <tt>FEATPOST</tt> macros this one
		can produce visually correct diagrams only in limited
		conditions. Can cast a shadow.
		<enum>
		  <item><tt>boolean</tt> Choose <tt>true</tt> to join
		    this line with a previously drawn line.</item>
		  <item><tt>numeric</tt> Factor of proportionality
		    ("diameter of the tube"). The tubes are just
		    sequences of dots drawn by <tt>signalvertex</tt>.</item>
		  <item><tt>colour</tt> Colour of the tube border.</item>
		  <item><tt>colour</tt> Colour of the tube.</item>
		  <item><tt>numeric</tt> Total number of dots on the
		    tube line.</item>
		  <item><tt>numeric</tt> Fraction of the tube diameter
		    that is drawn with the tube colour.</item>
		  <item><tt>numeric</tt> This is the number of dots
		    that are redrawn with the colour of the tube for
		    each drawn dot with the color of the tube
		    border. Usually 1 or 2 are enough.</item>
		  <item><tt>text</tt> This is the name a function
		    that returns a 3D point of the line for each value
		    of a parameter in beetween 0 and 1.
		    </item>
		</enum>
		<figure>
		  <eps file="../allps/joinedemptylines.1">
		  <img src="../allpng/joinedemptylines.1.gs.png">
		  <caption>Figure that uses <tt>emptyline</tt>.
		    The junction point of two different lines is indicated
		    by an arrow. Note the unperfection on the top
		    right, inside the upper turn. </caption>
		</figure><label id="joinedemptylines">
	      </item>
	      <item>draw <bf>closedline()</bf> This procedure produces
		a tube that can cross over itself. It
		facilitates the drawing of, for instance, thick
		helical curves but it won't
		look right as its thickness does not change with the
		distance from the point of view. The drawing is
		entirely done in two dimensions, so the tube diameter
		depends on the global variables <tt>ForePen</tt> and
		<tt>BackPen</tt>. There can be more than one
		line in a figure but all get the same diameter.
		When calling <tt>closedline()</tt> in different
		figures of the same program you must reinitialize both
		<tt>NCL</tt> and <tt>Nobjects</tt> (because
		<tt>closedline()</tt> uses <tt>getready()</tt>).
		<enum>
		  <item><tt>boolean</tt> Value of "the line is closed".
		    </item>		
		  <item><tt>numeric</tt> Total number of path segments
		    on the tube line.</item>
		  <item><tt>numeric</tt> Use 0.5 or more.</item>
		  <item><tt>numeric</tt> Use 0.75 or more.</item>
		  <item><tt>text</tt> This is the name of a function
		    that returns a 3D point of the line for each value
		    of a parameter in beetween 0 and 1.
		    </item>
		</enum>
	      </item>
	      <item>drawlabel <bf>angline()</bf>
	      Draws an arch beetween two straight lines with a
	      common point and places a label
	      near the middle of the arch (marks an
	      angle). Note that the arch is not circular. 
		<enum>
		  <item><tt>color</tt> Point of one line.</item>
		  <item><tt>color</tt> Point ot the other line.</item>
		  <item><tt>color</tt> Common point.</item>
		  <item><tt>numeric</tt> Distance beetween the arch and
		    the common point.</item>
		  <item><tt>picture</tt> Label.</item>
		  <item><tt>suffix</tt> Position of the label relatively
		    to the middle of the arch. May
		    be one of <tt>lft, rt, top, bot, ulft, urt,
		      llft</tt> and <tt>lrt</tt>.</item>
		</enum>
	      </item>
	      <item>drawlabel <bf>anglinen()</bf>
		The same as the previous function but the
		sixth argument is numeric:
		0=<tt>rt</tt>;
		1=<tt>urt</tt>;
		2=<tt>top</tt>;
		3=<tt>ulft</tt>;
		4=<tt>lft</tt>;
		5=<tt>llft</tt>;
		6=<tt>bot</tt>;
		7=<tt>lrt</tt>;
		any other number places the label
		on the middle of the arch.</item>
	      <item>draw <bf>squareangline()</bf>
		This is supposed to mark 90 degree angles
		but works for any angle value.
		<enum>
		  <item><tt>color</tt> Point of one line.</item>
		  <item><tt>color</tt> Point ot the other line.</item>
		  <item><tt>color</tt> Common point.</item>
		  <item><tt>numeric</tt> Distance beetween the "arch"
		    and the common point.</item>
		</enum>
	      </item>
	      <item>path <bf>rigorouscircle()</bf>
		3D circle. The total "time" of this path is 8. This
		small number makes it easy to select parts of the
		path. The circle is drawn using the
		"left-hand-rule". If you put your left-hand thumb
		parallel the circle axis then the other left-hand
		fingers curl in the same sense as the circle
		path. This path allways starts, approching the view
		point, from a point on a diameter of the
		circle that projects orthogonaly to its axis, and
		rotating around the axis in the way of the left-hand-rule.
		<enum>
		  <item><tt>color</tt> Center of the circle.</item>
		  <item><tt>color</tt> Direction orthogonal to the
		    circle (circle axis).</item>
		  <item><tt>numeric</tt> Radius of the circle.</item>
		</enum>
		<figure>
		  <eps file="../allps/anglinerigorouscircle.1">
		  <img src="../allpng/anglinerigorouscircle.1.gs.png">
		  <caption>Figure that uses <tt>anglinen</tt>
		    and <tt>rigorouscircle</tt>.</caption>
		</figure>
	      </item>
	      <item>draw <bf>tdarrow()</bf> Draws a flat arrow that
		begins at the first argument and ends at the second.
		The shape of the arrow is controled by the global
		variables <tt>TDAtiplen, TDAhalftipbase, TDAhalfthick</tt>.
	      </item>
	      <item>path <bf>twocyclestogether()</bf> This macro
		allows you to draw any solid that has no vertexes
		and that has two, exactly two, planar cyclic edges.
		In fact, it doesn't need to be a solid. Just
		provide the pathes of both cyclic edges as arguments
		but note that the returned path is polygonal.
		In order to complete
		the drawing of this solid you have to choose one of
		the edges to be drawn immediatly afterwards. This is
		done automatically by the <tt>whatisthis</tt> macro
		for the case of two parallel and concentric ellipses.
	      </item>
	      <item>path <bf>ellipticpath()</bf> Produces an elliptic
		path in 3D space.
		<enum>
		  <item><tt>color</tt> Position of the center.</item>
		  <item><tt>color</tt> Major or minor axis.</item>
		  <item><tt>color</tt> The other axis.</item>
		</enum>
	      </item>
	      <item>drawlabel <bf>labelinspace()</bf> Draw some 2D
		<tt>picture</tt> on some 3D plane (only when
		<tt>ParallelProj:=true</tt>).
		<enum>
		  <item><tt>color</tt> Position for the lower-left
		  corner. </item>
		  <item><tt>color</tt> Orientation of the picture's
		  bottom edge.</item>
		  <item><tt>color</tt> Orientation of the picture's
		  letf edge.</item>
		  <item><tt>text</tt> 2D picture's name.</item>
		</enum>
		<figure>
		  <eps file="../allps/labelinspace.1">
		  <img src="../allpng/labelinspace.1.gs.png">
		  <caption>Example that uses <tt>labelinspace</tt>.</caption>
		</figure>
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Standard Objects</heading>
	  <p>
	    <itemize>
	      <item>path <bf>goodcirclepath()</bf>
		Another 3D circle macro. More rigorous
		than <tt>rigorouscircle</tt> but when
		the direction ortogonal to the circle is almost
		orthogonal to the line <tt>viewpoint--center</tt>
		it doesn't work correctly.
		The total "time" of this path is 36.
		<enum>
		  <item><tt>color</tt> Center of the circle.</item>
		  <item><tt>color</tt> Direction ortogonal to
		    the circle.</item>
		  <item><tt>numeric</tt> Radius of the
		    circle.</item>
		</enum>
	      </item>
	      <item>draw <bf>spatialhalfsfear()</bf> An
		hemisphere. Doesn't work with <tt>f</tt> inside it.
		<enum>
		  <item><tt>color</tt> Center.</item>
		  <item><tt>color</tt> Vector ortogonal to
		    the frontier circle and pointing
		    out of the concavity.</item>
		  <item><tt>numeric</tt> Radius of the
		    (hemi)sphere.</item>
		</enum>
	      </item>
	      <item>path <bf>spatialhalfcircle()</bf>
		And yet another 3D circle macro. Only the visible or the hidden
		part. This is usefull to mark sections of
		cylinders or spherical major circles.
		<enum>
		  <item><tt>color</tt> Center of the circle.</item>
		  <item><tt>color</tt> Direction ortogonal to the
		    circle.</item>
		  <item><tt>numeric</tt> Radius of the circle.</item>
		  <item><tt>boolean</tt> The visible part is selected with
		    <tt>true</tt> and the hidden
		    with <tt>false</tt>.</item>
		</enum>
	      </item>
	      <item>draw <bf>rigorousdisc()</bf>
		3D opaque cylinder with/without a hole. Can cast a
		shadow (without the hole).
		<enum>
		  <item><tt>numeric</tt> Ray of an axial hole.</item>
		  <item><tt>boolean</tt> Option for completly opaque cylinder
		    (<tt>true</tt>) or partial
		    pipe (<tt>false</tt>) when there is no hole. When
		    the cylinder has an hole this option should be
		    <tt>true</tt>.</item>
		  <item><tt>color</tt> Center of one circular base.</item>
		  <item><tt>numeric</tt> Radius of both circular bases.</item>
		  <item><tt>color</tt> Vector that defines the length and
		    orientation of the
		    cylinder. The addition the third and fifth
		    arguments should give the
		    position of the center of the other circular base.
		  </item>
		</enum>
	      </item>
	      <item>draw <bf>verygoodcone()</bf> 3D cone. Can cast a shadow.
		<enum>
		  <item><tt>bolean</tt> Option to draw dashed evenly
		    the invisible edge (<tt>true</tt>) or not
		    (<tt>false</tt>).</item>
		  <item><tt>color</tt> Center of the circular base.</item>
		  <item><tt>color</tt> Direction ortogonal to the
		    circular base.</item>
		  <item><tt>numeric</tt> Radius of the circular base.</item>
		  <item><tt>color</tt> Position of the vertex</item>
		</enum>
	      </item>
	      <item>path <bf>rigorousfearpath()</bf>
		3D sphere. Simple but hard.
		<enum>
		  <item><tt>color</tt> Center position.</item>
		  <item><tt>numeric</tt> Radius.</item>
		</enum>
	      </item>
	      <item>draw <bf>tropicalglobe()</bf> Globe with
		minor circles. Can cast a shadow.
		<enum>
		  <item><tt>numeric</tt> Number of marked latitudes.</item>
		  <item><tt>color</tt> Center position.</item>
		  <item><tt>numeric</tt> Radius</item>
		  <item><tt>color</tt> Axis orientation.</item>
		</enum>
		<figure>
		  <eps file="../allps/tropicalglobe.1">
		  <img src="../allpng/tropicalglobe.1.gs.png">
		  <caption>Figure that uses <tt>tropicalglobe</tt>.
		  </caption>
		</figure>
	      </item>
	      <item>draw <bf>whatisthis()</bf> An elliptic
		frustum. Both edges are elliptic an have the same
		orientation but one may be greater than the other.
		Can cast a shadow.
		<enum>
		  <item><tt>color</tt> Reference edge center.</item>
		  <item><tt>color</tt> Major or minor axis.</item>
		  <item><tt>color</tt> The other axis.</item>
		  <item><tt>numeric</tt> Length of the original
		    cylinder.</item>
		  <item><tt>numeric</tt> Edges axis length ratio.</item>
		</enum>
	      </item>
	      <item>draw <bf>kindofcube()</bf> Polyhedron with six
		orthogonal faces (cuboid).
		<enum>
		  <item><tt>boolean</tt> Also draw the invisible edges
		    <tt>dashed evenly</tt> (<tt>true</tt>) or do not.</item>
		  <item><tt>boolean</tt> The reference point may be a
		  vertex (<tt>true</tt>) or the center(<tt>false</tt>).</item>
		  <item><tt>color</tt> Reference point.</item>
		  <item><tt>numeric</tt> Alpha1.</item>
		  <item><tt>numeric</tt> Alpha2.</item>
		  <item><tt>numeric</tt> Alpha3.</item>
		  <item><tt>numeric</tt> L1. Length of the first side.</item>
		  <item><tt>numeric</tt> L2. Length of the second side.</item>
		  <item><tt>numeric</tt> L3. Length of the third side.</item>
		</enum>
		These arguments are represented in the next figure.
		<figure>
		  <eps file="../allps/kindofcube.2">
		  <img src="../allpng/kindofcube.2.gs.png">
		  <caption>Figure that uses and explains
		    <tt>kindofcube</tt>. Note that the three indicated
		    angles may be used as arguments of <tt>eulerrotation</tt>.</caption>
		</figure><label id="kindofcube2">
	      </item>
	      <item>draw <bf>setthestage()</bf> Produces an horizontal
		square made of squares. Its <tt>Z</tt> coordinate is defined by
		<tt>HoriZon</tt>.
		<enum>
		  <item><tt>numeric</tt> Number of squares in each side.</item>
		  <item><tt>numeric</tt> Size of each side.</item>
		</enum>
	      </item>
	      <item>draw <bf>setthearena()</bf> Produces an horizontal
		circle made of circles. Its <tt>Z</tt> coordinate is defined by
		<tt>HoriZon</tt>. Due to the fact that the center of a
		circle is not on the center of its central perspective
		projection, this may look a bit strange.
		<enum>
		  <item><tt>numeric</tt> Number of circles on a
		  diameter.</item>
		  <item><tt>numeric</tt> Diameter.</item>
		</enum>
	      </item>
	      <item>draw <bf>smoothtorus()</bf> Toxic donut (not to be
		eaten). Produces an error message when <tt>f</tt> is
		close to the table.
		<enum>
		  <item><tt>color</tt> Center.</item>
		  <item><tt>color</tt> Direction orthogonal to the
		    torus plane.</item>
		  <item><tt>numeric</tt> Big ray.</item>
		  <item><tt>numeric</tt> Small ray.</item>
		</enum>
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Composed Objects</heading>
	  <p>
	    <itemize>
	    <item>draw <bf>positivecharge()</bf> Draws a sphere with a
	      plus or minus sign on the surface. The horizontal
	      segment of the sign is drawn on the horizontal plane
	      that contains the sphere center. The middle point of
	      this segment is on a vertical plane containing the
	      viewpoint.
	      <enum>
		<item><tt>boolean</tt> Selects the sign (<tt>true</tt>
		means positive).</item>
		<item><tt>color</tt> Position of the center.</item>
		<item><tt>numeric</tt> Sphere ray.</item>
	      </enum>
		<figure>
		  <eps file="../allps/positivecharge.1">
		  <img src="../allpng/positivecharge.1.gs.png">
		  <caption>Figure that uses <tt>positivecharge</tt>,
	      <tt>getready</tt> and <tt>doitnow</tt>.
		  </caption>
		</figure></item>
	    <item>draw <bf>simplecar()</bf> Draws a cuboid and four
	      discs in a configuration ressembling an automobile. The
	      first three arguments of <tt>simplecar</tt> are the same
	      as the the last seven arguments of <tt>kindofcube</tt>
	      but grouped in colors.
	      <enum>
		<item><tt>color</tt> Center of the cuboid that
	      constitutes the body of the car..</item>
		<item><tt>color</tt> Angles defining the orientation
	      of the car (see <tt>kindofcube</tt>).</item>
		<item><tt>color</tt> Dimensions of the car.</item>
		<item><tt>color</tt> Characteristics of the front
	      wheels. <tt>redpart</tt>-distance from the
	      front. <tt>greenpart</tt>-width of the front wheels (length
	      of the cylinders). <tt>bluepart</tt>-wheel ray.</item>
		<item><tt>color</tt> Same as above for the rear wheels</item>
	      </enum>
		<figure>
		  <eps file="../allps/simplecar.1">
		  <img src="../allpng/simplecar.1.gs.png">
		  <caption>Figure that uses <tt>setthearena</tt> and
	      <tt>simplecar</tt>.
		  </caption>
		</figure></item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Shadow Pathes</heading>
	  <p>
	    <itemize>
	    <item>draw <bf>signalshadowvertex()</bf> Draws the
	      shadow of a <tt>signalvertex</tt> dot.
	      <enum>
		<item><tt>color</tt> Location of the light-blocking dot.</item>
		<item><tt>numeric</tt> Factor of proportionality
		  ("size of the dot").</item>
		<item><tt>colour</tt> Colour of the dot.</item>
	      </enum>
	    </item>
	      <item>path <bf>ellipticshadowpath()</bf> Produces the
		shadow of an elliptic path.
		<enum>
		  <item><tt>color</tt> Position of the center.</item>
		  <item><tt>color</tt> Major or minor axis.</item>
		  <item><tt>color</tt> The other axis.</item>
		</enum>
	      </item>
	      <item>path <bf>circleshadowpath()</bf> Produces the
		shadow of a circle.
		<enum>
		  <item><tt>color</tt> Center of the circle.</item>
		  <item><tt>color</tt> Direction ortogonal to
		    the circle.</item>
		  <item><tt>numeric</tt> Radius of the
		    circle.</item>
		</enum>
	      </item>
	      <item>path <bf>rigorousfearshadowpath()</bf>
		3D sphere shadow.
		<enum>
		  <item><tt>color</tt> Center position.</item>
		  <item><tt>numeric</tt> Radius.</item>
		</enum>
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Differential Equations</heading>
	  <p>
	    Before we proceed, be aware that solving differential
	    equations (DE) is mainly an experimental activity. The most
	    probable result of a procedure that atempts to solve a DE
	    is garbage. The procedure may be unstable, the solution
	    may be littered with singularities or something may go
	    wrong. If you don't have a basic understanding of
	    differential equations then skip this section, please.
	  </p>
	  <p>
	    <itemize>
	      <item>path <bf>fieldlinepath()</bf> A vectorial field line is
		everywhere tangent to the field vectors.
		Two different parallel fields
		have the same field lines. So the field only
		constrains the direction of the field lines, not any kind
		of "speed" and, therefore, it is recommended to
		normalize the field before using this macro that
		contains a second-order Runge-Kutta method
		implementation.
		<enum>
		  <item><tt>numeric</tt> Total number of steps.</item>
		  <item><tt>color</tt> Initial position.</item>
		  <item><tt>numeric</tt> Step (arc)length.</item>
		  <item><tt>text</tt> Name of the function that
		    returns a field vector for each 3D position.</item>
		</enum>
	      </item>
	      <item>path <bf>trajectorypath()</bf> The acceleration of a
		particle in a conservative force field is equal to the
		ratio (conservative force)/(particle mass). The
		acceleration is also equal to the second order time
		derivative of the particle position. This produces a
		second order differential equation that we solve using a
		second-order Runge-Kutta method implementation.
		<enum>
		  <item><tt>numeric</tt> Total number of steps.</item>
		  <item><tt>color</tt> Initial position.</item>
		  <item><tt>color</tt> Initial velocity.</item>
		  <item><tt>numeric</tt> Time step.</item>
		  <item><tt>text</tt> Name of the function that
		    returns a (force/mass) vector for each 3D position.</item>
		</enum>
	      </item>
	      <item>path <bf>magnetictrajectorypath()</bf> The
		acceleration of a
		charged particle in a magnetic field is equal to the
		ratio (magnetic force)/(particle mass) but the magnetic
		force depends on both the velocity and the magnetic field. The
		acceleration is also equal to the second order time
		derivative of the particle position. This produces a
		second order differential equation that we solve using a
		fourth-order Runge-Kutta method implementation.
		<enum>
		  <item><tt>numeric</tt> Total number of steps.</item>
		  <item><tt>color</tt> Initial position.</item>
		  <item><tt>color</tt> Initial velocity.</item>
		  <item><tt>numeric</tt> Time step.</item>
		  <item><tt>text</tt> Name of the function that
		    returns a (charge)*(magnetic field)/(partcle mass)
		    vector for each 3D position.</item>
		</enum>
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Renderers</heading>
	  <p>
	    <itemize>
	      <item>draw <bf>sharpraytrace</bf> Heavy procedure that
		draws only the visible part of all edges of all defined
		faces. There's no point in using this procedure when
		there are no intersections beetween faces. Any how
		this will not work for non-convex faces nor when
		<tt>SphericalDistortion:=true</tt>.
	      </item>
	      <item>draw <bf>lineraytrace()</bf> Draws only the
		visible part of all defined lines using sequences of dots
		(<tt>signalvertex</tt> and <tt>PrintStep</tt>).
		<enum>
		  <item><tt>numeric</tt> Dot size.</item>
		  <item><tt>colour</tt> Dot colour.</item>
		</enum>
	      </item>
	      <item>draw <bf>faceraytrace()</bf> Draws only the
		visible part of all edges of all defined faces
		using sequences of dots
		(<tt>signalvertex</tt> and <tt>PrintStep</tt>).
		<enum>
		  <item><tt>numeric</tt> Dot size.</item>
		  <item><tt>colour</tt> Dot colour.</item>
		</enum>
	      </item>
	      <item>draw <bf>draw_all_test()</bf> Draws all defined
		edges (and lines) in a correct way independently of
		the kind of projection used. Can cast a shadow (but
		the shadow is not correct when
		<tt>SphericalDistortion:=true</tt>).
		<enum>
		  <item><tt>boolean</tt> If <tt>true</tt> the lines
		  are also drawn.</item>
		</enum>
	      </item>
	      <item>draw <bf>fill_faces()</bf> Unfills and draws all
		faces in the order they were defined (without
		sorting). Can cast a shadow.
		<enum>
		  <item><tt>text</tt> Like the argument of
		    <tt>drawoptions</tt> but used only inside this
		    macro and only for the edges.</item>
		</enum>
	      </item>
	      <item>draw <bf>draw_invisible()</bf> This is a fast way
		of removing hidden lines that doesn't
		allow for intersecting polygons nor
		polygons of very different area. It works by
		sorting all polygons by
		distance to <tt>f</tt> and then by "filling" the
		polygons. This routine may be used to draw graphs
		of 3D surfaces.
		<enum>
		  <item><tt>boolean</tt> If <tt>true</tt> polygons are
		    sorted relatively to
		    nearest vertex and, if <tt>false</tt>, relatively to their
		    mass center. Choose <tt>false</tt> for surface
		    plots.</item>
		  <item><tt>boolean</tt> If <tt>false</tt> then the
		    polygons are painted with their <tt>FC</tt> colour
		    modified by <tt>LightSource</tt>. If <tt>true</tt>
		    then the next two arguments are used and the
		    polygons are darkened proportionaly to their
		    distance from <tt>f</tt>.</item>
		  <item><tt>colour</tt> Colour of faces.</item>
		  <item><tt>colour</tt> Colour of the edges.</item>
		</enum>
	      </item>
	      <item>global <bf>getready()</bf> When you don't want to
		edit the source of the MetaPost program, to resort the
		objects so they'll be drawn correctly, use this macro
		and the next.
		<enum>
		  <item><tt>string</tt> Command line that would draw
		    some object. For instance:
		    <tt>"rigorousfearpath(black,1);"</tt>.</item>
		  <item><tt>color</tt> Reference position of that
		    object.</item>
		</enum>
	      </item>
	      <item>draw <bf>doitnow</bf> The reference positions
		given as arguments of previous <tt>getready</tt> calls
		are used to sort and draw the objects also given as
		string arguments to previous <tt>getready</tt>
		calls. Remember to initialize <tt>Nobjects:=0;</tt>
		before a second figure.
	      </item>
	    </itemize>
	  </p>
	</sect2>
	<sect2>
	  <heading>Nematics (Direction Fields)</heading>
	  <p>
	    Nematics are the least ordered liquid crystals. Their
	    configurations can be described by direction fields
	    (vector fields without arrows). The two following routines
	    ease the task of representing their configurations.
	  </p>
	  <p>
	    <itemize>
	      <item>global <bf>generatedirline()</bf> Defines a single
		straight line segment in a given position and with a
		given orientation.
		<enum>
		  <item><tt>numeric</tt> Line index number.</item>
		  <item><tt>numeric</tt> Angle beetween the <tt>X</tt>
		    axis and the projection of the line on the
		    <tt>XY</tt> plane.</item>
		  <item><tt>numeric</tt> Angle beetween the line
		    and the <tt>XY</tt> plane.</item>
		  <item><tt>numeric</tt> Line (arc)length.</item>
		  <item><tt>color</tt> Position of the line middle
		    point.</item>
		</enum>
	      </item>
	      <item>draw <bf>director_invisible()</bf> This is a
		direction field renderer that can sort direction
		lines. This routine
		draws straight lines of given "thickness" beetween the
		first all the points
		of all the <tt>L[]p[]</tt> lines. It is supposed to
		help you draw vector fields
		without arrows but taking care of invisibility.
		The lines may be
		generated by <tt>generatedirline</tt> or by other macros.
		<enum>
		  <item><tt>boolean</tt> When there is no need to sort
		    lines you may use <tt>false</tt> here.
		  </item>
		  <item><tt>numeric</tt> "Thickness" of the
		    direction lines</item>
		  <item><tt>boolean</tt> Use <tt>true</tt> for cyclic
		    "direction" lines.</item>
		</enum>
	      </item>
	    </itemize>
	    <figure>
	      <eps file="../allps/twistflat.1">
	      <img src="../allpng/twistflat.1.gs.png">
	      <caption>Figure that uses <tt>director_invisible</tt>
		and <tt>generatedirline</tt>.</caption>
	    </figure>
	  </p>
	</sect2>
	<sect2>
	  <heading>Surface Plots</heading>
	  <p>
	    Many powerfull plotting packages like
	    <tt><url url="http://www.gnuplot.info/" name="gnuplot"></tt> and
	    <tt><url url="http://gri.sourceforge.net/" name="gri"></tt>
	    are freely available. Because of this, <tt>FEATPOST</tt>
	    surface plots are geared towards unusual features like
	    equilateral triangular grid, hexagonal domain and merging
	    together functional and parametric surface descriptions.
	  </p>
	  <p>
	    <itemize>
	      <item>draw <bf>hexagonaltrimesh()</bf> Plots a
		functional surface on a triangular or hexagonal
		domain. Uses the <tt>LightSource</tt>.
		<enum>
		  <item><tt>boolean</tt> Select the kind of
		    domain. <tt>true</tt> for hexagonal and
		    <tt>false</tt> for triangular. The domain is
		    centered on the origin (<tt>black</tt>). When the
		    domain is hexagonal two of its corners are on the
		    <tt>-YY</tt> axis. When the
		    domain is triangular one of its corners is on the
		    <tt>X</tt> axis. </item>
		  <item><tt>numeric</tt> Number of small triangles on
		    each side of the triangular domain or three times
		    the number of small triangles on
		    each side of the hexagonal domain.</item>
		  <item><tt>numeric</tt> Length of the triangular
		    domain side or three times the hexagonal domain
		    side.</item>
		  <item><tt>text</tt> Name of the function that
		    returns the <tt>Z</tt> coordinate of a surface
		    point of coordinates <tt>X</tt> and <tt>Y</tt>.</item>
		</enum>
		<figure>
		  <eps file="../allps/hexagonaltrimesh.1">
		  <img src="../allpng/hexagonaltrimesh.1.gs.png">
		  <caption>Figure that uses <tt>hexagonaltrimesh</tt>.
		  </caption>
		</figure>
	      </item>
	      <item>global <bf>partrimesh()</bf> Defines a parametric
		surface that can be drawn with
		<tt>draw_invisible</tt>. In the following descriptions
		<tt>S</tt> and <tt>T</tt> are the parameters. Remember
		to initialize <tt>NF</tt>. The surface is defined so
		that quadrangles are used whenever possible. If
		impossible, two triangles are used but their
		orientation is selected to maximize the surface
		smoothness. Also note that, unlike
		<tt>hexagonaltrimesh()</tt>, the spatial range you
		require to be visible is always first reshaped into a
		cube and second compressed or extended vertically. How
		much the cube is compressed or extended depends on the
		last <tt>numeric</tt> argument, the compression factor
		for <tt>Z</tt>, meaning that the final height of the
		cube is 2/(compression factor). Thanks to Sebastian
		Sturm for pointing the need to explain this.
		<enum>
		  <item><tt>numeric</tt> Number of <tt>T</tt> steps.</item>
		  <item><tt>numeric</tt> Number of <tt>S</tt> steps.</item>
		  <item><tt>numeric</tt> Minimal <tt>T</tt> value.</item>
		  <item><tt>numeric</tt> Maximal <tt>T</tt> value.</item>
		  <item><tt>numeric</tt> Minimal <tt>S</tt> value.</item>
		  <item><tt>numeric</tt> Maximal <tt>S</tt> value.</item>
		  <item><tt>numeric</tt> Minimal <tt>X</tt> value.</item>
		  <item><tt>numeric</tt> Maximal <tt>X</tt> value.</item>
		  <item><tt>numeric</tt> Minimal <tt>Y</tt> value.</item>
		  <item><tt>numeric</tt> Maximal <tt>Y</tt> value.</item>
		  <item><tt>numeric</tt> Minimal <tt>Z</tt> value.</item>
		  <item><tt>numeric</tt> Maximal <tt>Z</tt> value.</item>
		  <item><tt>numeric</tt> Compression factor for <tt>Z</tt>
		    values.</item>
		  <item><tt>text</tt> Name of the function that
		    returns a surface point (of <tt>color</tt> type)
		  for each pair (<tt>S</tt>,<tt>T</tt>).</item>
		</enum>
	      </item>
	    </itemize>
	  </p>
	</sect2>
      </sect1>
    </sect>
  </article>
</linuxdoc>
