ePiX manual
***********

This is the manual for ePiX, Version 1.2 Copyright (C) 2001, 2002,
2003, 2004, 2005, 2006, 2007 Andrew D. Hwang

1 Introduction
**************

`ePiX', a collection of command line utilities for *nix, creates
mathematically accurate line figures, plots, and movies using
easy-to-learn syntax. `LaTeX' and `dvips' comprise the typographical
rendering engine, while `ImageMagick' is used to create bitmapped
images and animations.  The user interface resembles that of `LaTeX'
itself: You prepare a short scene description in a text editor, then
"compile" the input file into a picture. Default output formats are
`eepic' (a plain text enhancement to the `LaTeX' picture environment),
`eps', `pdf', `png', and `mng'.

   `ePiX''s strengths include:

   * Quality of output: `ePiX' creates mathematically accurate,
     publication-quality figures whose appearance matches that of
     `LaTeX'.    Typography may be put in a figure as easily as in an
     ordinary   `LaTeX' document.

   * Ease of use: Figure objects and their attributes are specified
     by simple, descriptive commands.

   * Flexibility: In `ePiX', an object is described by its attributes
     and Cartesian location; as in `LaTeX', printed appearance is
     determined when the figure is compiled. A well-designed figure can
      be altered dramatically, yet precisely, with minor changes to the
      input file.

   * Power and extendibility: `ePiX' inherits the power of `C++' as a
     programming language; variables, data structures, loops, and
     recursion can be used to draw complicated plots and figures with
     just a few lines of input. External code can be incorporated in an
      `ePiX' figure with a command line option or by using a Makefile.

   * Economy of storage and transmission: For a document containing
     many figures, a compressed tar file of the `LaTeX' sources and
     `ePiX' files is typically a few percent the size of the compressed
      PostScript file.

   * License: `ePiX' is _Free Software_.  You are granted the right to
     use the program for whatever purpose,   and to inspect, modify,
     and re-distribute the source code, so long   as you do not
     restrict the rights of others to do the same. In   short, the
     license is similar to the terms under which theorems are
     published.

   The relationship of `ePiX' to a graphical drawing program is
analogous to the relationship between `LaTeX' and a word processor;
`ePiX' facilitates logical structuring of mathematical figures. Though
`ePiX' makes a few stylistic defaults to streamline the creation of
simple figures, it imposes no internal restrictions on the contents or
appearance of a figure; aesthetic and practical decisions are left to
the user.

   This manual is meant to be read in stages rather than "cover to
cover". If you are a:

   * Potential user, you may wish to skip immediately to "Software
     Dependencies" before investing additional time.

   * New user, proceed from here until you have enough understanding
     to run the software, then experiment with the samples files while
     reading Chapter chapter, , or return to the
     manual as   needed.

   * More advanced user, browse at will, probably starting with
     Chapter chapter, .

   Please post to a mailing list if you have questions or comments (good
or bad) about the software or manual, or if you are willing and able to
join in development.

   This manual is relatively conversational, and occasionally redundant
(especially between portions meant for readers at different levels of
familiarity). Throughout, you are assumed to be familiar with `LaTeX'
and basic linear algebra (the description of points, vectors, lines,
and planes in three-dimensional space). Other material, such as `C++'
syntax, is introduced as needed.

1.1 Changes in Version 1.2
==========================

`ePiX' 1.2.x has been written almost entirely from scratch.  To the
user, however, `ePiX'-1.2.x naturally extends Version 1.0.x: The
conceptual model is the same, and there are only a few small changes of
syntax. If you're new to `ePiX', you'll probably want to skip straight
to Section section, . The rest of this section,
which describe the major new features, assumes you're familiar with
`ePiX' 1.0.x

Many old `ePiX' 1.0.x files will compile under Version 1.2.x. However,
geometric object commands (`circle', `plane', `segment', and `sphere')
which used to create class objects now perform drawing, just as
`ellipse', `line', `rect', etc., do. The classes are available with
capitalized names (`Circle', etc.).

   Global variables have been deprecated or removed, and should be
replaced by function calls in new files. The following changes are
either required, or else strongly recommended (and may become
mandatory).

   * (Recommended) The global size variables x_min,   x_max, y_min,
     y_max, x_size, and   y_size should be replaced by the function
     calls   xmin(), etc. (No underscores.)

   * (Mandatory) The global variable tix in a `flix'   file must be
     manipulated through the function tix().

   * (Recommended) The camera should be accessed through the function
     `the_camera()', not the global object `camera'.

   * (Mandatory) Camera orientation is controlled with functions
     named `tilt', `pan', and `roll'; each rotates   the camera about
     an axis through the viewpoint, not through the   target.

   * (Suggested) The size and bounding box are given in one command,
     such as `picture(P(-1,0), P(1,1), "4x3in")'. The old syntax   will
     be retained indefinitely.

   * (Mandatory) By default, `ePiX' performs color filling without
     PSTricks macros. PSTricks output is obtained systematically as an
     output format. The command `use_pstricks()' is obsolete.

   A few deprecated "aliases" no longer exist: `triple' (for the `P'
class), `D' (for `Deriv'), and `I' (for `Integral'). Lowercase trig
function names, which conflicted with the standard namespace, have been
removed.

   Non-member intersection operators for circles, planes, spheres, and
segments are provided.  A "non-generic" intersection does not throw an
exception, but instead returns an undrawable "malformed" object.

   * Colors are now a manipulable data type, available in RGB, CMY,
     CMYK, and Gray models. `xcolor'-style operations, such as   color
     model conversion, blending, superposition, and inversion are
     provided.

     The camera has a filter which affects the colors of all scene
     elements. In addition to the models above, `ePiX' 1.2.x supplies
     color filters that perform CMYK separation.

   * Color filling is controlled with declarations, similarly to line
     colors in `ePiX' 1.0.x.  Arrows and markers of type spot, dot,
     ddot,   and circ are colored like other markers.  Shaded surfaces
     may be   colored with user-specified color-valued functions.

     Filled regions are implemented as hatched regions in   `eepic'. If
     a figure contains many shaded elements, a more   color-capable
     output format (such as PSTricks) should be used.

   * `ePiX' 1.2.x performs page layout.  Figure elements may be placed
     into a `screen'; one or more `screen's are placed into the
     final figure by affine scaling. A `screen' may be cropped, or
     decorated with a border (line of specified width and color around
     the edge) or backing (solid color background).

1.2 Software Dependencies
=========================

If you run GNU/Linux, a BSD, or Solaris, you almost surely have (or can
install) all the external software needed to use `ePiX'.  For Mac OS X,
you will need the Apple developer tools (XCode on the Tiger install
medium), and will want to install an X server (XDarwin on the Tiger
disks) and the `fink' package manager to build a *nix environment.  For
Windows, you'll need to install Cygwin and several packages. Detailed
instructions are given below.

   "Under the hood", an input file is successively converted to
`eepic', `dvi', PostScript, `pdf' or `eps', and if desired, `png' or
`mng'.  `ePiX' comprises a compiled library written in `C++', a `C++'
header file, and four shell scripts--`epix', `laps', `elaps', and
`flix'--that automate the various file format conversions.  Each script
is written in GNU `bash'.  Consequently, there are two absolute
necessities: a `C++' compiler (preferably `g++') and `bash'. The script
`epix' uses only these programs.  `ePiX' is primarily a pre-processor
for `LaTeX', but does not absolutely require `LaTeX' for normal use.
However, without `LaTeX' and Ghostscript (particularly `dvips'), you
can't view or print `epix''s output files, nor can you run `flix' or
`elaps'.

   A text editor such as `emacs' or `vim' that facilitates formatting
`C' code is extremely useful for writing input files. `ePiX' comes with
an `emacs' mode, written by Jay Belanger, that allows you to write,
compile, and view `ePiX' figures without leaving `emacs'.

   In the presence of `LaTeX' and Ghostscript, only a few standard
utilities are needed to run `ePiX''s "conversion to `eps'/`pdf'" script
`elaps', namely `grep', `sed', `epstopdf', and `ps2epsi'.

   Finally, `flix' uses ImageMagick's `convert' utility to create `png'
images, and to assemble `png's into animated `mng' files. The programs
`animate' and `display' are useful for viewing `flix' output.

   Aside from their reliance on specific programs, `ePiX''s shell
scripts are written using Unix-style pathnames. Thus, the most
straightforward way to use `ePiX' is to install a Unix-like environment.

