/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 
 *  epix.h -- Automatically created on Mon Dec 22 22:19:20 EST 2003  * 
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 

/* 
 * globals.h -- Top-level header file
 *
 * This file is part of ePiX, a preprocessor for creating high-quality 
 * line figures in LaTeX 
 *
 * Version 0.8.8a
 */

/* 
 * Copyright (C) 2001, 2002  
 * Andrew D. Hwang <ahwang@mathcs.holycross.edu>
 * Department of Mathematics and Computer Science
 * College of the Holy Cross
 * Worcester, MA, 01610-2395, USA
 */

/*
 * ePiX is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ePiX is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ePiX; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#define _EPIX

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

namespace ePiX {


/* 
 * To find hardwired constants in the source code, do
 *
 *             grep "Hardwired" *.cc
 */

/* * * Tweakable constants * * */

const int EPIX_NUM_PTS=40;     /* Number of points in half-ellipses, splines */
const int EPIX_FILE_WIDTH=70;  /* Width of output file, in characters */
const double EPIX_SPOT_DIAM=4; /* Diameter of circles and spots in true pt */
const double EPIX_ARROWHEAD_WIDTH=1.5; /* Half-width of arrowheads in pt */
const double EPIX_ARROWHEAD_RATIO=5.5; /* Aspect ratio of arrowheads */

/* 
 * Determines accuracy of truncation in clipplot et. al.
 * smaller -> better accuracy, longer run
 */
const double EPIX_SEEK_SIZE=0.01;

/*
 * In calculus plotting, determines the size of the increment dt
 * and the number of increments per point printed. A value of 100
 * is adequate for simple plotting, while a value larger than
 * 1000 is not likely to improve the accuracy noticeably.
 *
 * larger -> better accuracy, longer run
 */
const int EPIX_ITERATIONS=200;

/* Dash length/dot separation parameters */
const double EPIX_DASH_LENGTH=5.0;
const double EPIX_DOT_SEP=40.0;

/* * * End of tweakable constans * * */

/* Path styles, data plot markers, and label alignment types */
enum epix_path_style {SOLID, DASHED, DOTTED};

enum epix_mark_type {PATH, CIRC, SPOT, RING, DOT, DDOT, PLUS, OPLUS, 
		     TIMES, OTIMES, DIAMOND, UP, DOWN, BOX, BBOX};

enum epix_label_posn {c, r, tr, rt, t, tl, lt, l, bl, lb, b, br, rb};


// coordinate axis tick marks
enum epix_tick_type {TICK_NULL, H_AXIS, V_AXIS};

// "vector field"-type objects
enum epix_field_type {SLOPE, DART, VECTOR};

/* Deprecated constants */

const int EPIX_PAIRS_PER_LINE=4;/* Number of pairs per line in output file */
const int EPIX_MAX_LINES=20000; /* Fatal error if this many lines printed */
extern int epix_lines_printed;  /* output counter */

/* 
 * ePiX depicts the rectangle [x_min, x_max] x [y_min, y_max] in a LaTeX
 * figure occupying (h_offset, v_offset) + [0, h_size] x [0, v_size]. If
 * appropriate, orthogonal projection to the plane normal to <viewpoint>
 * is performed.
 */

/* 
 * <Size> and <offset> of picture in PICTURE coordinates. Sizes 
 * define space in document alotted by LaTeX. Offsets shift the
 * origin from the CENTER of the picture; positive offsets shift
 * RIGHT and UP (contrast LaTeX behavior).
 */
extern double h_size, v_size, h_offset, v_offset; // zero offset by default

/*
 * Components of normal vector for 3-d plotting. When set to (0,0,a3),
 * ePiX draws the standard x-y plane in standard orientation. Otherwise
 * ePiX does orthogonal projection to the plane normal to <viewpoint>,
 * keeping the z-axis vertical. Because projection is orthogonal, overall
 * scale in <viewpoint> is immaterial (aside from round-off).
 */