Cygwin can be used to run `ePiX' under Windows. Download `setup.exe'
from `http://www.cygwin.com', then install the packages you need. The
following are recommended, and sufficient for the actions described in
this manual.

(Archive)    bzip2, tar
(Devel)      binutils, coreutils, gcc, gcc-g++, make, sed
(Editors)    emacs, emacs-X11, vim
(Graphics)   ImageMagick, ghostscript-base, ghostscript-x11, gv
(Publishing) tetex (all)
(Shells)     bash, bash-completion
(X11)        X-start-menu-icons, X-startup-scripts,
             XFree86-lib-compat, xorg-x11-fscl, xorg-x11-fsrv

1.3 Installation
================

`ePiX' is distributed over the World-Wide Web as source code. Packages
(stable and development) can be found at `http://math.holycross.edu/
ahwang/current/ePiX.html' In a web browser, <SHIFT>-click on a link to
download.  The latest stable release is also on the CTAN mirrors, in the
`graphics' directory. There are instructions for downloading an entire
directory; it is not recommended that you download the files
individually.  (Some users of Red Hat have reported file permission
problems when unpacking the CTAN tarballs. If you encounter this
difficulty, please try downloading the sources from the project main
page.)  Unpack the compressed tar file with the appropriate command:

  tar -zxvf epix-x.y.z_complete.tar.gz
  tar -jxvf epix-x.y.z_complete.tar.bz2
 (`x.y.z' is the version number) or, if your `tar' doesn't do
decompression,

  gunzip -c epix-x.y.z_complete.tar.gz | tar -xvf -
  bzcat epix-x.y.z_complete.tar.bz2 | tar -xvf -
 `cd' to the source directory, `epix-x.y.z'.  The `INSTALL' file
contains detailed installation instructions.  If you're impatient, the
short of it is `./configure [--options];   make; make install'.  Run
`./configure --help' for a list of options.

   By default, `ePiX' installs in subdirectories of `/usr/local'; if
you want to install elsewhere, supply `./configure' with the
appropriate `--prefix'. The `INSTALL' file contains detailed
instructions. You may also want to consult `POST-INSTALL' for
information on setting your `PATH' variable so your shell can find
`ePiX'.  The manual and sample files are in `/usr/local/share/doc/epix'.

   The command `make uninstall' removes installed components of `ePiX'
from your system. You must be in the source directory, and may need to
log in as `root'. (If you remove the sources, then later decide to
uninstall, you must unpack the sources, `./configure' the package
_using the same options as when you installed_, then run `make
uninstall'. If you kept the source directory after installing, you need
not re-configure.)

   To re-iterate, `ePiX' is not a stand-alone program, but consists of a
`C'/`C++' library, header, and shell scripts, and therefore requires a
compiler _for normal use_. The GNU compiler (`g++') and `C++' library
are strongly preferred, both because they are used to develop `ePiX',
and because they implement many mathematical features not specified by
`ANSI C'.  `ePiX' also relies on the GNU shell `bash'. If you port
`ePiX' to another shell or operating environment, or package `ePiX' for
other systems, please notify the author so that your work can be linked
from the project page and mentioned in the documentation.

There are two mailing lists for all versions of `ePiX', one for user
questions, one for development discussion. Please visit
`http://savannah.nongnu.org/mail/?group=epix' to subscribe.

2 Getting Started
*****************

This chapter describes the basics of creating figures in `ePiX' for
readers familiar with `LaTeX' but completely new to `C++'. No detailed
knowledge of `C++' is needed to use `ePiX', only a bit of grammar that
is easily absorbed by example.

   Section section, describes the commands (shell
scripts) comprising `ePiX', and explains how to set up a graphical
environment using standard *nix programs. Section
section, presents a few files side-by-side with their
output, and should be read at a computer so you can run the exercises.

2.1 Running `ePiX'
==================

Like `LaTeX', `ePiX' is non-interactive, and run from the command line.
An `ePiX' input file, which carries the preferred file extension `.xp'
(for eXtended Picture), is a plain-text figure specification written in
a human-friendly description language. An output file--`eepic', `eps',
`pdf', or `png'--is included directly into a `LaTeX' document with the
appropriate `LaTeX' packages. Conversion is accomplished with four shell
scripts--`laps', `epix', `elaps', and `flix'. Each accepts a `--help'
(or `-h') option, which describes the command line options. Portions of
a command enclosed in square brackets are optional.

   The code snippets below refer to a hypothetical `LaTeX' file,
`sample.tex', which contains a figure compiled from an `ePiX' file
`sample1.xp'. All packages mentioned are standard parts of modern
`LaTeX' distributions, and an ellipsis connotes `LaTeX' code separating
preamble commands from the document proper.

The script `laps' performs `LaTeX' to Postscript conversion, and is
independent of the rest of `ePiX'. By default, `laps' invokes `LaTeX'
and `dvips'. The command

  laps sample[.tex]
 creates `sample.ps'. The option `--pdf' creates a PDF file by
post-processing the PostScript with `ps2pdf'.  Alternatively, other
`TeX'-family processors (`pslatex', `pdftex', etc.) may be used instead
of `LaTeX'.

The default output of `epix' is `eepic', Conrad Kwok's enhancement to
the `LaTeX' picture environment that allows lines of arbitrary length,
slope, and width. An `eepic' file is included directly into a `LaTeX'
document:

\usepackage{epic,eepic,xcolor}
  ...
@center
  [Image]

 Rotated text requires the `rotating' package. PSTricks output requires
the `pstricks' package, naturally. (The most recent `pstricks' includes
`xcolor'. With older versions of `teTeX' and Ghostscript, you may need
to use `pstcol' instead of `pstricks'.)

   In a text editor, create an `ePiX' input file `sample1.xp' for the
figure, then issue the command `epix sample1[.xp]'.  Multiple files can
be specified, e.g. "`epix sample*.xp'".  By default, the output file
has the same name as the input, here "`sample1.eepic'". If only one
input file is given, the name of the output file may be specified with
a command line option.

   The file extensions "`.cc'", "`.c'", "`.C'", and "`.cpp'" are
recognized. However, if the `emacs' configuration file is properly set
up, `emacs' automatically enters `ePiX' mode when an `.xp' file is
opened, and inserts a preamble template when a new file is created.

   File extensions are optional on the command line; if no extension is
given, the script searches the current directory for matches, and
prints a warning if multiple matches are found. The help message lists
recognized extensions in decreasing order of precedence.

Stand-alone `LaTeX' figures (`eps' or `pdf', as opposed to `eepic') are
useful in a variety of contexts: individual figures can be changed
without recompiling an entire document, color is available when
previewing in `xdvi', and so forth. The commands `elaps sample1.xp' and
`elaps --pdf sample1.xp' produce the files `sample1.eps' and
`sample1.pdf' respectively. Multiple input files, and the name of the
output file, are given on the command line just as for `epix'.
Additional `LaTeX' packages and `dvips' options may be specified on the
command line. Finally, `elaps' can process `eepic' files (i.e., act as
`eepic2eps' and `eepic2pdf'), even those not produced with `ePiX'.

2.2 Tutorial
============

This section presents sample input files side-by-side with their output
so you can compare what you write with what you'll see on the screen or
page.  `ePiX' provides standard drawing capabilities, but like all
software has its own idioms and personality. The basic syntax, which
comes from `C'/`C++', should be mostly self-explanatory. As in `LaTeX',
drawing attributes remain in effect until superseded.  One-line
comments begin with the string "//".

   To use the sample files interactively, you'll need working software:
`bash', `emacs', `ePiX', `g++', `gv', and a running X server.  The
`POST-INSTALL' file contains detailed instructions on setting up Jay
Belanger's `epix' mode for `emacs', which allows you to compile files
with a couple of keystrokes from within `emacs'. (For example, the
`emacs' command `C-c C-l' creates a previewable `EPS' file from an
`ePiX' source file.)  To complete your "GUI", start `gv' and select
"Watch file" from the "State" menu. The loaded file will update
automatically when it changes.

   Create a "scratch" directory, `cd' into it, and run the command

  tar -zxf /usr/local/share/doc/epix/sample_src.tar.gz
 (Change the package name as appropriate for your installation.)  This
unpacks copies of the sample files into your scratch directory,
including all the files mentioned in this manual. The `README' file
serves as a table of contents.

   Open a sample file in `emacs', compile it, then open the `EPS' file
in `gv'. Now you're ready to follow the tutorial interactively. A few
suggested exercises are included with each file. Naturally, as you
study more files, you'll be able to make more interesting changes on
your own.

The first sample, `hello.xp', contains boilerplate code needed to
specify the figure's size (henceforth omitted for brevity), followed by
the classic greeting. The `border' command draws a box around the
figure in the specified color and width, and serves here merely to
delimit the output from the surrounding page.

/* -*-ePiX-*- */
#include "epix.h"
using namespace ePiX;  // analogous to a usepackage command

int main()
{
  picture(P(-1,-1), P(1,1), "2 x 1in"); // corners (-1,-1) and (1,1)

  begin(); // ---- Figure body starts here ----

  border(Black(), "1pt");

  font_size("Huge");  // May be any font size, e.g. "scriptsize"
  label(P(0,0), "Hello, world!");

  end();
}

[Image]

   * Change the color and width of the border. `RGB(r,g,b)'   creates
     an RGB color; CMY colors are analogous. (The arguments may   be
     any numbers, but should be between $0$ and $1$ for "expected"
     behavior.)

   * Put the command `crop_ellipse();' before the `border'   command.

   * Add `backing(Blue(1.9));' after the `crop_ellipse'   command.
     Change the order of the `border', `backing', and   `crop_ellipse'
     commands.

Our next file contains a simple 2-D house-and-sun scene.

int main()
{
  picture(P(0,0), P(5,2), "3.75 x 1.5in");

  begin();

  triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices
  circle(P(4,1.5), 0.25); // center and radius

  rect(P(1,0), P(3,1)); // opposite corners

  fill(Black(0.1));     // light gray
  rect(P(2.3,0), P(2.7,0.8));

  fill(White());
  rect(P(1.4,0.2), P(2, 0.6));
  bold();
  grid(P(1.4,0.2), P(2, 0.6), 2, 2); // corners, number of squares

  line(P(xmin(),0), P(xmax(),0));  // endpoints
  end();
}

[Image]

   * Insert color declarations, e.g., `rgb(1,0.9,0.5);' at   various
     locations.

   * Move the `fill' commands.

Plotted functions must be defined in the "preamble", before `main'.
"High-level" elements--coordinate axes and grids, axis labels, and
graphs--are drawn with mnemonically-named commands.

// double = double-precision floating point
double f(double x) { return 0.75*Sin(x) - 0.25*Sin(2*x); }

int main()
{
  picture(P(-2,-1), P(2,1), "5x1in"); // [-2,2] x [-1,1]

  begin();

  h_axis(16);
  v_axis(4);
  h_axis_labels(4, P(0,-4), b); // shift labels down 4pt, align below

  revolutions(); // set angle units
  red();
  plot(f, xmin(), xmax(), 120); // use 120 intervals

  end();
}

[Image]

   * Define and plot some different functions; adjust the bounding
     box as necessary. (Use repeated multiplication for polynomials.

   * Change the arguments to `h_axis_labels'. The first   specifies the
     number of intervals to label; the second gives the   label offset
     in `pt'. The last puts each label below (`b')   its Cartesian
     location. Add vertical axis labels.

Functions of two or three variables are defined just like functions of
one variable, but for plotting the return type must be a point (`P'),
not a real number (`double'). The `domain' class specifies the set of
inputs to plot.

P f(double r, double th)
{
  return P(r*Cos(th), r*Sin(th), pow(r, 3)*Cos(3*th));
}

int main()
{
  picture(P(-1,-1), P(1, 1), "2x1in");
  begin();

  // corners ([0,1] x [0,2\pi]) and fineness
  // (8x40 rectangles, plotted at 16x120 resolution)
  domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(16,120));

  camera.at(P(3,1,2)); // set the viewpoint
  arrow(P(0,0,0), P(1.25,0,0)); // coordinate axes
  arrow(P(0,0,0), P(0,1.25,0));
  arrow(P(0,0,0), P(0,0,1.25));

  plain(Blue(1.2)); // line color and width
  fill(Yellow());   // shading color
  surface(f, R);

  pst_format(); // use PSTricks macros for filling
  end();
}

[Image]

A function can be defined by an arbitrary algorithm, and a `domain' may
be used to plot a family of functions for several values of one
variable.

P sin_n(double x, double n)     // Taylor polynomial of sin x
{
  const int N((int) floor(n));
  const double sqx(-pow(x, 2)); // -x^2
  double val(x), summand(x);

  for (int i=1; i <= 2*N+1; i += 2)
    {
      summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)!
      val += summand;
    }

  return P(x, val);
}

int main()
{
  picture(P(0,-1),P(6*M_PI, 1), "5x1in");

  begin();

  crop();
  pen(Green(), "1pt");
  plot(Sin, 0, xmax(), 120);

  domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40));
  for (int i=0; i<4; ++i)
    {
      rgb(0.25*i, 0, 1-0.25*i);
      plot(sin_n, R.slice2(5*i+1)); // y = 5i+1
    }
  end();
}

[Image]

Page layout can be composed from sub-pages with `screen' objects.  In
the loop body below, objects added to the "active" `screen', which is
then `inset' into the "canvas", the screen representing the entire
figure.

P f(double u, double v)
{
  return P((u-v)*(u+v), 2*u*v, u);
}

int main()
{
  picture(P(0,0), P(2,3), "5x7.5in");

  begin();

  domain R(P(-1,-1), P(1,1), mesh(12,12), mesh(24,24));

  for (int i=0; i<2; ++i)
    for (int j=0; j<3; ++j)
      {
        screen my(P(-3,-3), P(3,3));
        activate(my);
        border(Red(0.6), "1pt");
        // frame-dependent viewpoint
        camera.at(sph(10, (2*j+i+1)*M_PI/8, M_PI/6));

        plot(f, R);
        arrow(P(0,0,0), 2*E_1);
        arrow(P(0,0,0), 2*E_2);
        // SW corner at (i, 2-j), padded by 0.05 on all sides
        inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j));
      }

  end();
}

[Image]

2.3 `C++' Basics
================

An `ePiX' source file is a `C++' program. If you've successfully
modified and compiled the sample files, you know enough `C++' to use
`ePiX'. In the author's experience, `C' grammar suffices for most
applications.  An excellent introduction to definitions of functions
and variables, control statements, and overall program structure is
Kernighan and Ritchie's _The `C' Programming Language_, second edition
`KnR'.

   Jay Belanger's `emacs' mode for `ePiX' inserts a file template when
an empty buffer is opened with the extension `xp'.  This section
explains the purposes served by the template. A few additional remarks
may help you avoid basic syntax pitfalls.

A `C++' file consists of "statements", analogous to ordinary sentences.
Common types include _declarations_ (which "register" a function,
variable, or type name with the compiler), _definitions_ (which assign
meaning to declared names), and _function calls_ (which cause a named
function to execute).  Most statements in an `ePiX' input file are
function calls ("`ePiX' commands").  Explicit declarations are
relatively rare, since a definition serves to declare any new names
that it contains.

   Every statement ends with a semicolon, and conventionally a file
contains one statement per line (when possible).  The compiler ignores
nearly all whitespace (spaces, tabs, and newlines), which should be
used liberally to make files easy to read.  Other punctuation (periods,
commas, (semi)colons, parentheses, braces, and quotes) dictates file
parsing, and must adhere stringently to grammar.

   An `ePiX' file always begins with the lines

#include "epix.h" // N.B. pre-processor directive, no semicolon
using namespace ePiX;
 The first line is analogous to a `LaTeX' `usepackage' command: It
"includes" the contents of a file, thereby importing the names of
commands provided by `ePiX'.

   To avoid name conflicts, `ePiX''s commands are enclosed in a
"namespace". For example, the `label' command is actually known to the
compiler as `ePiX::label'. The second line above tells the compiler to
apply the prefix tacitly.

Definitions of variables and functions play the same role in a figure
that macro definitions play in a `LaTeX' document: gathering and
organizing information on which the figure depends. A variable is
defined by supplying its type, name, and initial value. By far the most
common data types in `ePiX' are `double' (double-precision floating
point number), `P', and `int'. The name of a variable may consist
(only) of letters (including the underscore character) and digits, and
must begin with a letter:

my_var, my_var2,  _MY_var, __, aLongVariableName;  // valid
my-var,    2var, v@riable, $x, ${MY_VARIABLE}; // not valid
 Variable names are case-sensitive. There are numerous conventions
regarding the significance of capitalization. Generally, make names
descriptive but not unwieldy, and avoid names that begin with an
underscore (unless you know what you're doing).

   A function accepts "arguments" and "returns a value". To define a
function in `C++', you must specify the return type, the name of the
function, the types of the arguments, and the algorithm by which the
value is computed from the inputs.

`C++' has two types of comments. `C'-style comments, which may span
several lines, are delimited by the strings `/*' and `*/'. One-line
comments, analogous to the `LaTeX' `\%', are begun with `//'. A
one-line comment may appear within a multiline comment, but a `C'-style
comment may not; the compiler will mistake the first `*/' it encounters
as the end of the current multiline comment.

All the "action" in a `C++' program occurs inside the special function
`main'. Running a compiled `C++' program is viewed by the operating
system as calling the program's `main' function. The return value (an
`int') is the program's exit status.  In an `ePiX' file, the `main'
action usually consists of setting the logical and printed size of the
figure, then building and drawing the figure, changing attributes when
desired.  `ePiX' output proper starts with `begin()' and terminates
with `end()'. The intervening statements constitute the _body_ of the
file.

   In `C++', a function may not be defined inside another function.
Thus, variables may be defined inside `main', but functions cannot be.

More-or-less verbatim text can be printed to the output file. The
functions `write', `pre_write', and `post_write' accept strings of
characters. `write' prints its argument where the call appears in the
input file. The other functions print their arguments before or after
the completed picture, respectively. These commands must be in the file
body.

   A single backslash is produced by a double backslash in the input
file.  Certain letters have special meanings when backslash-escaped,
including "\n" (newline) and "\t" (TAB).  Unlike `LaTeX', `C++' does
not require a space to separate an escape sequence from following text;
the string "\textwidth" is read "`TABextwidth'" by the compiler.

   As an application, a complete `LaTeX' `figure' environment (with
caption and label) can be produced by an `ePiX' file, Figure
fig, .

#include "epix.h"
using namespace ePiX;

int main()
{
  picture(P(-1,-1), P(1,1), "10cm x 3in);
  begin();
  pre_write("\@float Figure[hbt]"); // comes before the picture

  post_write("\@caption{A \@code{LaTeX}\ figure.}"); // and after
  post_write("\@end float");

  < ... other ePiX commands ... >
  write("%% A comment near the end, but inside the picture.");
  end();
} // End of main()

Figure: Generating a self-contained figure in `ePiX'.

An algorithm's behavior usually depends on some internal state. A
_conditional statement_ causes blocks of code to be executed depending
on some criterion. A _loop_ repeatedly executes a code block, usually
changing the values of variables in a predictable way, so that the loop
exits after finitely many traversals.

2.4 Animation
=============

`ePiX' is well-suited to the creation of mathematically accurate
animations: If a figure depends suitably upon a "time" parameter, then
a loop can be used to draw the entire figure for multiple time values,
yielding successive "snapshots" of the figure as time progresses. The
shell script `flix' automates the process of compiling a suitable input
file into a collection of `png's and assembling these frames into a
`mng' or `gif' animation.  ImageMagick is the image-handling engine.

   A `flix' file is an `epix' file with two restrictions:
   * The `double' variable `tix()' is used as   "clock".

   * `main' accepts two command line arguments and sets   `tix()'
     accordingly.
   Jay Belanger's `emacs' mode recognizes the file extension `.flx' and
inserts template code if an empty buffer is opened. Creation of `flix'
files is as easy as creation of `epix' files.  The `samples' directory
contains a handful of `flix' files that may be consulted for ideas.

   A "typical" `.flx' file may take 30 seconds to a couple of minutes
to compile.  `flix' prints a reassuring progress bar, counting the
number of `eps' files that have been created. There will be a delay of
a few seconds (or more) after the last frame is produced, during which
ImageMagick's `convert' utility creates `png' files from `eps' files,
then assembles the movie.

   To facilitate debugging, `elaps' can be run on a `flix' file.
`elaps' runs in a fraction of the time, and if `elaps' can't produce a
viewable image, `flix' will surely fail.

   By default, `flix' creates movies with 24 frames, in which `tix()'
runs from 0 to 1, and animates at $0.08$ sec/frame.  Command-line
options change these and other parameters; please use `flix''s built-in
help for details.

2.5 Stereograms
===============

Stereograms are created by drawing a single scene twice from slightly
different points of view. To create a stereogram with `ePiX', write a
"scene" function containing the necessary drawing commands, then set
the camera appropriately and call the scene function twice, once for
each frame.

The sample files `lorenz.xp' and `twisted_cubic.xp' use page layout to
draw crossed-eyes stereograms. For each frame, create and activate a
`screen', set the camera, and call the scene function. The frames must
be inset side by side in the final picture; for a crossed-eyes
stereogram, the frame from the "rightmost" camera position is placed on
the left.

The sample files `cube.flx' and `mirrorball.flx' contain animated
red-cyan stereograms, suitable for viewing with 3-D glasses. The
technique works best with black-and-white line drawings, but the basic
approach is the same as for crossed-eyes stereograms: Create a scene
function and call it twice, setting the camera appropriately. Layout is
unnecessary since the frames are superposed.  Pen colors should be
close to red and cyan, but "optimal" choices depend on one's eyes and
3-D glasses.

Either form of stereogram can be animated in a `.flx' file, but keeping
one's eyes properly crossed requires practice while most people can
instantly see depth with 3-D glasses. As always when using `flix',
debug the scene with `elaps' before compiling a movie. If a
stereoscopic effect is difficult to see in a still image, it will be
even harder to perceive in a movie.

3 Reference Manual
******************

This chapter surveys the concepts behind figure creation, describes
`ePiX''s features and capabilities, and briefly introduces the
programming language `C++'.

   In code snippets, the following conventions hold. Arguments to
functions are given by type (`double', `P', etc.) and a mnemonic name.
A name alone will be given if context makes the type clear. A name
followed by an equals sign and a value signifies a _default_ argument;
if the argument is omitted in a user file, the compiler supplies the
default value. Only _trailing_ arguments take default values. For
example, the line

  circle(P ctr, double rad=1, P normal=P(0,0,1));
 describes three commands, accepting between one and three arguments.
If the `normal' argument is omitted, the compiler supplies the value
`P(0,0,1)'. If _in addition_ the `rad' argument is omitted, the
compiler supplies the value `1'. The `rad' argument may not be omitted
if `normal' is supplied.  In an input file, only values (not types) are
given, as in `circle(P(3,-1), 4)'.

3.1 File Structure
==================

An `ePiX' input file constitutes a short `C++' program. When this
program is compiled and run by one of the shell scripts, it creates a
figure file suitable for inclusion in `LaTeX'.

   Like a `LaTeX' document, an `ePiX' file contains a _preamble_, which
sets up a drawing environment, and a _body_, which contains actual
figure-generating commands.  The minimal file has the form

#include "epix.h"
using namespace ePiX;

int main() {
  picture(P(a1,b1), P(a2,b2), "n1 x n2 units");
  begin();
  end();
}
 The preamble ends at the `begin()' line. `ePiX' commands are of three
general types: drawing, attribute setting, and definitions (of data and
functions). Except as noted below, drawing and attribute commands must
appear in the body, between `begin()' and `end()'. Function definitions
must come in the preamble, before `main()'. Data definitions may appear
anywhere in the file.

The `end()' command writes the output file, by default using `eepic'
macros. If a `pst_format()' command appears in the figure body, the
output file will be written using PSTricks macros.

3.2 Picture Size and Aspect Ratio
=================================

The `picture' command specifies a figure's logical and true sizes.
These data must be defined before drawing commences. In the snippet
above, the _bounding box_ (logical size) is the Cartesian rectangle
$[a_1,a_2]\times[b_1,b_2]$ whose corners are given. Either pair of
opposite corners is acceptable, but confusion is less likely when the
SW and NE corners are given, in this order.

   `LaTeX' treats the contents of a picture environment as a single
box. The true (printed) width and height are read from the third
argument, a string containing a number and optional `LaTeX' length
unit, an `x', another number, and a mandatory length unit. Spaces are
recommended for legibility.

   The mandatory length unit becomes the `LaTeX' `unitlength'.  An
argument such as "4cm x 1in" creates a picture 4 cm wide and 1 in high,
but internally converts 4 cm to inches.  Recognized `LaTeX' length
units are `bp' (big point), `cm' (centimeter), `in' (inch), `mm'
(millimeter), `pc' (pica), `pt' (point, the default unit), and `sp'
(scaled point).  (There are 72 big points per inch, 12 points per pica,
and 65536 scaled points per point.)

   The logical and true sizes may be defined separately with the
commands

  bounding_box(P(a1,b1), P(a2,b2));
  picture(n1, n2);
  unitlength(units);

   By default, `LaTeX' aligns a picture on its lower left corner. An
`offset' command shifts the contents on the page. An `offset' command
accepts either two numbers, or a string (with the same meaning as the
true size). If the `unitlength' is 1 cm, either of the commands
`offset(0.25, -0.5)' or `offset("0.25 x -0.5cm")' shifts the picture
right $0.25$ cm and down $0.5$ cm.

   A non-zero `offset' causes the contents of a picture to appear in a
location where `LaTeX' does not expect them. This may be useful when an
`eepic' file is included into a `LaTeX' document, but requires visual
tweaking. An `offset' should not be used when compiling a figure into
EPS or PDF with `elaps', since `dvips' may crop the figure according to
rules of its own.

   The lower left and upper right corners of the bounding box are known
as `(xmin(),ymin())' and `(xmax(),ymax())', while the width and height
are `xsize()' and `ysize()'. The bounding box is a virtual, advisory
data structure; its dimensions are not directly related to the figure's
printed size, and picture elements are not constrained to the bounding
box by default. Affine scaling maps the bounding box to the picture box
when the output file is written.
[Image]

   The figure's aspect ratio is controlled by sizing the bounding box.
The aspect ratio is "true" if the bounding box and picture box are
geometrically similar, e.g., if both boxes are 1.5 times as wide as
they are tall.

3.3 Color
=========

In `ePiX' 1.2.x, `Color' is a data type. Four models are implemented:
RGB, CMY, CMYK, and Gray. RGB, CMY, and CMYK colors are written to the
output file as `xcolor' commands in the corresponding model. Gray
shades are written in `RGB'.

   A `Color' holds primary color "channels", each carrying an intensity
between 0 (no color) and 1 (full saturation).  ("No color" means black
in `RGB', white in `CMY(K)'.)

   Operations on red-green-blue colors are described below.
Functionally, colors are converted to RGB, operated upon, then
converted back to the original model. Color conversions are as
described in Uwe Kern's `xcolor' manual.

Each color model has a "constructor" that creates a color of specified
densities. The `RGB' and `CMY' models have named "primary"
constructors; the density argument is optional and defaults to 1.

  // red-green-blue colors
  RGB(double r=0, double g=0, double b=0);
  Red(d=1);   Green(d=1);   Blue(d=1);
  White(d=1);   Black(d=1);

  // cyan-magenta-yellow colors
  CMY(double c=0, double m=0, double y=0);
  Cyan(d=1);   Magenta(d=1);   Yellow(d=1);
  CMY_White(d=1);   CMY_Black(d=1);

  // gray
  Gray(double d=0); // equivalent to RGB(d, d, d)
 Each `CMY' constructor has a corresponding `CMYK' function, e.g.\
`CyanK()' or `CMYK_White()'.

   Though color densities lie between 0 and 1, `ePiX''s primary color
constructors take arguments mod 4, viewed as elements of $[-2,2]$.
Consider `Red(d)', "red with density $d$". For integer values of $d$,
the constructor has the following meanings: `Red(0)' is black, `Red(1)'
is red, `Red(2)'=`Red(-2)' is white, and `Red(-1)' is anti-red, or
cyan. For non-integer $d$, the constructor interpolates between the
bracketing integer values, Figure fig, . Other primary
constructors work analogously.

[Image]

Figure[hbt]

   Colors possess an "alpha-channel" for transparency. Except as
supported by the output format, this feature is a stub. `ePiX' 1.2.x
implements limited transparency in `eepic', but the visual effect tends
to be best for light colors, such as yellow.

Colors can be scaled, inverted, blended, superposed, and filtered. In
the code below, `tint' is a `Color'. The effect of each operation is
described in the `rgb' model; the visual result is the same in all
models.

  tint *= double c; // multiply each channel by c
  tint.invert();    // (r, g, b) -> (1-r, 1-g, 1-b)
  tint.blend(Color col, double t);  // (1-t)*tint + t*col
  tint.superpose(col); // add channels, then clip to [0,1]
  tint.filter(col); // take min density in each channel
  tint.alpha(double d); // set alpha channel to clip(d)

3.4 Scene Attributes
====================

Each drawing command adds an element to the final figure. An element's
appearance depends on the _camera_, the _active screen_, and on the
_crop state_.

By default, angles are measured in `radian's. Two other angular modes
are available: `degrees' and `revolutions'. The angular mode is set
with a named command, `radians()', `degrees()', or `revolutions()'.

Three-dimensional scenes are drawn on flat paper by applying a
mathematical transformation. By default, `ePiX' uses _point
projection_, the technique used by art students when they trace on a
window with grease pencil.

[Image]

Figure[hbt]

   `ePiX' depicts a Cartesian world by projecting mathematically to a
screen plane, then affinely scaling to a printed page. The camera,
which maps the world to the screen, consists of a _body_ (data that
determines the position and orientation of the camera), a _lens_ (the
actual mapping to the screen plane), and a _filter_ (a color through
which the scene is viewed).

The camera's spatial orientation is described by a triple of mutually
perpendicular unit vectors.  In memory of happy days at the beach,
these vectors are called _sea_, _sky_, and _eye_. The screen plane is
parallel to the sea-sky plane; the sea vector points horizontally to
the right, sky points vertically upward. The eye is their cross
product, which points directly at the viewer.

   The sea-sky-eye basis is located at the _viewpoint_, the camera's
spatial location. The _target_, the origin of the screen plane, lies on
the line through the viewpoint in the direction opposite the eye
vector.  The distance from the viewpoint to the target is the _range_.
The orientation, viewpoint, target, and range completely (and
redundantly) determine the camera's geometric situation in the world.

A _lens_ maps the world to the screen.  `ePiX' comes with four lenses:
_shadow_ (the default), _orthogonal_, _fisheye_, and _bubble_. Each
lens simulates the appearance of world objects as seen by an observer
at the viewpoint. The shadow lens is point projection from the
viewpoint to the screen plane. The orthogonal lens projects from
infinite distance.  Each of the other lenses performs radial projection
to a sphere centered at the viewpoint, then maps the sphere to the
screen plane; the fisheye lens does orthogonal projection (so the
entire image lies inside a disk) while the bubble lens does
stereographic projection from the point directly behind the viewpoint.

   At the start of a figure, the camera looks down on the
$(x_1,x_2)$-plane from a distant point on the $x_3$-axis. The resulting
view, essentially projection along the axis, is suitable for
2-dimensional figures.

   The camera is manipulated similarly to a real camera:

  camera.at(P posn);          // set viewpoint to posn
  camera.look_at(P targ);     // set target to targ
  camera.range(double dist);  // fix target, move viewpoint
  camera.focus(double dist);  // fix viewpoint, move target
  camera.tilt(double angle);  // rotate about the sea axis
  camera.pan(double angle);   // rotate about the sky axis
  camera.roll(double angle);  // rotate about the eye axis
  camera.clip_range(dist);    // cull scenery closer than dist
 Explicitly setting the viewpoint or target makes the sky vector
parallel to the projection of the $x_3$ axis when possible; otherwise
the $x_2$-axis is used. Setting the range or focus moves the camera
parallel along the eye line. Each command re-sizes the image; note that
increasing the focus _enlarges_ the image. The three rotation
operations fix the viewpoint, but only roll fixes the target.

The camera has a _filter_, a color through which all scene elements are
passed. In addition to ordinary colors, two special classes of filter
are provided: _neutral_ filters, which preserve the visual appearance
of a color but (possibly) convert its model, and _process_ filters,
which separate cyan, magenta, yellow, and black.

   The default camera filter is `Neutral', which performs no model
conversion. Each color model has a neutral filter, RGB_Neutral, etc.,
which converts colors to that model. Colors can be specified in
arbitrary models, then trivially converted to `CMY' in the output file,
for example.

   There are four process filters, named C_Process, etc., one for each
`CMYK' channel. The command `camera.filter(M_Process())' sets the
camera to separate the magenta channel. Normally, a `filter' command
goes at the start of the file body, before any visible elements have
been placed in the scene.

`ePiX' provides two masking operations to handle figure elements that
lie far from the target: clipping (in the world) and cropping (in the
screen).  The "clip box" defines a set of "walls", and objects outside
the walls are not visible. Initially, the clip box is a large cube
centered at the origin. The clip box is set with the commands

  clip_box(P pt1, P pt2); // opposite corners
  clip_box(P pt);         // opposite corners pt and -pt
  clip_to (P pt);         //                  pt and P(0,0,0)

   The "crop box" is a rectangle in the screen plane.  When cropping is
active, objects that project outside this rectangle are not visible.
By default, the crop box is the bounding box.  Since the figure is
drawn (on the page) by affinely scaling the bounding box to a specified
`LaTeX' box, default cropping ensures that a figure lies inside the
printed region allocated by `LaTeX'.

   By default, cropping is off. The command `crop(bool)' (de)activates
cropping. The argument defaults to `true'.  The crop box is given by a
pair of opposite corners, `crop_box(pt1,pt2)'; third coordinates are
discarded. With no arguments, the command `crop_box()' re-sets the crop
box to the bounding box.

By default, drawing occurs in the Cartesian coordinate system of the
canvas. However, insets, subfigures, and legends are most naturally
composed in "local" coordinates, then placed into their final location
as a unit, a process called _layout_. `ePiX' 1.2.x implements layout
with the `screen' class.

At any point of a file body, some screen is _active_, or "open for
drawing". A new screen is created from a pair of opposite corners, but
is not used until explicitly activated.

  screen subfig(P(a1,b1), P(a2,b2)); // [a1, a2] x [b1, b2]
  activate(subfig);   // open subfig for drawing
  // commands to draw in subfig
  activate(canvas()); // re-activate the default screen
 Drawing commands work in an arbitrary screen just as they do in the
canvas. A screen need not be activated immediately.

   A screen's contents must be incorporated explicitly with an `import'
or `inset' command. Importing affinely scales the bounding rectangle of
the imported screen to the canvas. An `inset' command specifies corners
of the rectangle in the "parent" screen where the inset is placed.

  import();           // active screen to canvas
  import(subfig);     // subfig to canvas
  inset(P sw, P ne);  // active screen to specified rectangle
  inset(subfig, sw, ne); // subfig to specified rectangle
  inset(subfig);      // inset to subfig's corners

Each `screen' has a _border_ (a solid line around the edge) and a
_backing_ (a solid color underlayer). By default, both are empty. The
shape of the border and backing are determined by the _crop mask_,
which is rectangular (default), elliptical, or diamond-shaped.  The
crop mask also delimits the visible region when the `screen' is
cropped. These commands set attributes in the active screen.

  crop();          // activate cropping
  crop(false);     // deactivate cropping
  crop_diamond();  // <>-shaped mask
  crop_ellipse();
  border(Color col, string len);
  backing(col);
 The `len' argument is a number followed by a two-letter `LaTeX' length
string, all enclosed between double quote characters. This format is
`ePiX''s customary way of specifying lengths.

3.5 Drawing Attributes
======================

`ePiX' maintains drawing states for filled regions, paths, and text
objects.

Filling is either on or off. When filling is active, closed paths are
filled with the current _fill color_.

  fill();   // turn filling on
  fill(Color col); // turn filling on and set fill color to col
  nofill(); // turn filling off, same as fill(false);

Paths and borders of filled regions are drawn with two _pen_s, each
described by color and line width. The _line pen_ draws all path-like
objects. The _base pen_ does nothing unless it is wider then the line
pen, in which case it draws an underlayer or border on the line pen.

  pen(double w);   // set line pen width to w pt
  pen(string len); // set line width to len, e.g. "1pt"
  pen(Color col);  // set line color, keep width
  pen(col, len);   // set color and width
 In the fourth command, `len' may be either a length string or a
`double', interpreted as a width in `pt'.  There are `base' functions
with the same signatures and analogous meanings for the base pen.

   The line width can be set with named declarations; the optional
argument sets the line color:

  plain([col]); // 0.4pt
  bold([col]);  // 0.8pt
  bbold([col]); // 1.6pt

By default, path-like objects are drawn with solid lines. Dashed,
dotted, and free-form path style patterns are also available. (The
`base' underlayer is always solid.) The page length of a pattern
defaults to 12 pt, but can be set.

  line_style(string);
  dash_size(len=12);
 The path style is set with a WYSIWYG string of dashes, spaces, and
periods, representing a pattern of dashes, gaps, and dots.
[Image]

   For brevity and uniformity, named commands are provided.

  solid(); "-"     dashed(); "-  -"    dotted(); " . "
 A sequence of $n$ dashes, spaces, and dots corresponds to a dash/dot
pattern in an interval divided into $n$ subintervals of equal length.
If the $i$th character is a dash or space, the $i$th subinterval is
drawn solid or empty, respectively. If the $i$th character is a period,
a dot is placed at the midpoint of the $i$th subinterval.

   This pattern is applied to a path-like object as follows. The page
length of each edge is divided by the current `dash_size' and the
ceiling (next largest integer) taken. This many copies of the current
path style are scaled onto the edge. The first and last characters are
adjacent in repeated units.

   There are three inequivalent ways to adjust the dash length/dot
spacing in a non-line path: Change the `dash_length', create a path
with a different number of points, or use a longer, repetitive pattern.
For best results, the style string should not be longer than about a
dozen characters.

   If you need several dashed/dotted line styles in multiple figures,