extern double viewpt1, viewpt2, viewpt3; // default viewpoint (0,0,0)

/* Bounding box of picture in Cartesian coordinates. */
extern double x_min, x_max, y_min, y_max;
/* Cartesian width and height of bounding box */
extern double x_size, y_size;

/*
 * Picture length units
 *
 * <pic_unit> is one of the following valid LaTeX length units: 
 *    cm, in, mm, pc, or pt.
 * <pic_size> is a double that (with pic_unit) specifies unitlength
 */
extern double pic_size; // e.g., 1
extern char *pic_unit;  // e.g., "pt" 

} /* end of namespace */

/* 
 * pairs.h -- ePiX pair:: class and mathematical operators
 *
 * Andrew D. Hwang                      <ahwang@mathcs.holycross.edu>
 *
 * Version: 0.8.8rc6
 * Last Change: December 02, 2002
 */

#define _EPIX_PAIRS


using namespace std;

class pair 
{
 public:
  double x1;
  double x2;

  // void constructor
  pair(void) {}

  // Cartesian constructor
  pair(double x1, double x2);

  // copy
  pair(const pair& old);

  // destructor
  ~pair() {}

  // increment operators
  pair& operator += (const pair&);
  pair& operator -= (const pair&);
  pair& operator *= (const double&);

  // complex multiplication and division
  pair& operator *= (const pair&);
  pair& operator /= (const pair&);
}; /* end of pair class */

/* pair creation */
pair P(double, double); 

#define polar(r, t) P((r)*cos(t),(r)*sin(t))

#define cis(t) P(cos(t), sin(t))

const pair e_1 = P(1,0);
const pair e_2 = P(0,1);

int  operator == (const pair&, const pair&);
pair operator - (const pair&);
pair operator + (const pair&, const pair&);
pair operator - (const pair&, const pair&);

// scalar multiplication
pair operator * (const double&, const pair&);
// Multiplication by i
pair J(pair);

// complex multiplication and division
pair operator * (const pair& u, const pair& v);
pair operator / (const pair& u, const pair& v);

// dot product
double operator |(const pair&, const pair&);
// (a,b)&(x,y)=(ax,by), for unit/coordinate conversion
pair operator &(const pair&, const pair&);

struct mesh {
  int n1;
  int n2;
};

struct mesh Net(int, int);

pair V(double, double, double); // (x1, x2, x3) projected by <viewpoint>

/* * * * Deprecated functions * * * */

/* Vector operations (now overloaded operators) */
pair add_pair(pair, pair);

pair diff_pair(pair, pair);

pair mult_s(double, pair);

/* Complex Multiplication */
pair mult_pair(pair, pair);

/* 
 * triples.h -- ePiX triple:: class and mathematical operators
 *
 * Andrew D. Hwang                      <ahwang@mathcs.holycross.edu>
 *
 * Version: 0.8.8rc6
 * Last Change: December 02, 2002
 */

#define _EPIX_TRIPLES


using namespace std;

class triple 
{
 public:
  double x1;
  double x2;
  double x3;

  // void constructor
  triple(void) {}

  // Cartesian constructor
  triple(double x1, double x2, double x3);

  // copy
  triple(const triple& old);

  // destructor
  ~triple() {}

  // increment operators
  triple& operator += (const triple&);
  triple& operator -= (const triple&);
  triple& operator *= (const double&);

  // complex multiplication and division
  triple& operator *= (const triple&);
  triple& operator /= (const triple&);
}; /* end of class */

/* triple creation */
triple P(double, double, double); 

// spherical constructor
#define sph(r, t, phi) P(r*cos(t)*cos(phi), r*sin(t)*cos(phi), r*sin(phi))

const triple E_1 = P(1,0,0);
const triple E_2 = P(0,1,0);
const triple E_3 = P(0,0,1);

pair V(triple); // Project <triple> according to current viewpoint

int  operator == (const triple&, const triple&);
triple operator - (const triple&);
triple operator + (const triple&, const triple&);
triple operator - (const triple&, const triple&);