it's best to define a custom header instead of hard-coding line styles.
See Section section, for guidance.

Two types of textual element may appear in a file: _labels_ (text
boxes) and _markers_ (`LaTeX' symbols). A marker occupies a box of zero
size, and is placed at a specified Cartesian location. A label has
typographical size, and is usually offset from its Cartesian location.
For placement, an _alignment point_ is attached to each label, and
Cartesian coordinates position the alignment point.

A label is printed as a `LaTeX' box.  By default, the alignment point
is its reference point, the intersection of the left edge and the
baseline, which is used by `LaTeX' to position the box on the
page:[Image]

   The alignment point may be _offset_ manually by a specified number
of `pt'. Additionally, a label's location with respect to the alignment
point can be chosen with an optional `LaTeX'-style alignment option.
This scheme allows labels to be placed easily where they will not
overlap other parts of the figure, and ensures labels stay properly
positioned when the size or aspect ratio of a figure changes.

  label(P posn, P offset, string msg, [align]);
  label(posn, msg);
 The first two components of the `offset' argument are numbers of `pt'
to shift the alignment point right and up.  The optional `align'
argument may be one--or an appropriate pair--of `t', `b', `r', or `l'
(top, bottom, right, left), or `c' (center). These alignment options
specify the position of the label _relative to the Cartesian location_
`posn', namely they work _opposite_ to the way they work in `LaTeX'.
[Image]\qquad   [Image]

   The `msg' argument is usually a snippet of `LaTeX' code enclosed in
double quotes. `C++' treats "\" as an escape character, so a double
backslash is needed in the source to get a single backslash in the
output. For example,

  label(P(0,0), P(2,-1), "$\\rho = \\sin\\theta$", br);
 positions an alignment point `2pt' right and `1pt' below the
(Cartesian) origin, and typesets the equation $\rho=\sin\theta$ below
and to the right.

   Labels can be rotated; the angle is set in current angle units with
the command `label_angle(theta)'. A rotation angle of 90 degrees prints
labels suitable for a vertical axis.  If an `eepic' file contains
rotated labels, the enclosing document must use the `rotating' package.
(`elaps' automatically includes all `LaTeX' packages that an `eepic'
file might require.)

By default, the font in an `ePiX' figure is that of the enclosing
document. The font size and face are changed with "declaration-style"
commands such as

font_size("Large");
font_face("sc");
 The argument of font_size is a valid `LaTeX' size, `normalsize' by
default; font_face accepts a two-letter string that is appended to the
string "`text'" to give a `LaTeX' font declaration command ("`textsc'"
above).

   Finer-grained control, such as different fonts or sizes in a single
label, must be accomplished by hard-coding `LaTeX' commands into an
ordinary label.

Each label command has a corresponding "mask" version (`masklabel')
that draws an opaque rectangle under the label text. The mask size
exceeds the label's size by an amount of _padding_, and the mask is
itself surrounded by a rectangular _border_, of specified color and
width.

  label_color(color);         // set label color
  label_mask(color=White());  // set mask color
  label_pad(string len);
  label_border(color, [len]); // set color (and length)
  label_border(len);          // set length only
  no_label_border();          // turn off borders

`ePiX''s marker types, listed in Table table, , are
obtained with the command marker(P pt, <MARKER TYPE>); Several
"dot-like" marker types are available by name: [Image]

  spot(P pt);  dot(P pt);   ddot(P pt);
     ---       box(P pt);   bbox(P pt);
  ring(P pt);  circ(P pt);     ---
 Each dot-like marker can also be called with label syntax, generating
a labeled marker with one command.

  dot(P posn, offset=P(0,0), msg="", align=none); // etc.

   By default, `spot' and `ring' are `4pt' in diameter; `dot', `box',
and `circ' are `3pt' in diameter; `ddot' and `bbox' are `2pt' in
diameter. At arbitrary diameter, a `spot' is $4/3$ the diameter of a
`dot' and a `ddot' is $2/3$ the diameter. The diameter of a `dot' is
set with `dot_size(diam)'.  The argument, 3 by default, is a number of
`pt'.

[Image]

Table[tb]

When constructing and placing a label,
   * Alignment offsets are specified in `pt' (i.e., page
     coordinates), not in Cartesian units. The alignment point should
     not   depend on the logical or printed size of the figure.

   * The label text is enclosed in double quotes (the single
     character `"'), and contains the `LaTeX' code to generate the
     label. Backslashes are doubled.

Old-style color declarations affect the fill color, line color, and
text color.

  rgb(r, g, b);      cmyk(c, m, y, k);
  rgb(P);            cmyk(P);  // for function-controlled colors
  red(d);  // similarly for other primaries

3.6 Creating and Drawing Objects
================================

Scene elements include geometric objects, coordinate grids, axis
labels, and function plots. A few commands create an object (a point,
line segment, circle, sphere, or plane) that can be used in subsequent
computations, but most drawing commands automatically create, draw, and
discard objects.

The simplest object in the world, and by far the most common named data
structure, is `P', an ordered triple of real numbers (double-precision
floats). The function `P(x1,x2,x3)' creates the point $(x_1,x_2,x_3)$.
If only two arguments are provided, $x_3=0$ by default. This convention
allows `ePiX' to treat 2- and 3-dimensional figures uniformly. The
standard basis is available: `E_1=P(1,0,0)', etc.

   A `P' ambiguously represents both a _location_ (point) and a
_displacement_ (vector).  In affine geometry, the concepts are
distinct: A sum of displacements is a displacement, and the sum of a
location and a displacement is a location, but two locations cannot be
added meaningfully. Almost all `ePiX' function treat a `P' as a point;
algebraic operators treat a `P' as a raw triple of numbers, and
commands that plot vector fields treat the field argument as a
displacement.

   Polar, cylindrical, and spherical coordinate `P' constructors are
sensitive to the current angular mode.

  P pt=polar(r,t);   // (r*Cos(t), r*Sin(t), 0)
  P pt=cis(t);       // (Cos(t), Sin(t), 0) = polar(1, t)
  P pt=cyl(r,t,z);   // (r*Cos(t), r*Sin(t), z)
  P pt=sph(r,t,phi); // polar(r,t)*Cos(phi) + (0,0,r*Sin(phi))

   Algebraic operations--addition/subtraction, scalar multiplication;
dot, cross, and componentwise products, and orthogonalization--can be
performed on `P's.  In compound expressions, the binary operators below
should be enclosed in parentheses, and scalars must be collected at
left, `P's at right.

  double u=pt.x1();   // first coordinate of pt, etc.
  P(a,b,c)|P(x,y,z);  // dot product, ax+by+cz
  P(a,b,c)&P(x,y,z);  // componentwise product (ax, by, cz)
  P(a,b,c)*P(x,y,z);  // cross product (bz-cy, cx-az, ay-bx)
  J(p);               // quarter turn about the x3-axis
  p%q;                // orthogonalization, p (mod q)
 Explicitly, `p\%q' is the unique vector `p+k*q' perpendicular to `q'.

   `P' operations express mathematical relationships, and therefore
imbue a figure with logical structure, making the input file easier to
read, modify, and maintain. Commonly, a file preamble will define a few
named points with hard-coded coordinates, then define additional points
of interest using `P' operators.

In addition to `P', objects of type `Circle', `Plane', `Segment', and
`Sphere' can be used for Euclidean geometry constructions. Simple
affine operations are supplied for each type, as is a `draw()'
function, which represents the object as a path in the screen.

  obj.shift(P arg);    // translate by arg
  obj.move_to(P arg);  // move center to arg
  obj.scale(double c); // scale about center by c
  obj.draw();
 A `Segment''s "center" is its midpoint. A `Plane' has no center;
`move_to' translates the `Plane' to pass through `arg', and `scale' has
no effect.

   A `Circle' data structure consists of a center, radius, and a
perpendicular unit vector. Three constructors are provided:

  Circle(center=P(0,0,0), double rad=1, normal=E_3);
  Circle(P center, P point);
  Circle(P p1, P p2, P p3);
 The second constructor creates the `Circle' parallel to the
$(x_1,x_2)$ plane, with given center, and radius equal to the distance
between the arguments. (A warning is printed if the second argument
does not lie on the circle, namely, if the arguments do not lie in a
plane parallel to the $(x_1,x_2)$ plane.) The third returns the
`Circle' passing through the given points; the points must not be
collinear.

   The data defining a `Circle' are recovered with member functions
named `center()', `radius()', and `perp()'.

   A `Plane' is specified by a point and normal vector, or by three
non-collinear points. The `draw()' function clips the plane and draws
the resulting polygon. Unless the clip box has been set manually, the
clipped polygon's vertices will have large coordinates.

   A `Segment' is constructed from its endpoints. The member function
`midpoint()' returns the center.

   A `Sphere' is specified by a point and a radius--by default the
origin and unity, or by the center and a point on the sphere. Member
functions `center()' and `radius()' return the defining data.
Capabilities specific to geography and spherical geometry are described
below, pp. See non-euclff.

   The `draw()' function of a `Sphere' draws the horizon visible from
the current viewpoint. While this horizon is a circle in object space,
its image in the screen is generally an ellipse.  Antipodal points are
not generally mapped to points symmetrically placed with respect to the
center of this ellipse. These effects are most pronounced when the
viewpoint is close to the `Sphere' and the center is not close to the
`target'.

To facilitate geometric computation, `ePiX''s `Circle', `Plane',
`Segment', and `Sphere' classes can be intersected with the `*'
operator.

   Naively, a `Circle' has a center, radius, and unit normal; a `Plane'
has a distinguished point and unit normal; a `Segment' has two
endpoints; a `Sphere' has a center and radius. An object is _malformed_
if these conditions are not satisfied.  The constructors return
well-formed objects with two exceptions: The `Circle' and `Plane'
constructors create malformed objects if called with three collinear
points.  The operator `*' returns a malformed object if either argument
is malformed, or if the operands are disjoint, tangent, or coincident.
Unlike in `ePiX'-1.0.x, malformedness is relatively benign: Calling
`draw()' on a malformed object has no effect.

A `frame' comprises three mutually perpendicular unit vectors.  The
constructor takes three vectors. The `frame''s third vector $e_3$ is
positively proportional to `v3', the second vector $e_2$ is positively
proportional to `v2\%v3', and the first is the cross product,
$e_1=e_2\times e_3$. Thus, a `frame' is right-handed, and does not
depend on `v1'.

  frame(P v1, P v2, P v3); // orthonormalize (v1, v2, v3)
 The standard `frame' `E_1', `E_2', `E_3' is constructed by `frame()'.

Basic path-like objects are drawn with named commands. Arguments of
polygon commands are endpoints/vertices. Except for `line' and `Line',
the following are subject to filling.

  line(P p1, P p2, [double expand]);
  Line(p1, p2);  // draw line through p1, p2 (crop required)
  triangle(P p1, P p2, P p3);
  rect(P p1, P p2);
  quad(P p1, P p2, P p3, P p4); // quadrilateral
  circle(ctr=P(0,0,0), rad=1, normal=E_3);
  circle(ctr, pt);
  circle(pt1, pt2, pt3);
 The optional `line' argument is an expansion parameter:
`line(p1,p2,t);' draws a segment centered at the midpoint of `p1' and
`p2', with length scaled by $2^t/100$. (Setting $t=100$ doubles the
length, while $t=-100$ halves the length.) The arguments of `rect()'
must lie in a plane parallel to a coordinate plane. The arguments to
`circle' commands are the same as for `Circle' constructors.

   Quadratic and cubic splines are described by their control points.  A
list of `P' is drawn as a "natural" spline (the $C^2$ piecewise cubic
curve with vanishing second derivatives at the endpoints); the number
of points per cubic segment must be specified.  Circular and elliptical
arcs are given by center, a basis, angular range, and an optional
number of intervals.

  spline(P p1, P p2, P p3, [int n]);       // quadratic
  spline(P p1, P p2, P p3, P p4, [int n]); // cubic
  spline(vector<P>, int n);                // natural spline

  arc(P ctr, rad, t_min, t_max);  // parallel to (x1,x2)-plane
  ellipse(P ctr, P v1, P v2);     // in plane spanned by v1, v2
  ellipse(P ctr, P v1, P v2, t_min, t_max, [int n]);
 If parameter bounds are omitted in an `ellipse' command, the entire
ellipse is drawn.  When the angular range subtends one or more full
turns in an `arc' or `ellipse' the curve is subject to filling.

   Commands for planar (half-)ellipses remain from `ePiX''s early days:

  ellipse(P ctr, P radius);
  ellipse_left(P ctr, P radius);
  ellipse_right(P ctr, P radius);
  ellipse_top(P ctr, P radius);
  ellipse_bottom(P ctr, P radius);
 If `radius' is `P(a,b)', these commands draw all or half of the
ellipse with given center in the $(x_1,x_2)$ plane, axes parallel to
the coordinate axes, and axis lengths $2a$ and $2b$.

Consider a path made up of equal-length segments that can point at any
angle of the form $2\pi k/n$ radians, for $0\leq k<n$, like spokes on a
wheel. A path is specified by a finite sequence of integers, taken
modulo $n$. For example, if $n=6$, then the sequence $0, 1, -1, 0$
corresponds to the ASCII path _/_.  `ePiX''s fractal approximation
starts with such a "seed" then recursively (up to a specified depth)
replaces each segment with a scaled and rotated copy of the seed. The
seed above generates the standard von Koch snowflake fractal. In code:

  const int seed[] = {6, 4, 0, 1, -1, 0};
  fractal(P(a,b), P(c,d), depth, seed);
 The first entry of `seed[]' (here 6) is the number of "spokes" $n$,
the second (4) is the number of terms in the seed, and the remaining
entries are the seed proper. The final path joins $(a,b)$ to $(c,d)$.
The number of segments in the final path grows exponentially in the
depth, so depths larger than 5 or 6 are likely to exceed the
capabilities of `LaTeX' and/or PostScript.

[Image]

Figure[hbt]

Line segments, splines, and arcs can be drawn with arrowheads at one
end.  In profile, an arrowhead's width is `3pt', and its height is 5.5
times the width.  The actual printed height depends on the head's
orientation with respect to the camera.  By default, an arrowhead is a
filled triangle. The shape and size are adjusted with declarations:

  arrow_width(w=3);   // width in pt
  arrow_ratio(r=5.5); // height-to-width
  arrow_camber(c=0);  // base indent as frac of ht
 [Image] Camber$=0$\qquad [Image] Camber$=0.25$\qquad [Image]
Camber$=0.5$ \\ The camber must be between $-1$ and $1$. Each `arrow'
command accepts an optional `scale' argument, which scales the
arrowhead.

  arrow(P tail, P tip, [scale]);
  arrow(P p1, P p2, P p3, [scale]);   // spline arrows
  arrow(P p1, P p2, P p3, P p4, [scale]);
  arrow(P ctr, P v1, P v2, t_min, t_max, [scale]); // ellipse
 A few "special-purpose" commands are supplied:

  dart (P p1, P p2);  // same as arrow(p1, p2, 0.5);
  aarrow(P p1, P p2); // double-headed arrow <--->
  arc_arrow(ctr, rad, t_min, t_max, [scale]);
 If an `arc_arrow' is too short, nothing is drawn.

A coordinate axis consists of a line between two points together with a
specified number of tick marks. Horizontal axes are generated with

  h_axis(p1, p2, n, align=c);    // n subintervals (n+1 ticks)
  h_log_axis(p1, p2, n, align=c, base=10);
 For vertical axes, use `v_axis'.  The style of tick mark is
appropriate for an axis of the given type.  Axis ticks are `6pt' long
by default. The command `tick_size(len)' changes this value. Horizontal
axis tick marks may be aligned `t' (above the axis) or `b' (below).
Similarly, vertical axis ticks may be aligned `r' or `l'.

   The endpoints arguments of a coordinate axis may be omitted, in which
case they default to $p_1=(x_min,0)$ and $p_2=(x_max,0)$ for a
horizontal axis, or to $p_1=(0,y_min)$ and $p_2=(0,y_max)$ for a
vertical axis. If the bounding box has integer width and/or height,
omitting the number of points draws tick marks one unit apart.

   Labels for a horizontal Cartesian or logarithmic axis are generated
with the commands

  h_axis_labels(P p1, P p2, int n, P offset, [align]);
  h_axis_masklabels(p1, p2, n, offset, [align]);
  h_axis_log_labels(p1, p2, offset, [align], base=10);
  h_axis_log_masklabels(p1, p2, offset, [align], base=10);
 Labels for a vertical axis are generated with `v_axis_labels', etc.
The labels are automatically generated to match their horizontal
location.  The first puts $(n+1)$ evenly-spaced labels on the segment
joining `p1' and `p2'. As with ordinary labels, the `offset' is in
`pt', and the optional `LaTeX'-style alignment option positions the
labels using their corners.  The second command draws masked labels
according to the current label masking attributes. The third writes
labels in exponential notation, using the Cartesian coordinate as
exponent.

   As for coordinate axes, the initial and final points may be omitted
in an `axis_[mask]labels' command, with the same defaults.  The
`offset' and number of labels must always be specified.

Cartesian grids fill a coordinate rectangle, and have a specified
number of lines in each direction. A polar grid has specified radius,
and numbers of rings and sectors.

  grid(n1, n2);         // fills the bounding box
  grid(p1, p2, n1, n2); // fills the box with corners p1, p2
  polar_grid(r, n1, n2);

   Log and semi-log grids are drawn with analogous syntax:

  log_grid (p1, p2, n1, n2, [base1], [base2]); // log-log
  log1_grid(p1, p2, n1, n2, [base]);           // log-lin
  log2_grid(p1, p2, n1, n2, [base]);           // lin-log
 The $n_i$ arguments dictate the number of squares, namely the number
of orders of magnitude spanned in the logarithmic direction(s).  The
(optional) base arguments default to 10, and control the number of
lines drawn per order of magnitude. As with Cartesian grids, the
corners are optional; if omitted, the grid fills the bounding box.

   Graph paper may be created by superimposing grids:
\beginminipage[b]2.5in

  pen(0.25);
  grid(10*xsize(), 10*ysize());
  pen(0.5);
  grid(2*xsize(), 2*ysize());
  pen(1);
  grid(xsize(), ysize());

   \endminipage   \qquad   [Image]

A `path' data structure is an ordered list of points that can be
cropped, clipped, mapped, concatenated, and drawn.  The first four
constructors mirror polygon-drawing commands above.  Function graphs
and parametric paths are built from a real- or `P'-valued function `f'
of one variable.

  path(p1, p2, expand=0);     // line (endpoints)
  path(p1, p2, p3, [n]);      // quadratic spline
  path(p1, p2, p3, p4, [n]);  // cubic spline
  path(p1, v1, v2, t_min, t_max, [n]); // ellipse
  path(f, t_min, t_max, [n]);

   The member function `pt()' accepts a `P' or three (or two) doubles
and appends the specified point to a `path'.  This snippet creates a
regular $n$-gon in `degrees()' mode:

  path ngon; // declare new path
  for (int i=0; i<=n; ++i)
    ngon.pt(cis(i*360.0/n));
 Compound paths may be built by concatenation.  If `path1' and `path2'
share an endpoint, the commands

  path1 += path2;
  path1 -= path2;
 replace `path1' with the result of traversing `path1' "forward", then
following `path2' in the forward or reverse direction (respectively).
For expected results, the first (or last) point on `path2' should be
the last point of `path1'. The notation suggests 1-dimensional homology
chains. The sample file `contour.xp' illustrates path creation and
manipulation.

   A `path' is a data structure, and must be drawn explicitly to create
visible output. By default a `path' is not a closed loop (even if the
first and last points are the same), and is not filled when drawn.
Member functions perform these tasks. Continuing the $n$-gon snippet
above,

  ngon.close(); // mark path as closed
  ngon.fill();  // draw filled region if filling is active
  ngon.draw();  // print to the screen
 `path::close()' adds a closing edge if necessary. Once a `path' is
closed, no more points can be added. A closed path clips and crops
differently than an open `path' with the same data. `path::fill()' has
no effect on an unclosed `path'.

The noun "map" refers to a `C++' function that accepts one or more
`double' arguments and returns a `double' or a `P'. Mathematically, a
map can be depicted in two ways: as a graph (which retains information
about the domain), or as a parametrized curve or surface (which
discards domain information). `ePiX' assumes that `double'-valued maps
are graphed and `P'-valued maps are drawn parametrically. Either sort
of depiction is called a "plot".  `ePiX' plots are either "wire mesh",
produced by a `plot' command, or "shaded", produced by a `surface'
command.

For the moment, "function" means "function of one variable" (precisely,
a `double'-valued function of a `double' variable). A function graph
depends on the domain and the number of points to use. Each of the
commands

  plot(f, t_min, t_max, n);
  polarplot(f, t_min, t_max, n);
  shadeplot(f, t_min, t_max, n);
 graphs the function `f' on the interval `[t_min, t_max]' by dividing
the interval into `n' subintervals of equal length.  The first gives a
Cartesian plot, the second a polar plot with bounds in current angular
units, the third shades the region between the graph and the horizontal
axis. If two functions are given to `shadeplot', the region between
their graphs is shaded.

An `ePiX' `domain' is a coordinate box of dimension one, two, or three,
specified by a pair of opposite corners and two _meshes_ ("coarse" and
"fine", respectively) which specify the amount of data to be plotted.
Plotting is explained in detail below.

  // [a1,a2] x [b1,b2]: n1 x n2 rectangles, m1 x m2 intervals
  domain R2(P(a1,b1), P(a2,b2), mesh(n1,n2), [mesh(m1,m2)]);

  // [a1,a2] x [b1,b2] x [c1,c2] divided analogously
  domain R3(P(a1,b1,c1), P(a2,b2,c2),
            mesh(n1,n2,n3), [mesh(m1,m2,m3)]);
 If unspecified, the fine mesh is the same as the coarse mesh. For
expected behavior, the coarse mesh should "divide" the fine mesh, in
that $m_i$ should be a (usually small) integer multiple of $n_i$ for
each $i$.

   A `domain' may be _resized_ in any coordinate for which the
thickness is positive, and can be _sliced_ by setting one variable to a
constant. The result of slicing is a `domain' whose dimension is one
smaller than the original.  Finally, "`slices'" operators return the
list of `domain's obtained by setting one variable to evenly-spaced
constants.  By default, the number of slices is specified by the coarse
mesh. An optional argument specifies the number of slices. This
argument need not be related to the coarse mesh.

  R2.resize2(a,b); // [a1,b1] x [a,b]
  R2.slice1(t);    // set x1 = t
  R3.slices3([n]); // (n+1) domains with x3 = const
[Image]

   \smallskip When possible, resizing preserves absolute grid sizes.
Generally, though, integer truncation occurs: If `R=domain(P(0,0),
P(1,1), mesh(10,4))', then `R.resize1(0,0.25)' is the rectangle
$[0,0.25]\times[0,1]$ subdivided into $2\times4$ subrectangles, since
$10\div4=2$ in integer arithmetic. To avoid unexpected behavior, choose
mesh sizes so that resizing does not cause integer truncation.

   The arguments of a `plot' command are a map, followed by either a
domain or its logical equivalent.

  double f(double t) { return t*t; }
  P F(double u, double v) { return P(u, v, exp(u)*Sin(v)); }
  P G(double u, double v, double w) { return P(v*w, u*w, u*v); }

  plot(f, a, b, n);       // f:[a,b] -> R, using n intervals
  plot(F, R2);            // graph of exp(u)*Sin(v)
  plot(G, R3.slice2(0.5); // G: R^3 -> R^3 restricted to y=0.5
 By (compiler-enforced) convention, `plot' commands involving a
`P'-valued map accept a `domain' argument, as in the second and third
commands above. To plot a `double'-valued function, by contrast, supply
the logical equivalent of a `domain', usually the endpoints and the
number of intervals, as in the first `plot' command above.

   Resizing and slicing allow a map `F' to be plotted selectively over
parts of its domain. This can be used to emphasize parts of the image,
layer scene elements, patch surfaces together, and so forth.  Resize
and slice(s) commands may be used directly in a `plot' command:

  plot(F, R2.resize1(0,0.5));
  plot(F, R2.slices1());

The `P' arguments of a `domain' are a pair of opposite corners. The
first `mesh' argument, the _coarse_ mesh, specifies the number of
subdivisions in each coordinate direction.  The second `mesh', the
_fine_ mesh, determines the number of points used in each direction
when plotting.

   Separating the roles of coarse and fine meshes allows a plot to
conform closely to a surface without using a fine grid of curves.  Both
parts of Figure fig, are drawn with a $6\times20$ coarse
mesh. In the first picture, the fine mesh is also $6\times20$, while in
the second, the fine mesh is $12\times60$.

[Image]     [Image]

Figure[hbt]

   The coarse mesh is significant only for domains of dimension at
least 2. The coarse mesh's size determines the number of curves or
surfaces plotted _perpendicularly_ to a coordinate direction, while the
fine mesh's size determines the number of segments used _along_ that
direction.  For predictable results, the fine mesh should be a small
multiple of the coarse mesh.

   Plotting works analogously for 3-dimensional `domain's and maps
depending on three variables: The "one-dimensional skeleton" of the
`domain''s image is drawn.  A `P'-valued map of three variables can be
plotted over a 1- or 2-dimensional `domain'. (The effect may be
unexpected unless the domain arises by slicing, however.) A map
depending on one or two variables cannot be plotted over a
3-dimensional `domain'.

`ePiX''s shaded surface plotting implements a degree of hidden surface
removal. The algorithm breaks a surface into mesh fragments, sorts them
in decreasing (approximate) distance to the camera, and prints them.
If filling is active, a mesh fragment is shaded according to the angle
between the normal vector and the direction to the camera, simulating
constant ambient lighting; otherwise, the current fill color is used.
This technique works fairly well for surfaces without intersection, and
even acceptably handles intersecting surfaces for which mesh elements
intersect only along boundaries.

   The syntax of a `surface' command is identical to a `plot' command
when only a single surface is drawn. For example,

  surface(F, R, cull=0);
 plots the `P'-valued function `F' over the domain `R', the shaded