// cross product
triple operator * (const triple&, const triple&);

// scalar multiplication
triple operator * (const double&, const triple&);

// dot product
double operator |(const triple&, const triple&);
// componentwise product (a,b,c)&(x,y,z) = (ax,by,cz)
triple operator &(const triple&, const triple&);

void rot1(const double& angle);
void rot2(const double& angle);
void rot3(const double& angle);

/*
 * lengths.h -- ePiX true and LaTeX length manipulation
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * In ePiX, there are three systems of coordinates:              *
 *                                                               *
 *   Cartesian (C) -- All the user needs to know about           *
 *   Picture   (P) -- The language of the LaTeX front end        *
 *   True      (T) -- Physical location on page from lower left  *
 *                                                               *
 * The coordinate triumvirates' initials form a bad physics pun. *
 *                                                               *
 * Recognized LaTeX units are: cm, in, mm, pc, and pt            *
 *                                                               *
 * All objects and locations are specified in C by the user; the *
 * conversion to true coordinates is transparent. The rationale  *
 * for retaining LaTeX coordinates, rather than forcing all ePiX *
 * figures to be specified in true pt, is of course that figures *
 * are sized according to printing requirements, and often not   *
 * in terms of true pt. The reason for using true pt is that raw *
 * scaling of a LaTeX figure is not robust; label positions must *
 * be specified with true pt offsets if their locations are to   *
 * scale properly when a figure is resized.                      *
 *                                                               *
 * An ePiX figure is a rectangle, described as follows:          *
 *   Cartesian: [x_min, x_max] x [y_min, y_max]                  *
 *   Picture:   [0, h_size] x [0, v_size] + (h_offset, v_offset) *
 *   True:      Only (La)TeX knows/needs to know this            *
 *                                                               *
 * ePiX provides six scale-changing functions:                   *
 *   c2p, p2c -- Cartesian -> LaTeX and back for points          *
 *   c2s, s2c -- Cartesian -> LaTeX and back for vectors         *
 *   p2t, t2p -- LaTeX -> True and back                          *
 *                                                               *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#define _EPIX_LENGTHS

#include <string.h>

namespace ePiX {

  using namespace std;

/* If less than 0.0001, set to zero */
double truncate(double);

pair truncate(pair);

/* Functions for declaring variables */
void bounding_box(pair, pair);
void picture(pair);
void unitlength (const char *);
void offset(pair);
void viewpoint(double, double, double);

/* Coordinate conversion routines */
pair c2p(pair);
pair p2c(pair);

pair c2s(pair);
pair s2c(pair);

double p2t(double);
double t2p(double);
pair p2t(pair);
pair t2p(pair);

double raw_len(pair); // Pythagorean length of pair/triple
double raw_len(triple p);

/* Length of pair given in picture coords */
double true_len(pair); // length in true pt

pair normalize(pair); // parallel true pt unit vector

} /* end of namespace */

/*
 * output.h -- ePiX file-formatting output routines
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

#define _EPIX_OUTPUT


namespace ePiX {

  using namespace std;

extern int EPIX_PATH_STYLE;
extern double epix_stretch_factor;

/* Sectioning Functions */

/* Begin/end picture */
void begin(void);

#define end() fprintf (stdout, "\n\\end{picture}\n")

/* Print Cartesian pair in form (p.x1,p.x2) */
void print(pair);
void print(triple);
void raw_print(pair);

void stretch(double);

/* Path style declarations */
void start_path(void);
/* (Un)fill closed path */
#define fill   fprintf (stdout, "\\blacken")
#define unfill fprintf (stdout, "\\whiten")

void epix_comment(char *);
void end_stanza(void);
void fatal_error(void);
void output(void);
void line_break(int, int);

/* Misc Styles and output formatting */
/* Output styles */
void pen(char *);
void pen(double);