equivalent of the corresponding `plot' command. The optional `cull'
argument removes elements that point toward (`cull=-1') or away from
(`cull=1') the camera. Naturally, orientation of mesh elements depends
on the parametrization `F', not merely on the surface. Culling reduces
the output file size, but is useful mostly for closed, convex surfaces.

   There are special commands for surfaces of rotation; each accepts a
final `cull' argument.

  surface_rev(f, t_min, t_max, n_lats, n_longs);
  surface_rev(f, g, t_min, t_max, n_lats, n_longs=24);
  surface_rev(f, g, R, frame coords);
 The first revolves the graph of $f$ about the $x$-axis, the second
uses the parametric curve $t\mapsto\bigl(f(t),g(t)\bigr)$ as profile.
In each case, the parameter interval [t_min,t_max] is divided into
n_lats equal-length subintervals, n_longs copies of the profile curve
are drawn, and the complete surface (one full turn) is drawn.

   The third form uses a `domain' to control the range of longitudes,
and draws a surface of rotation in the Cartesian coordinate system
defined by the orthonormal basis `coords', by default the standard
basis. The arguments `f' and `g' define a parametric curve in the plane
spanned by the first two elements of `coords', and the first element is
the axis of rotation.

   As in wire mesh plotting, the fine mesh is used to draw the
boundaries of surface patches; this tends to make surfaces look
smoother for modest-sized coarse meshes. If the coarse mesh is too
coarse, however, two visually undesirable effects can occur. First,
adjacent regions of the surface may be shaded very differently, since
shading is constant over patches defined by the coarse mesh. Second, a
patch nearly tangent to a line of sight may be drawn badly if the patch
bends back on itself, since the boundary of the _patch_ is drawn, not
the visible edge of the mathematical surface. See
`samples/artifacts.xp'.

A scene containing two or more shaded surfaces cannot generally be
built up one surface at a time. Instead, multiple surfaces must be
assembled into a single data structure before they can be drawn.
Multiple surfaces are built from one or more maps and one or more
2-dimensional `domain's. In the code snippets below, `F' and `G' are
`P'-valued functions of 3 variables, and `R' is a 3-dimensional
`domain'.

   To plot the images of several `domain's under a _single map_,
assemble the `domain's into a list if necessary, then issue a `surface'
command:

  surface(F, R.slices3(), cull=0);

  domain_list DL(R.slice1(0));  // build domain list
  DL.add(R.slice2(0.5));        // add a domain, etc.
  surface(G, DL, cull=0);       // draw
 For multiple maps, `ePiX' provides the `scenery' class. Conceptually,
`scenery' is an agglomeration of shaded surfaces, built one surface at
a time from maps and 2-dimensional `domain's. The `add' function
accepts two arguments--a map, and either a `domain' or a list of
`domain's--and contributes its data to the `scenery' rather than
plotting immediately. Completed `scenery' is drawn manually.

  scenery S(F, R.slice3(0.25)); // S contains one surface
  S.add(F, R.slice2(0));        // S contains two surfaces
  S.add(G, R.slices1(3));       // S contains six surfaces
  S.draw(cull=0);
 Complete examples are included in the `samples' directory:
`spherical.xp' and `minkowski.xp'.

   In principle, a scene may contain arbitrarily many surfaces. However,
figures that contain many objects tend to tax `LaTeX''s internal
stacks. Frequent color changes exacerbate the problem.  Even if you use
`hugelatex' (or increase `LaTeX''s memory), a figure containing more
than a few thousand mesh elements is unlikely to compile. At moderate
resolution, a surface can easily contain 1000 patches. Each shell
script has a command-line option to invoke `hugelatex'; your mileage
may vary.

By default, a `surface' or `scenery' is colored according to the
current fill color. For finer control, each `surface', `surface_rev',
and `scenery' command accepts an optional position-dependent `color'
specification.

  surface(F, R, color, cull=0);
  surface_rev(f, [g], t_min, t_max, n_lats, n_longs, color);
  surface_rev(f, g, R, color, [coords]);

  scenery S(F, R, color);
  S.add(F, R, color);
 The `color' argument is a `P'-valued function of two or three
`double's whose output is interpreted as a set of `RGB' densities. If
`color' takes two arguments, they are `domain' coordinates, and the
surface is colored according to parameter values. If `color' takes
three arguments, they are Cartesian coordinates, and the surface is
colored according to spatial location.  Please see the sample files
`surface_shade.xp' and `S2_harmonics.xp'.

Files of numerical data can be created, manipulated, analyzed, plotted
(paths, scatter plots, and histograms), read, and written.  The format
for a data file is one or more floating-point numbers per line, with
the same number of entries per line. Anything that appears on a line
after the `LaTeX' comment character `\%' is a comment.

   `ePiX' provides two `plot' commands for file data. The first
facilitates plotting selected columns; the second simplifies plotting
the first two columns with one or both scales logarithmic. Either form
can be used to plot selected columns logarithmically.

   The general commands read numbers from two or three columns of a
specified file, pass them as arguments to a `P'-valued function `F',
and plot the resulting points:

  plot("filename", STYLE, [i_1], [i_2], [i_3], [F]);
  plot("filename", STYLE, F, [i_1], [i_2], [i_3]);
 The first argument is the name of the data file. The `STYLE' may be
`PATH', which joins the points in the order they appear, or any of the
marker types in Table table, .  The integers $i_k$
specify columns from which to extract data; these default,
respectively, to the first column, second column, and null (a column of
zeroes). If the "coordinate system" `F' is omitted in the first
command, it defaults to the Cartesian point constructor. The function
`F' is mandatory in the second form; useful choices include `log_log',
`log_lin', and `lin_log', which plot the corresponding coordinate
logarithmically.

For more elaborate analysis, the `data_file' class presents an
interface to a file as an ordered list of columns. There are two
general ways to create a `data_file': read in an external file, or
generate data (up to three columns) using specified `double'-valued
functions. In the constructors below, each function `fi' is a
`double'-valued function of one variable.

  data_file DF("my_data"); // read data from disk file
  data_file DF(f1, t_min, t_max, num_pts); // values of f1
  data_file DF(f1, f2, t_min, t_max, num_pts);
  data_file DF(f1, f2, f3, t_min, t_max, num_pts);
  data_file DF(3);  // create empty data_file with 3 columns
  DF.read("file1"); // read a disk file

   Columns of a `data_file' can be transformed by a user-specified
function, averaged, correlated, extracted (for use by other code),
scatter plotted, and written to a disk file at specified precision.
Below, the function `f' is a `double'-valued function of one variable
and `F' is a `P'-valued function of two or three variables, whose
components are written back to the selected columns.

  DF.transform(f, i);    // apply f to selected column(s)
  DF.transform(F, i=1, j=2);
  DF.transform(F, i, j, k);
 Basic statistical operations on columns are provided.

  DF.dot(i,j);        // dot product of columns i, j
  DF.avg(i);          // mean of column i
  DF.var(i);          // population variance
  DF.covar(i,j);      // covariance
  DF.regression(i,j); // plot regression line
 A `data_file' is scatter plotted using syntax as described above.  %
The output is cropped automatically to the bounding box.

  DF.plot(STYLE, [i1], [i2], [i3], [F]);
  DF.plot(STYLE, F, [i1], [i2], [i3]);
 Histograms and bar charts are described below.

   A `data_file' can be written to a disk file as raw data, or in
specified format. Below, `fmt' denotes a `string'-valued formatting
function of two variables and `myfile' is the name of the disk file to
be written.

  DF.precision(4);    // set to 4 significant figures
  DF.write("myfile"); // write as tab-separated columns
  DF.write("myfile", fmt, [i1], [i2]); // apply fmt to cols
 A column can be extracted as a `C++' `vector' for use by another
function.

  DF.column(i);    // i-th column
  DF.column(f, i); // i-th column, transformed by f

`ePiX' provides a `data_mask' class for culling data from a file
according to the values in a specified column, and a `data_bins' class
for sorting data by value.

   A `data_mask' consists of an interval of numbers and a "filter"
function. The (closed, open, or half-open) interval is given as a
string in standard mathematical notation, or by its endpoints (for a
closed interval).  The filter is a `double'-valued function of
`double', by default the identity, $f(x)=x$.

  data_mask dm("[a, b]", [f]);
  data_mask dm(a, b, [f]);
 A `data_mask' "passes" inputs $x$ if $f(x)$ lies in the interval. The
member function `reverse()' inverts this logical test.

   The `data_file' class has `prune' functions to cull rows for which a
specified column's entry satisfies a `data_mask''s criterion.

  DF.prune(dm, i);   // remove row if i-th column entry fails
  DF.prune(a, b, i); // remove row if i-th column outside [a,b]

   A `data_bins' object models an interval subdivided at specified
locations, not necessarily equally-spaced. The lifetime of a
`data_bins' has two stages. In the first, "cuts" (endpoints of
subintervals) are added. Once data is read, the cuts are "locked", and
cannot subsequently be changed.

  // [xmin, xmax] divided into n equal intervals, 1 by default
  data_bins db(xmin, xmax, [n]);
  db.cut(x);  // add a cut at x (if x is in bounds)
  db.read(vector<double>); // read data, lock bins

   A `data_bins' object can be plotted as a histogram (rectangles'
_area_ is proportional to the bin population), bar chart (rectangles'
_height_ is proportional to the bin population), or spline
interpolation of a bar chart.

  db.histogram(c=1);  // c = vertical scale factor
  db.bar_chart(c=1);
  db.plot(c=1);
 By default (`c=1'), the height of a bar chart rectangle is the
fraction of the total population contained in the bin; thus, the height
is always between 0 and 1. For a histogram, the height of a rectangle
is the fraction of the population per horizontal unit contained in the
bin; thus, the total area over an interval $[a,b]$ does not depend on
how $[a,b]$ has been subdivided (so long as $a$ and $b$ are cuts). The
sample files `dataplot.xp' and `histogram.xp' illustrate use.

`ePiX' provides high-level commands for plotting derivatives and
definite integrals, Riemann sums, tangent lines, slope- and vector
fields, and solutions of planar and spatial systems of differential
equations.

   In this section, `f' and `g' are `double'-valued functions of one
variable.

  sup(f, a, b);     // max/min of f on [a,b]
  inf(f, a, b);
  newton(f, g, x0); // find approximate crossing point
 Newton's method returns the crossing point of the given functions,
starting from the specified seed, which should be reasonably close to
the expected solution. If a critical point is hit or 5 iterations pass,
a warning is issued and the current result (probably incorrect) is
returned. The second function $g$ defaults to the zero function if
omitted.

The classes `Deriv' and `Integral' are used to calculate values of
derivatives and integrals, and to plot these functions.

  Deriv df(f); // function object: df(x) = f'(x)
  df.eval(t);  // return f'(t)
  df.left(t);  // deriv from left at t:  (f(t)-f(t-dt))/dt
  df.right(t); // deriv from right at t: (f(t+dt)-f(t))/dt

  Integral prim(f,a); // function object: prim(x) = int_a^x f
  prim.eval(b);  // numerical integral of f over [a,b]
  double val(Integral(f).eval(1));   // val = \int_0^1 f
 The lower limit on an integral is 0 by default. `Deriv's and
`Integral's can be used directly in a `plot' command:

  plot(Deriv(f), a, b, n);  // plot f' over [a,b]
  plot(Integral(f, x0), a, b, n);
  riemann_sum(f, a, b, n, TYPE);
 The second graphs the definite integral $x\mapsto\int_x_0^x f(t)\,dt$
over $[a,b]$. As above, $x_0$ defaults to 0. The third draws rectangles
or trapezoids whose area approximates the definite integral of $f$ over
$[a,b]$. The `TYPE' may be `UPPER', `LOWER', `LEFT', `RIGHT', `MIDPT',
or `TRAP'.

   Tangent lines and envelopes (families of tangent lines) are drawn
with

  tan_line(f, t);                // f real- or vector-valued
  envelope(f, t_min, t_max, n);  // family of tangent lines
  tan_field(f, g, t_min, t_max, n); // field of tangents
 The sample files `conic.xp' and `lissajous.xp' illustrate these
features.

Let `F' be a `P'-valued function of two or three variables.

  ode_plot(F, p_0, t_min, t_max, n);
  flow(F, p_0, t_max, n);
 The first plots the solution curve of the initial-value problem
$\dotx=F(x)$, $x(0)=p_0$, over the specified time interval.  If $t_min$
is omitted, its value is 0, so the curve starts at $p_0$. With manual
calculation to rotate a planar field a quarter turn, `ode_plot' can be
used to draw level curves (isobars) of a function of two variables; see
the sample file `dipole.xp'.  The `flow' function returns the result of
starting at $p_0$ and flowing by $F$ for time $t_max$, using Euler's
method with $n$ timesteps.  This is useful for placing markers or
arrowheads precisely along a flow line.

   A planar or spatial vector field itself may be plotted over a domain
`R' in three styles:

  vector_field(F, R, [scale]); //  true length
  dart_field  (F, R, [scale]); // const length
  slope_field (F, R, [scale]); // const length
 The field is sampled at the grid points of the coarse mesh. If the
domain is two-dimensional, the plot is a planar slice of the field,
even if the field depends on three variables. If the domain is
three-dimensional, the field is drawn in successive slices
$x_3=\mathrmconst$, starting at the height of the first corner of `R'
and ending at the height of the second corner.

   The optional final argument, which defaults to $1$, scales the
arrowheads in a vector field, and scales the (constant) length of field
elements for slope and dart fields. The sample files `layout2.xp',
`lorenz.xp', `slopefield.xp', and `vfield.xp' illustrate usage.

   In each field-plotting command, the domain argument may be replaced
by two points, representing corners of a coordinate rectangle, and two
integers, the number of grid intervals in the selected coordinate
directions. Only planar slices of a vector field can be plotted using
the alternative syntax.

`ePiX' provides limited features for spherical and hyperbolic geometry:
the ability to draw lines in the half-plane and Poincar\'e disk models
of the hyperbolic plane, and to draw latitudes, longitudes, great
circle arcs, spherical triangles, regular polyhedra, and parametrized
curves on a sphere.

   Hyperbolic line segments are specified by their endpoints in the
upper half space or ball (Poincar\'e) models.  In each case there is no
output if either endpoint lies outside the model.

  hyperbolic_line(p, q);
  disk_line(p, q);
 For compatibility with 2-dimensional hyperbolic space, the half-space
model is the set $\(x_1,x_2,x_3)\mid x_2>0\$.

   A `frame' determines geographical coordinates on a `Sphere': the
first element points toward longitude 0 on the equator, the third
element points to the north pole.  A latitude line depends on a
`Sphere', a `frame', the numerical latitude, and a range of longitudes.
A longitude line is described similarly.

  latitude(lat, long_min, long_max, Sphere S, frame coords);
  longitude(lngtd, lat_min, lat_max, Sphere S, frame coords);
 By default, `coords' is the standard `frame' and `S' is the unit
sphere. These commands draw only the portion of the curve that is
visible from the current viewpoint. The function `back_latitude' draws
the invisible portion of a latitude line.

   Spherical arcs and triangles are described by their endpoints. Only
the direction vector from the center of the sphere to an endpoint is
significant; if a sphere is scaled or moved, the same function call
will draw the corresponding object on the new sphere.

   The following draw the visible (front) portions of great circle arcs:

  front_arc(p1, p2, S);  // short arc on S from p1 to p2
  front_arc2(p1, p2, S); // arc from p1 to -p1 through p2
  front_line(p1, p2, S); // great circle through p1 and p2
 Triangles and regular (Platonic) polyhedra are provided. The sample
file `sample/polyhedra.xp' illustrates usage.

  front_triangle(p1, p2, p3, S); // spherical triangle
  front_tetra(S, coords);  // regular tetrahedron
  front_cube(S, coords);   //    hexahedron
  front_octa(S, coords);   //    octahedron
  front_dodeca(S, coords); //    dodecahedron
  front_icosa(S, coords);  //    icosahedron
 Each function has a `back' version, which draws the hidden portion.
The tetrahedron, cube, and octahedron are (up to scale) inscribed in
the cube of side length $2$ centered at the origin whose sides are
parallel to `frame'. The point $(1,1,1)$ is a vertex of the tetrahedron.

   Up to scale, the icosahedron's vertices lie on the golden rectangle
with vertices $(\pm\gamma,0,\pm1)$ and its images under cyclic
permutation of coordinates. The dodecahedron is dual to the icosahedron.

Parametrized paths on a `Sphere S' (by default the unit sphere) can be
specified either by radial projection of a `P'-valued curve, or by
stereographic projection of a plane curve given as a pair of
`double'-valued functions:

  frontplot_R(phi, t_min, t_max, n, [S]);    // radial
  frontplot_N(f1, f2, t_min, t_max, n, [S]); // from north pole
  frontplot_S(f1, f2, t_min, t_max, n, [S]); // from south pole
 Attempts to perform radial projection on a path through the origin
will generate division-by-zero errors. Stereographic projection maps
the equatorial plane $\x_3=0\$ to the unit sphere by projection from
the corresponding pole: $N=(0,0,1)$, $S=(0,0,-1)$.

   Each spherical plot command has a `back' version that prints only
the portion of the path invisible from the current viewpoint.  Because
of the way `ePiX' layers output, it is generally best to put hidden
portions of the input before visible portions, with line width and/or
style that suggests hidden lines.

3.7 More About `C++'
====================

A textbook or similarly detailed reference is essential for serious
study of `C' or `C++'. _The `C' Programming Language_, second edition,
by Brian Kernighan and Dennis Ritchie `KnR', is an excellent,
manageable resource for the basics of procedural programming, while
_C++ Primer Plus_, by Stephen Prata, clearly lays out the extensive
details of `C++'.

   `C++' is a powerful, complex language whose syntax is similar to that
of `C', or to the scripting languages of Maple and Mathematica. An
`ePiX' input file is source code for a `C++' program that writes an
`eepic' file as output.  `ePiX' may be viewed as an extension to `C++';
in the same way that `LaTeX' furnishes a high-level interface to `TeX',
`ePiX' provides a high-level bridge between the computational power of
`C++' and the `LaTeX' `picture' environment.

   Like all high-level programming languages, `C++' provides variables,
functions, and control structures. Variables hold pieces of data such
as numerical values and geometric locations, while functions operate on
data. A control structure, such as a loop or conditional statement,
affects the program's course according to the program's current state.
A source file is composed primarily of "statements", which perform
actions ranging from defining variables and functions to setting figure
attributes, performing calculations, and writing objects to the output
file.

Names of variables and functions may consist (only) of letters, digits,
and the underscore character. The first character of a name must not be
a digit, and the language standard reserves names starting with
underscore for library authors. Names are case-sensitive, but it's
usually a bad idea to use a single name capitalized and uncapitalized
in a single file. Numerous capitalization conventions are used
informally; this document uses uncapitalized words separated by
underscores for variables and functions, and occasionally uses all
capitals for constants. As with names of `LaTeX' macros, primary
considerations are clarity (of meaning), readability, and consistency.

   Every variable in `C++' has a "type", such as integer (`int'),
double-precision floating point (`double'), or Boolean (`bool', true or
false).  `ePiX' provides additional types, the most common of which is
`P', for point. The construct `P(x,y,z)' creates $(x,y,z)$, while
`P(x,y)' gives $(x,y,0)$, which is effectively the pair $(x,y)$.  A
variable is defined by giving its type, its name, and an initializing
expression.

   In `C' and `C++', a _pointer_ is a variable that holds the memory
address of another variable. Though more subtle than ordinary
variables, pointers are useful in expressing certain algorithms, such
as sorting.\footnoteIn Japan, buildings' addresses are assigned
chronologically, rather than according to street location. A building
is analogous to a variable, while the address is a pointer. If the
Japanese parliament passed a law mandating that buildings be addressed
consecutively along the street, there would be two ways to proceed: Dig
up and relocate each physical building (move variables), or re-number
the buildings in place (sort pointers). For similar reasons of
efficiency, `C++''s sorting algorithms work with pointers.

   `C++' also provides _reference_ variables, which allow a variable to