#define bold     fprintf (stdout, "\n\\thicklines")
#define endbold  fprintf (stdout, "\n\\thinlines")
#define end_bold fprintf (stdout, "\n\\thinlines")
#define plain    fprintf (stdout, "\n\\thinlines")

/* set state variable */
#define solid    EPIX_PATH_STYLE = SOLID
#define dashed   EPIX_PATH_STYLE = DASHED
#define dotted   EPIX_PATH_STYLE = DOTTED

/*
 * Color handling
 *
 * ePiX provides  "pstcol" style colors, which are declarations rather 
 * than delimited environments. To make part of an ePiX file print red 
 * (say), use one of the following:
 *
 *   red;
 *   <epix commands>
 *   end_red;
 *
 *   rgb(1,0,0);
 *   <epix commands>
 *   black;
 *
 * rgb and cmyk colors are specified (respectively) by 3 or 4 floats,
 * the densities of the corresponding primary colors. If these densities
 * are specified outside the unit interval [0,1], they will be truncated,
 * e.g., rgb(2, -1, 0.3) = rgb(1, 0, 0.3).
 */

// red-green-blue
void rgb(double r, double g, double b); 
// cyan-magenta-yellow-black
void cmyk(double c, double m, double y, double k);

/* primary colors */

#define red     fprintf (stdout, "\n\\color[rgb]{1,0,0}")
#define green   fprintf (stdout, "\n\\color[rgb]{0,1,0}")
#define blue    fprintf (stdout, "\n\\color[rgb]{0,0,1}")
#define white   fprintf (stdout, "\n\\color[rgb]{1,1,1}")

#define cyan      fprintf (stdout, "\n\\color[cmyk]{1,0,0,0}")
#define magenta   fprintf (stdout, "\n\\color[cmyk]{0,1,0,0}")
#define yellow    fprintf (stdout, "\n\\color[cmyk]{0,0,1,0}")
#define black     fprintf (stdout, "\n\\color[cmyk]{0,0,0,1}")

/* 
 * depth of gray in shaded objects; argument is an integer from 0
 * (white) to 32 (black) 
 */
void gray(double);

} /* end of namespace */

/* 
 * objects.h -- Simple picture objects: axes, grids, markers, polygons
 *
 * Andrew D. Hwang                      <ahwang@mathcs.holycross.edu>
 *
 * Version: 0.8.8rc6
 * Last Change: December 02, 2002
 */

#define _EPIX_OBJECTS


namespace ePiX {

  using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *                    Picture objects                    *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 * label -- put string constant <label_text> 
 * at Cartesian position <pair> offset by <vect> true points.
 * Accepts an optional LaTeX-style positioning argument after the offset.
 * If no offset is specified, the label is centered at the given Cartesian
 * location.
 * masklabel requires the "color" package, and places the text in 
 * a white box that masks whatever is underneath and earlier in the file.
 */
void label(pair base, pair offset, char *label_text);
void label(pair base, char *label_text);
void label(pair base, pair offset, char *label_text, 
	   const int epix_label_posn);
void masklabel(pair base, pair offset, char *label_text);
void masklabel(pair base, char *label_text);
void masklabel(pair base, pair offset, char *label_text, 
	       const int epix_label_posn);

/*
 * Empty and filled LaTeX circles of diameter EPIX_SPOT_DIAM true pt
 */
void circ(pair); // filled white circ 4 pt in diameter
void ring(pair, double); // unfilled circ of specified diam
void spot(pair);
void dot(pair);
void ddot(pair);
void dot(pair, double); // filled circ of specified diam

/* Axes and coordinate grids. */

/* 
 * Coordinate axes, specified by initial and final points, and number
 * of steps. h/v_axis are identical except for style of tick marks.
 */
void h_axis_tick(pair);
void v_axis_tick(pair);
void h_axis(pair tail, pair head, int n);
void v_axis(pair tail, pair head, int n);

/*
 * h_axis_labels: Draws n+1 equally-spaced axis labels between 
 *    <tail> and <head>. Automatically generates label values from
 *    Cartesian coordinates, and offsets labels in true pt.
 */

void h_axis_labels(pair tail, pair head, int n, pair offset);
void v_axis_labels(pair tail, pair head, int n, pair offset);

void h_axis_masklabels(pair tail, pair head, int n, pair offset);
void v_axis_masklabels(pair tail, pair head, int n, pair offset);

/* Axis labels with LaTeX-style alignment option */

void h_axis_labels(pair tail, pair head, int n, pair offset, 
		   const int epix_label_posn);
void v_axis_labels(pair tail, pair head, int n, pair offset, 
		   const int epix_label_posn);

void h_axis_masklabels(pair tail, pair head, int n, pair offset, 
		       const int epix_label_posn);
void v_axis_masklabels(pair tail, pair head, int n, pair offset, 
		       const int epix_label_posn);

/* eepic.sty's ellipse comand */
void draw_native_ellipse (pair, pair);
void native_ellipse (pair, pair);

/* Cartesian grid filling bounding_box */
void draw_grid(int, int);
void grid(int, int);

/* Cartesian grid of specified size */
void draw_grid(pair, pair, int, int);
void grid(pair, pair, int, int);

/* Polar grid with n1 rings and n2 sectors */
void draw_polar_grid(double, int, int);
void polar_grid(double, int, int);

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *             Simple geometric objects                  *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* Lines can be "stretched" by double parameter */
void draw_line(pair, pair, int, double); 

/* Lines with stretch factor */
void line(pair, pair, double);     

/* Unstretched lines */
void line(pair, pair);    

/* Returns >0 iff p0 is left of directed segment from p1 to p2 */
double ccw(pair p0, pair p1, pair p2);
/* "Visible" portion of the line through p1, p2 */
void draw_Line(pair, pair, int);
void Line(pair, pair);

/* point-slope form */
void Line(pair, double);

void draw_triangle(pair, pair, pair); 
void triangle(pair, pair, pair);

/* 
 * If (a,b) and (c,d) are opposite corners of a rectangle, then
 * the corners -- in order -- are (a,b), (a,d), (c,d), and (c,b).
 */
void draw_rect(pair, pair); /* opposite corners */
void rect(pair, pair);
/* filled rectangle */
void swatch(pair, pair);

void draw_arrowhead(pair, pair, double);
void draw_shaft(pair, pair, double);
void draw_arrow(pair, pair);
void draw_boldarrow(pair, pair);
void arrow(pair, pair);
void boldarrow(pair, pair);

void draw_dart(pair, pair);
void draw_bolddart(pair, pair);
void dart(pair, pair);
void bolddart(pair, pair);

} /* end of namespace */

/*
 * curves.h -- Ellipses, arcs, splines
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

#define _EPIX_CURVES


namespace ePiX {

  using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *  Ellipses, half-ellipses, circular arcs, splines -- curves.c  *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* Ellipses */

/* Point-plotting functions */
void draw_half_ellipse (pair, pair);

/* Stanza-creating whole ellipse functions */
void draw_ellipse (pair, pair); 
void ellipse (pair, pair);

/* Stanza-creating standard half-ellipse functions */
void draw_half_ellipse(pair, pair, double);
void ellipse_left (pair, pair);
void ellipse_right (pair, pair);
void ellipse_top (pair, pair);
void ellipse_bottom (pair, pair);

/* Right half ellipse rotated through <double> revolutions */
void rotate_half_ellipse(pair, pair, double);
void ellipse_half (pair, pair, double);

/* Circular arcs */
void draw_proper_arc (pair, double, double, double);
void draw_arc (pair, double, double, double);

void arc (pair, double, double, double);

void draw_arc_arrow (pair, double, double, double);
void arc_arrow (pair, double, double, double);

/* Splines */
void draw_spline (pair, pair, pair);
void draw_spline (pair, pair, pair, pair);

/* Quadratc */
void spline (pair, pair, pair);

/* Cubic */
void spline (pair, pair, pair, pair);