be given an additional name. Their use arises because of the way `C++'
functions treat their arguments, see page references.

In a programming language, the term "function" refers to a block of
code that is executable by name.  A `C++' function takes a list of
"arguments", and has a "return value".  This information, together with
the function's name, must be provided when a function is defined.  A
function may not be defined inside another function. However, a
function may call other functions (including itself) as part of its
execution:

  int factorial(unsigned int n)
  {
    if (n == 0) return 1;
    else return n*factorial(n-1);
  }

   The special type `void' represents a "null type". A function that
performs an action but does not return a value has return type `void'.
A function that takes no arguments may be viewed as taking a single
`void' argument.

   Every `C++' program has a special function `main()', which is called
by the operating system when the program is run. The arguments of
`main()' are command-line arguments, and the return type is an integer
that signals success or failure. User-specified functions must be
defined before the call to `main()' or in a separately-compiled file.

   Functions in `C++' may be as simple as an algebraic formula or as
complex as an arbitrary algorithm. Greatest common divisors, finite
sums, numerical derivatives and integrals, solutions of differential
equations, recursively generated fractal curves, and curves of best fit
are a few applications in `ePiX'. Several sample files contain
user-level algorithms, which do not require knowledge of `ePiX''s
internal data structures. The source file `functions.cc' contains
simple functions defined by algorithms, and `functions.h' illustrates
the use of `C++' templates. Other source files, such as `plots.cc', may
be consulted for Simpson's rule, Euler's method, and the like.

   An error, such as division by zero or an attempt to intersect
parallel lines, may occur when a function is executed. In this
situation, a `C++' function can "throw an exception", or return an
error type that the caller "catches" and handles. If an uncaught
exception is thrown, the program terminates. `ePiX''s intersection
operators throw exceptions when certain conditions are not met.

`C++' knows several familiar mathematical functions by name:

  sqrt   exp   log   log10   ceil   floor   fabs
 (`fabs' is the absolute value for a floating-point argument.)  `ePiX'
provides trig and inverse trig functions sensitive to angular mode:
\begintabularp1.25inp1.25inp1.25in   `Cos'  & `Sin'  & `Tan' \\   `Sec'
& `Csc'  & `Cot' \\   `Acos' & `Asin' & `Atan' \endtabular

   The inverse functions are principle branches.

   The function `pow(x,y)' returns $x^y$ when $x>0$, and `atan2(y,x)'
(N.B. argument order) returns $\mathrmArg(x+iy)\in(-\pi,\pi]$, the
principle branch of arg.  `C++' knows many constants to 20 decimal
places, such as `M_PI', `M_PI_2', and `M_E' for $\pi$, $\pi/2$, and $e$
respectively.  `ePiX' defines a few additional functions:

  sgn   zero   sinx   cb
[Image]\qquad   [Image]\qquad   [Image]

   `sgn' is the signum function; `zero' is the constant function;
`sinx' is the function $x\mapsto \sin(x)/x$ with the discontinuity
removed; `cb' (for "Charlie Brown") is the period-2 extension of the
absolute value function on $[-1,1]$.

   The GNU `C++' library defines other functions, including inverse
hyperbolic functions (`acosh', etc.), `log' and `exp' with base 2, 10,
or arbitrary $b$ (`log2', etc.), the error and gamma functions (`erf'
and `tgamma' [sic], respectively), and Bessel functions of first and
second kind: `j0', `j1', `y0', etc. Use, e.g., `jn(5, )' to get higher
indices.  The GNU `C' library reference manual `GNUC' describes these
and other functions in detail.

   Functions may be used in subsequent definitions, and functions of two
(or more) variables are defined in direct analogy to functions of one
variable:

double f(double t) { return t*t*log(t*t); } // t^2 \ln(t^2)
double g(double s, double t) { return exp(2*s)*Sin(t); }

Unlike `C', `C++' supports "object-oriented programming". In a
nutshell, a _class_ is an abstraction in computer code of some concept,
such as a point, a sphere, a mapping that can be plotted, or a camera.
Classes allow a programmer to separate an object's _interface_ (the set
of meaningful operations) from its _implementation_ (the data
structures and algorithms that realize the interface).

   A class implementation consists of _members_ (named data elements)
and _member functions_ (functions that belong to the class and have
free access to members).  `C++' classes enforce access permissions on
their members, protecting data from being manipulated except as
promised by the interface.

   An ideal interface looks like a black box: It hides the
implementation completely.  In order to cooperate, two classes need
only know each other's interfaces. This separation of form and function
modularizes a program, and facilitates debugging, code reuse, and
overall maintainability, particularly in large programs.

   In simple programming, classes may be treated like built-in types.
Each class object has its own member functions, whose call syntax
differs from standard function calls:

  Circle C1(P(1,0), 1.5); // circle of given center and radius
  C1.draw();              // member function Circle::draw();
 Naturally, this call draws the circle `C1'. Generally, a member
function call consists of a class object's name, a period, and the name
of the member function. Arguments, if any, go in the parentheses after
the member function name, just as in a regular function call.

   A few short paragraphs cannot do more than scratch the surface of
classes and object-oriented programming. Please consult a book, such as
Stroustrup `S', for details.

`C' and `C++' are "call by value" languages. Variables are not passed
to a function; instead a copy of the value is made, and the function
operates only on the copy. Though this feature causes occasional
inconvenience, it prevents variables from being altered unexpectedly by
a function call in a different part of the program.  Calling by value
therefore localizes the logic of a program, and circumvents
easy-to-write but extremely hard-to-find bugs.

   There are two common reasons to grant a function access to a variable
rather than a copy: The variable is a large data structure for which
copying is prohibitively "expensive", or the function needs to modify
its arguments' values (e.g., a function `swap(x,y)' that exchanges the
values of `x' and `y'). In each situation, a function's value may be
passed as a reference. Roughly, a reference provides the size
efficiency of a pointer (memory address), but can be created and
manipulated in a file like an ordinary variable.

   Every reference variable is "bound" to an existing object. The
statements

  double  x=1;   // ordinary variable definition
  double& rx=x;  // bind a reference, signified by &
 define a variable `x' having the value 1, and bind a reference
variable `rx' to it. As long as `rx' exists, it refers to `x'. If the
value of `x' changes, the value of `rx' does as well. Conversely, the
value of `x' can be altered by assigning to `rx'. However, `rx' is the
size of a pointer, regardless of the size of `x', so `rx' can be passed
efficiently in a function call.

   Occasionally, a function has a legitimate need to alter the values of
its arguments. In such a case, call by reference can provide a tidy
solution. This technique of updating variables is sometimes touted as a
feature in `C++' texts. However, such trickery circumvents the data
encapsulation of calling by value, and should be avoided unless
absolutely necessary. If a function merely "updates" the value of a
variable, probably the variable should be of class type, and the update
should be performed by a member function.

   Functions that use reference variables for large arguments can do so
safely by declaring their arguments to be `const'. This keyword
signifies that the function does not change the value of the argument.
Any attempt to modify a `const' argument will be caught by the compiler.

   A function declaration must indicate that its arguments are
references. The declarations below have the indicated idiomatic
meanings.

  class matrix;
  double det(matrix); // call by value, perhaps inefficient
  matrix& transpose(matrix&); // probably changes its argument
  double trace(const matrix&); // does not change its argument
 Unlike pointer arguments, reference arguments impose no syntactic
burden on the user. If `A' is a `matrix', then `transpose(A);' and
`trace(A);' will compile. You need not declare explicit reference
variables and pass those to the function.

`C++' provides "overloading": Multiple functions can be given the same
name, so long as the number and/or type of their arguments differ. (It
is _not_ enough for the return types alone to differ.  The compiler
must be able to select a function from its calling syntax.)  To the
user, the appearance is that a single function intelligently handles
multiple argument lists. Naturally, overloaded names should refer to
functions that are conceptually related.  `ePiX' provides numerous
`plot' functions, for instance.

A `C++' statement ends with a semicolon. A collection of statements
enclosed by curly braces is a "code block", and may be viewed as a
single logical statement. Curly braces determine a "scope", inside of
which variable names may be re-used without ambiguity. A variable
defined between curly braces is said to be _local_ (to the scope in
which it is defined); its value cannot be used out of scope.

   Function bodies are code blocks, as are the alternatives associated
to control statements. The compiler is not picky about spaces, tabs, and
newlines, so an input file should be organized in a way that makes the
file easy to read. Indentation signifies levels of nesting within code
blocks, but specific details are the focus of passionate debate. As
with variable naming, clarity and consistency are the important
criteria.

A `C++' source file is compiled in multiple stages that occur
transparently to the user. The first step, pre-processing, involves
simple text replacement for file inclusion, macro expansion and
conditional compilation. Next, the source is compiled and assembled:
Human-readable language instructions are parsed, then represented in
assembly language. Finally, the object files are linked: Function calls
are resolved to hard-coded file offsets, possibly involving external
library files, and the program instructions are packaged into an
executable binary that the operating system can run.

   Pre-processing is used much less in `C++' than in `C'; the language
itself supports safer and more featureful alternatives to macros, such
as `const' variables and inline functions. File inclusion and
conditional compilation are the chief uses of the pre-processor. Lines
of the form

  #include <cstdlib>
  #include "epix.h"
 cause the contents of a _header file_ to be read into the source file.
A header file contains variable and function _declarations_, statements
that specify types and names but do not define actual data.
Declarations tell the compiler just enough to resolve expressions and
function calls without knowing specific values or function definitions.

   Conditional compilation is similar to conditional `LaTeX' code. For
example, a file might produce either color or monochrome output as
follows:

#ifdef COLOR
  ...  // code for generating color figure
#endif // COLOR
#ifndef COLOR
  ...  // monochrome code
#endif // undef COLOR
 The "compiler symbol" `COLOR' is an ordinary `C++' name. To control
compilation, either put a `\#define COLOR' line in the file, or
(better) supply the flag on the command line: \\   epix -DCOLOR
<file.xp> \\ Every `\#ifdef' must have a matching `\#endif'. Commenting
the `\#endif' is a good habit; in a realistic file, the start and end
of a conditional block may be separated by more than one screen.

As a programming language, `C++' provides certain features common to
all languages (such as `LaTeX', Metapost, Perl, Lisp\ldots) and adheres
to rules of grammar. Salient differences between `LaTeX' and `C++'
include:

  1. Every `C++' statement and function call must end with a
     semicolon. An omitted semicolon may result in a cryptic error
     message from the compiler. Pre-processor directives, which start
     with a `\#', do not end with a semicolon.

  2. Backslash is an escape character in `C++':
       // Put label $y=\sin x$ at (2,1)
       // Note single  ^ backslash in output
       label(P(2,1), P(0,0), "$y=\\sin x$");
       //       Double backslash ^^ in source

  3. Variable and function names may contain letters (including
     underscore) and digits _only_, are case sensitive, and must
     begin with a letter.

  4. Variables in `C++' must have a declared _type_, such as   `int'
     (integer) or `double' (double-precision floating   point). If a
     variable has global scope and its value does not   change, the
     definition should probably come in the preamble or at   the
     beginning of `main'. Local variables should be defined in   the
     smallest possible scope. Unlike `C', `C++' allows variables to be
     defined where they first appear.

  5. `C++' requires explicit use of `*' to denote multiplication;
     juxtaposition is not enough. `C++' does not support the use of   ^
     for exponentiation, e.g., t^2 is invalid. Instead,   use `t*t' or
     `pow(t,2)'.

  6. `C++' has single- and multi-line comments. Everything between a
     double slash and the next newline is ignored, while the strings
     /* and */ delimit multi-line comments. A single-line   comment may
     appear within a multi-line comment, but the compiler   does not
     nest multi-line comments.

   Between them, `C' and `C++' have about 100 reserved keywords which
cannot be used as function or variable names.

3.8 Attribute Quick Reference
=============================

In the body of an input file, the "drawing state" determines the
figure's appearance. Attributes are declarations, set by commands that
accept arguments of the stated type.

   A `len' argument is a double-quoted string containing a number and a
two-letter `LaTeX' length unit, such as `"1.5pt"' or `"6cm"'. A `color'
argument is a named primary (`Red()', `Cyan()', `White()', etc.), a
`Color' specified by densities (`RGB(...)', `CMYK(...)', etc.), or a
`Color' object. Using `Neutral()' as a `Color' argument generally turns
off the corresponding attribute.

   * Angular mode: `radians()', `degrees()', or   `revolutions()'.

     The angular mode affects all trigonometric operations, including
     camera rotations, the drawing of arcs and ellipses, polar plotting,
      label angle, and the trig functions themselves. Angle-sensitive
     trig   functions are capitalized, e.g., `Cos', `Tan'.

   * Fill style: `fill(color)', `fill(bool)',   `nofill()'.

   * Path style:

        * Width: `plain()', `bold()', `bbold()',     `pen(len)'.

        * Line style: `line_style(string)'. The argument is a
          WYSIWYG sequence of dashes, spaces, and periods.
          `dash_size(double)' and `dot_sep(double)' set the
          (approximate) length in `pt' of the pattern.  The commands
          `solid()', `dashed()', `dotted()' define     "standard"
          defaults for brevity.

        * Path color:     Paths can be drawn using _two_ pens, one atop
          the other. When     the "base" pen is white (or the
          background color) and wider than     the "line" pen, a path
          masks parts of the figure it crosses. A     3-D effect may be
          obtained by making the base pen a darker shade     than the
          "line" pen.

          `pen(color,[len])', `base(color,[len])'

          Standard widths: `plain(color)', `bold(color)',
          `bbold(color)'

   * Text attributes:

        * Color: `label_color(color)'

        * Mask: `label_mask(color)', `label_pad(len)'

        * Border: `label_border(color, [len])',     `label_boder(len)'.
          The command `no_label_border()'     turns off label borders.

        * Font size: `font_size(LaTeX size)', default is
          `normalsize'.

        * Font face: `font_face(LaTeX font)', two-letter font
          selection string, default is `rm'.

        * Rotation: `label_angle(double)'

   Do not confuse `Color' constructors with the similarly-named
(deprecated) lowercase attribute-setting commands, `rgb(r,g,b)',
`cmyk(c,m,y,k)', `red(d)', etc. These commands affect text, paths, and
filled regions. For example, `red()' is the same as `pen(Red())',
`fill(Red())', and `label_color(Red())'.

4 Advanced Topics
*****************

This chapter covers _ad hoc_ tricks and open-ended techniques that
require relatively more programming sophistication. You will almost
surely need an external `C++' reference if you do not speak the
language.

4.1 Hidden Object Removal
=========================

`ePiX' writes the output file in the same order that objects appear in
the input. The order is significant because PostScript builds a figure
in layers: Objects are drawn over objects that come earlier in the
file. Shaded polygons can be used to obtain surprisingly effective
hidden object removal in surface meshes. This section describes the
data structures defined in the source files `surface.*'.

   The basic idea is to create a shaded polygon class that knows its
approximate distance to the camera. For computational simplicity, a
mesh "facet" is treated as a quadrilateral, located at the arithmetic
mean of its vertices. A facet's boundary is created from a map and a
domain by tracing a fine mesh rectangle counterclockwise.

   To draw a parametrized surface, facets are stored in a `C++' vector,
sorted in decreasing order of distance to the camera, and printed to
the output file. If filling is active, the gray density of a facet
depends on the cosine of the angle between the normal vector and the
vector from the camera to the element.

   This simple algorithm works surprisingly well when mesh elements