/* Knot diagram primitives */
void draw_under_strand(pair p3, pair p6, pair p5, pair p2);
void draw_p_twist(pair p1, pair p4);
void draw_n_twist(pair p1, pair p4);

void p_twist (pair, pair);
void n_twist (pair, pair);
void twists (pair, pair, int);

} /* end of namespace */

/*
 * plots.h 
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 */

#define _EPIX_PLOTS


namespace ePiX {

  using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *          Plots of user-specified functions -- plots.c         *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* Adaptive plotting */
void draw_adapt_plot (double f1(double), double f2(double), 
		      double, double, int);
void adplot     (double f(double), double, double, int);
void adplot     (double f1(double), double f2(double), double, double, int);

void draw_adapt_plot (pair f(double), double, double, int);
void adplot     (pair f(double), double, double, int);

/* Ordinary graph plot */
void draw_plot (double f(double), double, double, int);
void plot      (double f(double), double, double, int);

/* Parametric plane curve */
void draw_plot (double f1(double), double f2(double), double, double, int);
void plot      (double f1(double), double f2(double), double, double, int);

void draw_plot (pair f(double), double, double, int);
void plot      (pair f(double), double, double, int);

/* Parametric space curve */
void draw_plot (double f1(double), double f2(double), double f3(double),
		double, double, int);

void plot      (double f1(double), double f2(double), double f3(double),
	        double, double, int);

void draw_plot (triple f(double), double, double, int);
void plot      (triple f(double), double, double, int);

/* Projection of space curve to plane through the origin */
void draw_shadowplot (double f1(double), double f2(double), double f3(double),
		      triple, double, double, int);
void shadow          (double f1(double), double f2(double), double f3(double),
		      triple, double, double, int);

void draw_shadowplot (triple f(double), triple, double, double, int);
void shadow          (triple f(double), triple, double, double, int);

/* Polar graph */
void draw_polarplot (double r(double), double, double, int);
void polarplot      (double r(double), double, double, int);

/* Plotting families of curves -- sliceplot1 holds first variable constant */
void draw_sliceplot1(double f1(double, double), double f2(double, double), 
		     double, double, double, int);
void draw_sliceplot2(double f1(double, double), double f2(double, double), 
		     double, double, double, int);

void sliceplot1 (double f1(double, double), double f2(double, double), 
		 double, double, double, int);
void sliceplot2 (double f1(double, double), double f2(double, double), 
		 double, double, double, int);

/* pair-valued plot argument */
void draw_sliceplot1(pair f(double, double), double, double, double, int);
void draw_sliceplot2(pair f(double, double), double, double, double, int);
void sliceplot1 (pair f(double, double), double, double, double, int);
void sliceplot2 (pair f(double, double), double, double, double, int);

/* multiplot = several sliceplots */
void draw_multiplot1 (double f1(double, double), double f2(double, double), 
		      pair, pair, mesh, int);
void draw_multiplot2 (double f1(double, double), double f2(double, double), 
		      pair, pair, mesh, int);

void multiplot1 (double f1(double, double), double f2(double, double), 
		 pair, pair, mesh, int);
void multiplot2 (double f1(double, double), double f2(double, double), 
		 pair, pair, mesh, int);
/* pair-valued plot argument */
void draw_multiplot1 (pair f(double, double), pair, pair, mesh, int);
void draw_multiplot2 (pair f(double, double), pair, pair, mesh, int);
void multiplot1 (pair f1(double, double), pair, pair, mesh, int);
void multiplot2 (pair f1(double, double), pair, pair, mesh, int);

/* "Clipped" plotting -- truncated to bounding_box */
void draw_clipplot (double f1(double), double f2(double), double f3(double),
		    double, double, int);
void draw_clipplot (pair f(double), double, double, int);
void draw_clipplot (triple f(double), double, double, int);

/* Ordinary plots */
void clipplot     (double f(double), double, double, int);
/* Parametric plane curves */
void clipplot     (double f1(double), double f2(double), double, double, int);
void clipplot     (pair f(double), double, double, int);

/* Parametric space curves */
void clipplot     (double f1(double), double f2(double), double f3(double),
		   double t_min, double t_max, int num_pts);
void clipplot     (triple f(double), double t_min, double t_max, int num_pts);

/* Data plotting from file */
void marker (pair, const int);
void data_plot (const char *, const int);

/* Derivatives and integrals */
void draw_deriv     (double f(double), double, double, int);
void plot_deriv     (double f(double t), double, double, int);

void tan_line(double f1(double t), double f2(double t), double t0);
void tan_line(double f(double t), double t0);
void tan_line(pair f(double t), double t0);

void envelope(double f1(double), double f2(double), double, double, int);
void envelope(double f(double), double, double, int);
void envelope(pair f(double), double, double, int);

void tan_field     (double f1(double), double f2(double), 
		    double, double, double);
void boldtan_field (double f1(double), double f2(double), 
		    double, double, double);
void tan_field     (pair f(double), double, double, double);
void boldtan_field (pair f(double), double, double, double);

/* lower limit is endpoint of plot interval */
void draw_int     (double f(double), double, double, int);
void plot_int     (double f(double), double, double, int);

/* separate lower limit */
void draw_int     (double f(double), double, double, double, int);
void plot_int     (double f(double), double, double, double, int);

/* Slope, dart, and vector fields */
void draw_slope_field  (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);
void slope_field       (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);
void boldslope_field   (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);

void draw_dart_field   (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);
void dart_field        (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);
void bolddart_field    (double f1(double, double), double f2(double, double),
		        pair, pair, int, int);

void draw_vector_field (double f1(double, double), double f2(double, double),
			pair, pair, int, int);
void vector_field      (double f1(double, double), double f2(double, double),
			pair, pair, int, int);
void boldvector_field  (double f1(double, double), double f2(double, double),
			pair, pair, int, int);

/* pair-valued vector field */
void draw_slope_field  (pair F(double, double), pair, pair, int, int);
void slope_field       (pair F(double, double), pair, pair, int, int);
void boldslope_field   (pair F(double, double), pair, pair, int, int);

void draw_dart_field   (pair F(double, double), pair, pair, int, int);
void dart_field        (pair F(double, double), pair, pair, int, int);
void bolddart_field    (pair F(double, double), pair, pair, int, int);

void draw_vector_field (pair F(double, double), pair, pair, int, int);
void vector_field      (pair F(double, double), pair, pair, int, int);
void boldvector_field  (pair F(double, double), pair, pair, int, int);

/* Solutions of ODE systems */
void draw_ode_plot (double f1(double, double), double f2(double, double),
		    pair, double, int);
void ode_plot      (double f1(double, double), double f2(double, double),
		    pair, double, int);

/* pair-valued vector field */
void draw_ode_plot (pair F(double, double), pair, double, int);
void ode_plot      (pair F(double, double), pair, double, int);

/* Image of a point set under a planar flow */
void draw_flow_plot(double f1(double, double), double f2(double, double),
		    pair f(double), triple color(double), double, int, int);
/* With and without color function */
void flow_plot(double f1(double, double), double f2(double, double),
	       pair f(double), triple color(double), double, int, int);
void flow_plot(double f1(double, double), double f2(double, double),
	       pair f(double), double, int, int);

/* pair-valued vector field */
void draw_flow_plot(pair F(double, double), pair f(double), 
		    triple color(double), double, int, int);
void flow_plot(pair F(double, double), pair f(double), 
	       triple color(double), double, int, int);
void flow_plot(pair F(double, double), pair f(double), double, int, int);

/* Jay Belanger's shaded plot routines -- December 1, 2002 */

void blackplot(double f(double), double, double, int);
void blackplot(double f1(double), double f2(double), double, double, int);

void whiteplot(double f(double), double, double, int);
void whiteplot(double f1(double), double f2(double), double, double, int);

void shadeplot(double f(double), double, double, int);
void shadeplot(double f1(double), double f2(double), double, double, int);

} /* end of namespace */

/*
 * geometry.h 
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 */

#define _EPIX_GEOMETRY


namespace ePiX {

  using namespace std;

/* Radial projection from origin to unit sphere */
void plot_R      (double f1(double), double f2(double), double f3(double), 
		  double t_min, double t_max, int num_pts);
void frontplot_R (double f1(double), double f2(double), double f3(double), 
		  double t_min, double t_max, int num_pts);
void backplot_R  (double f1(double), double f2(double), double f3(double), 
		  double t_min, double t_max, int num_pts);

/* triple-valued plot argument */
void plot_R      (triple phi(double), double t_min, double t_max, int num_pts);
void frontplot_R (triple phi(double), double t_min, double t_max, int num_pts);
void backplot_R  (triple phi(double), double t_min, double t_max, int num_pts);

/* Stereographic projection from the north pole... */
void plot_N      (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);
void frontplot_N (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);
void backplot_N  (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);

/* and the south */
void plot_S      (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);
void frontplot_S (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);
void backplot_S  (double f1(double), double f2(double),
		  double t_min, double t_max, int num_pts);

/* Hyperbolic lines */
void draw_hyperbolic_line (pair, pair);
void hyperbolic_line (pair, pair);

void draw_disk_line (pair, pair);
void disk_line (pair, pair);

} /* end of namespace */