intersect at most along complete edges. To incorporate line-like
elements (e.g., coordinate axes, wire-mesh plots) with shaded surfaces,
the best technique is often to order high-level scene elements
manually, breaking up shaded surfaces (for example, with domain
resizing or clipping) as necessary. The sample file `saddle.xp'
illustrates possible techniques.

   Shaded surfaces can be decorated with a bit of hackery. For example,
the `facet::draw' function in `facet.cc' can be modified easily to draw
line elements, tangents, or normal vectors along with the facet itself.
The sample file `decorate.xp' contains a couple of ideas. (The
decorations are activated by compiler flags; please consult the file
itself for information on compiling.)

4.2 Extensions
==============

Thanks to a suggestion of Andrew Sterian, `ePiX' is extensible. User
extensions span a spectrum, from header files that require only basic
knowledge of `C++' to separately compiled libraries that add
substantial new features.  The structure of the source code is outlined
in Section section, .

A `C++' header file conventionally has suffix `.h', as in `myheader.h'.
To use this custom header, put a line `\#include "myheader.h"' in your
source file.

   User definitions can be easily and robustly implemented with "inline
functions". Inline functions are superficially similar to macros, but
are far more safe and featureful (since they are handled by the
compiler rather than by the pre-processor).  Examples are

  inline void Bold() { pen(1.6); }
  inline void purple() { rgb(0.5, 0, 0.7); }
  inline void draw_square(double s) { rect(P(-s,-s),P(s,s)); }
  inline double cube(double x) { return pow(x,3); // x^3 }
 The keyword `void' signifies a function that does not return a value,
or (when used as an implicit parameter) a function that does not accept
arguments. Inline function definitions are syntactically identical to
ordinary function definitions, but _must_ occur in a header file or in
the source file where they are used. The examples above might be used
in an input file as follows:

  Bold();
  draw_square(cube(1.25));

The next few sections outline the creation of a "static library" on
GNU/Linux, and explain how to incorporate custom features at runtime.
The sample files `affine.cc' and `affine.h' illustrate the techniques
described below, and may be used for guidance and experimentation.

   A small library is usually written as a _header_ file, which
contains function declarations (also called "prototypes"), and a
_source_ file, which contains the actual code. Conventionally (under
*nix), these files have extension `.h' and `.cc' respectively. Header
and source files may "include" other header files, to incorporate
additional functionality.

/* my_code.h */
#ifndef MY_CODE
#define MY_CODE
#include <cmath>   // standard library math header
#include "epix.h"  // ePiX header
using ePiX::P;

namespace Mine {   // to avoid name conflicts
  // functions for special relativity
  double lorentz_norm(const P&);
  bool   spacelike(const P&);
} // end of namespace
#endif // MY_CODE
 This file exhibits two "safety features". The three `MY_CODE' lines
prevent the file from being included multiple times. In a file of this
size, inclusion protection is overkill, but as your code base grows and
the number of header files increases, this protection is essential.
Second, the header introduces a "Mine" namespace. Inside this
namespace, two functions are declared as prototypes, giving the
function's return type, name, and argument type(s). A header file
should be commented fairly liberally, so that a year or two from now
you'll be able to decipher the file's contents.  For a longer file,
version and contact information, an overall comment describing the
file's features, and license information are appropriate.

   Next, the corresponding source file; definitions are also placed into
the namespace, and must match their prototypes from the header file
exactly.

/* my_code.cc */
#include "my_code.h"
using namespace ePiX;

namespace Mine {
  double lorentz_norm(const P& arg)
  {
    double x(arg.x1()), y(arg.x2()), z(arg.x3()); // extract coords
    return (y-x)*(y+x) + z*z; // -x^2 + y^2 + z^2
  }
  bool spacelike(const P& arg)
  {
    return (lorentz_norm(arg) > 0); // true if inequality is
  }
} // end of namespace
 Copies of these files are included with the source code so you can
experiment with them. Next, the source file must be "compiled",
"archived", and "indexed". In the commands below, the percent sign is
the prompt.

% g++ -c my_code.cc
% ar -ru libcustom.a my_code.o
% ranlib libcustom.a
 Please see your system documentation for details on command options
and what each step does. For linking (below), the name of the library
file must begin "lib" and have the extension `.a'. Once these steps are
successfully completed, put the library `libcustom.a' and header file
`my_code.h' in your project directory. You're ready to use the code in
an `ePiX' figure.

The script `epix' allows input files to be linked with external
libraries at run time, when the input file is compiled into a temporary
executable.

   `epix' recognizes command line options and passes them verbatim to
the compiler. The most commonly used options are those of the form

   -I<include>     -L<libdir>     -l<lib>
 For example, to link `figure.xp' against `mylibs/libcustom.a', run the
command

   epix -Lmylibs -lcustom figure
 The options `-I. -L.' tell the compiler to look in the current
directory for header and library files.  Compiler options may appear in
any order, but must come before the name of the input file(s).

   Compiler options may be placed in the configuration file
`\$HOME/.epixrc', with syntax as above. A line in the config file that
contains a pound sign (`\#') is a comment, no matter where in the line
the `\#' appears. If any non-comment line fails to start with a dash,
the rest of the file is silently discarded.  Command-line options are
read before the config file.

The script `epix' links by default against the `C' math library
`libm.a' and the `ePiX' library `libepix.a'.  The command option
`--no-defaults' clears the header and include paths and removes
`libepix.a' from the link list. The script may therefore be used with
multiple versions of `ePiX', a potentially useful feature if you
regularly need to compile old source files, or simply prefer the syntax
of an older version.

   To install and use (say) Version 0.8.5, build the package according
to its `INSTALL' instructions, but _do not use the makefile   to
install_. Instead, manually install the header and library only, using
their version number:

# install -m 644 epix.h /usr/local/include/epix-0.8.5.h
# install -m 644 libepix.a /usr/local/lib/libepix-0.8.5.a
 A non-system directory may be used instead of `/usr/local'.  To use
the old version, a source file must `include' the appropriate header
file (which is identified by its version number).  To compile, issue a
command such as

epix --no-defaults -I/usr/local -L/usr/local -lepix-0.8.5 file.c

4.3 Programmer's Guide
======================

This section briefly surveys `ePiX''s implementation, and is intended
only for programmers (and extremely curious users). The source code of
Version 1.2 is divided into modules with small, well-defined
responsibilities, but the user interface is mostly compatible with the
syntax of Version 1.0. These constraints demanded a degree of
implementation hiding. The user-visible classes defined in `Color.h',
`path.h', and `screen.h' contain only a pointer to the implementation
class ("pimpl"), and style data is hidden behind global
attribute-setting commands.

   Functionally, the code consists of the user interface; implementation
classes comprising drawing attributes, implementations of spatial
objects, screens and representations of their elements, and output; and
miscellaneous utility functions. Only the interface headers are
installed.

These files (in order) comprise the global header \textttepix.h.

   `enums.h'  Marker, alignment, Riemann integral, and vector field
types.

   `length.h'  Physical lengths, conceptually a number and two-letter
`LaTeX' length unit.

   `interval.h'  Closed, open, and half-open interval ranges for data
culling.

   `triples.h' The `P'  class.

   `functions.h'  Angle-sensitive trig functions, miscellaneous utility
functions, the `Deriv' and `Integral' classes.

   `pairs.h'  Screen locations and displacements, with complex
arithmetic operations.

   `Color.h'  The Color class interface, named primaries and
constructors.

   `state.h'  Angle mode; clipping and cropping; label styles; filling;
arrow head style; dot and tick sizes, dash length; line style; line and
base pen attributes; color-setting commands.

   `frame.h'  Orthonormal bases.

   `domain.h'  Coordinate boxes for function plotting.

   `camera.h'  The camera and lenses.

   `screen.h'  The screen class.

   `picture.h'  Dimension-setting, offset, layout, decoration, verbatim
text, and output format commands.

   `markers.h'  Point markers, axis labels, and coordinate axes.

   `path.h'  The path class.

   `curves.h'  Polygons, arrows, ellipses, arcs, splines, coordinate
grids, and recursive fractal curves.

   `circle.h' The `Circle'  shape object class.

   `plane.h' The `Plane'  shape object class.

   `segment.h' The `Segment'  shape object class.

   `sphere.h' The `Sphere'  shape object class.

   `intersections.h'  Shape object intersection operators.

   `plots.h'  Plotting commands.

   `surface.h'  Shaded surface plots.

   `data_mask.h'  Helper class for data pruning.

   `data_file.h'  Class for storing and representing data.

   `data_bins.h'  Class for sorting and counting data.

   `geometry.h'  Latitudes and longitudes; spherical plotting, arcs,
polygons, and polyhedra; hyperbolic arcs.

`Color_Base.h'  The Color implementation interface.

   `Color_CMY.h'  The CMY color model.

   `Color_CMYK.h'  The CMYK color model.

   `Color_Gray.h'  The Gray color model.

   `Color_Neutral.h'  Each color class has a "Neutral" member that
converts colors to that model by filtering. This file defines the
unique "modelless" Neutral color for which filtering performs no action.

   `Color_RGB.h'  The RGB color model.

   `Color_Sep.h'  Classes for CMYK separation.

   `active_screen.h'  Pointer to active screen.

   `path_data.h'  Path implementation.

   `picture_data.h' Picture implementation: two `screen' s
(representing the `canvas' and the output page), true dimensions and
offsets, pointer to output format, list of colors, and lists of
verbatim text to write before and after printing the `picture'
environment in the output file. For simplicity, the `screen's and
dimensions are public; encapsulation from the user results from
"hiding" this header.

   `spline_data.h'  Templates for quadratic and cubic splines.

Declaration-style attributes are maintained with functions returning
static references: `the_angle_style()', `the_arrowhead_style()',
`the_label_style()', `the_mark_size()', `the_paint_style()', and
`the_path_style()'. Each function is declared in the analogously-named
header.

   `angle_units.h' Angular modes: `radians' , `revolutions', and
`degrees'.

   `arrow_style.h'  Arrow head style data: width, ratio, and camber
(similar to PSTricks' inset).

   `label_style.h'  Text object style: Label and mask colors, padding,
border color and width, alignment, font size, font face, and angle.

   `marker_style.h'  Dot and tick sizes.

   `paint_style.h'  Line and base pens, fill color.

   `path_style.h'  Solid, dashed, dotted lines.

   `pen_data.h'  The pen class.

`arrow_data.h'  Arrow representation.

   `facet.h'  Shaded surface elements.

   `label_data.h'  Text (label and marker) objects.

   `spline.h'  The natural spline class.

Elements in a `screen' are represented polymorphically as "`tile's", of
which there are five types: `glyph' (textual elements), `pen_arrow'
(arrows), `pen_fill' (filled regions), `pen_line' (path-like elements),
and `verbatim' (raw text).

   Border and background shape are dictated by the `screen_mask' class.
The cropping algorithm assumes the countour of a screen mask is convex.

   `cropping.h'  Screen mask cropping.

   `glyph.h'  Markers and labels.

   `mask_diamond.h'  Screen diamond mask.

   `mask_ellipse.h'  Screen elliptical mask.

   `mask_rectangle.h'  Screen rectangular mask.

   `pair_map.h'  Affine maps.

   `pen_arrow.h'  Arrows.

   `pen_fill.h'  Filled regions.

   `pen_line.h'  Paths.

   `screen_data.h'  Screen implementation class.

   `screen_mask.h'  Screen mask interface.

   `tile.h'  Screen element interface.

   `verbatim.h'  Text in output stream.

Output is divided into about a dozen high-level operations, which in
turn may be implemented by lower-level code.  To create a new output
format, one need only implement the `format' interface for the desired
file type. Label objects should normally be assumed to contain `LaTeX'
commands. Paths and filled regions may be implemented however the
output type dictates.

   `eepic.h'  eepic macros.

   `format.h'  The output interface.

   `pst.h'  PSTricks macros.

`Color_Utils.h'  Functions for setting color channel densities.

   `clipping.h'  The clip box.

   `constants.h'  Global constants: Line widths; dot, tick, and dash
sizes; arrowhead parameters; miscellaneous numerical constants and
internal parameters.

   `crop_algorithms.h'  Path and loop clipping templates.

   `deriv.h'  Finite difference template.

   `edge_data.h'  Path element representation template.

   `errors.h'  Warning and error messages.

   `halfspace.h'  Halfspace cutting.

   `hatching.h'  Filling regions in eepic.

   `map.h'  Wrappers for templated plotting.

   `plot_algorithms.h'  Plotting templates.

   `screen_crop.h'  Crop paths and loops.

   `utils.h'  Truncation, date and time, line breaking.

   \appendix

Appendix A Software Freedom
***************************

Academics in general, and mathematicians in particular, depend on Free
software in their work. A good case can be made that proprietary
software is contrary to the academic ethic. Issues of access aside, if
one does not know what exactly went into a program, then one cannot
fully trust the results that come out, any more than one can trust (for
purposes of scientific publication) results of a commercial testing
lab.  Access to the source code is not all that is required, though. To
promote the dissemination of information, users should be granted the
four freedoms laid out in the GNU General Public License: \smallskip

   `Free0': To run a program for any purpose

   `Free1': To study how the program works, and adapt it to your needs

   `Free2': To redistribute copies of the program

   `Free3': To improve the program, and release improvements to the
public %\smallskip

   Just as theorems are not restrictively licensed, I believe that
software we use in our academic work should be licensed in a way that
encourages openness and sharing. Releasing software under a standard
commercial license agreement is (to me) the equivalent of publishing
the statement of a theorem, while keeping the proof secret, and
charging people for each citation of the theorem. Releasing source code
alone, without giving users the freedom to modify it for their own
needs, is analogous to publishing a proof, but forbidding readers from
using the ideas of the proof in their own work.

   The ultimate purpose of software is to allow us to be productive and
creative. I hope that this modest program is, in conjunction with the
much larger efforts of others (especially Donald Knuth, Richard
Stallman, and the many people who have contributed to the authorship of
`LaTeX' and its packages), useful to you in your mathematical work.

   Please visit the Free Software Foundation, at `http://www.fsf.org',
to learn more about Free Software and how you can contribute to its
development and adoption.

Appendix B Acknowledgments
**************************

`ePiX' is built on the work of many people (unfortunately, most of whom
I am unaware). The following people have contributed, sometimes
unknowingly but always generously:

   \paragraphInfrastructure Donald Knuth, Conrad Kwok, Leslie Lamport,
Tim Morgan, Piet van Oostrum, Sunil Podar, Richard Stallman, Herbert
Voss, Timothy van Zandt

   \paragraphEnhancements Jay Belanger, Robin Blume-Kohout, Julian
Gilbey, Marcus Hanwell, Yvon Henel, Svend Daug\aard Pedersen, Andrew
Sterian

   \paragraphPorting and packaging Julian Gilbey (Debian); Tsuguru Kato
(FreeBSD); Danny van Dyk, Olivier Fisette, Marcus Hanwell, Peter
Johanson, and Patrick Kursawe (Gentoo); Guido Gonzato (RPM)

   \paragraphDebugging, advice, and other assistance Jay Belanger,
Felipe Paulo Guazzi Bergo, Karl Berry, Robin Blume-Kohout, Patrick
Cousot, Stephen Gibson, Julian Gilbey, Dov Grobgeld, Bob Grover, Jim
Hefferon, Jacques L'helgoual, Yvon Henel, Hartmut Henkel, Herng-Jeng
Jou, Walter Kehowski, Kevin McCormick, Ross Moore, Thorsten Riess, Alan
Sill, Neel Smith, Michael Somos, Andrew Sterian, Ryszard Tanas, Kai
Trukenmueller, Torbjorn Vik, Wenguang Wang, Gabe Weaver, Mariusz
Wodzicki

Index
*****