/*
 * arcana.h
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

#define _EPIX_ARCANA


namespace ePiX {

  using namespace std;

/* Implementation of the momentum construction */
void draw_profile (double f(double), double, double, int);
void plot_profile (double f(double), double, double, int);
void plot_profile (double f(double), double, double, double, int);

/* Plane linear transformations */
pair 
transf (pair, pair, pair);

pair 
reflect (double, pair);

/* Image of the "standard F" under a linear transformation */
void 
std_F (pair, pair);

/*
 * fractal generation
 *
 * The basic "level-1" recursion unit is a piecewise-linear path whose 
 * segments are parallel to spokes on a wheel, labelled modulo <spokes>.
 * Recursively up to <depth>, each segment is replaced by a copy of the
 * recursion unit.
 *
 * Sample data for _/\_ standard Koch snowflake:
 * const int pre_seed[] = {6, 4, 0, 1, -1, 0};
 * pre_seed[0] = spokes, pre_seed[1] = seed_length;
 */

void 
fractal (pair p, pair q, int depth, const int *pre_seed);

} /* end of namespace */

/*
 * meshplots.h
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

#define _EPIX_MESH


namespace ePiX {

  using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *                        meshplots.cc                           *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void 
draw_wiremesh(double f1(double, double),
	      double f2(double, double),
	      double f3(double, double), pair, pair, mesh, mesh);

/* Parametric surfaces */
void wiremesh(double f1(double, double), double f2(double, double), 
	      double f3(double, double), pair, pair, mesh, mesh);

/* Graphs of functions of two real variables */
void wiremesh(double f(double, double), pair, pair, mesh, mesh);

/* triple-valued plot argument */
void draw_wiremesh(triple Phi(double, double), pair, pair, mesh, mesh);
void wiremesh     (triple Phi(double, double), pair, pair, mesh, mesh);

} /* end of namespace */

/*
 * functions.h
 *
 * Andrew D. Hwang            <ahwang@mathcs.holycross.edu>
 *
 * Version 0.8.8rc6
 * Last Change: December 02, 2002
 *
 */

#define _EPIX_FUNCTIONS

namespace ePiX {

  using namespace std;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 *                         functions.c                           *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

double
id (double);

double
proj1 (double, double);

double
proj2 (double, double);

double
sinx (double);

double
sgn (double);

double
recip (double);

double
cb (double);

int 
gcd (int, int);

double
inf (double f(double), double, double);

double
sup (double f(double), double, double);

} /* end of namespace */

