summaryrefslogtreecommitdiff
path: root/graphics/epix
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/epix
Initial commit
Diffstat (limited to 'graphics/epix')
-rw-r--r--graphics/epix/AUTHORS5
-rw-r--r--graphics/epix/BUGS24
-rw-r--r--graphics/epix/COPYING340
-rw-r--r--graphics/epix/ChangeLog743
-rw-r--r--graphics/epix/Color.cc369
-rw-r--r--graphics/epix/Color.h156
-rw-r--r--graphics/epix/Color_Base.cc52
-rw-r--r--graphics/epix/Color_Base.h84
-rw-r--r--graphics/epix/Color_CMY.cc160
-rw-r--r--graphics/epix/Color_CMY.h82
-rw-r--r--graphics/epix/Color_CMYK.cc216
-rw-r--r--graphics/epix/Color_CMYK.h85
-rw-r--r--graphics/epix/Color_Gray.cc129
-rw-r--r--graphics/epix/Color_Gray.h67
-rw-r--r--graphics/epix/Color_Neutral.cc98
-rw-r--r--graphics/epix/Color_Neutral.h64
-rw-r--r--graphics/epix/Color_RGB.cc146
-rw-r--r--graphics/epix/Color_RGB.h68
-rw-r--r--graphics/epix/Color_Sep.cc278
-rw-r--r--graphics/epix/Color_Sep.h133
-rw-r--r--graphics/epix/Color_Utils.cc113
-rw-r--r--graphics/epix/Color_Utils.h66
-rw-r--r--graphics/epix/INSTALL179
-rw-r--r--graphics/epix/Makefile.am115
-rw-r--r--graphics/epix/Makefile.in1025
-rw-r--r--graphics/epix/NEWS91
-rw-r--r--graphics/epix/POST-INSTALL123
-rw-r--r--graphics/epix/README139
-rw-r--r--graphics/epix/THANKS122
-rw-r--r--graphics/epix/TODO0
-rw-r--r--graphics/epix/VERSION1
-rw-r--r--graphics/epix/aclocal.m4879
-rw-r--r--graphics/epix/active_screen.cc80
-rw-r--r--graphics/epix/active_screen.h72
-rw-r--r--graphics/epix/affine.cc300
-rw-r--r--graphics/epix/affine.h114
-rw-r--r--graphics/epix/angle_units.cc94
-rw-r--r--graphics/epix/angle_units.h77
-rw-r--r--graphics/epix/arrow_data.cc130
-rw-r--r--graphics/epix/arrow_data.h77
-rw-r--r--graphics/epix/arrow_style.cc103
-rw-r--r--graphics/epix/arrow_style.h76
-rw-r--r--graphics/epix/axis.cc925
-rw-r--r--graphics/epix/axis.h207
-rw-r--r--graphics/epix/bash_completions8
-rw-r--r--graphics/epix/camera.cc318
-rw-r--r--graphics/epix/camera.h134
-rw-r--r--graphics/epix/circle.cc197
-rw-r--r--graphics/epix/circle.h94
-rw-r--r--graphics/epix/clipping.cc136
-rw-r--r--graphics/epix/clipping.h77
-rw-r--r--graphics/epix/config.guess1497
-rw-r--r--graphics/epix/config.sub1608
-rw-r--r--graphics/epix/configure6396
-rw-r--r--graphics/epix/configure.ac58
-rw-r--r--graphics/epix/constants.h108
-rw-r--r--graphics/epix/crop_algorithms.h225
-rw-r--r--graphics/epix/cropping.cc88
-rw-r--r--graphics/epix/cropping.h68
-rw-r--r--graphics/epix/curves.cc663
-rw-r--r--graphics/epix/curves.h187
-rw-r--r--graphics/epix/data_bins.cc411
-rw-r--r--graphics/epix/data_bins.h101
-rw-r--r--graphics/epix/data_file.cc687
-rw-r--r--graphics/epix/data_file.h172
-rw-r--r--graphics/epix/data_mask.cc76
-rw-r--r--graphics/epix/data_mask.h66
-rw-r--r--graphics/epix/debug.h37
-rw-r--r--graphics/epix/depcomp530
-rw-r--r--graphics/epix/deriv.h49
-rw-r--r--graphics/epix/doc/Makefile.am45
-rw-r--r--graphics/epix/doc/Makefile.in364
-rw-r--r--graphics/epix/doc/alignment.eepic19
-rw-r--r--graphics/epix/doc/alignment.xp26
-rw-r--r--graphics/epix/doc/alignment_lr.eepic17
-rw-r--r--graphics/epix/doc/alignment_lr.xp24
-rw-r--r--graphics/epix/doc/arrow.eepic22
-rw-r--r--graphics/epix/doc/arrow.xp18
-rw-r--r--graphics/epix/doc/arrow25.eepic22
-rw-r--r--graphics/epix/doc/arrow50.eepic22
-rw-r--r--graphics/epix/doc/basepoint.eepic16
-rw-r--r--graphics/epix/doc/basepoint.xp36
-rw-r--r--graphics/epix/doc/camera.eepic285
-rw-r--r--graphics/epix/doc/camera.xp86
-rw-r--r--graphics/epix/doc/cb.eepic25
-rw-r--r--graphics/epix/doc/cb.xp22
-rw-r--r--graphics/epix/doc/color_density.eepic139
-rw-r--r--graphics/epix/doc/color_density.xp42
-rw-r--r--graphics/epix/doc/dots.eepic19
-rw-r--r--graphics/epix/doc/dots.xp28
-rw-r--r--graphics/epix/doc/ePiX.eepic1099
-rw-r--r--graphics/epix/doc/ePiX.xp156
-rw-r--r--graphics/epix/doc/epix.info4696
-rw-r--r--graphics/epix/doc/graphpaper.eepic101
-rw-r--r--graphics/epix/doc/graphpaper.xp24
-rw-r--r--graphics/epix/doc/hello.eepic15
-rw-r--r--graphics/epix/doc/hello.xp20
-rw-r--r--graphics/epix/doc/koch.eepic160
-rw-r--r--graphics/epix/doc/koch.xp24
-rw-r--r--graphics/epix/doc/layout.eepic1511
-rw-r--r--graphics/epix/doc/layout.xp36
-rw-r--r--graphics/epix/doc/manual.pdfbin0 -> 710725 bytes
-rw-r--r--graphics/epix/doc/manual.tex5030
-rw-r--r--graphics/epix/doc/marker.eepic39
-rw-r--r--graphics/epix/doc/marker.xp68
-rw-r--r--graphics/epix/doc/my_code.cc15
-rw-r--r--graphics/epix/doc/my_code.h10
-rw-r--r--graphics/epix/doc/objects.eepic412
-rw-r--r--graphics/epix/doc/objects.xp33
-rw-r--r--graphics/epix/doc/pathstyle.eepic225
-rw-r--r--graphics/epix/doc/pathstyle.xp24
-rw-r--r--graphics/epix/doc/plot_a.eepic95
-rw-r--r--graphics/epix/doc/plot_a.xp27
-rw-r--r--graphics/epix/doc/plot_b.eepic225
-rw-r--r--graphics/epix/doc/plot_b.xp27
-rw-r--r--graphics/epix/doc/plotting.eepic82
-rw-r--r--graphics/epix/doc/plotting.xp26
-rw-r--r--graphics/epix/doc/plotting2.eepic1766
-rw-r--r--graphics/epix/doc/plotting2.xp29
-rw-r--r--graphics/epix/doc/plotting3.eepic146
-rw-r--r--graphics/epix/doc/plotting3.xp43
-rw-r--r--graphics/epix/doc/scaling.eepic56
-rw-r--r--graphics/epix/doc/scaling.xp37
-rw-r--r--graphics/epix/doc/sgn.eepic30
-rw-r--r--graphics/epix/doc/sgn.xp28
-rw-r--r--graphics/epix/doc/sinx.eepic40
-rw-r--r--graphics/epix/doc/sinx.xp23
-rw-r--r--graphics/epix/doc/slices.eepic45
-rw-r--r--graphics/epix/doc/slices.xp39
-rw-r--r--graphics/epix/domain.cc370
-rw-r--r--graphics/epix/domain.h143
-rw-r--r--graphics/epix/edge_data.h75
-rw-r--r--graphics/epix/eepic.cc297
-rw-r--r--graphics/epix/eepic.h127
-rw-r--r--graphics/epix/elaps.11
-rw-r--r--graphics/epix/elaps.in485
-rw-r--r--graphics/epix/enums.h52
-rw-r--r--graphics/epix/epix-lib.sh179
-rw-r--r--graphics/epix/epix.1.in50
-rw-r--r--graphics/epix/epix.el.in1068
-rw-r--r--graphics/epix/epix.in340
-rw-r--r--graphics/epix/errors.h55
-rw-r--r--graphics/epix/facet.cc505
-rw-r--r--graphics/epix/facet.h105
-rw-r--r--graphics/epix/files224
-rw-r--r--graphics/epix/flix.11
-rw-r--r--graphics/epix/flix.in563
-rw-r--r--graphics/epix/fmt_template.cc177
-rw-r--r--graphics/epix/fmt_template.h170
-rw-r--r--graphics/epix/format.cc720
-rw-r--r--graphics/epix/format.h300
-rw-r--r--graphics/epix/frac.cc262
-rw-r--r--graphics/epix/frac.h81
-rw-r--r--graphics/epix/frame.cc114
-rw-r--r--graphics/epix/frame.h82
-rw-r--r--graphics/epix/functions.cc398
-rw-r--r--graphics/epix/functions.h147
-rw-r--r--graphics/epix/geometry.cc804
-rw-r--r--graphics/epix/geometry.h125
-rw-r--r--graphics/epix/glyph.cc145
-rw-r--r--graphics/epix/glyph.h85
-rw-r--r--graphics/epix/halfspace.cc67
-rw-r--r--graphics/epix/halfspace.h67
-rw-r--r--graphics/epix/hatching.cc258
-rw-r--r--graphics/epix/hatching.h123
-rw-r--r--graphics/epix/install-sh323
-rw-r--r--graphics/epix/intersections.cc318
-rw-r--r--graphics/epix/intersections.h70
-rw-r--r--graphics/epix/interval.cc228
-rw-r--r--graphics/epix/interval.h81
-rw-r--r--graphics/epix/label_data.cc140
-rw-r--r--graphics/epix/label_data.h97
-rw-r--r--graphics/epix/label_style.cc177
-rw-r--r--graphics/epix/label_style.h136
-rw-r--r--graphics/epix/laps.11
-rw-r--r--graphics/epix/laps.in259
-rw-r--r--graphics/epix/legend.cc204
-rw-r--r--graphics/epix/legend.h94
-rw-r--r--graphics/epix/legend_item.cc166
-rw-r--r--graphics/epix/legend_item.h120
-rw-r--r--graphics/epix/legend_tile.cc173
-rw-r--r--graphics/epix/legend_tile.h94
-rw-r--r--graphics/epix/length.cc277
-rw-r--r--graphics/epix/length.h110
-rw-r--r--graphics/epix/lens.cc162
-rw-r--r--graphics/epix/lens.h99
-rw-r--r--graphics/epix/make_header35
-rw-r--r--graphics/epix/map.h167
-rw-r--r--graphics/epix/marker_style.cc79
-rw-r--r--graphics/epix/marker_style.h59
-rw-r--r--graphics/epix/markers.cc308
-rw-r--r--graphics/epix/markers.h119
-rw-r--r--graphics/epix/mask_diamond.cc129
-rw-r--r--graphics/epix/mask_diamond.h89
-rw-r--r--graphics/epix/mask_ellipse.cc136
-rw-r--r--graphics/epix/mask_ellipse.h89
-rw-r--r--graphics/epix/mask_rectangle.cc129
-rw-r--r--graphics/epix/mask_rectangle.h89
-rw-r--r--graphics/epix/missing360
-rw-r--r--graphics/epix/mkinstalldirs158
-rw-r--r--graphics/epix/paint_style.cc145
-rw-r--r--graphics/epix/paint_style.h103
-rw-r--r--graphics/epix/pairs.cc158
-rw-r--r--graphics/epix/pairs.h88
-rw-r--r--graphics/epix/path.cc329
-rw-r--r--graphics/epix/path.h135
-rw-r--r--graphics/epix/path_data.cc280
-rw-r--r--graphics/epix/path_data.h101
-rw-r--r--graphics/epix/path_style.cc160
-rw-r--r--graphics/epix/path_style.h83
-rw-r--r--graphics/epix/pen_arrow.cc190
-rw-r--r--graphics/epix/pen_arrow.h83
-rw-r--r--graphics/epix/pen_data.cc88
-rw-r--r--graphics/epix/pen_data.h82
-rw-r--r--graphics/epix/pen_fill.cc149
-rw-r--r--graphics/epix/pen_fill.h83
-rw-r--r--graphics/epix/pen_line.cc125
-rw-r--r--graphics/epix/pen_line.h79
-rw-r--r--graphics/epix/picture.cc429
-rw-r--r--graphics/epix/picture.h170
-rw-r--r--graphics/epix/picture_data.cc193
-rw-r--r--graphics/epix/picture_data.h113
-rw-r--r--graphics/epix/plane.cc143
-rw-r--r--graphics/epix/plane.h74
-rw-r--r--graphics/epix/plot_algorithms.h245
-rw-r--r--graphics/epix/plots.cc613
-rw-r--r--graphics/epix/plots.h206
-rw-r--r--graphics/epix/pst.cc359
-rw-r--r--graphics/epix/pst.h124
-rw-r--r--graphics/epix/samples/Makefile.am20
-rw-r--r--graphics/epix/samples/Makefile.in340
-rw-r--r--graphics/epix/samples/README258
-rw-r--r--graphics/epix/samples/R_demo.xp69
-rw-r--r--graphics/epix/samples/S2_harmonics.xp104
-rw-r--r--graphics/epix/samples/artifacts.xp51
-rw-r--r--graphics/epix/samples/binom.cc37
-rw-r--r--graphics/epix/samples/bowl.xp55
-rw-r--r--graphics/epix/samples/butterfly.xp136
-rw-r--r--graphics/epix/samples/calculus.xp43
-rw-r--r--graphics/epix/samples/clipping.xp233
-rw-r--r--graphics/epix/samples/color_sep.xp76
-rw-r--r--graphics/epix/samples/conic.xp55
-rw-r--r--graphics/epix/samples/contour.xp56
-rw-r--r--graphics/epix/samples/coord_tricks.xp66
-rw-r--r--graphics/epix/samples/cropplot.xp35
-rw-r--r--graphics/epix/samples/cube.flx44
-rw-r--r--graphics/epix/samples/dataplot.xp55
-rw-r--r--graphics/epix/samples/decorate.xp120
-rw-r--r--graphics/epix/samples/demoivre.xp42
-rw-r--r--graphics/epix/samples/denom.xp39
-rw-r--r--graphics/epix/samples/densityplot.xp44
-rw-r--r--graphics/epix/samples/dipole.xp86
-rw-r--r--graphics/epix/samples/extract.xp109
-rw-r--r--graphics/epix/samples/geomsum.xp37
-rw-r--r--graphics/epix/samples/golden_rect.xp29
-rw-r--r--graphics/epix/samples/helicoid.flx133
-rw-r--r--graphics/epix/samples/hello.xp20
-rw-r--r--graphics/epix/samples/histogram.xp83
-rw-r--r--graphics/epix/samples/house.flx88
-rw-r--r--graphics/epix/samples/hyperboloid.xp63
-rw-r--r--graphics/epix/samples/inverse.xp74
-rw-r--r--graphics/epix/samples/koch.xp38
-rw-r--r--graphics/epix/samples/label_debug.xp132
-rw-r--r--graphics/epix/samples/layout.xp36
-rw-r--r--graphics/epix/samples/layout2.xp42
-rw-r--r--graphics/epix/samples/legend.xp72
-rw-r--r--graphics/epix/samples/levelset.xp60
-rw-r--r--graphics/epix/samples/levelset2.xp72
-rw-r--r--graphics/epix/samples/levelset3.xp89
-rw-r--r--graphics/epix/samples/lighting.flx132
-rw-r--r--graphics/epix/samples/lighting.h114
-rw-r--r--graphics/epix/samples/line_debug.xp126
-rw-r--r--graphics/epix/samples/lissajous.xp28
-rw-r--r--graphics/epix/samples/log.xp217
-rw-r--r--graphics/epix/samples/lorenz.xp70
-rw-r--r--graphics/epix/samples/medians.xp134
-rw-r--r--graphics/epix/samples/minkowski.xp103
-rw-r--r--graphics/epix/samples/mirrorball.flx93
-rw-r--r--graphics/epix/samples/newton.xp43
-rw-r--r--graphics/epix/samples/objects.xp32
-rw-r--r--graphics/epix/samples/oscillator.xp89
-rw-r--r--graphics/epix/samples/parabola.xp32
-rw-r--r--graphics/epix/samples/pascal.xp53
-rw-r--r--graphics/epix/samples/pendulum.flx62
-rw-r--r--graphics/epix/samples/planes.xp29
-rw-r--r--graphics/epix/samples/plotting.xp26
-rw-r--r--graphics/epix/samples/plotting2.xp29
-rw-r--r--graphics/epix/samples/plotting3.xp43
-rw-r--r--graphics/epix/samples/polar.xp29
-rw-r--r--graphics/epix/samples/pole.xp60
-rw-r--r--graphics/epix/samples/polyhedra.xp129
-rw-r--r--graphics/epix/samples/riemann.flx68
-rw-r--r--graphics/epix/samples/saddle.xp70
-rw-r--r--graphics/epix/samples/semicirc.xp28
-rw-r--r--graphics/epix/samples/shadeplot.xp61
-rw-r--r--graphics/epix/samples/slopefield.xp29
-rw-r--r--graphics/epix/samples/sphere.xp46
-rw-r--r--graphics/epix/samples/spherical.xp76
-rw-r--r--graphics/epix/samples/sqrt.xp51
-rw-r--r--graphics/epix/samples/sqrt2.xp64
-rw-r--r--graphics/epix/samples/std_F.cc124
-rw-r--r--graphics/epix/samples/std_F.h83
-rw-r--r--graphics/epix/samples/std_F.xp88
-rw-r--r--graphics/epix/samples/steiner.flx50
-rw-r--r--graphics/epix/samples/steiner2.flx70
-rw-r--r--graphics/epix/samples/surface_shade.xp46
-rw-r--r--graphics/epix/samples/symmetries.xp87
-rw-r--r--graphics/epix/samples/tori.xp63
-rw-r--r--graphics/epix/samples/torus.xp39
-rw-r--r--graphics/epix/samples/trig.flx74
-rw-r--r--graphics/epix/samples/twisted_cubic.xp106
-rw-r--r--graphics/epix/samples/uppersum.xp37
-rw-r--r--graphics/epix/samples/vfield.xp71
-rw-r--r--graphics/epix/samples/weierstrass.xp36
-rw-r--r--graphics/epix/samples/wheel.xp50
-rw-r--r--graphics/epix/screen.cc390
-rw-r--r--graphics/epix/screen.h175
-rw-r--r--graphics/epix/screen_crop.cc70
-rw-r--r--graphics/epix/screen_crop.h49
-rw-r--r--graphics/epix/screen_data.cc572
-rw-r--r--graphics/epix/screen_data.h153
-rw-r--r--graphics/epix/screen_mask.cc55
-rw-r--r--graphics/epix/screen_mask.h97
-rw-r--r--graphics/epix/segment.cc111
-rw-r--r--graphics/epix/segment.h84
-rw-r--r--graphics/epix/sphere.cc131
-rw-r--r--graphics/epix/sphere.h87
-rw-r--r--graphics/epix/spline.cc145
-rw-r--r--graphics/epix/spline.h63
-rw-r--r--graphics/epix/spline_data.h51
-rw-r--r--graphics/epix/state.cc509
-rw-r--r--graphics/epix/state.h213
-rw-r--r--graphics/epix/surface.cc1072
-rw-r--r--graphics/epix/surface.h194
-rw-r--r--graphics/epix/tikz.cc312
-rw-r--r--graphics/epix/tikz.h152
-rw-r--r--graphics/epix/tile.cc38
-rw-r--r--graphics/epix/tile.h62
-rw-r--r--graphics/epix/triples.cc211
-rw-r--r--graphics/epix/triples.h115
-rw-r--r--graphics/epix/utils.cc124
-rw-r--r--graphics/epix/utils.h56
-rw-r--r--graphics/epix/verbatim.cc80
-rw-r--r--graphics/epix/verbatim.h66
344 files changed, 71175 insertions, 0 deletions
diff --git a/graphics/epix/AUTHORS b/graphics/epix/AUTHORS
new file mode 100644
index 0000000000..24ded708ef
--- /dev/null
+++ b/graphics/epix/AUTHORS
@@ -0,0 +1,5 @@
+Jay P. Belanger
+Marcus D. Hanwell
+Andrew D. Hwang
+
+Please see THANKS for the list of contributors. \ No newline at end of file
diff --git a/graphics/epix/BUGS b/graphics/epix/BUGS
new file mode 100644
index 0000000000..3436bad2ed
--- /dev/null
+++ b/graphics/epix/BUGS
@@ -0,0 +1,24 @@
+ePiX-1.2 -- BUGS
+
+Last Change: September 19, 2007
+
+This file lists known idiosyncrasies ("features, not bugs") whose
+behavior may be unexpected. Some are too minor and/or messy to fix,
+some are outside the author's control.
+
+* The build-time script elaps-local calls epix, not epix-local.
+
+* Polygons are not shaded with simulated ambient light. The "fill"
+ attribute controls whether or not to color fill.
+
+* Surface mesh elements are always color-filled. The fill attribute
+ controls whether to use cos^2 (on) or flat (off) shading.
+
+* Dot-like markers may be slightly larger in tikz than in pst/eepic.
+
+* Line underlayer widths may be larger in pst than in eepic/tikz.
+
+* Line caps are round in eepic, square (butt) in pst/tikz.
+
+* Affine maps have no effect on label alignment, only on the offset.
+ (N.B. Non-invertible affine maps may cause NaN label positions.) \ No newline at end of file
diff --git a/graphics/epix/COPYING b/graphics/epix/COPYING
new file mode 100644
index 0000000000..14db8fc79d
--- /dev/null
+++ b/graphics/epix/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/graphics/epix/ChangeLog b/graphics/epix/ChangeLog
new file mode 100644
index 0000000000..832d25f939
--- /dev/null
+++ b/graphics/epix/ChangeLog
@@ -0,0 +1,743 @@
+ePiX 1.1.x
+
+Andrew D. Hwang <ahwang -at- mathcs -dot- holycross -dot- edu>
+
+2007-10.03 (ADH)
+ Version 1.2.1
+ * configure.ac, Makefile.am: New option --enable-epix-el
+ (formerly --with-nolisp)
+ * doc/Makefile.am: Build ps, pdf under manual-stamp so package can
+ be built with parallel make (error noted by Ren\'e Rebe)
+
+2007-09.28 (ADH)
+ * legend_tile.cc, legend_tile.h: Store offset as a pair
+ * legend.cc: (draw) Pass offset as a pair
+ * screen_data.cc: (paste) "affine" object named af, not affine
+
+2007-09.26 (ADH)
+ Version 1.2.0-2
+ * debug.h, interval.cc: #include <cstdlib> (Maik Beckmann)
+ * (Multiple files) Replace const double arguments by double
+
+2007-09.25 (ADH)
+ Version 1.2.0-1
+ * doc/plotting3.xp: crop -> set_crop, and update image
+
+2007-09.24 (ADH)
+ Version 1.1.22 (promoted to 1.2.0)
+ * lens.cc: bubble lens projects to camera sphere
+
+ * angle_units.cc, angle_units.h: (convert_to_radians) Remove
+ - (to_radians, to_degrees, from_degrees) New functions
+ - Store rad/unit, unit/deg, and rev/unit for efficiency
+
+ * state.cc, state.h: (angle) Remove function
+ - (full_turn) Reimplement as from_degrees(360)
+ * functions.cc: Use angle_state::to_radians in trig functions
+
+ * glyph.cc: (map_by) Reimplement label angle computation
+ * label_style.cc, label_style.h: New public void constructor
+ - Non-void constructor is private
+ - (label_angle) Pass non-const double
+ - (label_angle) Use the_angle_style to convert to degrees
+ - (label_angle()) Returns degrees, not current angle units
+
+2007-09.23 (ADH)
+ Version 1.1.21
+ * affine.cc, affine.h: Member functions accept P as well as pair
+
+2007-09.22 (ADH)
+ * length.cc: Remove support for scaled pt
+ * state.cc, state.h: crop() -> set_crop()
+ - (crop) New function, calls screen::crop
+ - (crop_rectangle, crop_ellipse, crop_diamond): Set crop state
+
+ * lens.cc: fisheye, bubble are *not* linear
+ * lens.cc, lens.h: (needs_clip) New function
+ * camera.cc, camera.h: (needs_clip) New function
+ - the_camera() -> cam()
+ * path_data.cc: (photo) Clip to camera.front_plane only if nec.
+ * arrow_data.cc: (photo) Clip to camera.front_plane only if nec.
+
+ * facet.cc, geometry.cc: camera, the_camera() -> cam()
+ * arrow_data.cc, axis.cc, curves.cc, label_data.cc, legend.cc,
+ legend_item.cc, path.cc, path_data.cc, screen_data.cc,
+ sphere.cc, state.cc: the_camera() -> cam()
+
+2007-09.19 (ADH)
+ Version 1.1.20
+ * pen_line.cc: (add_to_pallet) Needn't check for unset
+ * pen_data.cc, pen_data.h: (is_empty) New member
+ * pen_fill.cc: (is_unset) Check line pen for invisibility
+ - (print_to) If bd non-solid, draw fill/border only if visible
+ - (add_to_pallet) Needn't check for unset colors
+ * eepic.cc: (print_line) No base layer if narrower than line
+ * pst.cc: (print_line) Adjust base layer width (m_bwidth too large)
+
+2007-09.18 (ADH)
+ Version 1.1.19
+ * affine.cc: Group scaling operators in parentheses
+ * glyph.cc: (map_by) Map offset direction, not length
+
+2007-09.17 (ADH)
+ * format.cc: (print_mark) Use mask color for circ background, add
+ to pallet if necessary
+ - Fix label padding
+ - Draw label border if pen width is positive
+ * markers.cc: (circ) Handle like other markers
+ - (marker) Handle CIRC like other types
+ * label_style.cc: (seen_through) Needn't check for unset mask
+ * label_style.h: Default label_pad 0
+
+ * picture.cc: Remove mp_format stubs
+
+ * data_bins.cc, data_bins.h: Handle data on cuts
+ - New data member m_cut_hits
+ - (d_bin::insert) Rename add_datum
+ - Copy constructor mis-copied d_bins
+ - Implement m_bins as a list, not a vector
+
+2007-09.16 (ADH)
+ Version 1.1.18
+ * pair_map.cc, pair_map.h: Rename file, class to affine
+ * epix.h: Add affine.h
+ * screen.cc, screen.h: Pass-through affine operations
+ - (apply) New member function
+ * screen_data.cc, screen_data.h: Affine operations on contents
+
+ * label_data.cc, label_data.h: Store offset as a pair
+ * axis.cc, markers.cc: (label) Adjust label_data ctor
+ * glyph.cc, glyph.h: Store offset as a pair
+ * glyph.cc: (map_to) Adjust offset, label angle
+ * legend_item.cc: (key) Adjust glyph ctor
+
+2007-09.15 (ADH)
+ * pair_map.cc, pair_map.h: Complete re-write
+ * screen_data.cc: (paste) Use new pair_map ctor
+
+ * utils.cc, utils.h: (get_chars) New function
+ * path_style.cc: Rename get_breaks -> __epix_get_breakpts
+ - (extract) Move to utils, rename -> get_chars
+ - Use get_chars to extract dot/dash pattern
+ - (__epix_get_breakpts) Check for anomalous patterns
+
+ * screen_data.cc, screen_data.h: (is_cropped) Remove
+ * screen.cc, screen.h: (is_cropped) Remove
+
+2007-09.14 (ADH)
+ * format.cc: (print_color) Check for empty vector of densities
+ * picture_data.cc: (add_to_pallet) Check for unset color
+
+ * label_style.cc, label_style.h: Dependency cleanup
+ * format.cc, legend.cc, markers.cc, state.cc: Consequent changes
+ * arrow_data.cc, Color_Neutral.cc, glyph.cc, legend.cc,
+ path_data.h, path.cc, pen_arrow.cc, pen_data.cc, pen_fill.cc
+ picture.cc, picture_data.cc, plots.cc: Dependency cleanup
+
+2007-09.14 (ADH)
+ Version 1.1.17
+ * functions.cc, functions.h: (clip_to_unit) Move to Color_Utils
+ * Color_Utils.cc: #include "Color_Utils.h"
+ * Color_Utils.cc, Color_Utils.h: Move clip_to_unit from functions
+
+2007-09.13 (ADH)
+ * length.cc, length.h: (operator+, operator*) Pass one arg by value
+
+ * configure.ac, Makefile.am: --with-nolisp option (for Gentoo)
+ - Make scripts dependent on epix.el (to force build before install)
+
+ * Color_Base.h: print_to(format) -> model, densities
+ - Color is not a friend class
+ * Color.cc, Color.h: (print_to) Remove function
+ - (model, densities) New functions
+ * Color_CMY.cc, Color_CMY.h, Color_CMYK.cc, Color_CMYK.h: Same
+ * Color_Gray.cc, Color_Gray.h, Color_RGB.cc, Color_RGB.h: Same
+ * Color_Neutral.cc, Color_Neutral.h, Color_Sep.cc, Color_Sep.h: Same
+
+ * format.cc, format.h: (print_color(string, string, vector<double>)
+ New function, calls existing print_color functions
+
+ * plane.cc, plane.h: (pt, perp) New member functions
+ - Intersection operators aren't friends
+ * intersections.cc: Use Plane member functions
+
+2007-09.12 (ADH)
+ * (Update README et. al.)
+
+2007-09.11 (ADH)
+ Version 1.1.16
+ * picture.cc, picture.h: (end_picture) New function (formerly end)
+ - (end) Set output format on command-line flags, call end_picture
+
+ * elaps.in, epix.in, flix.in: --pst, --tikz, --eepic options
+
+2007-09.10 (ADH)
+ * facet.cc: (draw) Handle unset pen, reorganize logic
+
+ * Makefile.am: Install all headers under $(pkgincludedir)
+ - Remove libepix_a_HDRS from libepix_a_LIBADD deps
+ * make_header: Preserve include guards in epix.h
+ - Include string
+ - Don't include cstdio
+ * Color.h, Color_CMY.h, Color_CMYK.h, Color_Gray.h,
+ Color_Neutral.h, Color_RGB.h, Color_Sep.h, Color_Utils.h:
+ EPIX2 -> EPIX in include guard symbol
+
+2007-09.09 (ADH)
+ * eepic.cc: (print_circle_marker) Set allinethickness, draw once
+
+ * markers.h: (right_angle, arc_measure) Default size 8pt (was 12)
+
+2007-09.08 (ADH)
+ Version 1.1.15
+ * arrow_style.cc, arrow_style.h, pen_arrow.cc, state.cc, state.h:
+ camber -> inset
+ * constants.h: ACAMBER -> INSET
+
+ * label_style.cc, label_style.h: (is_masked) New function
+ * markers.cc: (label) Get mask flag from current label style
+
+ * glyph.cc: (print_to) Don't call print_latex_hbox on label text
+
+ * screen_data.h: Remove void constructor
+
+ * pair_map.cc, pair_map.h: const pair args -> const pair&
+
+ * screen_data.cc, screen_data.h: Store mask-indep corners
+ - (paste) Use corners, not mask, to generate affine_map
+ - (add_tile(tile*)) clone argument
+ - (extract, extract_diamond, extract_ellipse) New functions
+
+ * screen.cc: pair2P -> __epix_pair2P, accept const pair&
+ - (extract, extract_diamond, extract_ellipse) New functions
+
+2007-09.07 (ADH)
+ * format.h: (print_circle_marker) New function
+ * format.cc: (print_latex_marker) Needn't handle dot-like marks
+ - (print_mark) Use print_circle_marker for dot-like marks
+ - (print_edge) Use print_circle_marker for path dots
+
+ * eepic.cc, eepic.h: (print_circle_marker) New function
+ * pst.cc, pst.h: (print_circle_marker) New function
+ * tikz.cc, tikz.h: (print_circle_marker) New function
+
+ * tikz.cc: (put_box) truncate coordinates
+
+2007-09.05 (ADH)
+ * format.cc: (print_latex_hbox) "default" -> "rm"
+ - "normalsize" -> "nsz"
+ * label_style.h: (label_state) Same as above
+ * state.h: (font_size, font_face) Same as above
+
+ * mask_rectangle.h, mask_ellipse.h, mask_diamond.h: Remove void
+ constructor
+
+ * pen_fill.cc: (print_to, add_to_pallet) No action if is_empty
+
+2007-08.31 (ADH)
+ * epix-lib.sh: Remove unused global EPIX_VERBOSE
+ - New global LATEX_PKGS
+ - (ePiX_usepackages) New function (only used by elaps)
+
+ * elaps.in: (elaps_make_latex) Get LaTeX packages from input file
+
+2007-08.30 (ADH)
+ Version 1.1.14
+ * format.h: (usepackages) New function
+ * format.c (file_comments) Call usepackages
+
+ * eepic.cc, eepic.h: (usepackages)
+ * pts.cc, pst.h: (usepackages)
+ * tikz.cc, tikz.h: (usepackages)
+ * fmt_template.cc, fmt_template.h: (usepackages)
+
+2007-08.30 (ADH)
+ Version 1.1.13
+ * epix.el.in: New file
+ * epix.el: Obsolete file removed
+
+2007-08.29 (ADH)
+ * hatching.cc, hatching.h: Reimplement
+
+2007-08.25 (ADH)
+ * format.cc, format.h: (path_break) Default implementation
+ - (path_conector) New virtual function, default implementation
+ - (print_edge, print_paths) Use path_connector
+ - (xdefinecolor) Non-virtual functions for xcolor formats
+
+ * tikz.cc, tikz.h: New files
+
+ * eepic.cc: (print_color) Use xdefinecolor
+ * eepic.cc, eepic.h: (path_break) Use default implementation
+ * pst.cc, pst.h: (path_break) Use default implementation
+
+ * picture.cc, picture.h: (mp_format, print_mp) Comment out
+ - pgf_format -> tikz_format
+ - print_pgf -> print_tikz
+
+2007-08.23 (ADH)
+ * clipping.cc, clipping.h: New face list m_extras
+ - (clip_face, clip_slice, clip_restore) New functions
+ * state.cc, state.h: (clip_face, clip_slice, clip_restore) New
+ functions
+ - (label_border) Accept double for length arg
+
+ * legend.cc: (draw) Position is not camera-dependent
+
+ * picture.cc, picture.h: (border) Accept double for length arg
+ * screen.cc, screen.h: (border) Accept double for length arg
+
+2007-08.21 (ADH)
+ Version 1.1.12
+ * axis.cc: log labels in decimal by default, sci available
+
+2007-08.20 (ADH)
+ * axis.cc, axis.h: (unmark(double)) New member function
+
+2007-08.19 (ADH)
+ * label_data.cc: (label_data(P, mark, align): Axis tick markers
+ restrictively aligned, cannot be rotated
+
+ * legend_tile.cc, legend_tile.h: Copy ctor/assign, destructor
+
+ * lens.cc, lens.h: New files
+ - Add clone function
+ * camera.cc, camera.h: Factor out Lens code
+ - Add copy ctor/assign
+
+ * picture.cc, picture.h: (pic_units_per_pt, units_per_pic_unit,
+ pt_to_screen) New functions for true-size drawing
+ - Remove svg functions
+
+ * markers.cc, markers.h: (right_angle, arc_measure, axis_break,
+ h_error_bar, v_error_bar) New functions
+
+
+2007-08.18 (ADH)
+ Version 1.1.11
+ * screen_data.cc, screen_data.h: (print_to) Accept bool flag to
+ encapsulate in a picture-like environment
+
+ * format.h: (reset_state) New pure virtual function
+ * eepic.cc, eepic.h, pst.cc, pst.h: (reset_state) New function
+
+2007-08.17 (ADH)
+ * format.cc, format.h: (start_picture, end_picture, print_pallet,
+ print_latex_hbox, set_unitlength) New functions
+ - (pic_header, pic_footer) Implemented in lower-level functions
+ * glyph.cc: (print_to) Font attributes handled in format.
+
+ * legend_item.cc, legend_item.h: New files
+ * legend_tile.cc, legend_tile.h: New files
+
+2007-08.16 (ADH)
+ * format.cc, format.h: (print_latex_label) Masking flag
+ - (print_latex_label) Always print text color
+
+ * legend.cc, legend.h: New files
+
+ * length.cc, length.h: (name) New member function
+
+2007-08.15 (ADH)
+ * fmt_template.cc, fmt_template.h: New files
+
+ * active_screen.cc, active_screen.h: screen_broker class replaces
+ global screen pointer active_screen
+
+ * picture.cc, picture.h: (inlay, inlay_vertical, inlay_horizontal)
+ New functions
+ - (deactivate) New function
+ - (activate) Re-implement using screen_broker
+
+ * arrow_data.cc, axis.cc, curves.cc, label_data.cc, path.cc,
+ path_data.cc, state.cc: Use active_screen()
+
+2007-08.12 (ADH)
+ * curves.cc: grid calls rect for outmost lines (enables filling)
+
+ * format.h: Re-design interface
+ * eepic.cc, eepic.h, pst.cc, pst.h: Re-implement
+
+ * glyph.cc, pen_fill.cc, pen_line.cc: Re-implement print_to
+ * pen_arrow.cc: Generate own arrow head data
+ * picture_data.cc: Reimplement print_to
+ * pen_fill.h: Remove hatch angle members
+
+2007-08.09 (ADH)
+ Version 1.1.10
+ * mask_diamond.cc, mask_ellipse.cc, mask_rectangle.cc: (backing)
+ Use plain backing color for edge
+
+ * domain.cc: (resize1, resize2, resize3) Hack to avoid round-down
+
+2007-08.08 (ADH)
+ * curves.cc, curves.h: (line) Make num_pts argument unsigned
+ * curves.cc: (line, triangle, quad, arrow) Sensitive to whether
+ camera preserves lines
+
+ * constants.h: New constants MAX_LOG_BASE, DEF_PRECISION, MAX_PRECISION
+
+2007-08.07 (ADH)
+ * frac.cc, frac.h: New files (rational number class)
+
+ * pen_arrow.cc: (print_to) Use copy of label_state to print a dot
+
+ * label_data.cc, label_data.h: (mask_color, text_color, align_to)
+ New pass-through functions
+ * markers.cc, markers.h: Label commands use label_data
+ pass-through
+ - Move axis and axis label functions to new file axis.cc
+ * axis.cc, axis.h: New files (Coordinate axes, global functions)
+ - New log label commands with same signature as Cartesian versions
+ - New axes along sides of bounding box
+
+ * eepic.cc, pst.cc: (pic_header, pic_footer, print_color) Print
+ "%" at end of line
+
+2007-08.06 (ADH)
+ * state_data.h: Remove file
+ * state.cc: Include style headers explicitly
+
+ * pst.cc: (pic_footer, pic_header) Don't use pspicture* when cropping
+
+2007-08.04 (ADH)
+ * epix-lib.sh (ePiX_usage, ePiX_version): Update copyright,
+ licence notices
+ - Get script name from caller
+ - (ePiX_bugreport) New function
+ * elaps.in, epix.in, flix.in, laps.in: Specify script name for
+ usage, version
+ - Call ePiX_bugreport at end of help
+
+ * triples.cc, triples.h: (Several binary operators) Pass first
+ argument as value when implementation must copy anyway
+
+2007-08.03 (ADH)
+ Version 1.1.9
+ * flix.in: (flix_png) Pass tmax to bc, don't let shell evaluate
+
+ * path_data.c: (photo) Print filled only if >= 3 non-null edges
+
+2007-08.02 (ADH)
+ * spline.cc: (data) Indexing errors; increase max indices by 1
+
+ * data_bins.cc: (plot) Use 20 intervals per spline
+ - (bar_chart, histogram, plot): Check for sero population
+ - (bar_chart) Bar height = frac of population in bin
+ - (histogram) Box height = frac of pop per horizontal unit
+ - (pop) Implement function
+
+ * path_style.cc: (path_state(string)) Fix test for solidity
+
+ * README-changes, README-porting: Removed
+
+2007-08.01 (ADH)
+ * functions.h: Remove "D", "I" aliases for Deriv, Integral
+ * functions.cc: (recip) Return 1.0/x (sec, csc, tan have poles)
+ * functions.cc, functions.h: Remove nine lowercase trig functions
+ * plots.cc: D -> Deriv, I -> Integral
+
+ * triples.h: Remove "triple" alias for P
+ * triples.cc, triples.h: New member function is_valid()
+ - (midpoint) Remove function
+ * circle.cc: Replace P::midpoint
+
+ * elaps.in: Keep eepic file, back up existing file if any
+ - Unset EPIX_OUTFILE, EPIX_OUTROOT on loop exit
+ - Print informative (but fake) lines on latex/dvips failure
+
+ * curves.cc, curves.h: (spline(vector<P>, int)) New function
+ * data_bins.cc: (plot) Draw piecewise-cubic spline, not n_spline
+
+2007-07.31 (ADH)
+ * crop_algorithms.h: (loopify)
+ - Increment twice after insertion
+ - Erase lone edge correctly
+
+ * markers.cc, markers.h: (h_axis_tick, v_axis_tick) Alignment option
+ - (h_axis, h_log_axis, v_axis, v_log_axis) Alignment option
+ * label_data.cc, label_data.h: (label_data(P, mark_type)) Accepts
+ alignment option
+ * eepic.cc: (print_mark) Handle alignment
+ * pst.cc: (print_mark) Handle alignment
+ - (print_edges) Use pspolygon for closed paths
+
+ * path_data.cc, path_data.h: New constructor from list of edge3d
+ - (is_closed, is_filled) Move body to source file
+ - vector<P>, list<edge3d> constructors do not fill unless closed
+ * plot_algorithms.h: (plot_map_dom, euler_plot) Build plots from
+ edges, not vertices
+ - (plot_map_dom) Don't close or fill surface/solid plots
+
+2007-07.30 (ADH)
+ * circle.cc, circle.h, plane.cc, plane.h, segment.cc, segment.h,
+ sphere.cc, sphere.h:
+ - Remove intersection member operators
+ - Add bool malformed member, constructor for malformed objects
+ - Intersection operators do not throw
+ * intersections.cc, intersections.h: New files, handle
+ intersections of object classes
+ * make_header: Add intersections.h
+
+2007-07.29 (ADH)
+ * errors.h: Remove error type enums
+
+ * data_file.cc: (write(fmt)) Column indices reversed in try block
+
+ * curves.cc: (ellipse_left, ellipse_right) Correct angle bounds
+ * path.cc: Ellipse constructor creates path containing specified
+ number of edges
+
+ * markers.cc: marker(P, circ) calls circ
+ - masked log axis labels
+ - log axis labels accept optional base argument
+
+ * eepic.cc, pst.cc: BOX and DOT, BBOX and DDOT of the same size
+ - Label padding works more similarly to PSTricks
+ * pst.cc: (print(label_state, string)) If no label border, set
+ linestyle=none
+ * glyph.cc: (print_to) Handle font face
+
+ * constants.h: AVG_DOT=4 (was 2), AVG_TICK=3 (was 2)
+ - Arrow head parameter bounds (MIN_AWIDTH, MIN_ARATIO, etc.)
+ * arrow_style.cc, arrowhead_style.h:
+ - Handle bounds on arrow head dimensions
+ - (width, ratio, camber, fill) Return arrowhead_state& (not void)
+
+ * state.cc: (dash_size) Pass unchecked argument to path_state
+ - (dot_size, tick_size) Pass unchecked argument to marker_state
+ * marker_style.cc: (dot_size, tick_size)
+ - Handle unchecked arg
+ - Return marker_style& (not void)
+ * path_style.cc: (dash_size) Handle unchecked arg
+
+2007-07.28 (ADH)
+ Version 1.1.8
+ * eepic.cc: (print(label_state, string)): Fix masklabel padding
+ * markers.cc: Don't pad axis labels with \phantom{-}
+ * camera.cc: No warning if point is behind film plane
+ * screen_data.cc: backing(), border() activate cropping
+ * data_file.cc: (read) Don't try to read empty files
+ - (column) Check for empty m_data
+
+2007-07.22 (ADH)
+ * data_mask.cc: (reverse) return *this
+ * length.cc: (get_lengths) Initialize len1, len2
+ * crop_algorithms.h: (loopify) If only one edge is visible, return
+ empty edge list.
+
+2007-07.19 (ADH)
+ * edge_data.h: Rename seen() -> is_seen(), null() -> is_null()
+ * crop_algorithms.h, pen_fill.cc, pen_line.cc: seen() -> is_seen()
+ * pen_arrow.cc, pen_arrow.h: Remove member m_at_base (unused)
+ - (crop_to) Shaft visibility bug
+ - (print_to) Draw ddot if head, tail project to same location
+ * arrow_data.cc, arrow_data.h: Remove member m_at_base (unused)
+ - Remove clip() function (constructor applies automatically)
+ - seen() -> is_seen()
+ * format.h, eepic.h, pst.h: (print_arrow) Omit alignment argument
+ * eepic.cc, pst.cc: (print_arrow) Change signature, reimplement
+ - seen() -> is_seen()
+ * constants.h: Names in all caps
+ - New constants MIN_CLIP, TWO_PI
+ - BBOLD_WIDTH is 1.2pt (was 1.6pt)
+ * angle_units.cc, hatching.cc, marker_style.cc, path_style.cc,
+ state.cc: Use capitalized constants
+ * camera.cc, camera.h: Use MIN_CLIP
+ - Rename function to_front() -> clip_plane()
+
+2007-07.17 (ADH)
+ * crop_algorithms.h: New file for path-chopping templates
+ * halfspace.cc, halfspace.h: Remove private member functions
+ - Use crop_algorithms.h
+ * screen_crop.cc, screen_crop.h: New files for crop_path_2nd,
+ crop_loop_2nd (from edge_data.cc)
+ * edge_data.h: Move crop_path_2nd, crop_loop_2nd to screen_crop.cc
+ (file contains only template class and two typedefs)
+ * edge_data.cc: Remove file
+
+2007-07.16 (ADH)
+ * state.cc: (fill(true)) Set fill color to White() if unset
+ * halfspace.cc, halfspace.h: (clip_path) Out-of-order bug
+ - Move constructor body from header.
+
+2007-07.14 (ADH)
+ Version 1.1.7
+ * eepic.cc, eepic.h, pst.cc, pst.h: Implement path styles
+ - (print_edge, print_edges) New functions
+ - (print_line) Implement in terms of print_edge
+ - (print_verbatim): New function
+ * verbatim.cc, verbatim.h: New files, implementing tile class for
+ verbatim output to file
+ * picture.cc, picture.h: (write, pre_write, post_write) New
+ functions to write verbatim strings to output
+ * screen.h: Declare global "write" function a friend
+ * picture_data.cc, picture_data.h: Add support for pre- and
+ post-written strings in output
+ * constants.h: Default axis ticks 4pt long
+
+2007-07.13 (ADH)
+ * path_style.cc, path_style.h: Interface redesign
+ - String-parsing implementation
+ - Use constants.h
+ * marker_style.cc: Use constants.h
+ * state.cc: Reimplement path style functions
+ - Use constants.h
+ - (dash_size) New function
+ - (dash_fill, dash_length) Functions removed
+ - (pen(Color, double), base(Color, double)) New functions
+ * label_data.cc: Constructors set tick mark color to line color
+ * edge_data.h: (length) New member function
+
+2007-07.08 (ADH)
+ * markers.cc: (h_axis, h_axis_labels, v_axis, v_axis_labels) If no
+ endpoints are specified, use dimensions of active screen
+ * curves.cc: (grid, log_grid) If corners not specified, use
+ corners of active screen
+ * pst.cc: (print_arrow) Draw head manually
+ (print_line) Use PSTricks border attribute in two-pen versions
+ (update_base) Bug fixes
+ * facet.cc, facet.h: New files
+ * surface.cc: Factor out utility classes facet, by_distance
+ - Support domain-dependent coloring
+ * path_data.cc: (photo) Print unfilled paths in chunks of 250
+ points to ameliorate LaTeX overflow
+
+2007-07.07 (ADH)
+ Version 1.1.6
+ * surface.cc, surface.h: Support position-dependent coloring
+
+2007-07.06 (ADH)
+ * eepic.cc, pst.cc: (print(style, string)) Fix alignment bug
+ (print_mark) No padding, border
+ * screen.cc, screen.h, screen_data.cc, screen_data.h: (is_cropped)
+ New function to add support for label cropping
+ * format.h, eepic.cc, eepic.h: Change signature of pic_header
+ * pst.cc, pst.h: Add support for label cropping
+ * picture_data.cc: (print_to) Pass crop flag
+
+2007-07.05 (ADH)
+ * markers.h: (h_axis_log_labels, v_axis_log_labels) Align argument
+ defaults to none
+ * picture.cc, picture.h: (eepic, pst) New functions to set output
+ format. (mp, pgf, svg stubs written.)
+ * camera.cc: (to_front) Min clip distance is 0.01
+ * path_data.cc: (photo) Clip by camera.to_front()
+
+2007-07.04 (ADH)
+ * pst.cc, pst.h: New files
+ * eepic.cc: Implement label borders and padding
+ * state.cc, state.h: (new functions)
+ - plain(Color), bold(Color), bbold(Color), set line Color/width
+ - rgb(P), cmyk(P), use components as densities
+ - New functions to set label attributes
+ . label_color(Color);
+ . label_pad(string);
+ . label_border(Color, [string]), label_border(string);
+ . no_label_border();
+ * curves.cc, curves.h: (draw_rect, swatch, rect(P, P, bool),
+ draw_polar_grid) Remove functions
+ * domain.cc, domain.h:
+ - No default domain constructor
+ - New constructor domain(P, P, mesh)
+ - Inline 1-dim'l constructor moved to cc file
+ - domain data members made private
+ New functions corner1_x1(), coarse_n1(), etc.
+ - "Net" typename removed
+ * plot_algorithms.h, plots.cc, surface.cc: Use domain state
+ functions
+ * data_bins.cc, data_bins.h: (bar_chart) New function
+ * data_file.cc, data_file.h: New global functions
+ - plot(filename, mark_type, col1, col2, col3, [F])
+ plot(filename, mark_type, F, col1, col2, col3)
+ - histogram, bar_chart
+
+2007-07.03 (ADH)
+ * dataplot.cc, dataplot.h: Break up and remove files
+ * data_bins.cc, data_bins.h, data_file.cc, data_file.h,
+ data_mask.cc, data_mask.h, interval.cc, interval.h: New files
+ * samples: Remove sample document
+ * doc: Update
+
+2007-06.28 (ADH)
+ * circle,cc, circle.h:
+ - Rename class -> Circle
+ - Remove m_filled data member, fill operator
+ - Remove translation, scaling operators += and *=
+ - (translate) Rename "shift"
+ - (move_to) New function
+ - Circle::draw() fills according to current paint style
+ - (circle) New functions which draw automatically
+ * sphere.cc, sphere.h:
+ - Rename class -> Sphere
+ - Remove translation, scaling operators += and *=
+ - (shift, move_to, scale) New functions
+ - (poles) Remove global function
+ - (sphere) New functions which draw automatically
+ * plane.cc, plane.h:
+ - Rename class -> Plane
+ - (shift, move_to) New functions
+ - Remove translate, separates, parallel_to, contains, height
+ functions
+ - (draw) Reimplement
+ * segment.cc, segment.h:
+ - Rename class -> Segment
+ - (shift, move_to, scale) New functions
+ - Remove translation operator +=
+ * path.cc, path.h,path_data.cc, path_data.h: Update class names
+ Circle, Plane, Segment, Sphere
+ * polyhedron.cc, polyhedron.h: Remove files
+
+2007-06.25 (ADH)
+ * contrib: Remove package
+ * surface.cc: (facet) Class contains a normal vector,
+ (facet::front_facing) Use normal vector to test
+
+2007-06.25 (ADH)
+ * surface.cc: (facet::draw) Use "direction" to compute density
+ * path.cc: (ellipse constructor) Don't close/fill automatically
+ * curves.cc: (ellipse) Close/fill if appropriate
+ * format.h, eepic.cc, eepic.h: (file_comment) New function
+ * picture_data.cc, picture_data.h: (file_header) Move to format.h
+ * path_data.cc, path_data.h: (draw) Implement base pen,
+ draw filled regions with both pens
+ * state.cc, state.h: Functions to control drawing state
+ - pen(Color, [string]), base(Color, [string])
+ - fill(Color)
+ * doc/manual.tex: Update
+
+2007-06.20 (ADH)
+ Version 1.1.5
+ * pen_arrow.cc, pen_arrow.h: Store shaft as edge, not as two pairs
+ * format.h, eepic.cc, eepic.h: (print_arrow) Adjust call syntax
+ * mask_diamond.cc, mask_ellipse.cc: (crop_to) Fix crop criterion
+ * geometry.cc, geometry.h: Re-implement spherical geometry
+ * sphere.cc, sphere.h: (latitude, longitude) Move to geometry.*
+ * functions.cc, functions.h
+ - Remove templates for id, zero, proj1, proj2, min, max
+ (put id, proj1, proj2 in map.h)
+ - Implement "zero" function with four call signatures
+ * plots.cc: (shadeplot) Path closure bug
+ * path.cc: (ellipse constructors) Close and fill if appropriate
+ * markers.cc: (arrow) Re-implement labeled arrow
+ * label_data.cc, label_data.h: Add visibility flag
+ * glyph.cc: (print_to) Implement font_size
+ * edge_data.cc: (crop_path_2nd) Loop processing bug
+
+2007-06.19 (ADH)
+ Version 1.1.4
+
+ Clipping and cropping work. Elliptical and diamond-shaped screen
+ masks are implemented.
+
+2007-06.03 (ADH)
+ Version 1.1.3, first public release
+
+ Implements ePiX-2's color capabilities, including named models
+ (RGB, CMY, CMYK, and Gray), color blending, filtering, CMYK
+ separation, limited transparency, color filling and colorable
+ arrows in eepic, decorable screens, and page markup.
+
+ The global parameters x_min, etc., should be replaced with
+ function calls, e.g. xmin(), from now on. Aside from this, the
+ syntax is backward compatible with Version 1.0.x.
diff --git a/graphics/epix/Color.cc b/graphics/epix/Color.cc
new file mode 100644
index 0000000000..1b4d01b717
--- /dev/null
+++ b/graphics/epix/Color.cc
@@ -0,0 +1,369 @@
+/*
+ * Color.cc -- ePiX Color functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Base.h"
+#include "Color_Utils.h"
+
+#include "Color_CMY.h"
+#include "Color_CMYK.h"
+#include "Color_Gray.h"
+#include "Color_Neutral.h"
+#include "Color_RGB.h"
+#include "Color_Sep.h"
+
+#include "Color.h"
+
+namespace ePiX {
+
+ Color::Color()
+ : m_color(Neutral().m_color), m_alpha(1) { }
+
+ Color::Color(const Color_Base& col)
+ : m_color(col.clone()), m_alpha(1) { }
+
+ Color::Color(const Color_Base* col)
+ : m_color(col->clone()), m_alpha(1) { }
+
+
+ Color::Color(const Color& col)
+ : m_color(col.m_color->clone()), m_alpha(col.m_alpha) { }
+
+
+ Color& Color::operator= (const Color& col)
+ {
+ if (*this != col)
+ {
+ Color_Base* tmp(col.m_color->clone());
+ delete m_color;
+
+ m_color = tmp;
+ m_alpha = col.m_alpha;
+ }
+
+ return *this;
+ }
+
+ Color::~Color()
+ {
+ delete m_color;
+ }
+
+ const Color_Base* Color::operator->() const
+ {
+ return m_color;
+ }
+
+ double Color::alpha() const
+ {
+ return m_alpha;
+ }
+
+
+ bool Color::operator== (const Color& col) const
+ {
+ return m_color->name() == col.m_color->name();
+ }
+
+ bool Color::operator< (const Color& col) const
+ {
+ // N.B. add_colors_to() must check for Unset
+ return m_color->name() < col.m_color->name();
+ }
+
+ bool Color::is_unset() const
+ {
+ // we're Neutral()
+ return (name() == "");
+ }
+
+
+ // no effect if we or col are Neutral
+ Color Color::filter(const Color& col) const
+ {
+ if (m_color->name() == "" || col.is_unset())
+ return col;
+
+ else
+ {
+ Color_Base* fil(m_color->clone());
+ fil->filter(*(col.m_color));
+
+ Color val(fil);
+ delete fil;
+ return val;
+ }
+ }
+
+ Color& Color::operator*= (double c)
+ {
+ (*m_color) *= c;
+
+ return *this;
+ }
+
+ // Blending with Unset has no effect
+ Color& Color::blend(const Color& col, double d)
+ {
+ if (!col.is_unset())
+ m_color->blend(*(col.m_color), d);
+
+ return *this;
+ }
+
+ Color& Color::superpose(const Color& col)
+ {
+ if (!col.is_unset())
+ m_color->superpose(*(col.m_color));
+
+ return *this;
+ }
+
+ Color& Color::invert()
+ {
+ m_color->invert();
+
+ return *this;
+ }
+
+ Color& Color::alpha(double t)
+ {
+ m_alpha = t;
+ return *this;
+ }
+
+
+ std::string Color::model() const
+ {
+ return m_color->model();
+ }
+
+ std::string Color::name() const
+ {
+ return m_color->name();
+ }
+
+ std::vector<double> Color::densities() const
+ {
+ return m_color->densities();
+ }
+
+
+ // Named constructors
+ Color RGB(double r, double g, double b)
+ {
+ return Color(RGB_Color(r, g, b));
+ }
+
+ Color CMY(double c, double m, double y)
+ {
+ return Color(CMY_Color(c, m, y));
+ }
+
+ Color CMYK(double c, double m, double y, double k)
+ {
+ return Color(CMYK_Color(c, m, y, k));
+ }
+
+ Color Gray(double d)
+ {
+ return Color(Gray_Color(d));
+ }
+
+
+ // Scale operator
+ Color operator* (double c, const Color& col)
+ {
+ Color tmp(col);
+ return tmp *= c;
+ }
+
+
+ /* * * Extended primaries in the global namespace * * */
+ Color Red(double d)
+ {
+ return RGB(clippy(d), clippy(-d), clippy(-d));
+ }
+
+ Color Green(double d)
+ {
+ return RGB(clippy(-d), clippy(d), clippy(-d));
+ }
+
+ Color Blue(double d)
+ {
+ return RGB(clippy(-d), clippy(-d), clippy(d));
+ }
+
+ Color White(double d)
+ {
+ return RGB(clippy(d), clippy(d), clippy(d));
+ }
+
+ Color Black(double d)
+ {
+ return RGB(clippy(1-d), clippy(1-d), clippy(1-d));
+ }
+
+
+ /* * * CMY * * */
+ Color Cyan(double d)
+ {
+ return CMY_Color(clippy(d), clippy(-d), clippy(-d), true);
+ }
+
+ Color Magenta(double d)
+ {
+ return CMY_Color(clippy(-d), clippy(d), clippy(-d), true);
+ }
+
+ Color Yellow(double d)
+ {
+ return CMY_Color(clippy(-d), clippy(-d), clippy(d), true);
+ }
+
+ Color CMY_White(double d)
+ {
+ return CMY_Color(clippy(1-d), clippy(1-d), clippy(1-d), true);
+ }
+
+ Color CMY_Black(double d)
+ {
+ return CMY_Color(clippy(d), clippy(d), clippy(d), true);
+ }
+
+
+ /* * * CMYK * * */
+ Color CyanK(double d)
+ {
+ double c(clippy(d));
+ double m(clippy(-d));
+ double y(m); // [sic]
+ double k(min(c,m)); // y=m
+
+ return CMYK_Color(c-k, m-k, y-k, k, true);
+ }
+
+ Color MagentaK(double d)
+ {
+ double c(clippy(-d));
+ double m(clippy(d));
+ double y(c);
+ double k(min(c,m)); // y=c
+
+ return CMYK_Color(c-k, m-k, y-k, k, true);
+ }
+
+ Color YellowK(double d)
+ {
+ double c(clippy(-d));
+ double m(c);
+ double y(clippy(d));
+ double k(min(c,y)); // m=c
+
+ return CMYK_Color(c-k, m-k, y-k, k, true);
+ }
+
+ Color CMYK_White(double d)
+ {
+ return CMYK_Color(0, 0, 0, clippy(1-d), true);
+ }
+
+ Color CMYK_Black(double d)
+ {
+ return CMYK_Color(0, 0, 0, clippy(d), true);
+ }
+
+
+ Color C_Process(double d)
+ {
+ return Cyan_Layer(d);
+ }
+
+ Color M_Process(double d)
+ {
+ return Magenta_Layer(d);
+ }
+
+ Color Y_Process(double d)
+ {
+ return Yellow_Layer(d);
+ }
+
+ Color K_Process(double d)
+ {
+ return Black_Layer(d);
+ }
+
+
+ /* * * Neutral filters * * */
+ Color Neutral()
+ {
+ static Neutral_Color* neutral(new Neutral_Color());
+ return Color(*neutral);
+ }
+
+ Color RGB_Neutral()
+ {
+ static RGB_Color* rgb_neutral(new RGB_Color(1, 1, 1));
+ return Color(*rgb_neutral);
+ }
+
+ Color CMY_Neutral()
+ {
+ static CMY_Color* cmy_neutral(new CMY_Color(0, 0, 0, true));
+ return Color(*cmy_neutral);
+ }
+
+ Color CMYK_Neutral()
+ {
+ static CMYK_Color* cmyk_neutral(new CMYK_Color(0, 0, 0, 0, true));
+ return Color(*cmyk_neutral);
+ }
+
+ Color Gray_Neutral()
+ {
+ static Gray_Color* gray_neutral(new Gray_Color(1));
+ return Color(*gray_neutral);
+ }
+} // end of namespace
diff --git a/graphics/epix/Color.h b/graphics/epix/Color.h
new file mode 100644
index 0000000000..fc2db6127e
--- /dev/null
+++ b/graphics/epix/Color.h
@@ -0,0 +1,156 @@
+/*
+ * Color.h -- ePiX::Color class and helpers
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines the ePiX Color user interface:
+ * operator*= Modify intensity
+ * blend(Color, double) Color mixing
+ * filter(Color) Apply us as a filter
+ * superpose(Color) Add colors, clip intensities
+ * invert() Color negative
+ *
+ * - Named primary constructors
+ *
+ * Scaling and filtering are implemented by converting to the filter's
+ * color model. Color model conversions come from the LaTeX xcolor
+ * package documentation, V 1.11 (2044/05/09) by Uwe Kern.
+ */
+
+#ifndef EPIX_COLOR
+#define EPIX_COLOR
+
+#include <string>
+#include <vector>
+
+namespace ePiX {
+
+ class Color_Base;
+
+ class Color {
+ public:
+ Color();
+ Color(const Color_Base*);
+ Color(const Color_Base&);
+ Color(const Color&);
+
+ Color& operator= (const Color&);
+
+ ~Color();
+
+ const Color_Base* operator->() const;
+ double alpha() const;
+
+ bool operator== (const Color&) const;
+ bool operator< (const Color&) const; // needed for Screen::pallet
+ bool operator!= (const Color& col) const { return !((*this) == col); }
+ bool is_unset() const;
+
+ Color filter(const Color&) const;
+
+ Color& operator*= (double c); // scale the intensity
+ Color& blend(const Color&, double);
+ Color& superpose(const Color&);
+ Color& invert();
+ Color& alpha(double);
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ private:
+ Color_Base* m_color;
+ double m_alpha;
+
+ }; // end of class Color
+
+ Color operator* (double, const Color&);
+
+
+ /*
+ * * * Primary color functions in the global namespace * * *
+ *
+ * A primary color constructor accepts a numerical argument, which is
+ * reduced mod 4, then interpreted as a color density as follows:
+ * d = -2 or 2 : white
+ * d = -1: full anti-saturation
+ * d = 0: black
+ * d = 1: full saturation (default)
+ *
+ * The primary changes continuously, and linearly on each interval
+ * [-2,-1], [-1,0], [0,1], and [1,2].
+ *
+ * Example:
+ * Red(0.3) = rgb(0.3, 0, 0) = Red(-3.7)
+ * Red(1.3) = rgb(1,0.3,0.3) = Red(-2.7)
+ * Red(2.3) = rgb(0.7, 1, 1) = Red(-1.7)
+ * Red(3.3) = rgb(0,0.7,0.7) = Red(-0.7)
+ */
+ Color RGB(double r=0, double g=0, double b=0);
+ Color CMY(double c=1, double m=1, double y=1);
+ Color CMYK(double c=1, double m=1, double y=1,
+ double k=0); // void same as CMYK(0,0,0,1);
+ Color Gray(double d=0);
+
+ Color Red(double d=1);
+ Color Green(double d=1);
+ Color Blue(double d=1);
+ Color White(double d=1);
+ Color Black(double d=1);
+
+ Color Cyan(double d=1);
+ Color Magenta(double d=1);
+ Color Yellow(double d=1);
+ Color CMY_White(double d=1);
+ Color CMY_Black(double d=1);
+
+ Color CyanK(double d=1);
+ Color MagentaK(double d=1);
+ Color YellowK(double d=1);
+ Color CMYK_White(double d=1);
+ Color CMYK_Black(double d=1);
+
+ // color separation
+ Color C_Process(double d=1);
+ Color M_Process(double d=1);
+ Color Y_Process(double d=1);
+ Color K_Process(double d=1);
+
+ // "conversion filters"
+ Color Neutral();
+ Color RGB_Neutral();
+ Color CMY_Neutral();
+ Color CMYK_Neutral();
+ Color Gray_Neutral();
+
+} // end of namespace
+
+#endif /* EPIX_COLOR */
diff --git a/graphics/epix/Color_Base.cc b/graphics/epix/Color_Base.cc
new file mode 100644
index 0000000000..74fdf5c7a8
--- /dev/null
+++ b/graphics/epix/Color_Base.cc
@@ -0,0 +1,52 @@
+/*
+ * Color_Base.cc -- ePiX Color_Base functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.3
+ *
+ * Last Change: June 03, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "Color_Utils.h"
+#include "Color_Base.h"
+
+namespace ePiX {
+
+ Color_Base::RGB_Densities::RGB_Densities(double r,
+ double g,
+ double b)
+ : m_dens_red (make_r(r, g, b)),
+ m_dens_green(make_g(r, g, b)),
+ m_dens_blue (make_b(r, g, b)) { }
+
+ bool Color_Base::operator== (const Color_Base& col) const
+ {
+ return (name() == col.name());
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_Base.h b/graphics/epix/Color_Base.h
new file mode 100644
index 0000000000..7c369f33ba
--- /dev/null
+++ b/graphics/epix/Color_Base.h
@@ -0,0 +1,84 @@
+/*
+ * Color_Base.h -- ePiX::Color interface
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_COLOR_BASE
+#define EPIX_COLOR_BASE
+
+#include <string>
+#include <vector>
+
+namespace ePiX {
+
+ class Color_Base {
+
+ protected:
+ struct RGB_Densities
+ {
+ // ensures densities are in [0,1]
+ RGB_Densities (double r, double g, double b);
+
+ double m_dens_red, m_dens_green, m_dens_blue;
+ };
+
+ public:
+ virtual ~Color_Base() { }
+ virtual Color_Base* clone() const = 0;
+
+ // blending (all non-const)
+ // apply us as filter
+ virtual Color_Base& filter(const Color_Base&) = 0;
+
+ // scale intensities
+ virtual Color_Base& operator*= (double) = 0;
+
+ // clip d to [0,1], then return (1-d)*this + d*col
+ virtual Color_Base& blend(const Color_Base&, double) = 0;
+
+ // add channels
+ virtual Color_Base& superpose(const Color_Base&) = 0;
+
+ // return negative color
+ virtual Color_Base& invert() = 0;
+
+ // internal colorname and densities
+ virtual std::string model() const = 0;
+ virtual std::string name() const = 0;
+ virtual std::vector<double> densities() const = 0;
+
+ bool operator== (const Color_Base& col) const;
+ virtual RGB_Densities to_rgb() const = 0;
+
+ }; // end of class Color_Base
+
+} // end of namespace
+
+#endif /* EPIX_COLOR_BASE */
diff --git a/graphics/epix/Color_CMY.cc b/graphics/epix/Color_CMY.cc
new file mode 100644
index 0000000000..085823acc2
--- /dev/null
+++ b/graphics/epix/Color_CMY.cc
@@ -0,0 +1,160 @@
+/*
+ * Color_CMY.cc -- ePiX::CMY_Color functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Utils.h"
+#include "Color.h"
+#include "Color_CMY.h"
+
+namespace ePiX {
+
+ CMY_Color::CMY_Color(double c, double m, double y)
+ : cyan(make_r(c,m,y)), magenta(make_g(c,m,y)), yellow(make_b(c,m,y)) { }
+
+ // private, no arg checking, bool unused
+ CMY_Color::CMY_Color(double c, double m, double y,
+ const bool arg)
+ : cyan(c), magenta(m), yellow(y) { }
+
+
+ CMY_Color::CMY_Color(const RGB_Densities& s)
+ : cyan(1-s.m_dens_red),
+ magenta(1-s.m_dens_green),
+ yellow(1-s.m_dens_blue) { }
+
+
+ Color_Base::RGB_Densities CMY_Color::to_rgb() const
+ {
+ // Use conventional formulas since our densities are already in [0,1]
+ return Color_Base::RGB_Densities(1-cyan, 1-magenta, 1-yellow);
+ }
+
+ CMY_Color* CMY_Color::clone() const
+ {
+ return new CMY_Color(*this);
+ }
+
+ CMY_Color& CMY_Color::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ // filter in RGB; 1 - min(1-x, 1-y) = max(x, y)
+ cyan = max(cyan, 1-s.m_dens_red);
+ magenta = max(magenta, 1-s.m_dens_green);
+ yellow = max(yellow, 1-s.m_dens_blue);
+
+ return *this;
+ }
+
+ CMY_Color& CMY_Color::operator*= (double sc)
+ {
+ Color_Base::RGB_Densities s(to_rgb());
+
+ // scale in RGB
+ double r(sc*(s.m_dens_red));
+ double g(sc*(s.m_dens_green));
+ double b(sc*(s.m_dens_blue));
+
+ cyan = 1 - make_r(r, g, b);
+ magenta = 1 - make_g(r, g, b);
+ yellow = 1 - make_b(r, g, b);
+
+ return *this;
+ }
+
+ CMY_Color& CMY_Color::blend(const Color_Base& color, double d)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ double wt(clip_to_unit(d));
+
+ // blending is a convex lin. comb., may as well do in CMY
+ cyan += wt*(1 - cyan - s.m_dens_red);
+ magenta += wt*(1 - magenta - s.m_dens_green);
+ yellow += wt*(1 - yellow - s.m_dens_blue);
+
+ return *this;
+ }
+
+ CMY_Color& CMY_Color::superpose(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ // add in RGB
+ cyan = 1 - clip_to_unit(1 - cyan + s.m_dens_red);
+ magenta = 1 - clip_to_unit(1 - magenta + s.m_dens_green);
+ yellow = 1 - clip_to_unit(1 - yellow + s.m_dens_blue);
+
+ return *this;
+ }
+
+
+ CMY_Color& CMY_Color::invert()
+ {
+ cyan = 1 - cyan;
+ magenta = 1 - magenta;
+ yellow = 1 - yellow;
+
+ return *this;
+ }
+
+
+ std::string CMY_Color::model() const
+ {
+ return "cmy";
+ }
+
+ std::string CMY_Color::name() const
+ {
+ std::ostringstream nm;
+
+ nm << "cmy_" << dtohex(cyan) << dtohex(magenta) << dtohex(yellow);
+
+ return nm.str();
+ }
+
+ std::vector<double> CMY_Color::densities() const
+ {
+ std::vector<double> val(3);
+ val.at(0) = rd(cyan);
+ val.at(1) = rd(magenta);
+ val.at(2) = rd(yellow);
+ return val;
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_CMY.h b/graphics/epix/Color_CMY.h
new file mode 100644
index 0000000000..3a8b8ed821
--- /dev/null
+++ b/graphics/epix/Color_CMY.h
@@ -0,0 +1,82 @@
+/*
+ * Color_CMY.h -- ePiX::CMY_Color class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_CMY
+#define EPIX_COLOR_CMY
+#include <string>
+#include <vector>
+
+#include "Color_Base.h"
+#include "Color.h"
+
+namespace ePiX {
+
+ class CMY_Color : public Color_Base {
+ public:
+ explicit CMY_Color(double c=1, double m=1, double y=1);
+ CMY_Color(const RGB_Densities&);
+
+ CMY_Color* clone() const;
+
+ CMY_Color& filter(const Color_Base&);
+
+ CMY_Color& operator*= (double c);
+
+ CMY_Color& blend(const Color_Base&, double);
+ CMY_Color& superpose(const Color_Base&);
+ CMY_Color& invert();
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ RGB_Densities to_rgb() const;
+
+ // These need to call our private constructor
+ friend Color Cyan(double);
+ friend Color Magenta(double);
+ friend Color Yellow(double);
+ friend Color CMY_White(double);
+ friend Color CMY_Black(double);
+ friend Color CMY_Neutral();
+
+ private:
+ double cyan;
+ double magenta;
+ double yellow;
+
+ // Construct a CMY color without checking arguments. Final argument
+ // only changes call signature
+ CMY_Color(double c, double m, double y, const bool);
+ }; // end of class CMY_Color
+
+} // end of namespace
+#endif /* EPIX_COLOR_CMY */
diff --git a/graphics/epix/Color_CMYK.cc b/graphics/epix/Color_CMYK.cc
new file mode 100644
index 0000000000..ef730a1998
--- /dev/null
+++ b/graphics/epix/Color_CMYK.cc
@@ -0,0 +1,216 @@
+/*
+ * Color_CMYK.cc -- ePiX::CMYK_Color functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Utils.h"
+#include "Color.h"
+#include "Color_CMYK.h"
+
+namespace ePiX {
+
+ // Behaves "classically" if c+k, m+k, y+k are in [0,1]
+ // Except as noted, CMYK methods enforce/preserve this condition
+ CMYK_Color::CMYK_Color(double c, double m, double y,
+ double k)
+ : cyan(make_r(c+k, m+k, y+k)),
+ magenta(make_g(c+k, m+k, y+k)),
+ yellow(make_b(c+k, m+k, y+k)),
+ black(min(min(cyan, magenta), yellow))
+ {
+ /* conventional RGB densities
+ double r(1 - min(1, c+k));
+ double g(1 - min(1, m+k));
+ double b(1 - min(1, y+k));
+ */
+ cyan -= black;
+ magenta -= black;
+ yellow -= black;
+ }
+
+ // private, no arg checking, bool unused
+ CMYK_Color::CMYK_Color(double c, double m,
+ double y, double k, const bool arg)
+ : cyan(c), magenta(m), yellow(y), black(k) { }
+
+
+ // black = min(c,m,y), following Uwe Kern's xcolor documentation
+ // V 1.11, 2004/05/09, p. 31
+ CMYK_Color::CMYK_Color(const RGB_Densities& s)
+ {
+ // may assume densities are in [0,1]
+ double c(1-s.m_dens_red), m(1-s.m_dens_green), y(1-s.m_dens_blue);
+
+ black = min(min(c, m), y);
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+ }
+
+ Color_Base::RGB_Densities CMYK_Color::to_rgb() const
+ {
+ // Use conventional formulas since our densities are already in [0,1];
+ // "min" for safety, should be unnecessary.
+ return Color_Base::RGB_Densities(1 - min(1.0, cyan + black),
+ 1 - min(1.0, magenta + black),
+ 1 - min(1.0, yellow + black));
+ }
+
+ CMYK_Color* CMYK_Color::clone() const
+ {
+ return new CMYK_Color(*this);
+ }
+
+ CMYK_Color& CMYK_Color::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb()); // arg
+ Color_Base::RGB_Densities t(to_rgb()); // this
+
+ // filter in RGB
+ double c(1 - min(t.m_dens_red, s.m_dens_red));
+ double m(1 - min(t.m_dens_green, s.m_dens_green));
+ double y(1 - min(t.m_dens_blue, s.m_dens_blue));
+ black = min(min(c, m), y);
+
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+
+ return *this;
+ }
+
+
+ CMYK_Color& CMYK_Color::operator*= (double sc)
+ {
+ Color_Base::RGB_Densities s(to_rgb());
+
+ // scale in RGB
+ double r(sc*(s.m_dens_red));
+ double g(sc*(s.m_dens_green));
+ double b(sc*(s.m_dens_blue));
+
+ // Necessary b/c sc may not be in [0,1]
+ double c(1 - make_r(r, g, b));
+ double m(1 - make_g(r, g, b));
+ double y(1 - make_b(r, g, b));
+
+ black = min(min(c, m), y);
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+
+ return *this;
+ }
+
+ CMYK_Color& CMYK_Color::blend(const Color_Base& color, double d)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ double wt(clip_to_unit(d));
+
+ double c((1-wt)*min(1.0, cyan+black) + wt*(1 - s.m_dens_red));
+ double m((1-wt)*min(1.0, magenta+black) + wt*(1 - s.m_dens_green));
+ double y((1-wt)*min(1.0, yellow+black) + wt*(1 - s.m_dens_blue));
+
+ black = min(min(c, m), y);
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+
+ return *this;
+ }
+
+ CMYK_Color& CMYK_Color::superpose(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ Color_Base::RGB_Densities t(to_rgb());
+
+ // add in RGB
+ double c(1 - clip_to_unit(t.m_dens_red + s.m_dens_red));
+ double m(1 - clip_to_unit(t.m_dens_green + s.m_dens_green));
+ double y(1 - clip_to_unit(t.m_dens_blue + s.m_dens_blue));
+
+ black = min(min(c, m), y);
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+
+ return *this;
+ }
+
+ CMYK_Color& CMYK_Color::invert()
+ {
+ Color_Base::RGB_Densities s(to_rgb());
+
+ // invert in RGB
+ double c(1 - s.m_dens_red);
+ double m(1 - s.m_dens_green);
+ double y(1 - s.m_dens_blue);
+
+ black = min(min(c, m), y);
+ cyan = c-black;
+ magenta = m-black;
+ yellow = y-black;
+
+ return *this;
+ }
+
+ std::string CMYK_Color::model() const
+ {
+ return "cmyk";
+ }
+
+ std::string CMYK_Color::name() const
+ {
+ std::ostringstream nm;
+
+ nm << "cmyk_" << dtohex(cyan) << dtohex(magenta) << dtohex(yellow)
+ << dtohex(black);
+ return nm.str();
+ }
+
+ std::vector<double> CMYK_Color::densities() const
+ {
+ std::vector<double> val(4);
+ val.at(0) = rd(cyan);
+ val.at(1) = rd(magenta);
+ val.at(2) = rd(yellow);
+ val.at(3) = rd(black);
+ return val;
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_CMYK.h b/graphics/epix/Color_CMYK.h
new file mode 100644
index 0000000000..8b99aaa573
--- /dev/null
+++ b/graphics/epix/Color_CMYK.h
@@ -0,0 +1,85 @@
+/*
+ * Color_CMYK.h -- ePiX::CMYK_Color class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_CMYK
+#define EPIX_COLOR_CMYK
+#include <string>
+#include <vector>
+
+#include "Color_Base.h"
+#include "Color.h"
+
+namespace ePiX {
+
+ class CMYK_Color : public Color_Base {
+ public:
+ CMYK_Color(double c=1, double m=1, double y=1,
+ double k=1);
+ CMYK_Color(const RGB_Densities&);
+
+ CMYK_Color* clone() const;
+
+ CMYK_Color& filter(const Color_Base&);
+
+ CMYK_Color& operator*= (double c);
+
+ CMYK_Color& blend(const Color_Base&, double);
+ CMYK_Color& superpose(const Color_Base&);
+ CMYK_Color& invert();
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ RGB_Densities to_rgb() const;
+
+ // These need to call our private constructor
+ friend Color CyanK(double);
+ friend Color MagentaK(double);
+ friend Color YellowK(double);
+ friend Color CMYK_White(double);
+ friend Color CMYK_Black(double);
+ friend Color CMYK_Neutral();
+
+ private:
+ double cyan;
+ double magenta;
+ double yellow;
+ double black;
+
+ // Construct a CMYK color without checking arguments. Final argument
+ // only changes call signature
+ CMYK_Color(double c, double m, double y,
+ double k, const bool);
+ }; // end of class CMYK_Color
+
+} // end of namespace
+#endif /* EPIX_COLOR_CMYK */
diff --git a/graphics/epix/Color_Gray.cc b/graphics/epix/Color_Gray.cc
new file mode 100644
index 0000000000..9d0901ca29
--- /dev/null
+++ b/graphics/epix/Color_Gray.cc
@@ -0,0 +1,129 @@
+/*
+ * Color_Gray.cc -- ePiX::Gray_Color functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Utils.h"
+#include "Color_Gray.h"
+
+namespace ePiX {
+
+ Gray_Color::Gray_Color(double d)
+ : m_gray(clip_to_unit(d)) { }
+
+
+ Gray_Color::Gray_Color(const RGB_Densities& s)
+ : m_gray((1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue)) { }
+
+ Color_Base::RGB_Densities Gray_Color::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(m_gray, m_gray, m_gray);
+ }
+
+ Gray_Color* Gray_Color::clone() const
+ {
+ return new Gray_Color(*this);
+ }
+
+
+ Gray_Color& Gray_Color::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ m_gray = min(m_gray, (1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue));
+ return *this;
+ }
+
+ Gray_Color& Gray_Color::operator*= (double c)
+ {
+ m_gray = clip_to_unit(c*m_gray);
+ return *this;
+ }
+
+ Gray_Color& Gray_Color::blend(const Color_Base& color, double d)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ double wt(clip_to_unit(d));
+
+ m_gray += wt*((1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue)-m_gray);
+
+ return *this;
+ }
+
+ Gray_Color& Gray_Color::superpose(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ m_gray = clip_to_unit((1.0/3)*(s.m_dens_red +
+ s.m_dens_green +
+ s.m_dens_blue) + m_gray);
+
+ return *this;
+ }
+
+ Gray_Color& Gray_Color::invert()
+ {
+ m_gray = 1 - m_gray;
+ return *this;
+ }
+
+
+ std::string Gray_Color::model() const
+ {
+ return "rgb";
+ }
+
+ std::string Gray_Color::name() const
+ {
+ std::ostringstream nm;
+
+ nm << "gray_" << dtohex(m_gray);
+
+ return nm.str();
+ }
+
+ std::vector<double> Gray_Color::densities() const
+ {
+ std::vector<double> val(3);
+ val.at(0) = rd(m_gray);
+ val.at(1) = rd(m_gray);
+ val.at(2) = rd(m_gray);
+ return val;
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_Gray.h b/graphics/epix/Color_Gray.h
new file mode 100644
index 0000000000..681861affa
--- /dev/null
+++ b/graphics/epix/Color_Gray.h
@@ -0,0 +1,67 @@
+/*
+ * Color_Gray.h -- ePiX::Gray_Color class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_GRAY
+#define EPIX_COLOR_GRAY
+#include <string>
+#include <vector>
+
+#include "Color_Base.h"
+
+namespace ePiX {
+
+ class Gray_Color : public Color_Base {
+ public:
+ Gray_Color(double dens=0);
+ Gray_Color(const RGB_Densities&);
+
+ Gray_Color* clone() const;
+
+ Gray_Color& filter(const Color_Base&);
+
+ Gray_Color& operator*= (double c);
+
+ Gray_Color& blend(const Color_Base&, double);
+ Gray_Color& superpose(const Color_Base&);
+ Gray_Color& invert();
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ RGB_Densities to_rgb() const;
+
+ private:
+ double m_gray;
+ }; // end of class Gray_Color
+
+} // end of namespace
+#endif /* EPIX_COLOR_GRAY */
diff --git a/graphics/epix/Color_Neutral.cc b/graphics/epix/Color_Neutral.cc
new file mode 100644
index 0000000000..66e149eafd
--- /dev/null
+++ b/graphics/epix/Color_Neutral.cc
@@ -0,0 +1,98 @@
+/*
+ * Color_Neutral.cc -- ePiX::Neutral_Color
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <string>
+
+#include "Color.h"
+#include "Color_Neutral.h"
+
+namespace ePiX {
+
+ Neutral_Color::Neutral_Color() { }
+
+ Color_Base::RGB_Densities Neutral_Color::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(1, 1, 1);
+ }
+
+ Neutral_Color* Neutral_Color::clone() const
+ {
+ return new Neutral_Color(*this);
+ }
+
+
+ Color_Base& Neutral_Color::filter(const Color_Base& color)
+ {
+ Color_Base* tmp(color.clone());
+ return *tmp;
+ }
+
+ Neutral_Color& Neutral_Color::operator*= (double c)
+ {
+ return *this;
+ }
+
+ Neutral_Color& Neutral_Color::blend(const Color_Base& color, double d)
+ {
+ return *this;
+ }
+
+ Neutral_Color& Neutral_Color::superpose(const Color_Base& color)
+ {
+ return *this;
+ }
+
+ Neutral_Color& Neutral_Color::invert()
+ {
+ return *this;
+ }
+
+ // string identifier -- not output-specific
+ std::string Neutral_Color::name() const
+ {
+ return "";
+ }
+
+ std::string Neutral_Color::model() const
+ {
+ return "";
+ }
+
+ std::vector<double> Neutral_Color::densities() const
+ {
+ std::vector<double> value(0);
+ return value;
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_Neutral.h b/graphics/epix/Color_Neutral.h
new file mode 100644
index 0000000000..76d73ae284
--- /dev/null
+++ b/graphics/epix/Color_Neutral.h
@@ -0,0 +1,64 @@
+/*
+ * Color_Neutral.h -- ePiX::Neutral ("unset") class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_NEUTRAL
+#define EPIX_COLOR_NEUTRAL
+#include <string>
+
+#include "Color_Base.h"
+
+namespace ePiX {
+ class Neutral_Color : public Color_Base {
+ public:
+ Neutral_Color();
+
+ Color_Base& filter(const Color_Base&);
+
+ std::string name() const;
+
+ private:
+ // these functions are implemented, but should never be called
+ RGB_Densities to_rgb() const;
+ Neutral_Color* clone() const;
+
+ Neutral_Color& operator*= (double c);
+
+ Neutral_Color& blend(const Color_Base&, double);
+ Neutral_Color& superpose(const Color_Base&);
+ Neutral_Color& invert();
+
+ // not implemented, should never be called
+ std::string model() const;
+ std::vector<double> densities() const;
+ }; // end of class Neutral_Color
+
+} // end of namespace
+#endif /* EPIX_COLOR_NEUTRAL */
diff --git a/graphics/epix/Color_RGB.cc b/graphics/epix/Color_RGB.cc
new file mode 100644
index 0000000000..9ea0f6bb3f
--- /dev/null
+++ b/graphics/epix/Color_RGB.cc
@@ -0,0 +1,146 @@
+/*
+ * Color_RGB.cc -- ePiX::RGB_Color
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Utils.h"
+#include "Color_RGB.h"
+
+namespace ePiX {
+
+ RGB_Color::RGB_Color(double r, double g, double b)
+ : red(make_r(r, g, b)), green(make_g(r, g, b)), blue(make_b(r, g, b)) { }
+
+
+ RGB_Color::RGB_Color(const RGB_Densities& s)
+ : red(s.m_dens_red), green(s.m_dens_green), blue(s.m_dens_blue) { }
+
+ Color_Base::RGB_Densities RGB_Color::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(red, green, blue);
+ }
+
+ RGB_Color* RGB_Color::clone() const
+ {
+ return new RGB_Color(*this);
+ }
+
+
+ RGB_Color& RGB_Color::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ red = min(red, s.m_dens_red);
+ green = min(green, s.m_dens_green);
+ blue = min(blue, s.m_dens_blue);
+
+ return *this;
+ }
+
+ RGB_Color& RGB_Color::operator*= (double c)
+ {
+ double r(red*c);
+ double g(green*c);
+ double b(blue*c);
+
+ red = make_r(r, g, b);
+ green = make_g(r, g, b);
+ blue = make_b(r, g, b);
+
+ return *this;
+ }
+
+ RGB_Color& RGB_Color::blend(const Color_Base& color, double d)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ double wt(clip_to_unit(d));
+
+ red += wt*(s.m_dens_red - red);
+ green += wt*(s.m_dens_green - green);
+ blue += wt*(s.m_dens_blue - blue);
+
+ return *this;
+ }
+
+ RGB_Color& RGB_Color::superpose(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+
+ red = clip_to_unit(red + s.m_dens_red);
+ green = clip_to_unit(green + s.m_dens_green);
+ blue = clip_to_unit(blue + s.m_dens_blue);
+
+ return *this;
+ }
+
+ RGB_Color& RGB_Color::invert()
+ {
+ red = 1 - red;
+ green = 1 - green;
+ blue = 1 - blue;
+
+ return *this;
+ }
+
+ std::string RGB_Color::model() const
+ {
+ return "rgb";
+ }
+
+ std::string RGB_Color::name() const
+ {
+ std::ostringstream nm;
+
+ nm << "rgb_" << dtohex(red) << dtohex(green) << dtohex(blue);
+
+ return nm.str();
+ }
+
+ std::vector<double> RGB_Color::densities() const
+ {
+ std::vector<double> val(3);
+ val.at(0) = rd(red);
+ val.at(1) = rd(green);
+ val.at(2) = rd(blue);
+ return val;
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_RGB.h b/graphics/epix/Color_RGB.h
new file mode 100644
index 0000000000..696577466a
--- /dev/null
+++ b/graphics/epix/Color_RGB.h
@@ -0,0 +1,68 @@
+/*
+ * Color_RGB.h -- ePiX::RGB_Color class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_RGB
+#define EPIX_COLOR_RGB
+#include <string>
+#include <vector>
+
+#include "Color_Base.h"
+
+namespace ePiX {
+ class RGB_Color : public Color_Base {
+ public:
+ RGB_Color(double r=0, double g=0, double b=0);
+ RGB_Color(const RGB_Densities&);
+
+ RGB_Color* clone() const;
+
+ RGB_Color& filter(const Color_Base&);
+
+ RGB_Color& operator*= (double c);
+
+ RGB_Color& blend(const Color_Base&, double);
+ RGB_Color& superpose(const Color_Base&);
+ RGB_Color& invert();
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ RGB_Densities to_rgb() const;
+
+ private:
+ double red;
+ double green;
+ double blue;
+ }; // end of class RGB_Color
+
+} // end of namespace
+#endif /* EPIX_COLOR_RGB */
diff --git a/graphics/epix/Color_Sep.cc b/graphics/epix/Color_Sep.cc
new file mode 100644
index 0000000000..e9652a9d11
--- /dev/null
+++ b/graphics/epix/Color_Sep.cc
@@ -0,0 +1,278 @@
+/*
+ * Color_Sep.cc -- ePiX CMYK Color separation functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+#include "functions.h"
+
+#include "Color_Utils.h"
+#include "Color.h"
+#include "Color_Sep.h"
+
+namespace ePiX {
+
+ Cyan_Layer::Cyan_Layer(double arg)
+ : m_dens(clip_to_unit(arg)) { }
+
+ // Return Cyan channel of color
+ Cyan_Layer& Cyan_Layer::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ if (Color(color).is_unset())
+ s = Color_Base::RGB_Densities(1,1,1);
+
+ m_dens = min(m_dens, 1-s.m_dens_red);
+ return *this;
+ }
+
+ Cyan_Layer* Cyan_Layer::clone() const
+ {
+ return new Cyan_Layer(*this);
+ }
+
+ Color_Base::RGB_Densities Cyan_Layer::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(1-m_dens, 1, 1);
+ }
+
+
+ std::string Cyan_Layer::model() const
+ {
+ return "cmyk";
+ }
+
+ std::string Cyan_Layer::name() const
+ {
+ std::ostringstream nm;
+ nm << "c_proc_" << dtohex(m_dens);
+ return nm.str();
+ }
+
+ std::vector<double> Cyan_Layer::densities() const
+ {
+ std::vector<double> val(4);
+ val.at(0) = rd(m_dens);
+ val.at(1) = 0;
+ val.at(2) = 0;
+ val.at(3) = 0;
+ return val;
+ }
+
+
+ // Magenta_Layer
+ Magenta_Layer::Magenta_Layer(double arg)
+ : m_dens(clip_to_unit(arg)) { }
+
+ // Return Magenta channel of color
+ Magenta_Layer& Magenta_Layer::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ if (Color(color).is_unset())
+ s = Color_Base::RGB_Densities(1,1,1);
+
+ m_dens = min(m_dens, 1-s.m_dens_green);
+ return *this;
+ }
+
+ Magenta_Layer* Magenta_Layer::clone() const
+ {
+ return new Magenta_Layer(*this);
+ }
+
+ Color_Base::RGB_Densities Magenta_Layer::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(1, 1-m_dens, 1);
+ }
+
+
+ std::string Magenta_Layer::model() const
+ {
+ return "cmyk";
+ }
+
+ std::string Magenta_Layer::name() const
+ {
+ std::ostringstream nm;
+ nm << "m_proc_" << dtohex(m_dens);
+ return nm.str();
+ }
+
+ std::vector<double> Magenta_Layer::densities() const
+ {
+ std::vector<double> val(4);
+ val.at(0) = 0;
+ val.at(1) = rd(m_dens);
+ val.at(2) = 0;
+ val.at(3) = 0;
+ return val;
+ }
+
+
+ // Yellow_Layer
+ Yellow_Layer::Yellow_Layer(double arg)
+ : m_dens(clip_to_unit(arg)) { }
+
+ // Return Yellow channel of color
+ Yellow_Layer& Yellow_Layer::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ if (Color(color).is_unset())
+ s = Color_Base::RGB_Densities(1,1,1);
+
+ m_dens = min(m_dens, 1-s.m_dens_blue);
+ return *this;
+ }
+
+ Yellow_Layer* Yellow_Layer::clone() const
+ {
+ return new Yellow_Layer(*this);
+ }
+
+ Color_Base::RGB_Densities Yellow_Layer::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(1, 1, 1-m_dens);
+ }
+
+
+ std::string Yellow_Layer::model() const
+ {
+ return "cmyk";
+ }
+
+ std::string Yellow_Layer::name() const
+ {
+ std::ostringstream nm;
+ nm << "y_proc_" << dtohex(m_dens);
+ return nm.str();
+ }
+
+ std::vector<double> Yellow_Layer::densities() const
+ {
+ std::vector<double> val(4);
+ val.at(0) = 0;
+ val.at(1) = 0;
+ val.at(2) = rd(m_dens);
+ val.at(3) = 0;
+ return val;
+ }
+
+
+ // Black_Layer
+ Black_Layer::Black_Layer(double arg)
+ : m_dens(clip_to_unit(arg)) { }
+
+ // Return Black channel of color
+ Black_Layer& Black_Layer::filter(const Color_Base& color)
+ {
+ Color_Base::RGB_Densities s(color.to_rgb());
+ if (Color(color).is_unset())
+ s = Color_Base::RGB_Densities(1,1,1);
+
+ double c(1-s.m_dens_red), m(1-s.m_dens_green), y(1-s.m_dens_blue);
+ double k(min(min(c, m), y));
+
+ m_dens = min(m_dens, k);
+ return *this;
+ }
+
+ Black_Layer* Black_Layer::clone() const
+ {
+ return new Black_Layer(*this);
+ }
+
+ Color_Base::RGB_Densities Black_Layer::to_rgb() const
+ {
+ return Color_Base::RGB_Densities(1-m_dens, 1-m_dens, 1-m_dens);
+ }
+
+
+ std::string Black_Layer::model() const
+ {
+ return "cmyk";
+ }
+
+ std::string Black_Layer::name() const
+ {
+ std::ostringstream nm;
+ nm << "k_proc_" << dtohex(m_dens);
+ return nm.str();
+ }
+
+ std::vector<double> Black_Layer::densities() const
+ {
+ std::vector<double> val(4);
+ val.at(0) = 0;
+ val.at(1) = 0;
+ val.at(2) = 0;
+ val.at(3) = rd(m_dens);
+ return val;
+ }
+
+
+ // null operations
+ Cyan_Layer& Cyan_Layer::operator*= (double x) { return *this; }
+ Cyan_Layer& Cyan_Layer::blend(const Color_Base& col, double d)
+ { return *this; }
+
+ Cyan_Layer& Cyan_Layer::superpose(const Color_Base& col) { return *this; }
+ Cyan_Layer& Cyan_Layer::invert() { return *this; }
+
+
+ Magenta_Layer& Magenta_Layer::operator*= (double x) { return *this; }
+ Magenta_Layer& Magenta_Layer::blend(const Color_Base& col, double d)
+ { return *this; }
+
+ Magenta_Layer& Magenta_Layer::superpose(const Color_Base& col) { return *this; }
+ Magenta_Layer& Magenta_Layer::invert() { return *this; }
+
+
+ Yellow_Layer& Yellow_Layer::operator*= (double x) { return *this; }
+ Yellow_Layer& Yellow_Layer::blend(const Color_Base& col, double d)
+ { return *this; }
+
+ Yellow_Layer& Yellow_Layer::superpose(const Color_Base& col) { return *this; }
+ Yellow_Layer& Yellow_Layer::invert() { return *this; }
+
+
+ Black_Layer& Black_Layer::operator*= (double x) { return *this; }
+ Black_Layer& Black_Layer::blend(const Color_Base& col, double d)
+ { return *this; }
+
+ Black_Layer& Black_Layer::superpose(const Color_Base& col) { return *this; }
+ Black_Layer& Black_Layer::invert() { return *this; }
+
+} // end of namespace
diff --git a/graphics/epix/Color_Sep.h b/graphics/epix/Color_Sep.h
new file mode 100644
index 0000000000..599a14e039
--- /dev/null
+++ b/graphics/epix/Color_Sep.h
@@ -0,0 +1,133 @@
+/*
+ * Color_Sep.h -- ePiX CMYK Color separation classes
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_COLOR_SEP
+#define EPIX_COLOR_SEP
+#include <string>
+#include <vector>
+
+#include "Color_Base.h"
+
+namespace ePiX {
+
+ class Cyan_Layer : public Color_Base {
+ public:
+ Cyan_Layer(double dens=1);
+ // Return Cyan channel of input
+ Cyan_Layer& filter(const Color_Base&);
+
+ Cyan_Layer* clone() const;
+ RGB_Densities to_rgb() const; // returns RGB(0,1,1)
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ private:
+ double m_dens;
+
+ // null operations
+ Cyan_Layer& operator*= (double);
+ Cyan_Layer& blend(const Color_Base&, double);
+ Cyan_Layer& superpose(const Color_Base&);
+ Cyan_Layer& invert();
+ };
+
+ class Magenta_Layer : public Color_Base {
+ public:
+ Magenta_Layer(double dens=1);
+ // Return Magenta channel of input
+ Magenta_Layer& filter(const Color_Base&);
+
+ Magenta_Layer* clone() const;
+ RGB_Densities to_rgb() const; // returns RGB(0,1,1)
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ private:
+ double m_dens;
+
+ // null operations
+ Magenta_Layer& operator*= (double);
+ Magenta_Layer& blend(const Color_Base&, double);
+ Magenta_Layer& superpose(const Color_Base&);
+ Magenta_Layer& invert();
+ };
+
+ class Yellow_Layer : public Color_Base {
+ public:
+ Yellow_Layer(double dens=1);
+ // Return Yellow channel of input
+ Yellow_Layer& filter(const Color_Base&);
+
+ Yellow_Layer* clone() const;
+ RGB_Densities to_rgb() const; // returns RGB(0,1,1)
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ private:
+ double m_dens;
+
+ // null operations
+ Yellow_Layer& operator*= (double);
+ Yellow_Layer& blend(const Color_Base&, double);
+ Yellow_Layer& superpose(const Color_Base&);
+ Yellow_Layer& invert();
+ };
+
+ class Black_Layer : public Color_Base {
+ public:
+ Black_Layer(double dens=1);
+ // Return Black channel of input
+ Black_Layer& filter(const Color_Base&);
+
+ Black_Layer* clone() const;
+ RGB_Densities to_rgb() const; // returns RGB(0,1,1)
+
+ std::string model() const;
+ std::string name() const;
+ std::vector<double> densities() const;
+
+ private:
+ double m_dens;
+
+ // null operations
+ Black_Layer& operator*= (double);
+ Black_Layer& blend(const Color_Base&, double);
+ Black_Layer& superpose(const Color_Base&);
+ Black_Layer& invert();
+ };
+} // end of namespace
+#endif /* EPIX_COLOR_SEP */
diff --git a/graphics/epix/Color_Utils.cc b/graphics/epix/Color_Utils.cc
new file mode 100644
index 0000000000..0045aafcc3
--- /dev/null
+++ b/graphics/epix/Color_Utils.cc
@@ -0,0 +1,113 @@
+/*
+ * Color_Utils.cc -- Functions for manipulating color densities
+ * These functions are not normally available to users.
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <sstream>
+#include <cmath>
+
+// #include "constants.h"
+// #include "functions.h"
+
+#include "Color_Utils.h"
+
+namespace ePiX {
+
+ // Magic number: 8-bits per color channel
+ const int COLORS(0xFF);
+
+ // Force double to [0,1]
+ double clip_to_unit(double t)
+ {
+ if (t < 0) return 0;
+ else if (t > 1) return 1;
+ else return t;
+ }
+
+ double rd(double arg) // may assume arg in [0,1]
+ {
+ return floor(COLORS*arg)/COLORS; // round down to nearest 8-bit
+ }
+
+ // represent a double in [0,1] by an 8-bit hex string
+ std::string dtohex(double arg) // assumes arg>0
+ {
+ using std::ios_base;
+ int dens((int) floor(arg*COLORS));
+
+ std::ostringstream value;
+ value.setf(ios_base::hex, ios_base::basefield);
+
+ if (dens <= 0xF) // pad
+ value << "0";
+
+ value << dens;
+ return value.str();
+ }
+
+ // saw2th:R -> [-2,2] is (1) a sawtooth function; (2) the identity on [-2,2]
+ double saw2th(double x)
+ {
+ return x - 4*floor((x+2)/4);
+ }
+
+ /*
+ * clippy(x):
+ * 1.... ____ if (x >= 0)
+ * .\ /. . return x <= 1 ? x : 1;
+ * . \ / . .
+ * 0......\____/ . . else
+ * -2 -1 0 1 2 --> x return x >= -1 ? 0 : -1-x;
+ */
+ double clippy(double x)
+ {
+ x = saw2th(x);
+ return (x >= 0) ? ( x <= 1 ? x : 1 ) : ( x >= -1 ? 0 : -1-x );
+ }
+
+ double make_r(double r, double g, double b)
+ {
+ return clip_to_unit(clippy( r) + clippy(-g) + clippy(-b));
+ }
+
+ double make_g(double r, double g, double b)
+ {
+ return clip_to_unit(clippy(-r) + clippy( g) + clippy(-b));
+ }
+
+ double make_b(double r, double g, double b)
+ {
+ return clip_to_unit(clippy(-r) + clippy(-g) + clippy( b));
+ }
+} // end of namespace
diff --git a/graphics/epix/Color_Utils.h b/graphics/epix/Color_Utils.h
new file mode 100644
index 0000000000..9dc54f92c7
--- /dev/null
+++ b/graphics/epix/Color_Utils.h
@@ -0,0 +1,66 @@
+/*
+ * Color_Utils.h -- Functions for manipulating color densities
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ *
+ * Last Change: September 14, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_COLOR_UTILS
+#define EPIX_COLOR_UTILS
+
+#include <string>
+
+namespace ePiX {
+
+ double clip_to_unit(double t); // 0 if t<0, 1 if t>1, t otherwise
+
+ double rd(double); // assumes arg is in [0,1]
+
+ // represent a double in [0,1] by an 8-bit hex string
+ std::string dtohex(double arg); // assumes arg>0
+
+ // saw2th:R -> [-2,2] is (1) a sawtooth function; (2) the identity on [-2,2]
+ double saw2th(double x);
+
+ /*
+ * clippy(x):
+ * 1.... ____ if (x >= 0)
+ * .\ /. . return x <= 1 ? x : 1;
+ * . \ / . .
+ * 0......\____/ . . else
+ * -2 -1 0 1 2 --> x return x >= -1 ? 0 : -1-x;
+ */
+ double clippy(double x);
+
+ double make_r(double r, double g, double b);
+ double make_g(double r, double g, double b);
+ double make_b(double r, double g, double b);
+} // end of namespace
+
+#endif /* EPIX_COLOR_UTILS */
diff --git a/graphics/epix/INSTALL b/graphics/epix/INSTALL
new file mode 100644
index 0000000000..fb13967718
--- /dev/null
+++ b/graphics/epix/INSTALL
@@ -0,0 +1,179 @@
+ePiX-1.2 -- INSTALL
+
+Last Change: September 12, 2007
+
+Please consult the following files as appropriate:
+
+INSTALL (this file) -- Detailed installation instructions
+NEWS -- Recent major changes (see ChangeLog for code changes)
+README -- General overview and information
+
+
+CONVENTIONS
+
+Lines starting with a "%" denote commands typed at a shell prompt.
+Lines starting with a "#" denote commands run as root.
+Don't type the prompt characters "%" or "#". :)
+
+"$(prefix)" stands for the complete path to the install directory,
+e.g. "/usr/local" or "/home/pootle/epix".
+
+
+DEPENDENCIES
+
+The following software must be installed on your system in order for
+you to use ePiX:
+
+ * The GNU shell, bash
+ * A C++ compiler and development libraries, preferably g++ (> 3.2)
+ * GhostScript, ImageMagick, and teTeX
+ * GNU binutils, textutils, and fileutils (ar, sed, grep, ln, rm...)
+
+Please consult your system documentation for information on installing
+these components. The POST-INSTALL file contains potentially helpful
+information, as well. The manual contains more detailed instructions
+for Windows (Cygwin) and Mac OS X (fink/fink commander) users.
+
+
+INSTALLATION
+
+--- Synopsis ---
+
+(1) Unpack
+(2) Configure:
+
+% ./configure [options]
+
+(3) Build:
+
+% make
+% make install (may require system privileges)
+
+
+--- Step-by-step Instructions ---
+
+(1) Unpack
+
+ Tarballs are available gzip or bzip2 compressed. To unpack, use the
+ appropriate version number and tar options (z for .gz, j for .bz2, v
+ to see filenames unpacked):
+
+% tar -zxf epix-x.y.z.tar.gz
+
+ or
+
+% tar -jxf epix-x.y.z.tar.bz2
+
+ If your "tar" doesn't understand decompression, do
+
+% gunzip -c epix-x.y.z.tar.gz | tar -xf -
+
+ or
+
+% bzcat epix-x.y.z.tar.bz2 | tar -xf -
+
+
+ Change to the source directory:
+
+% cd epix-x.y.z
+
+
+(2) Configure the package:
+
+ Most users can run the command
+
+% ./configure
+
+ To change the installation directory from the default (/usr/local)
+ to (say) your home directory, do
+
+% ./configure --prefix=${HOME}
+
+ To list all options, run
+
+% ./configure --help
+
+
+(3) Compile and install:
+
+% make
+
+ Be sure you are using GNU make. If the build fails immediately with
+ an error about unexpected characters in the Makefile, speak to your
+ system administrator about availability of GNU make, or try running
+ the command "gmake".
+
+ If there are no build errors, you're ready to install.
+
+ You must have write permission in the install directory you selected
+ in step (2). If you have been logged on as yourself until now (a Very
+ Good Idea) and are installing in a system directory, do:
+
+% su
+Password: <your root password>
+
+# make install
+
+ (The root prompt on many systems is # rather than %.) If the install
+ succeeds, you're done:
+
+# exit
+
+ If you are installing somewhere in your HOME directory, just type
+
+% make install
+
+
+(4) Post-Install:
+
+ Documentation is installed in $(prefix)/share/doc/epix, as compiled
+ files (ps, pdf, info) and tarred LaTeX sources.
+
+ The directory $(prefix)/share/doc/epix/config contains two optional
+ files: Jay Belanger's emacs mode for working with ePiX files, and
+ completions for users of Ian MacDonald's bash completions package.
+ POST-INSTALL has instructions on installing and using these files.
+
+ From the source directory, do
+
+% make clean
+
+ to clean the source tree of compiled files. This command removes the
+ top-level Makefile. Run ./configure to re-create the Makefile if
+ necessary.
+
+
+(5) Uninstalling:
+
+ To remove a version of ePiX from your system, go to the directory
+ where the sources were unpacked, run ./config.status, log on as root
+ if necessary, and do:
+
+# make uninstall
+
+
+ Alternatively, remove the following files and directories manually,
+ replacing $(prefix) with the install path, e.g. "/usr/local".
+
+[] Shell scripts
+ $(prefix)/bin/{elaps,epix,flix,laps}
+
+[] Static libraries and shell code
+ $(prefix)/lib/epix/
+
+[] Header files
+ $(prefix)/include/epix.h (user header)
+ $(prefix)/include/epix/ (devel headers)
+
+[] Configuration files, manuals, and samples
+ $(prefix)/share/doc/epix/
+
+
+--- Contact Information ---
+
+If you have questions, comments, suggestions, etc., please write to:
+
+Andrew D. ("Andy") Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+Dept. of Mathematics and Computer Science
+College of the Holy Cross
+Worcester, MA, 01610-2395, USA
diff --git a/graphics/epix/Makefile.am b/graphics/epix/Makefile.am
new file mode 100644
index 0000000000..eada49e89c
--- /dev/null
+++ b/graphics/epix/Makefile.am
@@ -0,0 +1,115 @@
+## epix-1.x Makefile.am for top-level directory
+##
+## Process this file with automake to produce Makefile.in
+
+#if BUILD_CONTRIB
+ # Must be in this order!
+# MAYBE_DIRS = contrib contrib/doc
+#endif
+
+# SUBDIRS = . samples doc $(MAYBE_DIRS)
+SUBDIRS = . samples doc
+
+# Now stuff for this directory specifically
+
+bin_SCRIPTS = epix elaps flix laps
+
+pkglib_LIBRARIES = libepix.a
+pkglib_DATA = epix-lib.sh
+include_HEADERS = epix.h
+
+libepix_a_CXXSOURCES = active_screen.cc affine.cc angle_units.cc \
+ arrow_data.cc arrow_style.cc axis.cc camera.cc circle.cc clipping.cc \
+ Color_Base.cc Color.cc Color_CMY.cc Color_CMYK.cc Color_Gray.cc \
+ Color_Neutral.cc Color_RGB.cc Color_Sep.cc Color_Utils.cc \
+ cropping.cc curves.cc \
+ data_bins.cc data_file.cc data_mask.cc domain.cc \
+ eepic.cc facet.cc format.cc frac.cc frame.cc functions.cc \
+ geometry.cc glyph.cc halfspace.cc hatching.cc \
+ intersections.cc interval.cc label_data.cc label_style.cc \
+ legend.cc legend_item.cc legend_tile.cc \
+ length.cc lens.cc markers.cc marker_style.cc \
+ mask_diamond.cc mask_ellipse.cc mask_rectangle.cc \
+ paint_style.cc pairs.cc path.cc path_data.cc \
+ path_style.cc pen_arrow.cc pen_data.cc pen_fill.cc pen_line.cc \
+ picture.cc picture_data.cc plane.cc plots.cc pst.cc \
+ screen.cc screen_crop.cc screen_data.cc screen_mask.cc \
+ segment.cc spline.cc sphere.cc state.cc surface.cc tikz.cc tile.cc \
+ triples.cc utils.cc verbatim.cc
+# polygon.cc
+
+libepix_a_HDRS = $(libepix_a_CXXSOURCES:.cc=.h) constants.h \
+ crop_algorithms.h deriv.h edge_data.h enums.h errors.h \
+ map.h plot_algorithms.h spline_data.h
+
+libepix_a_SOURCES = $(libepix_a_CXXSOURCES) $(libepix_a_HDRS)
+
+libepix_a_LIBADD = $(libepix_a_CXXSOURCES:.cc=.o)
+
+pkginclude_HEADERS = $(libepix_a_HDRS)
+
+man_MANS = epix.1 elaps.1 flix.1 laps.1
+
+if ENABLE_EPIX_EL
+ EPIX_EL = epix.el
+endif
+
+EPIX_CONFFILES = bash_completions $(EPIX_EL)
+
+EPIX_NOTEFILES = AUTHORS BUGS ChangeLog COPYING INSTALL NEWS POST-INSTALL \
+ README THANKS VERSION
+
+EXTRA_DIST = $(bin_SCRIPTS) $(man_MANS) $(EPIX_CONFFILES) $(EPIX_NOTEFILES) \
+ $(pkgdata_DATA)
+
+CLEANFILES = *~ $(libepix_a_OBJECTS) $(bin_SCRIPTS) $(bin_SCRIPTS:=-local) \
+ epix.h epix.1 epix.el
+
+# Headers
+epix.h: $(libepix_a_HDRS)
+ ./make_header
+
+# Scripts; we create local variants which will work during the build process
+epix elaps flix laps: %: %.in epix.el
+ sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \
+ -e 's%@bindir\@%$(bindir)%;' \
+ -e 's%@pkglibdir\@%$(pkglibdir)%;' \
+ -e 's%@includedir\@%$(includedir)%;' \
+ -e 's%@RUNTIME_COMPILER\@%$(RUNTIME_COMPILER)%;' $< > $@
+ sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \
+ -e 's%@bindir\@%$(CURDIR)%;' \
+ -e 's%@pkglibdir\@%$(CURDIR)%;' \
+ -e 's%@includedir\@%$(CURDIR)%;' \
+ -e 's%@RUNTIME_COMPILER\@%$(CXX)%;' $< > $@-local
+ chmod a+x $@ $@-local
+
+# libepix.a
+libepix.a: $(libepix_a_OBJECTS)
+ ar -ru libepix.a $(libepix_a_OBJECTS)
+ $(RANLIB) libepix.a
+
+# object file dependencies
+$(libepix_a_LIBADD): %.o: %.cc %.h
+
+# Manpage
+epix.1: epix.1.in
+ sed -e 's%@docdir\@%$(docdir)%;' $< > $@
+
+# emacs mode
+epix.el: epix.el.in
+ sed -e 's%@docdir\@%$(docdir)%;' $< > $@
+
+# Extra things to install
+install-data-local:
+ @echo; echo "Installing notes and configuration files"
+ ./mkinstalldirs $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config
+ $(INSTALL_DATA) $(EPIX_NOTEFILES) $(DESTDIR)$(docdir)/notes
+ $(INSTALL_DATA) $(EPIX_CONFFILES) $(DESTDIR)$(docdir)/config
+
+# This is being installed by install-exec, but should not be executable
+install-exec-local: install-pkglibDATA
+ chmod a-x $(DESTDIR)$(pkglibdir)/epix-lib.sh
+
+uninstall-local:
+ -rm -rf $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config
+ -rmdir $(DESTDIR)$(docdir)
diff --git a/graphics/epix/Makefile.in b/graphics/epix/Makefile.in
new file mode 100644
index 0000000000..7aee503276
--- /dev/null
+++ b/graphics/epix/Makefile.in
@@ -0,0 +1,1025 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \
+ $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
+ ChangeLog INSTALL NEWS THANKS TODO config.guess config.sub \
+ depcomp install-sh missing mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkglibdir)" \
+ "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"
+pkglibLIBRARIES_INSTALL = $(INSTALL_DATA)
+LIBRARIES = $(pkglib_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libepix_a_AR = $(AR) $(ARFLAGS)
+am__DEPENDENCIES_1 = active_screen.o affine.o angle_units.o \
+ arrow_data.o arrow_style.o axis.o camera.o circle.o clipping.o \
+ Color_Base.o Color.o Color_CMY.o Color_CMYK.o Color_Gray.o \
+ Color_Neutral.o Color_RGB.o Color_Sep.o Color_Utils.o \
+ cropping.o curves.o data_bins.o data_file.o data_mask.o \
+ domain.o eepic.o facet.o format.o frac.o frame.o functions.o \
+ geometry.o glyph.o halfspace.o hatching.o intersections.o \
+ interval.o label_data.o label_style.o legend.o legend_item.o \
+ legend_tile.o length.o lens.o markers.o marker_style.o \
+ mask_diamond.o mask_ellipse.o mask_rectangle.o paint_style.o \
+ pairs.o path.o path_data.o path_style.o pen_arrow.o pen_data.o \
+ pen_fill.o pen_line.o picture.o picture_data.o plane.o plots.o \
+ pst.o screen.o screen_crop.o screen_data.o screen_mask.o \
+ segment.o spline.o sphere.o state.o surface.o tikz.o tile.o \
+ triples.o utils.o verbatim.o
+libepix_a_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 = active_screen.$(OBJEXT) affine.$(OBJEXT) \
+ angle_units.$(OBJEXT) arrow_data.$(OBJEXT) \
+ arrow_style.$(OBJEXT) axis.$(OBJEXT) camera.$(OBJEXT) \
+ circle.$(OBJEXT) clipping.$(OBJEXT) Color_Base.$(OBJEXT) \
+ Color.$(OBJEXT) Color_CMY.$(OBJEXT) Color_CMYK.$(OBJEXT) \
+ Color_Gray.$(OBJEXT) Color_Neutral.$(OBJEXT) \
+ Color_RGB.$(OBJEXT) Color_Sep.$(OBJEXT) Color_Utils.$(OBJEXT) \
+ cropping.$(OBJEXT) curves.$(OBJEXT) data_bins.$(OBJEXT) \
+ data_file.$(OBJEXT) data_mask.$(OBJEXT) domain.$(OBJEXT) \
+ eepic.$(OBJEXT) facet.$(OBJEXT) format.$(OBJEXT) \
+ frac.$(OBJEXT) frame.$(OBJEXT) functions.$(OBJEXT) \
+ geometry.$(OBJEXT) glyph.$(OBJEXT) halfspace.$(OBJEXT) \
+ hatching.$(OBJEXT) intersections.$(OBJEXT) interval.$(OBJEXT) \
+ label_data.$(OBJEXT) label_style.$(OBJEXT) legend.$(OBJEXT) \
+ legend_item.$(OBJEXT) legend_tile.$(OBJEXT) length.$(OBJEXT) \
+ lens.$(OBJEXT) markers.$(OBJEXT) marker_style.$(OBJEXT) \
+ mask_diamond.$(OBJEXT) mask_ellipse.$(OBJEXT) \
+ mask_rectangle.$(OBJEXT) paint_style.$(OBJEXT) pairs.$(OBJEXT) \
+ path.$(OBJEXT) path_data.$(OBJEXT) path_style.$(OBJEXT) \
+ pen_arrow.$(OBJEXT) pen_data.$(OBJEXT) pen_fill.$(OBJEXT) \
+ pen_line.$(OBJEXT) picture.$(OBJEXT) picture_data.$(OBJEXT) \
+ plane.$(OBJEXT) plots.$(OBJEXT) pst.$(OBJEXT) screen.$(OBJEXT) \
+ screen_crop.$(OBJEXT) screen_data.$(OBJEXT) \
+ screen_mask.$(OBJEXT) segment.$(OBJEXT) spline.$(OBJEXT) \
+ sphere.$(OBJEXT) state.$(OBJEXT) surface.$(OBJEXT) \
+ tikz.$(OBJEXT) tile.$(OBJEXT) triples.$(OBJEXT) \
+ utils.$(OBJEXT) verbatim.$(OBJEXT)
+am__objects_2 =
+am__objects_3 = $(am__objects_2)
+am_libepix_a_OBJECTS = $(am__objects_1) $(am__objects_3)
+libepix_a_OBJECTS = $(am_libepix_a_OBJECTS)
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libepix_a_SOURCES)
+DIST_SOURCES = $(libepix_a_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+pkglibDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkglib_DATA)
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS) $(pkginclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASH_PATH = @BASH_PATH@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@
+ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RUNTIME_COMPILER = @RUNTIME_COMPILER@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+# MAYBE_DIRS = contrib contrib/doc
+#endif
+
+# SUBDIRS = . samples doc $(MAYBE_DIRS)
+SUBDIRS = . samples doc
+
+# Now stuff for this directory specifically
+bin_SCRIPTS = epix elaps flix laps
+pkglib_LIBRARIES = libepix.a
+pkglib_DATA = epix-lib.sh
+include_HEADERS = epix.h
+libepix_a_CXXSOURCES = active_screen.cc affine.cc angle_units.cc \
+ arrow_data.cc arrow_style.cc axis.cc camera.cc circle.cc clipping.cc \
+ Color_Base.cc Color.cc Color_CMY.cc Color_CMYK.cc Color_Gray.cc \
+ Color_Neutral.cc Color_RGB.cc Color_Sep.cc Color_Utils.cc \
+ cropping.cc curves.cc \
+ data_bins.cc data_file.cc data_mask.cc domain.cc \
+ eepic.cc facet.cc format.cc frac.cc frame.cc functions.cc \
+ geometry.cc glyph.cc halfspace.cc hatching.cc \
+ intersections.cc interval.cc label_data.cc label_style.cc \
+ legend.cc legend_item.cc legend_tile.cc \
+ length.cc lens.cc markers.cc marker_style.cc \
+ mask_diamond.cc mask_ellipse.cc mask_rectangle.cc \
+ paint_style.cc pairs.cc path.cc path_data.cc \
+ path_style.cc pen_arrow.cc pen_data.cc pen_fill.cc pen_line.cc \
+ picture.cc picture_data.cc plane.cc plots.cc pst.cc \
+ screen.cc screen_crop.cc screen_data.cc screen_mask.cc \
+ segment.cc spline.cc sphere.cc state.cc surface.cc tikz.cc tile.cc \
+ triples.cc utils.cc verbatim.cc
+
+# polygon.cc
+libepix_a_HDRS = $(libepix_a_CXXSOURCES:.cc=.h) constants.h \
+ crop_algorithms.h deriv.h edge_data.h enums.h errors.h \
+ map.h plot_algorithms.h spline_data.h
+
+libepix_a_SOURCES = $(libepix_a_CXXSOURCES) $(libepix_a_HDRS)
+libepix_a_LIBADD = $(libepix_a_CXXSOURCES:.cc=.o)
+pkginclude_HEADERS = $(libepix_a_HDRS)
+man_MANS = epix.1 elaps.1 flix.1 laps.1
+@ENABLE_EPIX_EL_TRUE@EPIX_EL = epix.el
+EPIX_CONFFILES = bash_completions $(EPIX_EL)
+EPIX_NOTEFILES = AUTHORS BUGS ChangeLog COPYING INSTALL NEWS POST-INSTALL \
+ README THANKS VERSION
+
+EXTRA_DIST = $(bin_SCRIPTS) $(man_MANS) $(EPIX_CONFFILES) $(EPIX_NOTEFILES) \
+ $(pkgdata_DATA)
+
+CLEANFILES = *~ $(libepix_a_OBJECTS) $(bin_SCRIPTS) $(bin_SCRIPTS:=-local) \
+ epix.h epix.1 epix.el
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+ cd $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+install-pkglibLIBRARIES: $(pkglib_LIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(pkglibLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(pkglibLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
+ else :; fi; \
+ done
+ @$(POST_INSTALL)
+ @list='$(pkglib_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ p=$(am__strip_dir) \
+ echo " $(RANLIB) '$(DESTDIR)$(pkglibdir)/$$p'"; \
+ $(RANLIB) "$(DESTDIR)$(pkglibdir)/$$p"; \
+ else :; fi; \
+ done
+
+uninstall-pkglibLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkglibdir)/$$p'"; \
+ rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
+ done
+
+clean-pkglibLIBRARIES:
+ -test -z "$(pkglib_LIBRARIES)" || rm -f $(pkglib_LIBRARIES)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Base.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_CMY.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_CMYK.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Gray.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Neutral.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_RGB.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Sep.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/active_screen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/angle_units.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arrow_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arrow_style.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/axis.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camera.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/circle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipping.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cropping.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_bins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_mask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domain.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eepic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/facet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frac.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyph.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/halfspace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hatching.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intersections.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label_style.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend_item.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend_tile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/length.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lens.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker_style.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_diamond.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_ellipse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_rectangle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paint_style.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pairs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_style.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_arrow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_fill.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_line.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picture.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picture_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plane.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plots.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pst.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_crop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_mask.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/segment.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sphere.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tikz.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triples.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verbatim.Po@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-man1: $(man1_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+install-pkglibDATA: $(pkglib_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+uninstall-pkglibDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(includedir)/$$f"; \
+ done
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgincludedir)" || $(mkdir_p) "$(DESTDIR)$(pkgincludedir)"
+ @list='$(pkginclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgincludedir)/$$f'"; \
+ $(pkgincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgincludedir)/$$f"; \
+ done
+
+uninstall-pkgincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkginclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgincludedir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ mkdir $(distdir)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-pkglibLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-data-local install-includeHEADERS install-man \
+ install-pkgincludeHEADERS
+
+install-exec-am: install-binSCRIPTS install-exec-local \
+ install-pkglibDATA install-pkglibLIBRARIES
+
+install-info: install-info-recursive
+
+install-man: install-man1
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-includeHEADERS \
+ uninstall-info-am uninstall-local uninstall-man \
+ uninstall-pkgincludeHEADERS uninstall-pkglibDATA \
+ uninstall-pkglibLIBRARIES
+
+uninstall-info: uninstall-info-recursive
+
+uninstall-man: uninstall-man1
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+ check-am clean clean-generic clean-pkglibLIBRARIES \
+ clean-recursive ctags ctags-recursive dist dist-all dist-bzip2 \
+ dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
+ distclean-compile distclean-generic distclean-recursive \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binSCRIPTS install-data install-data-am \
+ install-data-local install-exec install-exec-am \
+ install-exec-local install-includeHEADERS install-info \
+ install-info-am install-man install-man1 \
+ install-pkgincludeHEADERS install-pkglibDATA \
+ install-pkglibLIBRARIES install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-binSCRIPTS \
+ uninstall-includeHEADERS uninstall-info-am uninstall-local \
+ uninstall-man uninstall-man1 uninstall-pkgincludeHEADERS \
+ uninstall-pkglibDATA uninstall-pkglibLIBRARIES
+
+
+#if BUILD_CONTRIB
+ # Must be in this order!
+
+# Headers
+epix.h: $(libepix_a_HDRS)
+ ./make_header
+
+# Scripts; we create local variants which will work during the build process
+epix elaps flix laps: %: %.in epix.el
+ sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \
+ -e 's%@bindir\@%$(bindir)%;' \
+ -e 's%@pkglibdir\@%$(pkglibdir)%;' \
+ -e 's%@includedir\@%$(includedir)%;' \
+ -e 's%@RUNTIME_COMPILER\@%$(RUNTIME_COMPILER)%;' $< > $@
+ sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \
+ -e 's%@bindir\@%$(CURDIR)%;' \
+ -e 's%@pkglibdir\@%$(CURDIR)%;' \
+ -e 's%@includedir\@%$(CURDIR)%;' \
+ -e 's%@RUNTIME_COMPILER\@%$(CXX)%;' $< > $@-local
+ chmod a+x $@ $@-local
+
+# libepix.a
+libepix.a: $(libepix_a_OBJECTS)
+ ar -ru libepix.a $(libepix_a_OBJECTS)
+ $(RANLIB) libepix.a
+
+# object file dependencies
+$(libepix_a_LIBADD): %.o: %.cc %.h
+
+# Manpage
+epix.1: epix.1.in
+ sed -e 's%@docdir\@%$(docdir)%;' $< > $@
+
+# emacs mode
+epix.el: epix.el.in
+ sed -e 's%@docdir\@%$(docdir)%;' $< > $@
+
+# Extra things to install
+install-data-local:
+ @echo; echo "Installing notes and configuration files"
+ ./mkinstalldirs $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config
+ $(INSTALL_DATA) $(EPIX_NOTEFILES) $(DESTDIR)$(docdir)/notes
+ $(INSTALL_DATA) $(EPIX_CONFFILES) $(DESTDIR)$(docdir)/config
+
+# This is being installed by install-exec, but should not be executable
+install-exec-local: install-pkglibDATA
+ chmod a-x $(DESTDIR)$(pkglibdir)/epix-lib.sh
+
+uninstall-local:
+ -rm -rf $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config
+ -rmdir $(DESTDIR)$(docdir)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/graphics/epix/NEWS b/graphics/epix/NEWS
new file mode 100644
index 0000000000..c9b7c4ddd6
--- /dev/null
+++ b/graphics/epix/NEWS
@@ -0,0 +1,91 @@
+ePiX-1.2 -- NEWS
+
+Last Change: September 12, 2007
+
+Please consult the following files as appropriate:
+
+INSTALL -- Detailed installation instructions
+NEWS (this file) -- Recent major changes (see ChangeLog for code changes)
+README -- General overview and information
+
+
+If you are new to ePiX, you may safely ignore this file.
+
+OVERVIEW
+
+ePiX 1.2.x has been written almost entirely from scratch. The drawing
+model is unchanged, and some old files will compile as is, but there
+are a few changes of syntax.
+
+
+SYNTAX CHANGES
+
+Generally, global variables have been deprecated or removed, and
+should be replaced by function calls in new files.
+
+* (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().
+
+* (Suggested) The camera may be accessed through the function
+ the_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 may be given in one command,
+ such as picture(P(-1,0), P(1,1), "4x3in"). The old syntax will be
+ retained indefinitely.
+
+* (Mandatory) The command use_pstricks() is obsolete.
+
+* (Mandatory) Deprecated aliases no longer exist: triple (for the P
+ class), D (for Deriv), and I (for Integral). Lowercase trig function
+ names conflicted with the standard namespace and have been removed.
+
+* (Mandatory) The geometric object commands (circle, plane, segment,
+ sphere) which used to create class objects now perform drawing. The
+ classes are available with capitalized names (Circle, Plane,
+ Segment, Sphere).
+
+
+NEW FEATURES
+
+* Output is cleanly separated from the internal representation.
+ Figures may be written with a choice of macros---PSTricks, tikz, and
+ eepic at present---and new output types are easily coded so long as
+ the format supports arbitrary line segments, color, and the ability
+ to place a LaTeX box at a specified location.
+
+* Colors are 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. Filters performing CMYK separation are provided.
+
+* 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 now colored like other markers. Shaded surfaces may be
+ colored with position-dependent functions.
+
+ If a figure contains many shaded elements, a color-capable output
+ format (PSTricks or tikz) should be used for efficiency. Filled
+ regions are implemented as fine hatching in eepic.
+
+* An axis class provides coordinate axes with labels in a variety of
+ styles: decimals or scientific notation of specified precision,
+ fractions, trig fractions, logarithmic labels in arbitrary (integer)
+ base, and user-supplied styles.
+
+* ePiX 1.2.x performs page layout. Sub-figures may be manipulated
+ flexibly. The sample files give several applications.
+
+* Non-member intersection operators for Circles, Planes, Segments, and
+ Spheres are provided. A ``non-generic'' intersection does not
+ throw an exception, but instead returns an undrawable ``malformed''
+ object.
diff --git a/graphics/epix/POST-INSTALL b/graphics/epix/POST-INSTALL
new file mode 100644
index 0000000000..5dec6e6970
--- /dev/null
+++ b/graphics/epix/POST-INSTALL
@@ -0,0 +1,123 @@
+ePiX-1.2 -- POST-INSTALL
+
+Last Change: September 12, 2007
+
+This file contains post-install configuration instructions for users.
+Please consult the following files as appropriate:
+
+INSTALL -- Detailed installation instructions
+NEWS -- Recent major changes (see ChangeLog for code changes)
+README -- General overview and information
+
+
+CONVENTIONS
+
+Lines starting with a "%" denote commands typed at a shell prompt.
+Lines starting with a "#" denote commands run as root.
+Don't type the prompt characters "%" or "#". :)
+
+"$(prefix)" stands for the complete path to the install directory,
+e.g. "/usr/local" or "/home/pootle/epix".
+
+Files mentioned below are installed in $(prefix)/share/doc/epix/config/
+
+
+PROGRAMMABLE COMPLETION in bash
+
+If you type "epix c[TAB]", bash normally displays all files and
+directories whose name starts with "c". If programmable completion is
+enabled, bash will show only those files whose name starts with "c"
+*and* whose extension is that of an epix input file.
+
+Programmable completion in bash is available only with Version 2.05 and
+later, and you must install Ian MacDonald's bash completion package. Do
+a search for "bash programmable completion" at
+
+ http://freshmeat.net
+
+The file "$(prefix)/share/doc/epix/config/bash_completions" contains
+programmable completion code for ePiX's shell scripts. These lines
+should be put into your bash config file (~/.bashrc) just after the
+line that includes the system-wide bash completion config file (q.v.).
+
+
+EMACS MODE
+
+Jay Belanger has kindly provided an emacs mode (epix.el) for working
+with epix source files. To use epix mode, put a copy of the file
+"epix.el" in your emacs load path; under GNU/Linux, an appropriate
+system directory is /usr/share/emacs. If you are not the superuser,
+use a directory such as ${HOME}/share/emacs:
+
+% mkdir -p ~/share/emacs
+% cp $(prefix)/share/doc/epix/config/epix.el ~/share/emacs/
+
+Then add these lines to your .emacs file:
+---(snip)---
+(setq load-path (cons "~/share/emacs/" load-path))
+(setq auto-mode-alist (cons '("\\.xp" . epix-mode) auto-mode-alist))
+(autoload 'epix-mode "epix" "ePiX editing mode" t)
+(setq epix-mark-files-as-epix t)
+(setq epix-insert-template-in-empty-buffer t)
+
+(autoload 'flix-mode "epix" "ePiX editing mode" t)
+(setq auto-mode-alist (cons '("\\.flx" . flix-mode) auto-mode-alist))
+---(snip)---
+
+Change "~/share/emacs/" in the first line as appropriate. If you open
+a new file with extension ".xp" or ".flx", emacs will automatically
+insert a matching preamble template and enter epix-mode or flix-mode,
+respectively. You can then compile and preview ePiX source files with
+emacs commands, or read the info file; please see epix.el for more
+details.
+
+If necessary (for instance, if your source file must have extension
+".cc" for some reason), you can enter epix mode manually by typing
+
+M-x epix-mode
+
+in emacs. (The notation "M-x" means the emacs META key, usually ESC,
+followed by "x".)
+
+
+OTHER CONFIG FILES
+
+The files ~/.dvipsrc and ~/.epixrc affect the behavior of epix, elaps,
+and laps. The use of .epixrc is documented in the tutorial. Neither
+file is required in order to use ePiX.
+
+
+SETTING the PATH
+
+If you've installed ePiX but receive a "command not found" error
+message when trying to compile figures, you probably need to set your
+PATH, the shell environment variable listing the directories to be
+searched for executable code.
+
+As above, $(prefix) stands for the directory in which ePiX has been
+installed and "%" denotes a prompt. Below, $(prefix) must be replaced
+with the actual path. Issue the command
+
+% echo $PATH
+
+If $(prefix)/bin is not shown, you must determine what shell you're
+using and edit the appropriate shell configuration file. Do
+
+% ?
+
+If the response is: Put this line: Into the file:
+------------------- -------------- --------------
+bash: ?: command not found export PATH=$PATH:$(prefix)/bin ~/.bashrc
+
+?: no match setenv PATH $PATH:$(prefix)/bin ~/.cshrc
+
+In the first case, do not put spaces around the equals sign. If the
+response is something else, please consult your system administrator
+for assistance.
+
+Now re-load the appropriate configuration file and try an ePiX command:
+
+% source ~/.bashrc
+% epix --help
+
+If this still doesn't work, please consult your system administrator.
diff --git a/graphics/epix/README b/graphics/epix/README
new file mode 100644
index 0000000000..91d8889ceb
--- /dev/null
+++ b/graphics/epix/README
@@ -0,0 +1,139 @@
+ePiX -- README
+
+Last Change: September 12, 2007
+
+Please consult the following files as appropriate:
+
+INSTALL -- Detailed installation instructions
+NEWS -- Recent major changes (see ChangeLog for code changes)
+README (this file) -- General overview and information
+
+
+DESCRIPTION
+
+ePiX (pronounced like "epic" with a soft "k", playing on "TeX"), a
+collection of command line utilities for *nix, creates mathematically
+accurate figures, plots, and movies using easy-to-learn syntax. The
+output is expressly designed for use with LaTeX.
+
+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. LaTeX- and web-compatible output types include a LaTeX
+picture-like environment written with PSTricks, tikz, or eepic macros;
+vector images (eps, ps, and pdf); and bitmap images (png, mng, gif).
+
+
+INSTALLATION
+
+Please see the "INSTALL" file.
+
+
+OVERVIEW
+
+ePiX's command-line conversion utilities are
+
+* epix: ePiX to eepic
+
+* elaps: ePiX and eepic to eps or pdf
+
+* laps: (La)TeX to PostScript
+
+* flix: ePiX to png or mng
+
+Each script prints a detailed help message when invoked with the
+option "-h" (help)
+
+
+DOCUMENTATION
+
+ePiX documentation is installed in $(prefix)/share/doc/epix, by
+default /usr/local/share/doc/epix.
+
+The manual, a complete description of ePiX's features and use, is
+installed as PostScript (for printing), hyperlinked PDF (for online
+reading), GNU info (for reference within emacs), and as LaTeX sources.
+
+
+DEVELOPER FILES
+
+The header files are installed in $(pkgincludedir), by default
+$(prefix)/include/epix.
+
+
+INTERNET DOWNLOAD SITES
+
+* http://math.holycross.edu/~ahwang/epix/ePiX.html
+
+ Links to currently available packages and documentation, general
+ information, sample images and animations, and summaries of the
+ latest developments.
+
+
+* http://freshmeat.net/projects/epix
+
+ Announcements of recent releases, project stats, and links.
+
+
+* http://www.ctan.org/tex-archive/graphics/epix/
+
+ Stable releases with synchronized documentation.
+
+
+* http://savannah.nongnu.org/cgi-bin/viewcvs/epix/1.2
+
+ The very latest source code by CVS.
+
+
+As with all free (GPL) software, the source code can be obtained on a
+floppy disk from the author by post ("snail mail"), in this case from:
+
+Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+Dept. of Mathematics and Computer Science
+College of the Holy Cross
+Worcester, MA, 01610-2395, USA
+
+
+PYEPIX
+
+Though ePiX can be compiled and run using CygWin, Windows users may be
+more interested in Andrew Sterian's Pyepix package, an implementation
+of ePiX-1.0.4 in Python. Pyepix is available from
+
+ http://claymore.engineer.gvsu.edu/~steriana/Python/index.html
+
+and requires Python 2.2 or newer.
+
+
+MAILING LIST
+
+There are two mailing lists, for users and for development issues.
+Please visit
+
+ http://savannah.nongnu.org/mail/?group=epix
+
+to subscribe.
+
+
+COPYLEFT and DISTRIBUTION
+
+ePiX and its documentation are distributed under the terms of the GNU
+GPL. This program and its documentation come with ABSOLUTELY NO
+WARRANTY OF ANY KIND, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE. This is the same guarantee granted
+by all common software, including expensive, proprietary software
+whose quality you have no way to verify directly, and whose license
+you tacitly accept merely by opening the package.
+
+Feedback about this program (suggestions for features, etc.) is
+welcome. If you find this program useful, please consider making a
+contribution to the Free Software Foundation; see
+
+ http://www.fsf.org
+
+
+--- Contact Information ---
+
+Andrew D. ("Andy") Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+Dept. of Mathematics and Computer Science
+College of the Holy Cross
+Worcester, MA, 01610-2395, USA
diff --git a/graphics/epix/THANKS b/graphics/epix/THANKS
new file mode 100644
index 0000000000..49890d72bc
--- /dev/null
+++ b/graphics/epix/THANKS
@@ -0,0 +1,122 @@
+ePiX -- THANKS
+
+ePiX is built on the work of many people (unfortunately, most of whom
+I am unaware). A few of the obvious ones are, in alphabetical order:
+
+Donald E. Knuth TeX, and so much more
+Conrad Kwok eepic
+
+Leslie Lamport LaTeX
+
+Tim Morgan tpic
+
+Piet van Oostrum eepic
+
+Sunil Podar the epic style
+
+Richard M. Stallman the GNU project
+
+Till Tantau pgf/tikz
+
+Herbert Voss PSTricks
+Timothy Van Zandt
+
+----------------------------------------------------------------------
+
+Special thanks to: For:
+
+Jay Belanger The emacs mode
+Robin Blume-Kohout Design suggestions
+
+Svend Daugaard Pedersen Extended coordinate systems and plotting capability
+
+Julian Gilbey Getting ePiX to work with autoconf/automake
+Guido Gonzato Creating and maintaining the RPM
+
+Marcus Hanwell Data plotting and manipulation code
+Yvon Henel French translation of the manual
+
+Jean-Michel Sarlat http://melusine.eu.org/syracuse/epix/
+Andrew Sterian Pyepix and its Windows package
+
+
+---
+
+Ports contributors and maintainers:
+
+Crux:
+Youn\`es Hafri http://yhafri.club.fr/crux/index.html
+
+Debian: http://packages.debian.org/unstable/tex/epix1
+Julian Gilbey
+
+
+FreeBSD: http://www.freshports.org/graphics/epix/
+Tsuguru Kato
+
+
+Gentoo: http://packages.gentoo.org/search/?sstring=epix
+Markus Dittrich
+Danny van Dyk
+Christian Faulhammer
+Olivier Fisette
+Chris Gianelloni
+Michael Hanselmann
+Marcus Hanwell
+David Holm
+Peter Johanson
+Patrick Kursawe
+Tobias Scherbaum
+Markus Ullmann
+
+T2: http://www.t2-project.org/packages/epix.html
+Ren\'e Rebe
+
+
+----------------------------------------------------------------------
+
+Many thanks to the following people, who have helped publicize ePiX
+or reported and/or patched bugs (in both code and documentation)
+
+<Anonymous>
+
+Maik Beckmann
+Jay Belanger
+Felipe Paulo Guazzi Bergo
+Karl Berry
+Robin Blume-Kohout
+
+Patrick Cousot
+
+Stephen Gibson
+Julian Gilbey
+Dov Grobgeld
+Bob Grover
+
+Jim Hefferon
+Yvon Henel
+Hartmut Henkel
+
+Herng-Jeng Jou
+
+Walter A. Kehowski
+
+Jacques L'helgoual
+
+Kevin McKormick
+Ross Moore
+
+Thorsten Riess
+
+Neel Smith
+Michael Somos
+Andrew Sterian
+
+Ryszard Tanas
+Kai Trukenmueller
+
+Torbjorn Vik
+
+Wenguang Wang
+Gabe Weaver
+Mariusz Wodzicki
diff --git a/graphics/epix/TODO b/graphics/epix/TODO
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/graphics/epix/TODO
diff --git a/graphics/epix/VERSION b/graphics/epix/VERSION
new file mode 100644
index 0000000000..6085e94650
--- /dev/null
+++ b/graphics/epix/VERSION
@@ -0,0 +1 @@
+1.2.1
diff --git a/graphics/epix/aclocal.m4 b/graphics/epix/aclocal.m4
new file mode 100644
index 0000000000..b6186f2ab8
--- /dev/null
+++ b/graphics/epix/aclocal.m4
@@ -0,0 +1,879 @@
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.9.6])])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 7
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out. Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
diff --git a/graphics/epix/active_screen.cc b/graphics/epix/active_screen.cc
new file mode 100644
index 0000000000..05fafc804e
--- /dev/null
+++ b/graphics/epix/active_screen.cc
@@ -0,0 +1,80 @@
+/*
+ * active_screen.cc -- ePiX screen_broker class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.11
+ * Last Change: August 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "screen.h"
+#include "picture_data.h"
+#include "picture.h"
+#include "active_screen.h"
+
+namespace ePiX {
+
+ screen_broker::screen_broker()
+ {
+ m_screens.push_front(&the_picture().the_canvas);
+ }
+
+ screen* screen_broker::active() const
+ {
+ return *(m_screens.begin());
+ }
+
+ void screen_broker::push(screen& scr)
+ {
+ m_screens.push_front(&scr);
+ }
+
+ screen* screen_broker::pop()
+ {
+ std::list<screen*>::const_iterator sp(m_screens.begin());
+
+ screen* val(*sp);
+
+ if (++sp != m_screens.end())
+ m_screens.pop_front();
+
+ return val;
+ }
+
+
+ // global functions
+ screen_broker& the_screen_stack()
+ {
+ static screen_broker* the_screen_broker(new screen_broker());
+ return *the_screen_broker;
+ }
+
+ screen* active_screen()
+ {
+ return the_screen_stack().active();
+ }
+} // end of namespace
diff --git a/graphics/epix/active_screen.h b/graphics/epix/active_screen.h
new file mode 100644
index 0000000000..79bb909063
--- /dev/null
+++ b/graphics/epix/active_screen.h
@@ -0,0 +1,72 @@
+/*
+ * active_screen.h -- ePiX screen_broker class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.11
+ * Last Change: August 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * A screen_broker is a simple stack of screen*, permitting client code
+ * to activate a screen then restore the state later. No attempt is made
+ * to handle concurrent threads, but the global "deactivate" function
+ * in picture.h prints a warning if its argument is not active.
+ */
+#ifndef EPIX_ACTIVE_SCREEN
+#define EPIX_ACTIVE_SCREEN
+
+#include <list>
+
+namespace ePiX {
+
+ class screen;
+
+ class screen_broker {
+ public:
+ screen_broker();
+
+ // no need for destructor; we don't manage resources
+
+ screen* active() const;
+ void push(screen&);
+ screen* pop();
+
+ private:
+ std::list<screen*> m_screens;
+
+ // forbid copying
+ screen_broker(const screen_broker&);
+ screen_broker& operator= (const screen_broker&);
+ };
+
+ screen_broker& the_screen_stack();
+ screen* active_screen();
+} // end of namespace
+
+#endif /* EPIX_ACTIVE_SCREEN */
diff --git a/graphics/epix/affine.cc b/graphics/epix/affine.cc
new file mode 100644
index 0000000000..cc28e40cbf
--- /dev/null
+++ b/graphics/epix/affine.cc
@@ -0,0 +1,300 @@
+/*
+ * affine.cc -- ePiX::affine class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 23, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "errors.h"
+#include "constants.h"
+
+#include "pairs.h"
+#include "triples.h"
+#include "functions.h"
+
+#include "affine.h"
+
+namespace ePiX {
+
+ // rotate/reflect about (0,0)
+ static pair __epix_rotate(double Cs, double Sn, const pair& arg)
+ {
+ double x(arg.x1()), y(arg.x2());
+ return pair(Cs*x - Sn*y, Sn*x + Cs*y);
+ }
+
+ static pair __epix_reflect(double Cs, double Sn, const pair& arg)
+ {
+ double x(arg.x1()), y(arg.x2());
+ return pair(Cs*x + Sn*y, Sn*x - Cs*y);
+ }
+
+ // identity
+ affine::affine()
+ : m_00(0,0), m_10(1,0), m_01(0,1) { }
+
+ // images of (1,0), (0,1), (0,0)
+ affine::affine(const pair& pr1, const pair& pr2, const pair& loc)
+ : m_00(loc), m_10(pr1), m_01(pr2) { }
+
+ affine::affine(const P& pr1, const P& pr2, const P& loc)
+ : m_00(loc.x1(), loc.x2()),
+ m_10(pr1.x1(), pr1.x2()),
+ m_01(pr2.x1(), pr2.x2()) { }
+
+ affine& affine::shift(const pair& arg)
+ {
+ m_00 += arg;
+ m_10 += arg;
+ m_01 += arg;
+
+ return *this;
+ }
+
+ affine& affine::shift(const P& arg)
+ {
+ return shift(pair(arg.x1(), arg.x2()));
+ }
+
+ affine& affine::rotate(double theta, const pair& ctr)
+ {
+ const double Cs(Cos(theta));
+ const double Sn(Sin(theta));
+
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ // rotate about origin and shift back
+ m_00 = __epix_rotate(Cs, Sn, m_00) + ctr;
+ m_10 = __epix_rotate(Cs, Sn, m_10) + ctr;
+ m_01 = __epix_rotate(Cs, Sn, m_01) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::rotate(double theta, const P& ctr)
+ {
+ return rotate(theta, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::reflect(double theta, const pair& ctr)
+ {
+ const double Cs(Cos(2*theta));
+ const double Sn(Sin(2*theta));
+
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ // reflect about origin and shift back
+ m_00 = __epix_reflect(Cs, Sn, m_00) + ctr;
+ m_10 = __epix_reflect(Cs, Sn, m_10) + ctr;
+ m_01 = __epix_reflect(Cs, Sn, m_01) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::reflect(double theta, const P& ctr)
+ {
+ return reflect(theta, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::h_scale(double sc, const pair& ctr)
+ {
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ const pair scale(sc, 1);
+
+ m_00 = (m_00 & scale) + ctr;
+ m_10 = (m_10 & scale) + ctr;
+ m_01 = (m_01 & scale) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::h_scale(double sc, const P& ctr)
+ {
+ return h_scale(sc, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::v_scale(double sc, const pair& ctr)
+ {
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ const pair scale(1, sc);
+
+ m_00 = (m_00 & scale) + ctr;
+ m_10 = (m_10 & scale) + ctr;
+ m_01 = (m_01 & scale) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::v_scale(double sc, const P& ctr)
+ {
+ return v_scale(sc, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::scale(double sc, const pair& ctr)
+ {
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ const pair scale(sc, sc);
+
+ m_00 = (m_00 & scale) + ctr;
+ m_10 = (m_10 & scale) + ctr;
+ m_01 = (m_01 & scale) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::scale(double sc, const P& ctr)
+ {
+ return scale(sc, pair(ctr.x1(), ctr.x2()));
+ }
+
+
+ affine& affine::h_shear(double sc, const pair& ctr)
+ {
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ m_00 += pair(sc*m_00.x2(), 0) + ctr;
+ m_10 += pair(sc*m_10.x2(), 0) + ctr;
+ m_01 += pair(sc*m_01.x2(), 0) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::h_shear(double sc, const P& ctr)
+ {
+ return h_shear(sc, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::v_shear(double sc, const pair& ctr)
+ {
+ // shift
+ m_00 -= ctr;
+ m_10 -= ctr;
+ m_01 -= ctr;
+
+ m_00 += pair(0, sc*m_00.x1()) + ctr;
+ m_10 += pair(0, sc*m_10.x1()) + ctr;
+ m_01 += pair(0, sc*m_01.x1()) + ctr;
+
+ return *this;
+ }
+
+ affine& affine::v_shear(double sc, const P& ctr)
+ {
+ return v_shear(sc, pair(ctr.x1(), ctr.x2()));
+ }
+
+ affine& affine::postcomp(const affine& af)
+ {
+ m_00 = af(m_00);
+ m_10 = af(m_10);
+ m_01 = af(m_01);
+
+ return *this;
+ }
+
+ affine& affine::invert()
+ {
+ m_10 -= m_00;
+ m_01 -= m_00;
+
+ const double denom(m_10.x1()*m_01.x2() - m_10.x2()*m_01.x1());
+
+ if (fabs(denom) < EPIX_EPSILON)
+ {
+ // restore
+ m_10 += m_00;
+ m_01 += m_00;
+ epix_warning("affine not invertible, no action");
+ return *this;
+ }
+
+ // else compute inverse entries
+ const double a11( m_01.x2()/denom);
+ const double a12(-m_01.x1()/denom);
+ const double a21(-m_10.x2()/denom);
+ const double a22( m_10.x1()/denom);
+
+ pair tmp_00(-a11*m_00.x1() + a12*m_00.x2(),
+ a21*m_00.x1() - a22*m_00.x2());
+
+ m_00 = tmp_00;
+ m_10 = m_00 + pair(a11, a21);
+ m_01 = m_00 + pair(a12, a22);
+
+ return *this;
+ }
+
+
+ // evaluation
+ pair affine::operator() (const pair& arg) const
+ {
+ return m_00 + arg.x1()*(m_10 - m_00) + arg.x2()*(m_01 - m_00);
+ }
+
+ pair affine::operator() (const P& arg) const
+ {
+ return m_00 + arg.x1()*(m_10 - m_00) + arg.x2()*(m_01 - m_00);
+ }
+
+ // pre-composition
+ affine affine::operator() (const affine& af) const
+ {
+ return affine(this->operator()(af.m_10),
+ this->operator()(af.m_01),
+ this->operator()(af.m_00));
+ }
+
+ bool affine::reverses_orientation() const
+ {
+ const pair col1(m_10 - m_00);
+ const pair col2(m_01 - m_00);
+
+ return (col1.x1()*col2.x2() - col1.x2()*col2.x1() < -EPIX_EPSILON);
+ }
+} // end of namespace
diff --git a/graphics/epix/affine.h b/graphics/epix/affine.h
new file mode 100644
index 0000000000..a56758e550
--- /dev/null
+++ b/graphics/epix/affine.h
@@ -0,0 +1,114 @@
+/*
+ * affine.h -- ePiX::affine class (affine screen maps)
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 23, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * An affine map is constructed from the images of the "standard
+ * triple" (0,0), (1,0), and (0,1).
+ *
+ * An affine map may be (post)-composed with translation, rotation,
+ * reflection, scaling along either or both coordinate axes, shearing,
+ * and may be inverted. An optional pair argument, defaulting to
+ * (0,0), gives the center of the operation (if appropriate).
+ *
+ * An affine map may be post-composed via member function, and
+ * pre-composed with operator syntax. The evaluation operator
+ * returns the image of the argument.
+ */
+
+#ifndef EPIX_AFFINE
+#define EPIX_AFFINE
+
+#include "pairs.h"
+#include "triples.h"
+
+namespace ePiX {
+
+ class affine {
+ public:
+ // the identity map
+ affine();
+
+ // images of (1,0), (0,1), (0,0)
+ affine(const pair&, const pair&, const pair& loc=pair(0,0));
+ affine(const P&, const P&, const P& loc=P(0,0));
+
+ // post-operations
+ // translate by arg
+ affine& shift(const pair& arg);
+ affine& shift(const P& arg);
+
+ // rotate by theta about ctr
+ affine& rotate(double theta, const pair& ctr = pair(0,0));
+ affine& rotate(double theta, const P& ctr);
+
+ // reflect in angle-theta line through ctr
+ affine& reflect(double theta, const pair& ctr = pair(0,0));
+ affine& reflect(double theta, const P& ctr);
+
+ // scale coord direction(s) fixing ctr
+ affine& h_scale(double, const pair& ctr=pair(0,0));
+ affine& v_scale(double, const pair& ctr=pair(0,0));
+ affine& scale(double, const pair& ctr=pair(0,0));
+
+ affine& h_scale(double, const P& ctr);
+ affine& v_scale(double, const P& ctr);
+ affine& scale(double, const P& ctr);
+
+ // shear, fixing ctr
+ affine& h_shear(double, const pair& ctr=pair(0,0));
+ affine& v_shear(double, const pair& ctr=pair(0,0));
+
+ affine& h_shear(double, const P& ctr);
+ affine& v_shear(double, const P& ctr);
+
+ // post-compose
+ affine& postcomp(const affine&);
+
+ affine& invert();
+
+ // evaluation
+ pair operator() (const pair&) const;
+ pair operator() (const P&) const;
+
+ // pre-compose
+ affine operator() (const affine&) const;
+
+ bool reverses_orientation() const;
+
+ private:
+ pair m_00;
+ pair m_10;
+ pair m_01;
+ };
+} // end of ePiX namespace
+
+#endif /* EPIX_AFFINE */
diff --git a/graphics/epix/angle_units.cc b/graphics/epix/angle_units.cc
new file mode 100644
index 0000000000..cbc8973703
--- /dev/null
+++ b/graphics/epix/angle_units.cc
@@ -0,0 +1,94 @@
+/*
+ * angle_units.cc -- Implementation of ePiX's angular units
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+#include "angle_units.h"
+
+namespace ePiX {
+
+ angle_state::angle_state()
+ : m_rad_per_unit(1.0),
+ m_unit_per_deg(PI_180),
+ m_rev_per_unit(1.0/TWO_PI) { }
+
+ void angle_state::set_radians_mode()
+ {
+ m_rad_per_unit = 1.0;
+ m_unit_per_deg = PI_180;
+ m_rev_per_unit = 1.0/TWO_PI;
+ }
+
+ void angle_state::set_degrees_mode()
+ {
+ m_rad_per_unit = PI_180;
+ m_unit_per_deg = 1.0;
+ m_rev_per_unit = 1.0/360;
+ }
+
+ void angle_state::set_revolutions_mode()
+ {
+ m_rad_per_unit = TWO_PI;
+ m_unit_per_deg = 1.0/360;
+ m_rev_per_unit = 1.0;
+ }
+
+
+ double angle_state::to_radians(double t)
+ {
+ return t *= m_rad_per_unit;
+ }
+
+ // result lies in (-180, 180]
+ double angle_state::to_degrees(double t)
+ {
+ t *= m_rev_per_unit;
+
+ t -= 0.5; // shift half a turn
+ t -= ceil(t); // map to (-1,0]
+ t += 0.5; // shift to (-0.5, 0.5]
+
+ return t *= 360.0;
+ }
+
+ double angle_state::from_degrees(double t)
+ {
+ return t *= m_unit_per_deg;
+ }
+
+ angle_state& the_angle_style()
+ {
+ static angle_state* the_angle_state(new angle_state());
+ return *the_angle_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/angle_units.h b/graphics/epix/angle_units.h
new file mode 100644
index 0000000000..b250b02d51
--- /dev/null
+++ b/graphics/epix/angle_units.h
@@ -0,0 +1,77 @@
+/*
+ * angle_units.h -- Implementation of ePiX's angular units
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file contains:
+ *
+ * [] angle_state
+ * Angular mode (radians, degrees, revolutions)
+ *
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h. This header is not part of epix.h.
+ */
+#ifndef EPIX_ANGLE_UNITS
+#define EPIX_ANGLE_UNITS
+
+#include <cmath>
+
+namespace ePiX {
+
+ class angle_state {
+ public:
+ angle_state();
+
+ void set_radians_mode();
+ void set_degrees_mode();
+ void set_revolutions_mode();
+
+ // convert to radians, for angle-sensitive trig functions
+ double to_radians(double t);
+
+ // current angle units to/from degrees, for label_style
+ double to_degrees(double t);
+ double from_degrees(double t);
+
+ private:
+ // store state redundantly; small overhead, saves conversion
+ double m_rad_per_unit;
+ double m_unit_per_deg;
+ double m_rev_per_unit;
+ }; // end of class angle_state
+
+ angle_state& the_angle_style();
+
+} // end of namespace
+
+#endif /* EPIX_ANGLE_UNITS */
diff --git a/graphics/epix/arrow_data.cc b/graphics/epix/arrow_data.cc
new file mode 100644
index 0000000000..2c50b0f8bc
--- /dev/null
+++ b/graphics/epix/arrow_data.cc
@@ -0,0 +1,130 @@
+/*
+ * arrow_data.cc -- ePiX arrow class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <list>
+#include <cmath>
+
+#include "triples.h"
+#include "functions.h"
+
+#include "camera.h"
+
+#include "edge_data.h"
+#include "path_data.h"
+#include "clipping.h"
+
+#include "arrow_style.h"
+#include "pen_data.h"
+#include "paint_style.h"
+
+#include "halfspace.h"
+#include "pen_line.h"
+#include "pen_arrow.h"
+
+#include "screen_data.h"
+#include "screen.h"
+#include "active_screen.h"
+
+#include "arrow_data.h"
+
+namespace ePiX {
+
+ arrow_data::arrow_data(const std::vector<P>& pv, const P& base, const P& tip,
+ double scale)
+ : m_base(base), m_tip(tip), m_scale(scale),
+ m_head_seen(!the_clip_box().clips(m_tip))
+ {
+ for (unsigned int i=0; i<pv.size()-1; ++i)
+ m_shaft.push_back(edge3d(pv.at(i), pv.at(i+1), true));
+
+ the_clip_box().clip_path(m_shaft);
+ }
+
+ arrow_data& arrow_data::clip_to(const halfspace& knife)
+ {
+ knife.clip_path(m_shaft);
+ if (knife.clips(m_tip))
+ m_head_seen = false;
+
+ return *this;
+ }
+
+
+ void arrow_data::photo(screen& scr, const Camera& mycam,
+ const pen_data& line, const pen_data& under) const
+ {
+ arrow_data tmp_data(*this);
+ if (mycam.needs_clip())
+ tmp_data.clip_to(mycam.clip_plane());
+
+ std::list<edge2d> edges;
+ for (std::list<edge3d>::const_iterator p=tmp_data.m_shaft.begin();
+ p != tmp_data.m_shaft.end(); ++p)
+ {
+ edge2d tmp(mycam((*p).tail()), mycam((*p).head()), (*p).is_seen());
+
+ if (!tmp.is_null()) // endpoints not equal
+ edges.push_back(tmp);
+ }
+
+ // draw shaft
+ scr.m_screen->add_tile(pen_line(line.seen_through(mycam),
+ under.seen_through(mycam), edges));
+
+ // and arrowhead
+ if (m_head_seen)
+ {
+ const P dir(m_tip-m_base);
+ const P to_cam(mycam.viewpt()-m_base);
+
+ const double sin_th(norm(dir*to_cam)/(norm(dir)*norm(to_cam)));
+
+ scr.m_screen->add_tile(pen_arrow(mycam(m_base), mycam(m_tip),
+ line.seen_through(mycam),
+ under.seen_through(mycam),
+ m_scale, sin_th, m_head_seen));
+ }
+ }
+
+ void arrow_data::draw() const
+ {
+ photo(*active_screen(), cam(),
+ the_paint_style().line_pen(), the_paint_style().base_pen());
+ }
+
+ void arrow_data::draw(const pen_data& p1, const pen_data& p2) const
+ {
+ photo(*active_screen(), cam(), p1, p2);
+ }
+} // end of namespace
diff --git a/graphics/epix/arrow_data.h b/graphics/epix/arrow_data.h
new file mode 100644
index 0000000000..5840cd35d3
--- /dev/null
+++ b/graphics/epix/arrow_data.h
@@ -0,0 +1,77 @@
+/*
+ * arrow_data.h -- ePiX implementation class for arrows
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 19, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_ARROW_DATA
+#define EPIX_ARROW_DATA
+
+#include <list>
+#include <vector>
+
+#include "triples.h"
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class Camera;
+ class Color;
+ class halfspace;
+ class pen_data;
+ class screen;
+
+ // sequence of vertices
+ class arrow_data {
+ public:
+ arrow_data(const std::vector<P>&, const P& base, const P& tip,
+ double scale=1);
+
+ arrow_data& clip();
+ arrow_data& clip_to(const halfspace&);
+
+ void photo(screen&, const Camera&, const pen_data&, const pen_data&) const;
+
+ void draw() const;
+ void draw(const pen_data&, const pen_data&) const;
+
+ private:
+ // head data
+ P m_base, m_tip;
+ double m_scale; // size multiplier
+ bool m_head_seen;
+
+ // shaft
+ std::list<edge3d> m_shaft;
+ }; // end of class arrow_data
+
+} // end of namespace
+
+#endif /* EPIX_ARROW_DATA */
diff --git a/graphics/epix/arrow_style.cc b/graphics/epix/arrow_style.cc
new file mode 100644
index 0000000000..1397545909
--- /dev/null
+++ b/graphics/epix/arrow_style.cc
@@ -0,0 +1,103 @@
+/*
+ * arrow_atyle.cc -- ePiX's arrowhead parameters
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h. This header is not part of epix.h.
+ */
+#include <cmath>
+
+#include "constants.h"
+#include "functions.h" // for snip_to
+#include "arrow_style.h"
+
+namespace ePiX {
+
+ arrowhead_state::arrowhead_state()
+ : m_width(0.5*AVG_AWIDTH), m_ratio(AVG_ARATIO),
+ m_inset(AVG_INSET), m_fill(false) { }
+
+ // set
+ arrowhead_state& arrowhead_state::width(double w)
+ {
+ m_width = fabs(0.5*snip_to(w, MIN_AWIDTH, MAX_AWIDTH));
+ return *this;
+ }
+
+ arrowhead_state& arrowhead_state::ratio(double r)
+ {
+ m_ratio = fabs(snip_to(r, MIN_ARATIO, MAX_ARATIO));
+ return *this;
+ }
+
+ arrowhead_state& arrowhead_state::inset(double arg)
+ {
+ m_inset = snip_to(arg, MIN_INSET, MAX_INSET);
+ return *this;
+ }
+
+ arrowhead_state& arrowhead_state::fill(bool fill)
+ {
+ m_fill = fill;
+ return *this;
+ }
+
+
+ // get
+ double arrowhead_state::width() const
+ {
+ return m_width;
+ }
+
+ double arrowhead_state::ratio() const
+ {
+ return m_ratio;
+ }
+
+ double arrowhead_state::inset() const
+ {
+ return m_inset;
+ }
+
+ bool arrowhead_state::fill() const
+ {
+ return m_fill;
+ }
+
+ arrowhead_state& the_arrowhead_style()
+ {
+ static arrowhead_state* the_arrowhead_state(new arrowhead_state());
+ return *the_arrowhead_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/arrow_style.h b/graphics/epix/arrow_style.h
new file mode 100644
index 0000000000..0f9691516e
--- /dev/null
+++ b/graphics/epix/arrow_style.h
@@ -0,0 +1,76 @@
+/*
+ * arrow_style.h -- ePiX's arrowhead parameters
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h. This header is not part of epix.h.
+ */
+#ifndef EPIX_ARROW_STYLE
+#define EPIX_ARROW_STYLE
+
+namespace ePiX {
+
+ // arrowhead parameters
+ // Magic numbers: initialization constants
+ class arrowhead_state {
+ public:
+ arrowhead_state();
+
+ // set
+ arrowhead_state& width(double w);
+ arrowhead_state& ratio(double r);
+ arrowhead_state& inset(double arg);
+
+ arrowhead_state& fill(bool);
+
+ // get
+ double width() const;
+ double ratio() const;
+ double inset() const;
+
+ bool fill() const;
+
+ private:
+ double m_width; // Half-width of arrowheads in pt
+ double m_ratio; // 2*Length/width ratio of arrowheads
+ double m_inset; // Base indentation (frac of width*ratio)
+
+ bool m_fill;
+ }; // end of class arrowhead_state
+
+ arrowhead_state& the_arrowhead_style();
+
+} // end of namespace
+
+#endif /* EPIX_ARROW_STYLE */
diff --git a/graphics/epix/axis.cc b/graphics/epix/axis.cc
new file mode 100644
index 0000000000..ed86be7ee3
--- /dev/null
+++ b/graphics/epix/axis.cc
@@ -0,0 +1,925 @@
+/*
+ * axis.cc -- ePiX axis class and global compatibility functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 18, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <sstream>
+
+#include "errors.h"
+
+#include "constants.h"
+#include "triples.h"
+
+#include "pairs.h"
+#include "frac.h"
+#include "functions.h"
+
+#include "length.h"
+#include "picture.h"
+
+#include "camera.h"
+
+#include "screen.h"
+#include "active_screen.h"
+#include "curves.h"
+
+#include "label_data.h"
+
+#include "markers.h"
+#include "axis.h"
+
+namespace ePiX {
+
+ // functions to get axis label from position
+ double __epix_coord1(const P&);
+ double __epix_coord2(const P&);
+ double __epix_coord3(const P&);
+
+ // string representations of double
+ std::string __epix_coord_as_double(double x, unsigned int digits,
+ unsigned int base);
+ std::string __epix_coord_as_frac(double x, unsigned int digits,
+ unsigned int base);
+ std::string __epix_coord_as_trig_frac(double x, unsigned int digits,
+ unsigned int base);
+ std::string __epix_coord_as_log(double x, unsigned int digits,
+ unsigned int base);
+ std::string __epix_coord_as_log_sci(double x, unsigned int digits,
+ unsigned int base);
+ std::string __epix_coord_as_sci(double x, unsigned int digits,
+ unsigned int base);
+
+ //// Member functions ////
+ // Constructor automatically selects coordinate function from endpoints
+ axis::axis(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN)
+ : m_tail(tail), m_head(head), m_major_segs(n), m_minor_segs(n),
+ m_tick_ratio(0.5), m_align_ticks(c),
+ m_offset(offset), m_align_labels(POSN),
+ m_log_base(10), m_log(false), m_precision(DEF_PRECISION),
+ m_coord(__epix_coord1), m_rep(__epix_coord_as_double)
+ {
+ m_log_tags.insert(1);
+ int count(fabs(head.x1() - tail.x1()) < EPIX_EPSILON ? 0 : 1);
+ if (EPIX_EPSILON < fabs(head.x2() - tail.x2()))
+ {
+ ++count;
+ m_coord = __epix_coord2;
+ }
+
+ if (EPIX_EPSILON < fabs(head.x3() - tail.x3()))
+ {
+ ++count;
+ m_coord = __epix_coord3;
+ }
+
+ if (1 < count)
+ epix_warning("Axis not parallel to a Cartesian axis");
+
+ else if (count == 0)
+ epix_warning("Degenerate coordinate axis");
+ }
+
+
+ axis& axis::frac()
+ {
+ m_rep = __epix_coord_as_frac;
+ return *this;
+ }
+
+ axis& axis::trig()
+ {
+ m_rep = __epix_coord_as_trig_frac;
+ m_log = false;
+
+ return *this;
+ }
+
+ axis& axis::sci()
+ {
+ if (m_log)
+ m_rep = __epix_coord_as_log_sci;
+ else
+ m_rep = __epix_coord_as_sci;
+ return *this;
+ }
+
+ // f(x, precision, base) returns a string representing x
+ axis& axis::label_rep(std::string f(double, unsigned int, unsigned int))
+ {
+ m_rep = f;
+ return *this;
+ }
+
+ axis& axis::unmark(double arg)
+ {
+ m_omitted.insert(arg);
+ return *this;
+ }
+
+ axis& axis::log(unsigned int base)
+ {
+ if (m_rep == __epix_coord_as_sci) // preserve sci notation
+ m_rep = __epix_coord_as_log_sci;
+ else
+ m_rep = __epix_coord_as_log;
+
+ if (2 <= base && base <= MAX_LOG_BASE)
+ m_log_base = base;
+ else
+ epix_warning("axis::log base out of range, ignoring");
+
+ m_log = true;
+
+ return *this;
+ }
+
+ // add logarithmic labels
+ axis& axis::tag(double arg)
+ {
+ if (0 < arg && 2 < m_log_base)
+ {
+ int k((int) ceil(-std::log(arg)/std::log((double)m_log_base)));
+
+ // arg != b^-k
+ if (k == (int) floor(1 - std::log(arg)/std::log((double)m_log_base)))
+ m_log_tags.insert(arg*pow(m_log_base, k));
+ }
+
+ return *this;
+ }
+
+ axis& axis::tag235()
+ {
+ if (m_log_base == 10)
+ {
+ m_log_tags.insert(2);
+ m_log_tags.insert(3);
+ m_log_tags.insert(5);
+ }
+
+ return *this;
+ }
+
+ axis& axis::tags()
+ {
+ for (unsigned int i=1; i<m_log_base; ++i)
+ m_log_tags.insert(i);
+
+ return *this;
+ }
+
+ axis& axis::untag(double arg)
+ {
+ m_log_tags.erase(arg);
+ return *this;
+ }
+
+ axis& axis::untag()
+ {
+ m_log_tags.clear();
+ return *this;
+ }
+
+ axis& axis::align_labels(epix_label_posn POSN)
+ {
+ m_align_labels = POSN;
+ return *this;
+ }
+
+ axis& axis::align(epix_label_posn POSN)
+ {
+ m_align_ticks = POSN;
+ return *this;
+ }
+
+
+ // number of minor ticks per segment
+ axis& axis::subdivide(unsigned int n)
+ {
+ m_minor_segs = m_major_segs*((unsigned int) snip_to(n, 1, MAX_LOG_BASE));
+ return *this;
+ }
+
+ // set tick length; printed size governed by MIN/MAX_TICK, but 0 significant
+ axis& axis::tick_ratio(double ratio)
+ {
+ m_tick_ratio = snip_to(ratio, 0, 1);
+ return *this;
+ }
+
+
+ // set precision for printing axis labels in decimal
+ axis& axis::precision(unsigned int digits)
+ {
+ if (digits == 0)
+ m_precision = DEF_PRECISION;
+
+ else
+ m_precision = (unsigned int) min(digits, MAX_PRECISION);
+
+ return *this;
+ }
+
+ void axis::draw_ticks() const
+ {
+ const P major_step((1.0/m_major_segs)*(m_head - m_tail));
+
+ const pair screen_dir(cam()(m_head) - cam()(m_tail));
+
+ if (norm(screen_dir) < EPIX_EPSILON) // poke in the eye
+ return;
+
+ // else, are we closer to horiz or vert?
+ bool nearly_horiz(fabs(screen_dir.x2()) < fabs(screen_dir.x1()));
+
+ // axis
+ line(m_tail, m_head);
+
+ // major ticks
+ for (unsigned int i=0; i <= m_major_segs; ++i)
+ {
+ if (nearly_horiz)
+ h_axis_tick(m_tail + i*major_step, m_align_ticks);
+
+ else
+ v_axis_tick(m_tail + i*major_step, m_align_ticks);
+ }
+
+ // Cartesian minor ticks
+ if (!m_log && m_tick_ratio != 0 && m_major_segs != m_minor_segs)
+ {
+ // get tick size
+ const double old_tick_len(the_mark_size().tick_size());
+
+ the_mark_size().tick_size(m_tick_ratio*old_tick_len);
+ const P minor_step((1.0/m_minor_segs)*(m_head - m_tail));
+
+ for (unsigned int i=0; i <= m_minor_segs; ++i)
+ {
+ if (nearly_horiz)
+ h_axis_tick(m_tail + i*minor_step, m_align_ticks);
+
+ else
+ v_axis_tick(m_tail + i*minor_step, m_align_ticks);
+ }
+
+ the_mark_size().tick_size(old_tick_len); // restore state
+ }
+
+ // logarithmic minor ticks
+ else if (m_log && m_tick_ratio != 0)
+ {
+ // get tick size
+ const double old_tick_len(the_mark_size().tick_size());
+
+ the_mark_size().tick_size(m_tick_ratio*old_tick_len);
+
+ const double denom(std::log((double)m_log_base));
+
+ for (unsigned int i=0; i < m_major_segs; ++i)
+ for (unsigned int j=1; j<m_log_base; ++j)
+ {
+ if (nearly_horiz)
+ h_axis_tick(m_tail + (i+std::log((double)j)/denom)*major_step,
+ m_align_ticks);
+
+ else
+ v_axis_tick(m_tail + (i+std::log((double)j)/denom)*major_step,
+ m_align_ticks);
+ }
+
+ the_mark_size().tick_size(old_tick_len); // restore state
+ }
+ }
+
+ void axis::draw_labels() const
+ {
+ const P major_step((1.0/m_major_segs)*(m_head - m_tail));
+
+ if (!m_log)
+ for (unsigned int i=0; i <= m_major_segs; ++i)
+ {
+ const P loc(m_tail + i*major_step);
+ const double tmp_lbl(m_coord(loc));
+ if (m_omitted.find(tmp_lbl) != m_omitted.end()) // omit marked labels
+ continue;
+
+ // else
+ label_data mk(loc, m_offset,
+ m_rep(tmp_lbl, m_precision, m_log_base));
+
+ mk.align_to(m_align_labels).draw();
+ }
+
+ else if (2 < m_log_base) // m_log
+ {
+ const double denom(std::log((double)m_log_base));
+
+ for (unsigned int i=0; i < m_major_segs; ++i)
+ for (std::set<double>::const_iterator tp=m_log_tags.begin();
+ tp != m_log_tags.end(); ++tp)
+ {
+ double dx(std::log(*tp)/denom);
+ const P posn(m_tail + (i + dx)*major_step);
+
+ label_data mk(posn, m_offset,
+ m_rep(m_coord(posn), m_precision, m_log_base));
+
+ mk.align_to(m_align_labels).draw();
+ }
+
+ // final label
+ label_data mk(m_head, m_offset,
+ m_rep(m_coord(m_head), m_precision, m_log_base));
+
+ mk.align_to(m_align_labels).draw();
+ }
+ }
+
+ void axis::draw() const
+ {
+ draw_ticks();
+ draw_labels();
+ }
+
+
+ //// Misc utilities for global functions ////
+ // raw Cartesian coordinates
+ std::string __epix_axis_label(double x)
+ {
+ std::stringstream obuf;
+ obuf << "$" << x << "$";
+
+ return obuf.str();
+ }
+
+ std::string __epix_axis1_label(double x, double y)
+ {
+ return __epix_axis_label(x);
+ }
+
+ std::string __epix_axis2_label(double x, double y)
+ {
+ return __epix_axis_label(y);
+ }
+
+ // log coordinates
+ std::string __epix_log_label(double x, const unsigned int base)
+ {
+ std::stringstream obuf;
+
+ int N((int) ceil(x));
+
+ double k(pow(base, x - N));
+
+ // obuf.precision(2);
+ obuf << "$";
+ if (k != 1.0)
+ {
+ k *= base;
+ N -= 1;
+ obuf << k << "\\times";
+ }
+
+ obuf << base << "^{" << N << "}$";
+
+ return obuf.str();
+ }
+
+ std::string __epix_log_axis1_label(double x, double y,
+ const unsigned int base=10)
+ {
+ return __epix_log_label(x, base);
+ }
+
+ std::string __epix_log_axis2_label(double x, double y,
+ const unsigned int base=10)
+ {
+ return __epix_log_label(y, base);
+ }
+
+ //// Global functions ////
+ // Draws n+1 equally-spaced axis labels between <tail> and <head>.
+ // Uses the string-valued function f to generate label text.
+ void __epix_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ std::string f(double, double), bool masked)
+ {
+ const P step((1.0/n)*(head - tail));
+
+ // get mask color, if any
+ Color my_mask(masked ? the_label_style().mask_color() : Neutral());
+
+ if (masked && my_mask.is_unset())
+ my_mask = White();
+
+ for (unsigned int i=0; i<= n; ++i)
+ {
+ label_data mk(tail+i*step, offset, f);
+
+ mk.mask_color(my_mask).align_to(POSN).draw();
+ }
+ }
+
+
+ //// User-visible commands ////
+ // Not implemented with the axis class because masking behavior differs.
+ void h_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis1_label, false);
+ }
+
+ void v_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis2_label, false);
+ }
+
+
+ void h_axis_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis1_label, true);
+ }
+
+ void v_axis_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis2_label, true);
+ }
+
+
+ // automatic endpoints
+ void h_axis_labels(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(P(active_screen()->h_min(), 0),
+ P(active_screen()->h_max(), 0), n, offset, POSN,
+ __epix_axis1_label, false);
+ }
+
+ void h_axis_masklabels(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(P(active_screen()->h_min(), 0),
+ P(active_screen()->h_max(), 0), n, offset, POSN,
+ __epix_axis1_label, true);
+ }
+
+ void v_axis_labels(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(P(0, active_screen()->v_min()),
+ P(0, active_screen()->v_max()), n, offset, POSN,
+ __epix_axis2_label, false);
+ }
+
+ void v_axis_masklabels(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ __epix_axis_labels(P(0, active_screen()->v_min()),
+ P(0, active_screen()->v_max()), n, offset, POSN,
+ __epix_axis2_label, true);
+ }
+
+
+ // log axis labels
+ void __epix_log_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ std::string f(double, double, unsigned int),
+ bool masked, unsigned int base=10)
+ {
+ const P step((1.0/n)*(head - tail));
+
+ // get mask color, if any
+ Color my_mask(masked ? the_label_style().mask_color() : Neutral());
+
+ if (masked && my_mask.is_unset())
+ my_mask = White();
+
+ for (unsigned int i=0; i<= n; ++i)
+ {
+ P here(tail+i*step);
+ std::string text(f(here.x1(), here.x2(), base));
+
+ label_data mk(here, offset, text);
+
+ mk.mask_color(my_mask).align_to(POSN).draw();
+ }
+ }
+
+ // number of labels specified
+ void h_axis_log_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ __epix_log_axis_labels(tail, head, n, offset, POSN,
+ __epix_log_axis1_label, false, base);
+ }
+
+ void v_axis_log_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ __epix_log_axis_labels(tail, head, n, offset, POSN,
+ __epix_log_axis2_label, false, base);
+ }
+
+
+ // put labels at integer coordinates
+ void h_axis_log_labels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ if (EPIX_EPSILON < (tail.x2() - head.x2()) ) // non-horizontal axis
+ return;
+
+ const double my_y(tail.x2());
+
+ // get integers in horiz interval
+ const int k_lo((int) ceil(min(tail.x1(), head.x1())));
+ const int k_hi((int) floor(max(tail.x1(), head.x1())));
+
+ h_axis_log_labels(P(k_lo, my_y), P(k_hi, my_y), k_hi - k_lo,
+ offset, POSN, base);
+ }
+
+ void v_axis_log_labels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ if (EPIX_EPSILON < (tail.x1() - head.x1()) ) // non-vertical axis
+ return;
+
+ const double my_x(tail.x1());
+
+ // get integers in vert interval
+ const int k_lo((int) ceil(min(tail.x2(), head.x2())));
+ const int k_hi((int) floor(max(tail.x2(), head.x2())));
+
+ v_axis_log_labels(P(my_x, k_lo), P(my_x, k_hi), k_hi - k_lo,
+ offset, POSN, base);
+ }
+
+
+ //// masked versions
+ void h_axis_log_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ __epix_log_axis_labels(tail, head, n, offset, POSN,
+ __epix_log_axis1_label, true, base);
+ }
+
+ void v_axis_log_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ __epix_log_axis_labels(tail, head, n, offset, POSN,
+ __epix_log_axis2_label, true, base);
+ }
+
+
+ // put labels at integer coordinates
+ void h_axis_log_masklabels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ if (EPIX_EPSILON < (tail.x2() - head.x2()) ) // non-horizontal axis
+ return;
+
+ const double my_y(tail.x2());
+
+ // get integers in horiz interval
+ const int k_lo((int) ceil(min(tail.x1(), head.x1())));
+ const int k_hi((int) floor(max(tail.x1(), head.x1())));
+
+ h_axis_log_masklabels(P(k_lo, my_y), P(k_hi, my_y), k_hi - k_lo,
+ offset, POSN, base);
+ }
+
+ void v_axis_log_masklabels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN,
+ unsigned int base)
+ {
+ if (EPIX_EPSILON < (tail.x1() - head.x1()) ) // non-vertical axis
+ return;
+
+ const double my_x(tail.x1());
+
+ // get integers in vert interval
+ const int k_lo((int) ceil(min(tail.x2(), head.x2())));
+ const int k_hi((int) floor(max(tail.x2(), head.x2())));
+
+ v_axis_log_masklabels(P(my_x, k_lo), P(my_x, k_hi), k_hi - k_lo,
+ offset, POSN, base);
+ }
+
+
+ // Coordinate axes
+ void h_axis(const P& tail, const P& head, unsigned int n, epix_label_posn AL)
+ {
+ line(tail, head);
+
+ const P step((1.0/n)*(head - tail));
+
+ for (unsigned int i=0; i <= n; ++i)
+ h_axis_tick(tail + i*step, AL);
+ }
+
+ void v_axis(const P& tail, const P& head, unsigned int n, epix_label_posn AL)
+ {
+ line(tail, head);
+
+ const P step((1.0/n)*(head - tail));
+
+ for (unsigned int i=0; i <= n; ++i)
+ v_axis_tick(tail + i*step, AL);
+ }
+
+ // n+1 = #ticks, num_pts = #segments used to draw
+ void h_axis(unsigned int n, epix_label_posn AL)
+ {
+ h_axis(P(active_screen()->h_min(), 0),
+ P(active_screen()->h_max(), 0), n, AL);
+ }
+
+ void v_axis(unsigned int n, epix_label_posn AL)
+ {
+ v_axis(P(0, active_screen()->v_min()),
+ P(0, active_screen()->v_max()), n, AL);
+ }
+
+
+ void h_log_axis(const P& tail, const P& head,
+ unsigned int segs, epix_label_posn AL, unsigned int base)
+ {
+ line(tail, head, 0, segs);
+
+ const P step((1.0/segs)*(head - tail));
+ const double denom(log(base));
+
+ for (unsigned int i=0; i < segs; ++i)
+ for (unsigned int j=1; j<base; ++j)
+ h_axis_tick(tail + (i+log(j)/denom)*step, AL);
+
+ h_axis_tick(head, AL);
+ }
+
+ void v_log_axis(const P& tail, const P& head,
+ unsigned int segs, epix_label_posn AL, unsigned int base)
+ {
+ line(tail, head, 0, segs);
+
+ const P step((1.0/segs)*(head - tail));
+ const double denom(log(base));
+
+ for (unsigned int i=0; i < segs; ++i)
+ for (unsigned int j=1; j<base; ++j)
+ v_axis_tick(tail + (i+log(j)/denom)*step, AL);
+
+ v_axis_tick(head, AL);
+ }
+
+
+ //// New global functions ////
+ axis top_axis(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ axis A(active_screen()->tl(), active_screen()->tr(), n, offset, POSN);
+ A.align(b);
+ return A;
+ }
+
+ axis bottom_axis(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ axis A(active_screen()->bl(), active_screen()->br(), n, offset, POSN);
+ A.align(t);
+ return A;
+ }
+
+ axis left_axis(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ axis A(active_screen()->bl(), active_screen()->tl(), n, offset, POSN);
+ A.align(r);
+ return A;
+ }
+
+ axis right_axis(unsigned int n, const P& offset, epix_label_posn POSN)
+ {
+ axis A(active_screen()->br(), active_screen()->tr(), n, offset, POSN);
+ A.align(l);
+ return A;
+ }
+
+
+ //// Formatting functions for ePiX::axis ////
+ // standard functions to get axis label from position
+ double __epix_coord1(const P& arg)
+ {
+ return arg.x1();
+ }
+
+ double __epix_coord2(const P& arg)
+ {
+ return arg.x2();
+ }
+
+ double __epix_coord3(const P& arg)
+ {
+ return arg.x3();
+ }
+
+
+ // String representations of double
+ // triples separated by commas
+ std::string __epix_coord_as_double(double x, unsigned int digits,
+ unsigned int base)
+ {
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ obuf << "$" << x << "$";
+
+ if (fabs(x) < 1000)
+ return obuf.str();
+
+ // else insert commas
+ std::string val(obuf.str());
+
+ std::string::size_type i(val.find_first_of("."));
+
+ if (i == std::string::npos)
+ i = val.size()-1;
+
+ while (4 < i)
+ {
+ i -= 3;
+ val.insert(i, ",");
+ }
+
+ return val;
+ }
+
+ // [-]\frac{p}{q}
+ std::string __epix_coord_as_frac(double x, unsigned int digits,
+ unsigned int base)
+ {
+ ePiX::frac xfrac(x);
+
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ obuf << "$";
+
+ if (xfrac.is_int())
+ obuf << xfrac.num() << "$";
+
+ else
+ {
+ if (xfrac.num() < 0) // x may have rounded to zero
+ obuf << "-";
+
+ obuf << "\\frac{" << abs(xfrac.num()) << "}"
+ << "{" << xfrac.denom() << "}$";
+ }
+
+ return obuf.str();
+ }
+
+ // [-]\frac{p\pi}{q}
+ std::string __epix_coord_as_trig_frac(double x, unsigned int digits,
+ unsigned int base)
+ {
+ ePiX::frac xfrac(x/M_PI);
+
+ int xnum(xfrac.num());
+
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ obuf << "$";
+
+ if (xfrac.is_int())
+ {
+ if (xnum == 0)
+ obuf << 0 << "$";
+
+ else if (xnum == 1)
+ obuf << "\\pi$";
+
+ else if (xnum == -1)
+ obuf << "-\\pi$";
+
+ else
+ obuf << xfrac.num() << "\\pi$";
+ }
+
+ else // xfrac not an int
+ {
+ if (xfrac.num() < 0)
+ obuf << "-";
+
+ if (abs(xnum) == 1)
+ obuf << "\\frac{\\pi}{" << xfrac.denom() << "}$";
+
+ else
+ obuf << "\\frac{" << abs(xnum) << "\\pi}"
+ << "{" << xfrac.denom() << "}$";
+ }
+
+ return obuf.str();
+ }
+
+ // b^x
+ std::string __epix_coord_as_log(double x, unsigned int digits,
+ unsigned int base)
+ {
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ obuf << "$" << pow(base, x) << "$";
+
+ return obuf.str();
+ }
+
+ // x = N + k, write as eval(b^k) \times b^N
+ std::string __epix_coord_as_log_sci(double x, unsigned int digits,
+ unsigned int base)
+ {
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ int N((int) ceil(x));
+
+ double k(pow(base, x - N));
+
+ obuf << "$";
+ if (k != 1.0)
+ {
+ k *= base;
+ N -= 1;
+ obuf << k << "\\times";
+ }
+
+ obuf << base << "^{" << N << "}$";
+
+ return obuf.str();
+ }
+
+ std::string __epix_coord_as_sci(double x, unsigned int digits,
+ unsigned int base)
+ {
+ std::stringstream obuf;
+ obuf.precision(digits);
+
+ int sgn(x < 0 ? -1 : 1);
+ x = fabs(x);
+ if (x < EPIX_EPSILON)
+ return "$0$";
+
+ // else
+ const double tmp(log10(x)/log10(base));
+
+ int N((int) floor(tmp));
+
+ double k(pow(base, tmp - N));
+
+ obuf << "$";
+ if (sgn < 0)
+ obuf << "-";
+
+ if (k != 1.0)
+ obuf << k << "\\times";
+
+ obuf << base << "^{" << N << "}$";
+
+ return obuf.str();
+ }
+} // end of namespace
diff --git a/graphics/epix/axis.h b/graphics/epix/axis.h
new file mode 100644
index 0000000000..2c5d47d568
--- /dev/null
+++ b/graphics/epix/axis.h
@@ -0,0 +1,207 @@
+/*
+ * axis.h -- Decorable coordinate axis class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.13
+ * Last Change: August 23, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_AXIS
+#define EPIX_AXIS
+
+#include <string>
+#include <set>
+
+#include "enums.h"
+#include "triples.h"
+
+namespace ePiX {
+
+ class axis {
+ public:
+ axis(const P&, const P&, unsigned int n,
+ const P& offset = P(0,0), epix_label_posn POSN=none);
+
+ // attribute-setting
+ axis& dec(); // default
+ axis& frac(); // fractional labels
+ axis& trig(); // fractions times pi
+ axis& sci(); // scientific notation
+
+ // f(x, precision, base) returns a string representing x
+ axis& label_rep(std::string f(double, unsigned int, unsigned int));
+
+ // unmark selected location (non-log labels only)
+ axis& unmark(double arg=0);
+
+ // add or remove logarithmic tags ("sublabels")
+ axis& log(unsigned int base=10); // log ticks and labels
+ axis& tag(double); // put label at arg in log mode
+ axis& tag235(); // tags at 2, 3, 5 in log10 mode
+ axis& tags(); // tags at 2, ..., b-1 in logb mode
+
+ axis& untag(); // remove all log tags
+ axis& untag(double); // remove selected tag
+
+ axis& align_labels(epix_label_posn);
+ axis& align(epix_label_posn); // align tick marks
+
+ // number of minor ticks per segment
+ axis& subdivide(unsigned int);
+
+ // set length of minor ticks
+ axis& tick_ratio(double);
+
+ // set precision for axis labels
+ axis& precision(unsigned int digits=0); // 0: reset to default
+
+ void draw_ticks() const;
+ void draw_labels() const;
+ void draw() const;
+
+ private:
+ P m_tail;
+ P m_head;
+
+ unsigned int m_major_segs;
+ unsigned int m_minor_segs;
+
+ double m_tick_ratio;
+
+ epix_label_posn m_align_ticks;
+
+ P m_offset;
+ epix_label_posn m_align_labels;
+
+ unsigned int m_log_base;
+ bool m_log;
+ unsigned int m_precision;
+
+ double (*m_coord)(const P&); // value to place at arg
+
+ // represent arg as string
+ std::string (*m_rep)(double arg, unsigned int prec, unsigned int base);
+
+ std::set<double> m_omitted;
+ std::set<double> m_log_tags;
+ }; // end of axis class
+
+ // axes along sides of bounding box, ticks automatically aligned
+ axis top_axis(unsigned int n, const P& offset=P(0,0),
+ epix_label_posn POSN=t);
+ axis bottom_axis(unsigned int n, const P& offset=P(0,0),
+ epix_label_posn POSN=b);
+ axis left_axis(unsigned int n, const P& offset=P(0,0),
+ epix_label_posn POSN=l);
+ axis right_axis(unsigned int n, const P& offset=P(0,0),
+ epix_label_posn POSN=r);
+
+
+ // Global functions from Version 1.0
+ void h_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none);
+
+ void v_axis_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none);
+
+ void h_axis_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none);
+
+ void v_axis_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none);
+
+ // Axis labels with default endpoints
+ void h_axis_labels(unsigned int n, const P& offset,
+ epix_label_posn POSN=none);
+ void h_axis_masklabels(unsigned int n, const P& offset,
+ epix_label_posn POSN=none);
+
+ void v_axis_labels(unsigned int n, const P& offset,
+ epix_label_posn POSN=none);
+ void v_axis_masklabels(unsigned int n, const P& offset,
+ epix_label_posn POSN=none);
+
+ //// logarithmic labels ////
+ // labels written $k x base^i$ at i + log_b(k)
+ void h_axis_log_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ void v_axis_log_labels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ // labels written $base^i$ at coord i
+ void h_axis_log_labels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ void v_axis_log_labels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+
+ void h_axis_log_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ void v_axis_log_masklabels(const P& tail, const P& head, unsigned int n,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ void h_axis_log_masklabels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+ void v_axis_log_masklabels(const P& tail, const P& head,
+ const P& offset, epix_label_posn POSN=none,
+ unsigned int base=10);
+
+
+ // Coordinate axes, specified by initial and final points, number of
+ // tick marks. h/v_axis are identical except for style of tick marks.
+
+ // n subintervals
+ void h_axis(const P& tail, const P& head, unsigned int n,
+ epix_label_posn align=c);
+ void v_axis(const P& tail, const P& head, unsigned int n,
+ epix_label_posn align=c);
+
+ // Default endpoints (xmin(), 0), xmax(), 0), etc.
+ void h_axis(unsigned int n = xsize(), epix_label_posn align=c);
+ void v_axis(unsigned int n = ysize(), epix_label_posn align=c);
+
+ void h_log_axis(const P& tail, const P& head, unsigned int segs,
+ epix_label_posn align=c, unsigned int base=10);
+
+ void v_log_axis(const P& tail, const P& head, unsigned int segs,
+ epix_label_posn align=c, unsigned int base=10);
+
+} // end of namespace
+
+#endif /* EPIX_AXIS */
diff --git a/graphics/epix/bash_completions b/graphics/epix/bash_completions
new file mode 100644
index 0000000000..a05daab7e4
--- /dev/null
+++ b/graphics/epix/bash_completions
@@ -0,0 +1,8 @@
+# If you use Ian MacDonald's bash completion package, put these
+# lines in either /etc/bash_completions or $HOME/.bashrc to use
+# programmable completion with ePiX.
+#
+complete -f -X '!*.@(xp|flx|cc|c|C|cpp)' epix
+complete -f -X '!*.@(tex|dtx|ltx)' laps
+complete -f -X '!*.@(xp|flx|cc|c|C|cpp|eepic)' elaps
+complete -f -X '!*.@(flx|cc|c|C|cpp)' flix
diff --git a/graphics/epix/camera.cc b/graphics/epix/camera.cc
new file mode 100644
index 0000000000..0a70da081b
--- /dev/null
+++ b/graphics/epix/camera.cc
@@ -0,0 +1,318 @@
+/*
+ * camera.cc -- ePiX::camera functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "errors.h"
+#include "constants.h"
+
+#include "pairs.h"
+#include "triples.h"
+#include "frame.h"
+
+#include "functions.h"
+
+#include "halfspace.h"
+
+#include "lens.h"
+#include "camera.h"
+
+namespace ePiX {
+
+ // Need to initialize frame argument for Apple gcc; otherwise cam()
+ // gets null vectors in frame()...
+ Camera::Camera()
+ : the_viewpt(P(0,0,EPIX_INFTY)), the_target(P(0,0,0)),
+ the_orient(frame(E_1, E_2, E_3)),
+ the_distance(EPIX_INFTY), the_clip_range(MIN_CLIP),
+ the_filter(Neutral()), the_lens(new Perspective()) { }
+
+ // viewpt, target, orient
+ Camera::Camera(const P& vpt)
+ : the_viewpt(vpt), the_target(P(0,0,0)), the_clip_range(MIN_CLIP),
+ the_filter(Neutral())
+ {
+ if (the_viewpt == P(0,0,0))
+ {
+ epix_warning("Cannot initialize Camera at Origin, using (0, 0, oo)");
+ the_viewpt = P(0, 0, EPIX_INFTY);
+ }
+ P viewer(the_viewpt - the_target);
+ the_distance = norm(viewer);
+
+ viewer *= recip(norm(viewer));
+
+ // viewer is "eye", if possible E_3 is "sky"
+ P tmp_sea(E_3*viewer);
+
+ if (norm(tmp_sea) < EPIX_EPSILON) // we're on the "z-axis through vpt"
+ tmp_sea = E_1;
+
+ // eye*sea = sky
+ the_orient = frame(tmp_sea, viewer*tmp_sea, viewer);
+ adjust();
+
+ the_lens = new Perspective();
+ }
+
+
+ Camera::Camera(const Camera& cam)
+ : the_viewpt(cam.the_viewpt), the_target(cam.the_target),
+ the_orient(cam.the_orient), the_distance(cam.the_distance),
+ the_clip_range(cam.the_clip_range), the_filter(cam.the_filter),
+ the_lens(cam.the_lens->clone()) { }
+
+ Camera& Camera::operator= (const Camera& cam)
+ {
+ Lens* tmp_lens(cam.the_lens->clone());
+ the_lens = tmp_lens;
+
+ the_viewpt = cam.the_viewpt;
+ the_target = cam.the_target;
+ the_orient =cam.the_orient;
+ the_distance = cam.the_distance;
+ the_clip_range = cam.the_distance;
+
+ the_filter = cam.the_filter;
+
+ return *this;
+ }
+
+ Camera::~Camera()
+ {
+ delete the_lens;
+ }
+
+ // rotate up/down
+ Camera& Camera::tilt(double angle)
+ {
+ the_orient.rot1(-angle);
+ the_target = the_viewpt + (-the_distance)*the_orient.eye();
+ return *this;
+ }
+
+ // rotate left/right
+ Camera& Camera::pan(double angle)
+ {
+ the_orient.rot2(-angle);
+ the_target = the_viewpt + (-the_distance)*the_orient.eye();
+ return *this;
+ }
+
+ // rotate about viewing axis
+ Camera& Camera::roll(double angle)
+ {
+ the_orient.rot3(-angle); // target unchanged
+ return *this;
+ }
+
+ // fix target, move viewpt radially along eye()
+ Camera& Camera::range(double d)
+ {
+ if (d == 0)
+ d = EPIX_INFTY;
+
+ the_distance = d;
+ the_viewpt = the_target + d*the_orient.eye();
+
+ return *this;
+ }
+
+ // fix viewpt, move target radially along eye()
+ Camera& Camera::focus(double d)
+ {
+ if (d == 0)
+ d = EPIX_INFTY;
+
+ the_distance = d;
+ the_target = the_viewpt - d*the_orient.eye();
+
+ return *this;
+ }
+
+ // clip everything behind this
+ Camera& Camera::clip_range(double dist)
+ {
+ the_clip_range = (dist < MIN_CLIP ? MIN_CLIP : dist);
+ return *this;
+ }
+
+ // fix target, set viewpt
+ Camera& Camera::at(const P& vpt)
+ {
+ the_viewpt = vpt;
+ adjust();
+
+ return *this;
+ }
+
+ // fix viewpt, set target
+ Camera& Camera::look_at(const P& tgt)
+ {
+ the_target = tgt;
+ adjust();
+
+ return *this;
+ }
+
+ Camera& Camera::at(double x1, double x2, double x3)
+ {
+ the_viewpt = P(x1, x2, x3);
+ adjust();
+
+ return *this;
+ }
+
+ // fix viewpt, set target
+ Camera& Camera::look_at(double x1, double x2, double x3)
+ {
+ the_target = P(x1, x2, x3);
+ adjust();
+
+ return *this;
+ }
+
+ Camera& Camera::filter(const Color& filter)
+ {
+ the_filter=filter;
+ return *this;
+ }
+
+ Camera& Camera::perspective()
+ {
+ delete the_lens;
+ the_lens = new Perspective;
+ return *this;
+ }
+
+ Camera& Camera::orthog()
+ {
+ delete the_lens;
+ the_lens = new Orthog;
+ return *this;
+ }
+
+ Camera& Camera::fisheye()
+ {
+ delete the_lens;
+ the_lens = new Fisheye;
+ return *this;
+ }
+
+ Camera& Camera::bubble()
+ {
+ delete the_lens;
+ the_lens = new Bubble;
+ return *this;
+ }
+
+ Color Camera::operator() (const Color& in_color) const
+ {
+ Color temp = the_filter;
+ return temp.filter(in_color);
+ }
+
+ // lens interface
+ pair Camera::operator() (const P& arg) const
+ {
+ return (*the_lens)(arg, the_orient, the_viewpt, the_distance);
+ }
+
+ bool Camera::is_linear() const
+ {
+ return (*the_lens).is_linear();
+ }
+
+ bool Camera::needs_clip() const
+ {
+ return (*the_lens).needs_clip();
+ }
+
+
+ halfspace Camera::clip_plane() const
+ {
+ const P N(-the_orient.eye());
+ return halfspace(the_viewpt + the_clip_range*N, N);
+ }
+
+ P Camera::eye() const
+ {
+ return the_orient.eye();
+ }
+
+ P Camera::viewpt() const
+ {
+ return the_viewpt;
+ }
+
+ // private function
+ void Camera::adjust()
+ {
+ P temp(the_target - the_viewpt);
+ the_distance = norm(temp);
+
+ if (the_distance < EPIX_EPSILON)
+ {
+ epix_warning("Cannot make viewpoint and target the same, no action");
+ return;
+ }
+
+ // else
+ temp *= -1.0/the_distance; // reverse direction
+
+ double z_ht(temp|E_3);
+
+ // too close to "z-axis" through target?
+ if (sqrt((1-z_ht)*(1+z_ht)) < EPIX_EPSILON)
+ {
+ if (z_ht >= 0)
+ the_orient = frame();
+
+ else // z_ht < 0
+ the_orient = frame(-E_1, E_2, -E_3);
+ }
+
+ else // far enough from axis
+ the_orient = frame(P(-temp.x2(), temp.x1(), 0), E_3, temp);
+ }
+
+
+ Camera& cam()
+ {
+ static Camera* the_camera(new Camera());
+ return *the_camera;
+ }
+
+ Camera& camera(cam());
+
+} // end of namespace
diff --git a/graphics/epix/camera.h b/graphics/epix/camera.h
new file mode 100644
index 0000000000..87a3590db2
--- /dev/null
+++ b/graphics/epix/camera.h
@@ -0,0 +1,134 @@
+/*
+ * camera.h -- ePiX::Camera
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * A Camera has a location, orientation, lens, and color filter. The
+ * viewer sits at given <distance> from the <target>, in the direction
+ * of the <eye>. The vectors <sea> and <sky> point horizontally to the
+ * right and vertically upward on the screen. The viewing angle is
+ * controlled by changing the viewer, target, and/or the distance
+ * between them.
+ *
+ * The implementation data comprise:
+ * - a frame ({sea, sky, eye}, with the intuitive meanings:)
+ * - a viewpoint
+ * - a target (at the center of the field of view)
+ * - the distance from the viewpoint to the target
+ * - a "filter" color, Neutral by default, for color separation, etc.
+ * - a Lens
+ *
+ * A Lens is a mapping P -> pair. In the implementation, the Camera
+ * ("body") passes the orientation, target, and distance to the Lens
+ * operator.
+ */
+
+#ifndef EPIX_CAMERA
+#define EPIX_CAMERA
+
+#include "triples.h"
+#include "frame.h"
+#include "Color.h"
+
+namespace ePiX {
+
+ class halfspace;
+ class Lens;
+ class pair;
+
+ class Camera {
+ public:
+ Camera();
+ Camera(const P& vpt);
+
+ Camera(const Camera&);
+ Camera& operator= (const Camera&);
+ ~Camera();
+
+ // rotate
+ Camera& tilt(double angle); // up/down (pitch)
+ Camera& pan(double angle); // left/right (yaw)
+ Camera& roll(double angle); // about viewing axis
+
+ // fix target, move viewpt radially along eye()
+ Camera& range(double);
+ // fix viewpt, move target radially along eye()
+ Camera& focus(double);
+
+ // set clip distance
+ Camera& clip_range(double);
+
+ Camera& at(const P& arg); // fix target, set viewpt
+ Camera& look_at(const P& arg); // fix viewpt, set target
+
+ // alternative syntax
+ Camera& at(double, double, double);
+ Camera& look_at(double, double, double);
+
+ Camera& filter(const Color&);
+
+ // set lens
+ Camera& perspective(); // default
+ Camera& orthog(); // faster
+ Camera& fisheye();
+ Camera& bubble();
+
+ // Functions for internal use
+ // Camera maps
+ Color operator() (const Color&) const; // filter
+ pair operator() (const P&) const; // lens map
+ bool is_linear() const; // lens preserves lines?
+
+ bool needs_clip() const; // lens needs scene pre-clipping
+ halfspace clip_plane() const;
+
+ // situation
+ P eye() const;
+ P viewpt() const;
+
+ private:
+ P the_viewpt; // center of projection
+ P the_target; // mapped to Screen origin
+ frame the_orient; // our {sea, sky, eye}
+ double the_distance;
+ double the_clip_range;
+
+ Color the_filter;
+ void adjust(); // re-orient according to target, viewpt
+ Lens* the_lens;
+ }; // end of class Camera
+
+ // global Camera
+ Camera& cam();
+ extern Camera& camera;
+} // end of namespace
+
+#endif /* EPIX_CAMERA */
diff --git a/graphics/epix/circle.cc b/graphics/epix/circle.cc
new file mode 100644
index 0000000000..b81150587a
--- /dev/null
+++ b/graphics/epix/circle.cc
@@ -0,0 +1,197 @@
+/*
+ * circle.cc -- ePiX::Circle class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "errors.h"
+
+#include "constants.h"
+
+#include "triples.h"
+#include "state.h"
+
+#include "segment.h"
+#include "frame.h"
+#include "camera.h"
+
+#include "path.h"
+
+#include "paint_style.h"
+
+#include "intersections.h"
+
+#include "circle.h"
+
+namespace ePiX {
+
+ static const double EPS(EPIX_EPSILON);
+
+ Circle::Circle(const P& ctr, const double rad, const P& perp)
+ : m_center(ctr), m_radius(rad), m_perp(perp), m_malformed(false)
+ {
+ double temp(norm(perp));
+ if (temp < EPS)
+ {
+ epix_warning("Degenerate circle normal, using (0,0,1)");
+ m_perp=E_3;
+ }
+
+ else
+ m_perp *= (1.0/temp); // normalize
+ }
+
+ // point-and-center constructor -- parallel to (x1,x2,0)-plane
+ Circle::Circle(const P& ctr, const P& pt)
+ : m_center(ctr), m_radius(norm(pt - ctr)), m_perp(E_3), m_malformed(false)
+ {
+ if (fabs(E_3|(pt - ctr)) > EPS)
+ epix_warning("Circle requested with point not in (x,y) plane");
+ }
+
+ // three-point circle constructor
+ Circle::Circle(const P& pt1, const P& pt2, const P& pt3)
+ : m_malformed(false)
+ {
+ P D21(pt2-pt1), D31(pt3-pt1), D32(pt3-pt2), N(D21*D31);
+
+ if (norm(D21) < EPS ||
+ norm(D31) < EPS ||
+ norm(D32) < EPS ||
+ norm(N) < EPS)
+ {
+ epix_warning("Collinear points in Circle constructor");
+ m_malformed = true;
+ }
+
+ else
+ {
+ m_perp = (1.0/norm(N))*N;
+
+ P q2(0.5*(pt1+pt2));
+ P dir2(m_perp*(q2-pt1));
+
+ P q3(0.5*(pt1+pt3));
+ P dir3(m_perp*(q3-pt1));
+
+ m_center = Segment(q2, q2+dir2)*Segment(q3, q3+dir3);
+ m_radius = norm(m_center - pt1);
+ }
+ }
+
+
+ Circle::Circle(bool tag) : m_malformed(true) { }
+
+
+ P Circle::center() const
+ {
+ return m_center;
+ }
+
+ double Circle::radius() const
+ {
+ return m_radius;
+ }
+
+ P Circle::perp() const
+ {
+ return m_perp;
+ }
+
+ bool Circle::malformed() const
+ {
+ return m_malformed;
+ }
+
+ // translation
+ Circle& Circle::shift(const P& arg)
+ {
+ if (!m_malformed)
+ m_center += arg;
+ return *this;
+ }
+
+ Circle& Circle::move_to(const P& arg)
+ {
+ if (!m_malformed)
+ m_center = arg;
+ return *this;
+ }
+
+ // scale radius
+ Circle& Circle::scale(const double c)
+ {
+ if (!m_malformed)
+ m_radius *= c;
+ return *this;
+ }
+
+
+ // project to screen by camera
+ void Circle::draw() const
+ {
+ if (m_malformed)
+ return;
+
+ // else
+ double r(m_radius);
+ P N(m_perp);
+ frame axes; // standard basis
+
+ if (EPS <= norm(N*E_3))
+ axes = frame(E_3*N, E_3, N);
+
+ path data(m_center, r*(axes.sea()), r*(axes.sky()), 0, full_turn());
+ data.close().fill(the_paint_style().fill_flag());
+ data.draw();
+ }
+
+
+ //// global functions ////
+ void circle(const P& ctr, const double rad, const P& perp)
+ {
+ Circle C(ctr, rad, perp);
+ C.draw();
+ }
+
+ void circle(const P& ctr, const P& pt)
+ {
+ Circle C(ctr, pt);
+ C.draw();
+ }
+
+ void circle(const P& pt1, const P& pt2, const P& pt3)
+ {
+ Circle C(pt1, pt2, pt3);
+ C.draw();
+ }
+} // end of namespace
diff --git a/graphics/epix/circle.h b/graphics/epix/circle.h
new file mode 100644
index 0000000000..5d3e80dd72
--- /dev/null
+++ b/graphics/epix/circle.h
@@ -0,0 +1,94 @@
+/*
+ * circle.h -- ePiX::Circle class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides:
+ *
+ * The Circle class (center, radius, unit normal).
+ *
+ * - Circle() (defaults to origin, unit radius, in (x1,x2,0)-plane
+ * - Circle(ctr, pt) (parallel to (x1,x2,0)-plane, center ctr, through pt)
+ * - Circle(pt1, pt2, pt3) (arbitrary non-collinear points)
+ * - center(), radius(), perp()
+ * - affine operations: shift(P), move_to(P), scale(double)
+ * - draw() (ePiX ellipse)
+ */
+#ifndef EPIX_CIRCLE
+#define EPIX_CIRCLE
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class Circle {
+ public:
+ // defaults to unit circle in (x1,x2,0) plane
+ Circle(const P& ctr=P(0,0,0), double rad=1, const P& perp=E_3);
+
+ Circle(const P& ctr, const P& pt); // center, and point, normal = E_3
+ Circle(const P& pt1, const P& pt2, const P& pt3); // three points
+
+ Circle(bool); // malformed Circle for intersection operators
+
+ P center() const;
+ double radius() const;
+ P perp() const;
+
+ bool malformed() const;
+
+ // translate
+ Circle& shift(const P&);
+ Circle& move_to(const P&);
+ // scale radius by c
+ Circle& scale(double c);
+
+ void draw() const;
+
+ private:
+ P m_center;
+ double m_radius;
+ P m_perp; // unit normal, even if rad = 0
+
+ bool m_malformed;
+ }; // end of Circle class
+
+ // global object-drawing commands
+ void circle(const P& ctr=P(0,0,0), double rad=1, const P& perp=E_3);
+
+ void circle(const P& ctr, const P& pt); // center, and point, normal = E_3
+ void circle(const P& pt1, const P& pt2, const P& pt3); // three points
+
+} // end of namespace
+
+#endif /* EPIX_CIRCLE */
diff --git a/graphics/epix/clipping.cc b/graphics/epix/clipping.cc
new file mode 100644
index 0000000000..8da785d2f5
--- /dev/null
+++ b/graphics/epix/clipping.cc
@@ -0,0 +1,136 @@
+/*
+ * clipping.cc -- Implementation of ePiX's current drawing state
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.13
+ * Last Change: August 23, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+
+#include "constants.h"
+#include "triples.h"
+#include "functions.h"
+#include "clipping.h"
+
+namespace ePiX {
+
+ typedef std::list<halfspace>::const_iterator Hp;
+ static const double INF(EPIX_INFTY);
+
+ clip_state::clip_state(const P& arg1, const P& arg2)
+ {
+ double min1(min(arg1.x1(), arg2.x1())), max1(max(arg1.x1(), arg2.x1()));
+ double min2(min(arg1.x2(), arg2.x2())), max2(max(arg1.x2(), arg2.x2()));
+ double min3(min(arg1.x3(), arg2.x3())), max3(max(arg1.x3(), arg2.x3()));
+
+ double avg1(0.5*(min1+max1)), avg2(0.5*(min2+max2)), avg3(0.5*(min3+max3));
+
+ // inward-pointing faces of clip_box
+ m_walls.push_back(halfspace(P(max1,avg2,avg3), P(-1, 0, 0)));
+ m_walls.push_back(halfspace(P(min1,avg2,avg3), P( 1, 0, 0)));
+
+ m_walls.push_back(halfspace(P(avg1,max2,avg3), P( 0,-1, 0)));
+ m_walls.push_back(halfspace(P(avg1,min2,avg3), P( 0, 1, 0)));
+
+ m_walls.push_back(halfspace(P(avg1,avg2,max3), P( 0, 0,-1)));
+ m_walls.push_back(halfspace(P(avg1,avg2,min3), P( 0, 0, 1)));
+ }
+
+ clip_state::clip_state()
+ {
+ m_walls.push_back(halfspace(P( INF, 0, 0), P(-1, 0, 0)));
+ m_walls.push_back(halfspace(P(-INF, 0, 0), P( 1, 0, 0)));
+
+ m_walls.push_back(halfspace(P( 0, INF, 0), P( 0,-1, 0)));
+ m_walls.push_back(halfspace(P( 0,-INF, 0), P( 0, 1, 0)));
+
+ m_walls.push_back(halfspace(P( 0, 0, INF), P( 0, 0,-1)));
+ m_walls.push_back(halfspace(P( 0, 0,-INF), P( 0, 0, 1)));
+ }
+
+
+ clip_state& clip_state::add_face(const P& loc, const P& perp)
+ {
+ if (EPIX_EPSILON < norm(perp))
+ m_extras.push_back(halfspace(loc, perp));
+
+ return *this;
+ }
+
+
+ clip_state& clip_state::clear_extras()
+ {
+ m_extras.clear();
+
+ return *this;
+ }
+
+
+ bool clip_state::clips(const P& arg) const
+ {
+ for (Hp p=m_walls.begin(); p != m_walls.end(); ++p)
+ if ( (*p).clips(arg) )
+ return true;
+
+ for (Hp p=m_extras.begin(); p != m_extras.end(); ++p)
+ if ( (*p).clips(arg) )
+ return true;
+
+ return false;
+ }
+
+ // return reference to clipped argument
+ std::list<edge3d>& clip_state::clip_path(std::list<edge3d>& L) const
+ {
+ for (Hp p=m_walls.begin(); p != m_walls.end(); ++p)
+ (*p).clip_path(L);
+
+ for (Hp p=m_extras.begin(); p != m_extras.end(); ++p)
+ (*p).clip_path(L);
+
+ return L;
+ }
+
+ std::list<edge3d>& clip_state::clip_loop(std::list<edge3d>& L) const
+ {
+ for (Hp p=m_walls.begin(); p != m_walls.end(); ++p)
+ (*p).clip_loop(L);
+
+ for (Hp p=m_extras.begin(); p != m_extras.end(); ++p)
+ (*p).clip_loop(L);
+
+ return L;
+ }
+
+ clip_state& the_clip_box()
+ {
+ static clip_state* the_clip_state(new clip_state());
+ return *the_clip_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/clipping.h b/graphics/epix/clipping.h
new file mode 100644
index 0000000000..bec60a3801
--- /dev/null
+++ b/graphics/epix/clipping.h
@@ -0,0 +1,77 @@
+/*
+ * clipping.h -- ePiX's clip box
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.13
+ * Last Change: August 23, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h. This header is not part of epix.h.
+ */
+#ifndef EPIX_CLIPPING
+#define EPIX_CLIPPING
+
+#include <string>
+
+#include "edge_data.h"
+#include "halfspace.h"
+
+namespace ePiX {
+
+ class P;
+
+ class clip_state {
+ public:
+ // create inward-pointing faces of clip_box
+ clip_state(const P& arg1, const P& arg2);
+ clip_state(); // very large box by default
+
+ // add and remove faces
+ clip_state& add_face(const P& loc, const P& perp);
+ clip_state& clear_extras();
+
+ bool clips(const P&) const;
+
+ // return reference to clipped argument
+ std::list<edge3d>& clip_path(std::list<edge3d>&) const;
+ std::list<edge3d>& clip_loop(std::list<edge3d>&) const;
+
+ private:
+ std::list<halfspace> m_walls; // always present
+
+ std::list<halfspace> m_extras; // user-added
+ }; // end of class clip_state
+
+ clip_state& the_clip_box();
+
+} // end of namespace
+
+#endif /* EPIX_CLIPPING */
diff --git a/graphics/epix/config.guess b/graphics/epix/config.guess
new file mode 100644
index 0000000000..c38553dc74
--- /dev/null
+++ b/graphics/epix/config.guess
@@ -0,0 +1,1497 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file 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.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS_NT-*:*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ x86:Interix*:[345]*)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T:Interix*:[345]*)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/graphics/epix/config.sub b/graphics/epix/config.sub
new file mode 100644
index 0000000000..ad9f395711
--- /dev/null
+++ b/graphics/epix/config.sub
@@ -0,0 +1,1608 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file 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.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | mt \
+ | msp430 \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m32c)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ m32c-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/graphics/epix/configure b/graphics/epix/configure
new file mode 100644
index 0000000000..14efb92c86
--- /dev/null
+++ b/graphics/epix/configure
@@ -0,0 +1,6396 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.60 for epix 1.2.1.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell autoconf@gnu.org about your system,
+ echo including any error possibly output before this
+ echo message
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works. Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ as_executable_p="test -x"
+else
+ as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='epix'
+PACKAGE_TARNAME='epix'
+PACKAGE_VERSION='1.2.1'
+PACKAGE_STRING='epix 1.2.1'
+PACKAGE_BUGREPORT=''
+
+ac_unique_file="utils.h"
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+CYGPATH_W
+PACKAGE
+VERSION
+ACLOCAL
+AUTOCONF
+AUTOMAKE
+AUTOHEADER
+MAKEINFO
+install_sh
+STRIP
+INSTALL_STRIP_PROGRAM
+mkdir_p
+AWK
+SET_MAKE
+am__leading_dot
+AMTAR
+am__tar
+am__untar
+MAINTAINER_MODE_TRUE
+MAINTAINER_MODE_FALSE
+MAINT
+CXX
+CXXFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CXX
+EXEEXT
+OBJEXT
+DEPDIR
+am__include
+am__quote
+AMDEP_TRUE
+AMDEP_FALSE
+AMDEPBACKSLASH
+CXXDEPMODE
+am__fastdepCXX_TRUE
+am__fastdepCXX_FALSE
+LN_S
+RANLIB
+ENABLE_EPIX_EL_TRUE
+ENABLE_EPIX_EL_FALSE
+BASH_PATH
+RUNTIME_COMPILER
+CC
+CFLAGS
+ac_ct_CC
+CCDEPMODE
+am__fastdepCC_TRUE
+am__fastdepCC_FALSE
+CPP
+GREP
+EGREP
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval enable_$ac_feature=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval enable_$ac_feature=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval with_$ac_package=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval with_$ac_package=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { echo "$as_me: error: Working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures epix 1.2.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/epix]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of epix 1.2.1:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-epix-el Install emacs mode for ePiX files
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-bash=<bash> The path to bash
+ --with-runtime=<g++> The runtime compiler
+
+Some influential environment variables:
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CC C compiler command
+ CFLAGS C compiler flags
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" || continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+epix configure 1.2.1
+generated by GNU Autoconf 2.60
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by epix $as_me 1.2.1, which was
+generated by GNU Autoconf 2.60. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+ set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+ set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+ set x "$ac_default_prefix/share/config.site" \
+ "$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+am__api_version="1.9"
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm -f conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ SET_MAKE=
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='epix'
+ VERSION='1.2.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; }
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort. b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions. Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cxx_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cxx_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+{ echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CXX" am_compiler_list=
+
+{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6; }
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ SET_MAKE=
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Check whether --enable-epix-el was given.
+if test "${enable_epix_el+set}" = set; then
+ enableval=$enable_epix_el; enable_epix_el=${enableval-yes}
+else
+ enable_epix_el=yes
+fi
+
+
+
+if test "$enable_epix_el" = yes; then
+ ENABLE_EPIX_EL_TRUE=
+ ENABLE_EPIX_EL_FALSE='#'
+else
+ ENABLE_EPIX_EL_TRUE='#'
+ ENABLE_EPIX_EL_FALSE=
+fi
+
+
+# Extract the first word of "bash", so it can be a program name with args.
+set dummy bash; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_BASH_PATH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $BASH_PATH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BASH_PATH="$BASH_PATH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_BASH_PATH="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_BASH_PATH" && ac_cv_path_BASH_PATH="/bin/bash"
+ ;;
+esac
+fi
+BASH_PATH=$ac_cv_path_BASH_PATH
+if test -n "$BASH_PATH"; then
+ { echo "$as_me:$LINENO: result: $BASH_PATH" >&5
+echo "${ECHO_T}$BASH_PATH" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+# Check whether --with-bash was given.
+if test "${with_bash+set}" = set; then
+ withval=$with_bash; BASH_PATH=$withval
+fi
+
+
+# Extract the first word of "g++", so it can be a program name with args.
+set dummy g++; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_RUNTIME_COMPILER+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $RUNTIME_COMPILER in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RUNTIME_COMPILER="$RUNTIME_COMPILER" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_RUNTIME_COMPILER="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_RUNTIME_COMPILER" && ac_cv_path_RUNTIME_COMPILER="g++"
+ ;;
+esac
+fi
+RUNTIME_COMPILER=$ac_cv_path_RUNTIME_COMPILER
+if test -n "$RUNTIME_COMPILER"; then
+ { echo "$as_me:$LINENO: result: $RUNTIME_COMPILER" >&5
+echo "${ECHO_T}$RUNTIME_COMPILER" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+# Check whether --with-runtime was given.
+if test "${with_runtime+set}" = set; then
+ withval=$with_runtime; RUNTIME_COMPILER=$withval
+fi
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet. If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+ xno)
+ { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC" am_compiler_list=
+
+{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
+ # Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+ $ac_path_GREP_found && break 3
+ done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+ { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
+ # Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+ $ac_path_EGREP_found && break 3
+ done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+ { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !x[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_c_const=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+{ echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6; }
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6; }
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+
+for ac_func in strtod
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ac_config_files="$ac_config_files Makefile samples/Makefile doc/Makefile"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${ENABLE_EPIX_EL_TRUE}" && test -z "${ENABLE_EPIX_EL_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"ENABLE_EPIX_EL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"ENABLE_EPIX_EL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works. Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ as_executable_p="test -x"
+else
+ as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by epix $as_me 1.2.1, which was
+generated by GNU Autoconf 2.60. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+epix config.status 1.2.1
+configured by $0, generated by GNU Autoconf 2.60,
+ with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ CONFIG_SHELL=$SHELL
+ export CONFIG_SHELL
+ exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+CYGPATH_W!$CYGPATH_W$ac_delim
+PACKAGE!$PACKAGE$ac_delim
+VERSION!$VERSION$ac_delim
+ACLOCAL!$ACLOCAL$ac_delim
+AUTOCONF!$AUTOCONF$ac_delim
+AUTOMAKE!$AUTOMAKE$ac_delim
+AUTOHEADER!$AUTOHEADER$ac_delim
+MAKEINFO!$MAKEINFO$ac_delim
+install_sh!$install_sh$ac_delim
+STRIP!$STRIP$ac_delim
+INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim
+mkdir_p!$mkdir_p$ac_delim
+AWK!$AWK$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+am__leading_dot!$am__leading_dot$ac_delim
+AMTAR!$AMTAR$ac_delim
+am__tar!$am__tar$ac_delim
+am__untar!$am__untar$ac_delim
+MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim
+MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim
+MAINT!$MAINT$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+DEPDIR!$DEPDIR$ac_delim
+am__include!$am__include$ac_delim
+am__quote!$am__quote$ac_delim
+AMDEP_TRUE!$AMDEP_TRUE$ac_delim
+AMDEP_FALSE!$AMDEP_FALSE$ac_delim
+AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim
+CXXDEPMODE!$CXXDEPMODE$ac_delim
+am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
+am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
+LN_S!$LN_S$ac_delim
+RANLIB!$RANLIB$ac_delim
+ENABLE_EPIX_EL_TRUE!$ENABLE_EPIX_EL_TRUE$ac_delim
+ENABLE_EPIX_EL_FALSE!$ENABLE_EPIX_EL_FALSE$ac_delim
+BASH_PATH!$BASH_PATH$ac_delim
+RUNTIME_COMPILER!$RUNTIME_COMPILER$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+CCDEPMODE!$CCDEPMODE$ac_delim
+am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
+am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
+CPP!$CPP$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+ ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+ ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in :F $CONFIG_FILES :C $CONFIG_COMMANDS
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ ac_file_inputs="$ac_file_inputs $ac_f"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input="Generated from "`IFS=:
+ echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ fi
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin";;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out"; rm -f "$tmp/out";;
+ *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+ esac
+ ;;
+
+
+ :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5
+echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir=$dirpart/$fdir
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+
+ esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/graphics/epix/configure.ac b/graphics/epix/configure.ac
new file mode 100644
index 0000000000..b751aa69c4
--- /dev/null
+++ b/graphics/epix/configure.ac
@@ -0,0 +1,58 @@
+dnl Process this file with autoconf 2.60 or later
+dnl to produce a configure script.
+AC_INIT(epix, 1.2.1)
+AC_PREREQ(2.60)
+AC_CONFIG_SRCDIR(utils.h)
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
+dnl Checks for programs.
+AC_PROG_CXX
+AC_PROG_LN_S
+AC_PROG_RANLIB
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+dnl User may request epix.el non-installation
+AC_ARG_ENABLE(epix-el,
+ AS_HELP_STRING([--enable-epix-el],
+ [Install emacs mode for ePiX files]),
+ enable_epix_el=${enableval-yes},
+ enable_epix_el=yes)
+AM_CONDITIONAL(ENABLE_EPIX_EL, [test "$enable_epix_el" = yes])
+
+dnl For all shell scripts
+AC_PATH_PROG(BASH_PATH, bash, /bin/bash)
+AC_ARG_WITH(bash,
+ AS_HELP_STRING([--with-bash=<bash>],
+ [The path to bash]),
+ BASH_PATH=$withval)
+
+dnl For epix and flix
+AC_PATH_PROG(RUNTIME_COMPILER, g++, g++)
+AC_ARG_WITH(runtime,
+ AS_HELP_STRING([--with-runtime=<g++>],
+ [The runtime compiler]),
+ RUNTIME_COMPILER=$withval)
+
+dnl AC_ARG_WITH(contrib,
+dnl AS_HELP_STRING([--with-contrib],
+dnl [Build contributed code and docs]))
+dnl AM_CONDITIONAL(BUILD_CONTRIB, [test "$with_contrib" = yes])
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS(strtod)
+
+AC_CONFIG_FILES([Makefile samples/Makefile doc/Makefile])
+dnl contrib/Makefile contrib/doc/Makefile])
+
+AC_OUTPUT
diff --git a/graphics/epix/constants.h b/graphics/epix/constants.h
new file mode 100644
index 0000000000..c888c1d4da
--- /dev/null
+++ b/graphics/epix/constants.h
@@ -0,0 +1,108 @@
+/*
+ * constants.h -- ePiX's hidden compile-time constants
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_CONSTANTS
+#define EPIX_CONSTANTS
+
+#include "length.h"
+
+namespace ePiX {
+
+ // See lengths.cc for units conversion factors
+
+ //// Style Parameters -- min, default, max ////
+ // standard pen widths
+ const length PLAIN_WIDTH("0.4pt");
+ const length BOLD_WIDTH("0.8pt");
+ const length BBOLD_WIDTH("1.2pt");
+
+
+ // dot diam in pt
+ const double MIN_DOT(1);
+ const double AVG_DOT(4);
+ const double MAX_DOT(36);
+
+ // page length of dash pattern in pt
+ const double MIN_SEP(4);
+ const double AVG_SEP(12);
+ const double MAX_SEP(36);
+
+ // axis tick half-lengths
+ const double MIN_TICK(1);
+ const double AVG_TICK(3);
+ const double MAX_TICK(8);
+
+ // arrow head parameters
+ const double MIN_AWIDTH(1);
+ const double AVG_AWIDTH(3);
+ const double MAX_AWIDTH(12);
+
+ const double MIN_ARATIO(1);
+ const double AVG_ARATIO(5.5);
+ const double MAX_ARATIO(8);
+
+ const double MIN_INSET(-1);
+ const double AVG_INSET(0);
+ const double MAX_INSET(0.95); // not 1, so head can be hatched
+
+
+ // too small/large
+ const double EPIX_EPSILON(0.0001); // 10^-4 (prints as decimal)
+ const double EPIX_INFTY(100000.0); // 10^5
+
+ // Numerical constants
+ const double PI_180(0.01745329251994329577);
+ const double TWO_PI(6.28318530717958647692);
+
+ // smallest distance from camera to clipping plane
+ const double MIN_CLIP(0.01);
+
+ // No more than this many minor ticks per segment in log axis
+ const unsigned int MAX_LOG_BASE(100);
+
+ // For output
+ const unsigned int DEF_PRECISION(6);
+ const unsigned int MAX_PRECISION(20);
+
+ // In calculus plotting, the interval between adjacent points is too large
+ // for accuracy. Divide each such interval into this many subintervals
+ const unsigned int EPIX_ITERATIONS(200);
+
+ // Output-formatting constants:
+ const unsigned int EPIX_NUM_PTS(120); // # of points in ellipses, splines
+ const unsigned int EPIX_FILE_WIDTH(70); // Width of output file
+
+} // end of namespace
+
+#endif /* EPIX_CONSTANTS */
diff --git a/graphics/epix/crop_algorithms.h b/graphics/epix/crop_algorithms.h
new file mode 100644
index 0000000000..e81646958e
--- /dev/null
+++ b/graphics/epix/crop_algorithms.h
@@ -0,0 +1,225 @@
+/*
+ * crop_algorithms.h -- clipping/cropping templates
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 31, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines list<edge> manipulating template functions and
+ * associated utilities. Each chop function returns a reference to its
+ * list<edge> argument.
+ *
+ * double height(perp, base, arg)
+ * PT cut_location(perp, base, tail, head)
+ * cull(edges) // remove edges whose tail and head are equal
+ * loopify(edges) // replace contiguous unseen edges with one seen edge
+ * chop_path(perp, base, edges) // cull to a halfspace/halfplane
+ * chop_loop(perp, base, edges) // same, for loops
+ */
+
+#ifndef EPIX_CROP_ALGO
+#define EPIX_CROP_ALGO
+
+#include <list>
+
+#include "constants.h"
+
+namespace ePiX {
+
+ // perp assumed to be *unit*
+ template <typename PT>
+ double height(const PT& perp, const PT& base, const PT& arg)
+ {
+ // return (perp|(operator-(arg, base)));
+ return (perp|(arg - base));
+ }
+
+ // no check for parallel
+ template <typename PT>
+ PT cut_location(const PT& perp, const PT& base, const PT& p1, const PT& p2)
+ {
+ // PT dir(operator-(p2, p1)); // -dir to base
+ // return p1 + (((operator-(base, p1))|perp)/(dir|perp))*dir;
+ PT dir(p2 - p1); // -dir to base
+ return p1 + (((base - p1)|perp)/(dir|perp))*dir;
+ }
+
+ // remove edges whose tail, head are equal
+ template <typename PT>
+ std::list<edge_data<PT> >& cull(std::list<edge_data<PT> >& edges)
+ {
+ typename std::list<edge_data<PT> >::iterator ep(edges.begin());
+
+ while (ep != edges.end())
+ {
+ if ((*ep).is_null())
+ ep = edges.erase(ep);
+
+ else
+ ++ep;
+ }
+
+ return edges;
+ }
+
+ template <typename PT>
+ std::list<edge_data<PT> >& loopify(std::list<edge_data<PT> >& edges)
+ {
+ if (edges.begin() == edges.end())
+ return edges;
+
+ typename std::list<edge_data<PT> >::iterator ep(edges.begin());
+ bool in_path(false); // currently in a visible sublist?
+
+ // After first pass, ep points to first visible edge
+ while (ep != edges.end())
+ {
+ if (!(*ep).is_seen()) // invisible edge
+ {
+ ep=edges.erase(ep);
+ in_path=false;
+ continue;
+ }
+
+ // else visible edge
+ if (in_path)
+ {
+ ++ep;
+ continue;
+ }
+
+ // else
+ in_path=true;
+ if (ep != edges.begin()) // join our tail to previous head
+ {
+ typename std::list<edge_data<PT> >::iterator prev(ep);
+ --prev;
+ ep = edges.insert(ep, edge_data<PT>((*prev).head(),
+ (*ep).tail(),
+ true));
+ ++ep;
+ ++ep;
+ }
+ }
+
+ // all edges examined; if we contain multiple edges, close final cut
+ ep = edges.begin();
+ // contains at most one edge
+ if (ep == edges.end())
+ ; // return below
+
+ else if (++ep == edges.end())
+ edges.erase(edges.begin());
+
+ else
+ {
+ ep = edges.end();
+ --ep;
+ edges.push_back(edge_data<PT>((*ep).head(),
+ (*edges.begin()).tail(),
+ true));
+ }
+
+ return edges;
+ } // end of loopify()
+
+
+ // return result of clipping edges to half space/plane through base
+ // with unit inward normal perp
+ template <typename PT>
+ std::list<edge_data<PT> >& chop_path(const PT& perp, const PT& base,
+ std::list<edge_data<PT> >& edges)
+ {
+ typename std::list<edge_data<PT> >::iterator ep(edges.begin());
+
+ while(ep != edges.end())
+ {
+ if (!(*ep).is_seen())
+ {
+ ++ep;
+ continue;
+ }
+
+ // else
+ const PT tail((*ep).tail());
+ const PT head((*ep).head());
+
+ const double ht_tail(height(perp, base, tail));
+ const double ht_head(height(perp, base, head));
+
+ // non-crossings:
+ // unclipped
+ if (-EPIX_EPSILON < ht_tail && -EPIX_EPSILON < ht_head)
+ {
+ ++ep;
+ continue;
+ }
+
+ // clipped
+ else if (ht_tail <= 0 && ht_head <= 0)
+ {
+ (*ep).seen(false);
+ ++ep;
+ continue;
+ }
+
+ // else one end below -EPS, one above 0; split edge
+ const PT crossing(cut_location(perp, base, tail, head));
+
+ // visibility of segments
+ bool vis_tail(false), vis_head(true);
+
+ if (0 < ht_tail)
+ {
+ vis_tail=true;
+ vis_head=false;
+ }
+
+ ep = edges.erase(ep);
+ ep=edges.insert(ep, edge_data<PT>(crossing, head, vis_head));
+ ep=edges.insert(ep, edge_data<PT>(tail, crossing, vis_tail));
+ ++ep;
+ ++ep;
+ } // all edges examined
+
+ return cull(edges);
+ } // end of chop_path()
+
+
+ template <typename PT>
+ std::list<edge_data<PT> >& chop_loop(const PT& perp, const PT& base,
+ std::list<edge_data<PT> >& edges)
+ {
+ return loopify(chop_path(perp, base, edges));
+ }
+} // end of namespace
+
+#endif /* EPIX_CROP_ALGO */
diff --git a/graphics/epix/cropping.cc b/graphics/epix/cropping.cc
new file mode 100644
index 0000000000..3bc89a030b
--- /dev/null
+++ b/graphics/epix/cropping.cc
@@ -0,0 +1,88 @@
+/*
+ * state_data.cc -- Implementation of ePiX's current drawing state
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.4
+ * Last Change: June 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines (wrapper functions for) static objects that hold
+ * the current drawing state
+ */
+
+#include <list>
+
+#include "constants.h"
+#include "screen_mask.h"
+#include "mask_ellipse.h"
+#include "mask_rectangle.h"
+
+#include "cropping.h"
+
+namespace ePiX {
+
+ crop_state::crop_state(const crop_state& cs)
+ : crop_state_mask(cs.crop_state_mask->clone()) { }
+
+ crop_state& crop_state::operator= (const crop_state& cs)
+ {
+ if (this != &cs)
+ {
+ screen_mask* tmp(cs.crop_state_mask->clone());
+
+ delete crop_state_mask;
+ crop_state_mask=tmp;
+ }
+
+ return *this;
+ }
+
+ crop_state::~crop_state()
+ {
+ delete crop_state_mask;
+ }
+
+ std::list<edge2d>& crop_state::crop_path(std::list<edge2d>& L) const
+ {
+ return crop_state_mask->crop_path(L);
+ }
+
+ std::list<edge2d>& crop_state::crop_loop(std::list<edge2d>& L) const
+ {
+ return crop_state_mask->crop_loop(L);
+ }
+
+ crop_state& the_crop_box()
+ {
+ const pair M(EPIX_INFTY, EPIX_INFTY);
+ static crop_state* current_crop_box(new crop_state(mask_rectangle(-M,M)));
+ return *current_crop_box;
+ }
+} // end of namespace
diff --git a/graphics/epix/cropping.h b/graphics/epix/cropping.h
new file mode 100644
index 0000000000..b8885e528b
--- /dev/null
+++ b/graphics/epix/cropping.h
@@ -0,0 +1,68 @@
+/*
+ * cropping.h -- Implementation of ePiX's current drawing state.
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 07, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h. This header is not part of epix.h.
+ */
+#ifndef EPIX_CROPPING
+#define EPIX_CROPPING
+
+#include <string>
+
+#include "edge_data.h"
+#include "screen_mask.h"
+
+namespace ePiX {
+
+ class crop_state {
+ public:
+ crop_state(const screen_mask& M)
+ : crop_state_mask(M.clone()) { }
+
+ crop_state(const crop_state&);
+ crop_state& operator= (const crop_state&);
+ ~crop_state();
+
+ std::list<edge2d>& crop_path(std::list<edge2d>&) const;
+ std::list<edge2d>& crop_loop(std::list<edge2d>&) const;
+
+ private:
+ screen_mask* crop_state_mask;
+
+ }; // end of class crop_state
+
+} // end of namespace
+
+#endif /* EPIX_CROPPING */
diff --git a/graphics/epix/curves.cc b/graphics/epix/curves.cc
new file mode 100644
index 0000000000..5783dcf83c
--- /dev/null
+++ b/graphics/epix/curves.cc
@@ -0,0 +1,663 @@
+/*
+ * curves.cc -- polygons, ellipses, circular arcs, splines
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+
+#include "constants.h"
+#include "triples.h"
+#include "errors.h"
+
+#include "functions.h"
+#include "pairs.h"
+
+#include "camera.h"
+
+#include "active_screen.h"
+#include "screen.h"
+
+#include "paint_style.h"
+
+#include "state.h"
+#include "domain.h"
+
+#include "arrow_data.h"
+#include "path.h"
+#include "picture.h"
+
+#include "spline.h"
+#include "spline_data.h"
+#include "curves.h"
+
+namespace ePiX {
+
+ // Simple geometric objects
+
+ // Lines take a stretch factor, roughly in percent
+ void line(const P& tail, const P& head, double expand)
+ {
+ unsigned int num_pts(cam().is_linear() ? 2 : EPIX_NUM_PTS);
+
+ path data(tail, head, expand, num_pts);
+ data.draw();
+ }
+
+ void line(const P& tail, const P& head, double expand,
+ unsigned int num_pts)
+ {
+ if (!cam().is_linear())
+ num_pts = (unsigned int) max(num_pts, EPIX_NUM_PTS);
+
+ path data(tail, head, expand, num_pts);
+ data.draw();
+ }
+
+ // Line(p1, p2) -- draw uncropped portion of long line through p1, p2
+ void Line(const P& arg1, const P& arg2)
+ {
+ P dir(arg2-arg1);
+ const double denom(norm(dir));
+
+ if (EPIX_EPSILON < denom)
+ {
+ // TO DO: Not as robust as could be:
+ // 1. Assumes endpoint(s) are fairly close to origin
+ // 2. May not handle non-linear lenses well
+ dir *= 1/denom;
+ line(arg1-EPIX_INFTY*dir, arg1+EPIX_INFTY*dir);
+ }
+ } // end of Line
+
+
+ // point-slope form
+ void Line(const P& tail, double slope)
+ {
+ Line(tail, tail+P(1, slope, 0));
+ }
+
+
+ void triangle(const P& p1, const P& p2, const P& p3)
+ {
+ path data;
+ if (cam().is_linear())
+ data.pt(p1).pt(p2).pt(p3);
+ else
+ {
+ // Magic number 60
+ const unsigned int N(60);
+ const double dt(1.0/N);
+
+ const P step12(dt*(p2-p1));
+ const P step23(dt*(p3-p2));
+ const P step31(dt*(p1-p3));
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p1 + i*step12);
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p2 + i*step23);
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p3 + i*step31);
+ }
+
+ data.close().fill(the_paint_style().fill_flag());
+ data.draw();
+ }
+
+ void quad(const P& p1, const P& p2, const P& p3, const P& p4)
+ {
+ path data;
+ if (cam().is_linear())
+ data.pt(p1).pt(p2).pt(p3).pt(p4);
+ else
+ {
+ // Magic number 60 -> quad has 240 pts, is printed in one segment
+ const unsigned int N(60);
+ const double dt(1.0/N);
+
+ const P step12(dt*(p2-p1));
+ const P step23(dt*(p3-p2));
+ const P step34(dt*(p4-p3));
+ const P step41(dt*(p1-p4));
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p1 + i*step12);
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p2 + i*step23);
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p3 + i*step34);
+
+ for (unsigned int i=0; i<N; ++i)
+ data.pt(p4 + i*step41);
+ }
+
+ data.close().fill(the_paint_style().fill_flag());
+ data.draw();
+ }
+
+ // Draw coordinate rectangle with opposite corners as given. Arguments
+ // must lie is a plane parallel to a coordinate plane, but not on a
+ // line parallel to a coordinate axis.
+
+ void rect(const P& p1, const P& p2)
+ {
+ P diagonal(p2 - p1);
+ P jump;
+ int perp_count(0);
+
+ // count coordinate axes perp to diagonal and flag normal
+ if (fabs(diagonal|E_1) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump = E_2&(diagonal);
+ }
+ if (fabs(diagonal|E_2) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump = E_3&(diagonal);
+ }
+ if (fabs(diagonal|E_3) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump = E_1&(diagonal);
+ }
+
+ quad(p1, p1+jump, p2, p2-jump);
+ } // end rect
+
+ void dart(const P& tail, const P& head)
+ {
+ arrow(tail, head, 0.5);
+ }
+
+ void aarrow(const P& tail, const P& head, double scale)
+ {
+ P midpt(0.5*(tail+head));
+ arrow(midpt, tail, scale);
+ arrow(midpt, head, scale);
+ }
+
+ void ellipse(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ path data(center, axis1, axis2, t_min, t_max, num_pts);
+
+
+ if (min(fabs(t_max-t_min)/full_turn(), 1) == 1)
+ {
+ data.close();
+ if (the_paint_style().fill_flag())
+ data.fill();
+ }
+ data.draw();
+ }
+
+ void ellipse(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max)
+ {
+ ellipse(center, axis1, axis2, t_min, t_max, EPIX_NUM_PTS);
+ }
+
+
+ void ellipse(const P& center, const P& axis1, const P& axis2)
+ {
+ ellipse(center, axis1, axis2, 0, full_turn());
+ }
+
+
+ void ellipse_arc(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max)
+ {
+ ellipse(center, axis1, axis2, t_min, t_max);
+ }
+
+
+ void arrow(const P& tail, const P& head, double scale)
+ {
+ std::vector<P> shaft(2);
+ shaft.at(0) = tail;
+ shaft.at(1) = head;
+
+ arrow_data data(shaft, tail, head, scale);
+ data.draw();
+ }
+
+ void ellipse(const P& center, const P& radius)
+ {
+ ellipse(center, radius.x1()*E_1, radius.x2()*E_2);
+ }
+
+ // Standard half-ellipse functions
+ void ellipse_left (const P& center, const P& radius)
+ {
+ ellipse(center, radius.x1()*E_1, radius.x2()*E_2,
+ 0.25*full_turn(), 0.75*full_turn());
+ }
+
+ void ellipse_right (const P& center, const P& radius)
+ {
+ ellipse(center, radius.x1()*E_1, radius.x2()*E_2,
+ -0.25*full_turn(), 0.25*full_turn());
+ }
+
+ void ellipse_top (const P& center, const P& radius)
+ {
+ ellipse(center, radius.x1()*E_1, radius.x2()*E_2, 0, 0.5*full_turn());
+ }
+
+ void ellipse_bottom (const P& center, const P& radius)
+ {
+ ellipse(center, radius.x1()*E_1, radius.x2()*E_2, -0.5*full_turn(), 0);
+ }
+
+ void arc(const P& center, double r,
+ double start, double finish)
+ {
+ ellipse(center, r*E_1, r*E_2, start, finish);
+ }
+
+ void arrow(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max, double scale)
+ {
+ // EPIX_NUM_PTS pts = one full turn; scale accordingly
+ double frac(fabs(t_max-t_min)/full_turn());
+ unsigned int num_pts((unsigned int) max(2, ceil(frac*EPIX_NUM_PTS)));
+
+ const double dt((t_max - t_min)/num_pts);
+
+ std::vector<P> shaft(num_pts+1);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ {
+ double t(t_min + i*dt);
+ shaft.at(i) = center + ((Cos(t)*axis1)+(Sin(t)*axis2));
+ }
+
+ arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale);
+ data.draw();
+ }
+
+ // circular arcs parallel to (x,y)-plane
+
+ void arc_arrow(const P& center, double r,
+ double start, double finish, double scale)
+ {
+ arrow(center, r*E_1, r*E_2, start, finish, scale);
+ }
+
+
+ // quadratic spline
+ void spline(const P& p1, const P& p2, const P& p3, unsigned int num_pts)
+ {
+ path data(p1, p2, p3, num_pts);
+ data.draw();
+ }
+
+ void spline(const P& p1, const P& p2, const P& p3)
+ {
+ spline(p1, p2, p3, EPIX_NUM_PTS);
+ }
+
+ void arrow(const P& p1, const P& p2, const P& p3, double scale)
+ {
+ const unsigned int num_pts(EPIX_NUM_PTS);
+ const double dt(1.0/num_pts);
+ std::vector<P> shaft(num_pts+1);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ shaft.at(i) = spl_pt(p1, p2, p3, i*dt);
+
+ arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale);
+ data.draw();
+ }
+
+ // cubic spline
+ void spline(const P& p1, const P& p2,
+ const P& p3, const P& p4, unsigned int num_pts)
+ {
+ path data(p1, p2, p3, p4, num_pts);
+ data.draw();
+ }
+
+ void spline(const P& p1, const P& p2, const P& p3, const P& p4)
+ {
+ spline(p1, p2, p3, p4, EPIX_NUM_PTS);
+ }
+
+ // natural spline through points
+ void spline(const std::vector<P>& data, unsigned int num_pts)
+ {
+ n_spline tmp(data, data.at(0) == data.at(data.size()-1));
+ path trace(tmp.data(num_pts));
+
+ trace.draw();
+ }
+
+ void arrow(const P& p1, const P& p2, const P& p3, const P& p4, double scale)
+ {
+ const unsigned int num_pts(EPIX_NUM_PTS);
+ const double dt(1.0/num_pts);
+ std::vector<P> shaft(num_pts+1);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ shaft.at(i) = spl_pt(p1, p2, p3, p4, i*dt);
+
+ arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale);
+ data.draw();
+ }
+
+
+ // n1 x n2 Cartesian grid, where coarse = (n1, n2)
+ void grid(const P& p1, const P& p2, mesh coarse, mesh fine)
+ {
+ P diagonal(p2 - p1);
+ P jump1, jump2; // sides of grid
+
+ int perp_count(0);
+
+ int N1(coarse.n1());
+ int N2(coarse.n2());
+
+ // count coordinate axes diagonal is perp to and flag normal
+ if (fabs(diagonal|E_1) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_2&diagonal;
+ jump2 = E_3&diagonal;
+
+ }
+ if (fabs(diagonal|E_2) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_3&diagonal;
+ jump2 = E_1&diagonal;
+ }
+ if (fabs(diagonal|E_3) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_1&diagonal;
+ jump2 = E_2&diagonal;
+ }
+
+ if (perp_count != 1)
+ epix_warning("Ignoring degenerate coordinate grid");
+
+ else
+ {
+ // grid line spacing
+ P grid_step1((1.0/N1)*jump1);
+ P grid_step2((1.0/N2)*jump2);
+
+ // makes grid subject to filling
+ rect(p1, p1 + jump1 + jump2);
+
+ for (int i=1; i < N1; ++i)
+ line(p1+i*grid_step1, p1+i*grid_step1+jump2, 0, fine.n2());
+
+ for (int j=1; j < N2; ++j)
+ line(p1+j*grid_step2, p1+j*grid_step2+jump1, 0, fine.n1());
+ }
+ }
+
+ // Grids that fill bounding_box with default camera
+ void grid(const P& p1, const P& p2, unsigned int n1, unsigned int n2)
+ {
+ grid(p1, p2, mesh(n1, n2), mesh(1,1));
+ }
+
+ void grid(unsigned int n1, unsigned int n2)
+ {
+ grid(active_screen()->bl(), active_screen()->tr(), n1, n2);
+ }
+
+
+ // polar grid with specified radius, mesh (rings and sectors), and resolution
+ void polar_grid(double radius, mesh coarse, mesh fine)
+ {
+ for (int i=1; i <= coarse.n1(); ++i)
+ ellipse(P(0,0,0),
+ (i*radius/coarse.n1())*E_1, (i*radius/coarse.n1())*E_2,
+ 0, full_turn(), fine.n2());
+
+ for (int j=0; j < coarse.n2(); ++j)
+ line(P(0,0,0), polar(radius, j*(full_turn())/coarse.n2()),
+ 0, 2*fine.n1());
+ }
+
+ void polar_grid(double radius, unsigned int n1, unsigned int n2)
+ {
+ polar_grid(radius, mesh(n1,n2), mesh(n1,EPIX_NUM_PTS));
+ }
+
+
+ // logarithmic grids
+
+ // local helpers
+ void grid_lines1_log(double x_lo, double x_hi, double y_lo, double y_hi,
+ unsigned int segs, unsigned int base)
+ {
+ if (segs == 0)
+ return;
+
+ const double dx((x_hi-x_lo)/segs); // "major grid" steps
+ const double denom(log(base)); // "minor"/log grid scale factor
+
+ for (unsigned int i=0; i < segs; ++i)
+ for (unsigned int j=1; j<base; ++j)
+ {
+ double x_tmp(x_lo + dx*(i+log(j)/denom));
+
+ line(P(x_tmp, y_lo), P(x_tmp, y_hi));
+ }
+
+ line(P(x_hi,y_lo), P(x_hi, y_hi)); // draw rightmost line manually
+ }
+
+ void grid_lines2_log(double x_lo, double x_hi, double y_lo, double y_hi,
+ unsigned int segs, unsigned int base)
+ {
+ if (segs == 0)
+ return;
+
+ const double dy((y_hi-y_lo)/segs);
+ const double denom(log(base));
+
+ for (unsigned int i=0; i < segs; ++i)
+ for (unsigned int j=1; j<base; ++j)
+ {
+ double y_tmp(y_lo + dy*(i+log(j)/denom));
+
+ line(P(x_lo, y_tmp), P(x_hi, y_tmp));
+ }
+
+ line(P(x_hi,y_lo), P(x_hi, y_hi));
+ }
+
+ // global functions
+ void log_grid(const P& p1, const P& p2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base1, unsigned int base2)
+ {
+ grid_lines1_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()),
+ segs1, base1);
+
+ grid_lines2_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()),
+ segs2, base2);
+ }
+
+ void log1_grid(const P& p1, const P& p2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base1)
+ {
+ grid_lines1_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()),
+ segs1, base1);
+
+ grid_lines2_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()),
+ segs2, 2);
+ }
+
+ void log2_grid(const P& p1, const P& p2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base2)
+ {
+ grid_lines1_log(min(p1.x1(), p2.x1()),
+ max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()),
+ max(p1.x2(), p2.x2()),
+ segs1, 2);
+
+ grid_lines2_log(min(p1.x1(), p2.x1()),
+ max(p1.x1(), p2.x1()),
+ min(p1.x2(), p2.x2()),
+ max(p1.x2(), p2.x2()),
+ segs2, base2);
+ }
+
+
+ // grids fill current bounding box
+ void log_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base1, unsigned int base2)
+ {
+ grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs1, base1);
+
+ grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs2, base2);
+ }
+
+ void log1_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base1)
+ {
+ grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs1, base1);
+
+ grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs2, 2);
+ }
+
+ void log2_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base2)
+ {
+ grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs1, 2);
+
+ grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(),
+ active_screen()->v_min(), active_screen()->v_max(),
+ segs2, base2);
+ }
+
+
+ // fractal generation
+ //
+ // The basic 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, scaled and rotated in order to join p to q.
+ //
+ // Kludge: pre_seed[0] = spokes, pre_seed[1] = length of seed;
+ //
+ // Sample data for _/\_ standard Koch snowflake:
+ // const int seed[] = {6, 4, 0, 1, -1, 0};
+
+ P jump(int spokes, int length, const std::vector<int>& seed)
+ {
+ P sum(P(0,0));
+
+ for (int i=0; i< length; ++i)
+ sum += cis(seed.at(i)*(full_turn())/spokes);
+
+ return sum;
+ }
+
+ void fractal(const P& p, const P& q, const int depth, const int *pre_seed)
+ {
+ int spokes(pre_seed[0]);
+ int seed_length(pre_seed[1]);
+ std::vector<int> seed(seed_length);
+
+ // extract seed from pre_seed
+ for (int i=0; i<seed_length; ++i)
+ seed.at(i) = pre_seed[i+2];
+
+ // Unit-length steps in <seed> sequence add up to <scale>
+ P scale(jump(spokes, seed_length, seed));
+
+ // Number of points in final fractal
+ int length(1+(int)pow(seed_length, depth));
+ std::vector<int> dir(length); // stepping information
+ std::vector<P> data(length); // vertices
+
+ // dir[] starts out [0, 1, -1, 0, ..., 0] (seed_length^depth entries)
+ // then take repeated "Kronecker sum" with seed = [0, 1, -1, 0]
+
+ for(int i=0; i<seed_length; ++i)
+ dir.at(i) = seed.at(i);
+
+ for(int i=1; i<depth; ++i) // recursively fill dir array
+ for(int j=0; j < pow(seed_length,i); ++j)
+ for(int k=seed_length-1; 0 < k; --k)
+ dir.at(k*(int)pow(seed_length,i) + j) = dir.at(j) + seed.at(k);
+
+ P curr(p);
+ // 10/09/06: -depth -> 1-depth
+ double radius(pow(norm(scale), 1-depth));
+
+ for(int i=0; i<length; ++i)
+ {
+ data.at(i) = curr;
+ // increment between successive points as a pair
+ pair temp((polar(radius, dir.at(i)*(full_turn())/spokes))*pair(q-p));
+
+ // complex arithmetic
+ temp /= pair(scale); // homothety to join p to q
+
+ curr += P(temp.x1(), temp.x2());
+ }
+
+ path fractal(data, false, false);
+ fractal.draw();
+ }
+
+} // end of namespace
diff --git a/graphics/epix/curves.h b/graphics/epix/curves.h
new file mode 100644
index 0000000000..d15966d9b0
--- /dev/null
+++ b/graphics/epix/curves.h
@@ -0,0 +1,187 @@
+/*
+ * curves.h -- Ellipses, arcs, splines, coordinate grids
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_CURVES
+#define EPIX_CURVES
+
+#include <vector>
+
+#include "constants.h"
+
+namespace ePiX {
+
+ class P;
+ class mesh;
+
+ // lines can be "stretched" by double parameter
+ void line(const P& tail, const P& head, double expand=0);
+ void line(const P& tail, const P& head, double expand,
+ unsigned int num_pts);
+
+ // "Visible" portion of the line through p1, p2
+ void Line(const P& tail, const P& head);
+
+ // point-slope form
+ void Line(const P&, double);
+
+ void triangle(const P&, const P&, const P&);
+ void quad(const P&, const P&, const P&, const P&);
+
+ void rect(const P&, const P&);
+ void rect(const P&, const P&, bool solid);
+
+ // arrows
+ void arrow(const P& tail, const P& head, double scale=1);
+ void dart(const P& tail, const P& head);
+
+ // double-tipped
+ void aarrow(const P& tail, const P& head, double scale=1);
+
+ // arbitrary elliptical arc
+ void arrow(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max, double scale=1);
+
+ // Algebraic curves (elliptical and circular arcs, splines)
+ void ellipse(const P& center, const P& axis1, const P& axis2); // full turn
+
+ void ellipse(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max); // angle range
+
+ void ellipse(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max, unsigned int num_pts);
+
+ // for backward compatibility
+ void ellipse_arc(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max);
+
+ // old style "center and polyradius"
+ void ellipse (const P& center, const P& radius);
+
+ // Standard half-ellipse functions
+ void ellipse_left (const P&, const P&);
+ void ellipse_right (const P&, const P&);
+ void ellipse_top (const P&, const P&);
+ void ellipse_bottom (const P&, const P&);
+
+ // Circular arcs parallel to (x,y)-plane
+ void arc(const P& center, double r,
+ double start, double finish);
+
+ void arc_arrow (const P& center, double r,
+ double start, double finish,
+ double scale=1);
+
+
+ // Quadratic and cubic splines/spline arrows
+ void spline(const P& p1, const P& p2, const P& p3, unsigned int num_pts);
+ void spline(const P& p1, const P& p2, const P& p3);
+
+ void arrow(const P& p1, const P& p2, const P& p3, double scale=1);
+
+ void spline (const P& p1, const P& p2, const P& p3, const P& p4,
+ unsigned int num_pts);
+ void spline (const P& p1, const P& p2, const P& p3, const P& p4);
+
+ void arrow(const P&, const P&, const P&, const P&, double scale=1);
+
+ // natural spline
+ void spline(const std::vector<P>&, unsigned int num_pts);
+
+
+ // A "mesh" is an ordered pair of positive integers, and is used to
+ // specify the "fineness" of a grid. Grids, like parametric surface
+ // meshes, have a "coarse mesh" -- the numbers of grid intervals in
+ // each direction, and a "fine mesh" -- the numbers of points used
+ // to render the grid lines. Since an ePiX camera does not always
+ // map lines in object space to lines on the screen, grid lines cannot
+ // generally be drawn using only two points.
+ // A grid may look strange unless each component of fine is a multiple
+ // of the corresponding entry of coarse, of course. :)
+
+ // Cartesian grid of specified size, mesh, and resolution
+ void grid(const P& arg1, const P& arg2, mesh coarse, mesh fine);
+
+ // coarse = fine = (n1,n2)
+ void grid(const P& arg1, const P& arg2,
+ unsigned int n1=1, unsigned int n2=1);
+ void grid(unsigned int n1=1, unsigned int n2=1);
+
+ // polar grid of specified radius, mesh (rings and sectors), and resolution
+ void polar_grid(double r, mesh coarse, mesh fine);
+
+ // polar grid with n1 rings and n2 sectors
+ void polar_grid(double r, unsigned int n1, unsigned int n2);
+
+
+ // (semi-)logarithmic grids specified by corners and numbers of orders of
+ // magnitude or grid divisions in each direction. Optional arguments
+ // specify the log base (10 by default). If corners are omitted, the grid
+ // fills the bounding box.
+ void log_grid(const P& arg1, const P& arg2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base1=10, unsigned int base2=10);
+
+ void log1_grid(const P& arg1, const P& arg2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base1=10);
+
+ void log2_grid(const P& arg1, const P& arg2,
+ unsigned int segs1, unsigned int segs2,
+ unsigned int base2=10);
+
+ void log_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base1=10, unsigned int base2=10);
+
+ void log1_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base1=10);
+
+ void log2_grid(unsigned int segs1, unsigned int segs2,
+ unsigned int base2=10);
+
+ // 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 (const P& p, const P& q, const int depth, const int *pre_seed);
+
+} // end of namespace
+
+#endif /* EPIX_CURVES */
diff --git a/graphics/epix/data_bins.cc b/graphics/epix/data_bins.cc
new file mode 100644
index 0000000000..9474c1de25
--- /dev/null
+++ b/graphics/epix/data_bins.cc
@@ -0,0 +1,411 @@
+/*
+ * data_bins.cc -- ePiX::data_bins class for histogram data
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <string>
+#include <sstream>
+#include <list>
+#include <vector>
+
+#include "errors.h"
+
+#include "constants.h"
+#include "functions.h"
+#include "triples.h"
+
+#include "path.h"
+#include "spline.h"
+
+#include "curves.h"
+
+#include "data_bins.h"
+
+namespace ePiX {
+
+ // print summary statistics
+ static void __epix_out_of_range(const std::string& fcn,
+ unsigned int lo, unsigned int hi,
+ unsigned int hits)
+ {
+ if (0 == lo + hi && 0 == hits)
+ return;
+
+ // else
+ if (0 < lo + hi)
+ {
+ std::stringstream buf;
+ buf << fcn << " has " << lo + hi << " point(s) out of range: ";
+
+ bool need_comma(false);
+
+ if (0 < lo)
+ {
+ buf << lo << " below";
+ need_comma = true;
+ }
+
+ if (0 < hi)
+ {
+ if (need_comma)
+ buf << ", ";
+
+ buf << hi << " above";
+ }
+ epix_warning(buf.str());
+ }
+
+ if (0 < hits)
+ {
+ std::stringstream buf;
+ buf << fcn << " has " << hits/2 << " point(s) on cuts";
+ epix_warning(buf.str());
+ }
+ }
+
+
+ //// histogram data bin ////
+ class d_bin {
+ public:
+ d_bin(double low, double high)
+ : m_lo(low), m_hi(high), m_dbl_count(0) { }
+
+ double add_datum(double x)
+ {
+ if (x < m_lo || m_hi < x)
+ return 0.0;
+
+ else if (m_lo < x && x < m_hi)
+ {
+ m_dbl_count += 2;
+ return 1.0;
+ }
+
+ else // x == m_lo || x == m_hi
+ {
+ ++m_dbl_count;
+ return 0.5;
+ }
+ }
+
+ // draw rectangle; height = scale*population
+ void draw_ht(double scale) const
+ {
+ rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count));
+ }
+
+ // area = scale*population
+ void draw_area(double scale) const
+ {
+ if (EPIX_EPSILON < m_hi - m_lo)
+ rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count/(m_hi - m_lo)));
+ }
+
+ double lo() const
+ {
+ return m_lo;
+ }
+
+ double hi() const
+ {
+ return m_hi;
+ }
+
+ double ht(double scale) const
+ {
+ return 0.5*scale*m_dbl_count;
+ }
+
+ P loc(double scale) const
+ {
+ return P(0.5*(m_lo + m_hi), 0.5*scale*m_dbl_count);
+ }
+
+ d_bin* clone() const
+ {
+ return new d_bin(*this);
+ }
+
+ private:
+ double m_lo, m_hi; // end values
+
+ // twice the number of elements; endpoint hits count as 1
+ unsigned int m_dbl_count;
+ }; // end of class d_bin
+
+
+ //// data_bins functions ////
+ data_bins::data_bins(double lo, double hi, unsigned int n)
+ : m_lo_val(min(lo, hi)), m_hi_val(max(lo, hi)),
+ m_lo_ct(0), m_hi_ct(0), m_pop(0), m_cut_hits(0),
+ m_cuts_locked(false)
+ {
+ // divide [lo, hi] into n pieces (n>0), or into unit pieces (n=0)
+ unsigned int ct(n>0 ? n : (unsigned int)(m_hi_val - m_lo_val));
+ const double dx((m_hi_val - m_lo_val)/ct);
+
+ for (unsigned int i=0; i<=ct; ++i)
+ m_cuts.push_back(m_lo_val + i*dx);
+ }
+
+ data_bins::data_bins(const data_bins& db)
+ : m_lo_val(db.m_lo_val), m_hi_val(db.m_hi_val),
+ m_lo_ct(db.m_lo_ct), m_hi_ct(db.m_hi_ct),
+ m_pop(db.m_pop), m_cut_hits(db.m_cut_hits),
+ m_cuts_locked(db.m_cuts_locked), m_cuts(db.m_cuts)
+ {
+ for (std::list<d_bin*>::const_iterator p=db.m_bins.begin();
+ p != db.m_bins.end(); ++p)
+ m_bins.push_back((*p)->clone());
+ }
+
+ data_bins& data_bins::operator= (const data_bins& db)
+ {
+ if (this != &db)
+ {
+ std::list<d_bin*> tmp;
+ for (std::list<d_bin*>::const_iterator p=db.m_bins.begin();
+ p!=db.m_bins.end(); ++p)
+ tmp.push_back((*p)->clone());
+
+ // assign data
+ m_lo_val = db.m_lo_val;
+ m_hi_val = db.m_hi_val;
+
+ m_lo_ct = db.m_lo_ct;
+ m_hi_ct = db.m_hi_ct;
+ m_pop = db.m_pop;
+ m_cut_hits = db.m_cut_hits;
+ m_cuts_locked = db.m_cuts_locked;
+
+ // deallocate memory
+ for (std::list<d_bin*>::iterator p=m_bins.begin();
+ p!=m_bins.end(); ++p)
+ delete *p;
+
+ m_cuts = db.m_cuts;
+ swap(m_bins, tmp);
+ }
+
+ return *this;
+ }
+
+ data_bins::~data_bins()
+ {
+ for (std::list<d_bin*>::iterator p=m_bins.begin(); p!=m_bins.end(); ++p)
+ delete *p;
+ }
+
+
+ data_bins& data_bins::cut(double x)
+ {
+ if (m_cuts_locked)
+ epix_warning("cut() called on locked data_bins, no action");
+
+ else if (x < m_lo_val || m_hi_val < x)
+ epix_warning("cut() out of range, no action");
+
+ else
+ m_cuts.push_back(x);
+
+ return *this;
+ }
+
+ data_bins& data_bins::read(const std::vector<double>& data)
+ {
+ if (0 < data.size())
+ {
+ if (!m_cuts_locked)
+ initialize();
+
+ for (std::vector<double>::const_iterator p=data.begin();
+ p != data.end(); ++p)
+ insert(*p);
+ }
+ return *this;
+ }
+
+ unsigned int data_bins::pop() const
+ {
+ return m_pop;
+ }
+
+ // rectangles
+ void data_bins::histogram(double scale) const
+ {
+ if (m_pop == 0)
+ return;
+
+ // else
+ __epix_out_of_range("histogram", m_lo_ct, m_hi_ct, m_cut_hits);
+
+ // const double denom((m_hi_val - m_lo_val)/m_pop);
+ const double adj(scale/m_pop);
+
+ for (std::list<d_bin*>::const_iterator p=m_bins.begin();
+ p != m_bins.end(); ++p)
+ (*p)->draw_area(adj);
+ }
+
+ void data_bins::bar_chart(double scale) const
+ {
+ if (m_pop == 0)
+ return;
+
+ // else
+ __epix_out_of_range("bar_chart", m_lo_ct, m_hi_ct, m_cut_hits);
+
+ const double adj(scale/m_pop); // scale=1 -> ht=frac of pop in bin
+
+ for (std::list<d_bin*>::const_iterator p=m_bins.begin();
+ p != m_bins.end(); ++p)
+ (*p)->draw_ht(adj);
+ }
+
+ // piecewise-cubic interpolation of bar_chart
+ void data_bins::plot(double scale) const
+ {
+ if (m_pop == 0)
+ return;
+
+ // else
+ __epix_out_of_range("data_bins::plot", m_lo_ct, m_hi_ct, m_cut_hits);
+
+ // get rectangle corners
+ std::vector<P> vertices;
+
+ std::list<d_bin*>::const_iterator bn(m_bins.begin());
+ vertices.push_back(P((*bn)->lo(),0));
+
+ for (bn = m_bins.begin(); bn != m_bins.end(); ++bn)
+ {
+ vertices.push_back(P((*bn)->lo(), (*bn)->ht(scale/m_pop)));
+ vertices.push_back(P((*bn)->hi(), (*bn)->ht(scale/m_pop)));
+ }
+
+ --bn; // last bin
+ vertices.push_back(P((*bn)->hi(),0));
+
+ const unsigned int N(vertices.size());
+
+ // draw piecewise cubic interpolation
+ line(vertices.at(0), 0.5*(vertices.at(0) + vertices.at(1)));
+
+ // Magic number 20 to reduce file size
+ for (unsigned int i=1; i< N-1; ++i)
+ spline(0.5*(vertices.at(i-1) + vertices.at(i)),
+ vertices.at(i),
+ vertices.at(i),
+ 0.5*(vertices.at(i) + vertices.at(i+1)), 20);
+
+ line(0.5*(vertices.at(N-2) + vertices.at(N-1)), vertices.at(N-1));
+ } // end of plot(scale)
+
+
+ // private bookkeeping functions
+ void data_bins::initialize()
+ {
+ if (!m_cuts_locked) // defensive redundancy
+ {
+ // sort list of cuts, remove duplicates, and lock
+ m_cuts.sort();
+ m_cuts.unique();
+
+ m_cuts_locked=true;
+
+ // allocate d_bins
+ for (std::list<double>::const_iterator curr = m_cuts.begin();
+ curr != m_cuts.end(); ++curr)
+ {
+ std::list<double>::const_iterator next(curr);
+ ++next;
+
+ if (next != m_cuts.end() && *curr != *next)
+ m_bins.push_back(new d_bin(*curr, *next));
+
+ else if (*curr != m_hi_val)
+ m_bins.push_back(new d_bin(*curr, m_hi_val));
+ }
+ }
+ }
+
+ // Ideally no data lies on a cut, but we'll cope as well as possible
+ // otherwise. Data on an end cut is "out of range". Data on an interior
+ // cut contributes 1/2 to the population of each adjacent bin.
+ void data_bins::insert(double x)
+ {
+ ++m_pop;
+
+ std::list<d_bin*>::iterator p(m_bins.begin());
+
+ // check end bins first
+ if (x <= m_lo_val)
+ {
+ ++m_lo_ct;
+ if (fabs(x - m_lo_val) < EPIX_EPSILON)
+ {
+ (*p)->add_datum(x);
+ m_cut_hits += 2;
+ }
+ return;
+ }
+
+ if (m_hi_val <= x)
+ {
+ ++m_hi_ct;
+ if (fabs(x - m_hi_val) < EPIX_EPSILON)
+ {
+ p = m_bins.end();
+ --p;
+ (*p)->add_datum(x);
+ m_cut_hits += 2;
+ }
+ return;
+ }
+
+ // else
+ double success(0.0);
+ p = m_bins.begin();
+
+ // try "normal" bins serially
+ while (success < 0.75 && p!=m_bins.end()) // success is a half-integer
+ {
+ double ct((*p++)->add_datum(x)); // 1 for yes, 0.5 for endpt, 0 for no
+ success += ct;
+ if (fabs(ct - 0.5) < EPIX_EPSILON)
+ ++m_cut_hits;
+ }
+
+ if (success < 0.75) // still not added!
+ epix_warning("data_bin::insert() internal error");
+ }
+} // end of namespace
diff --git a/graphics/epix/data_bins.h b/graphics/epix/data_bins.h
new file mode 100644
index 0000000000..e0d9a200e6
--- /dev/null
+++ b/graphics/epix/data_bins.h
@@ -0,0 +1,101 @@
+/*
+ * data_bins.h -- ePiX::data_bins class for histogram data
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.19
+ * Last Change: September 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides the "data_bins" class.
+ *
+ * An object of type data_bins models a closed interval [lo, hi]
+ * divided into subintervals (not necessarily of equal length). Each
+ * subinterval is a "d_bin", whose endpoints are "cuts". A data_bins
+ * can read and sort numerical data, count how many numbers lie in
+ * each bin, and print the result as a bar chart (rectangle height
+ * proportional to population), histogram (area proportional to
+ * population), or as a spline interpolation.
+ *
+ * Ideally no data lies outside (lo, hi) or on a cut. Data on an end
+ * cut is "out of range", data on an interior cut contributes 1/2 to
+ * the population of each adjacent bin. A summary statistic warning is
+ * printed if any points are out of range or lie on a cut.
+ */
+
+#ifndef EPIX_DATA_BINS
+#define EPIX_DATA_BINS
+
+#include <vector>
+#include <list>
+
+namespace ePiX {
+
+ class d_bin;
+
+ class data_bins {
+ public:
+ data_bins(double lo, double hi, unsigned int n=1);
+
+ data_bins(const data_bins&);
+ data_bins& operator= (const data_bins&);
+ ~data_bins();
+
+ data_bins& cut(double); // add a cut
+ data_bins& read(const std::vector<double>&);
+
+ unsigned int pop() const; // current population
+
+ // draw rectangles
+ void histogram(double scale=1) const; // area prop to pop
+ void bar_chart(double scale=1) const; // height prop to pop
+ void plot(double scale=1) const; // smooth interpolation
+
+ private:
+ double m_lo_val;
+ double m_hi_val;
+
+ unsigned int m_lo_ct; // population smaller than m_lo_val
+ unsigned int m_hi_ct; // population larger than m_hi_val
+ unsigned int m_pop; // current total population
+
+ unsigned int m_cut_hits; // number of data on a cut
+ bool m_cuts_locked; // true once we read data
+
+ std::list<double> m_cuts;
+ std::list<d_bin*> m_bins;
+
+ // bookkeeping
+ void initialize(); // convert cuts to bins and lock
+ void insert(double); // add data point
+ }; // end of class data_bins
+
+} // end of namespace
+
+#endif /* EPIX_DATA_BINS */
diff --git a/graphics/epix/data_file.cc b/graphics/epix/data_file.cc
new file mode 100644
index 0000000000..fb2e6a5a5b
--- /dev/null
+++ b/graphics/epix/data_file.cc
@@ -0,0 +1,687 @@
+/*
+ * data_file.cc -- ePiX::data_file class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <fstream>
+#include <sstream>
+#include <list>
+#include <vector>
+#include <stdexcept>
+
+#include "errors.h"
+
+#include "functions.h"
+#include "triples.h"
+#include "path.h"
+#include "spline.h"
+
+#include "label_data.h"
+#include "curves.h"
+
+#include "interval.h"
+#include "data_bins.h"
+#include "data_mask.h"
+#include "data_file.h"
+
+namespace ePiX {
+
+ const std::string default_delim("\t");
+ const std::string default_commt("%");
+
+ // magic number -- precision for data_file.write()
+ const unsigned int PRECISION(6);
+
+ double truncate(double arg, const unsigned int n)
+ {
+ if (fabs(arg) < pow(0.1, n))
+ return 0;
+
+ return arg;
+ }
+
+ // warning message for data_file::tokenize
+ void non_parsable(const std::string& msg)
+ {
+ std::stringstream obuf;
+ obuf << "data_file::tokenise():" << std::endl
+ << " Non-parsable input \"" << msg << "\", setting value to 0";
+ epix_warning(obuf.str());
+ }
+
+ //// private data_file functions ////
+ // returns # of columns, i.e. # of entries in first parsable row
+ unsigned int data_file::entries(const char* filename)
+ {
+ std::ifstream input(filename);
+ if (!input)
+ {
+ epix_warning("Cannot open file \""+std::string(filename)+"\"");
+ return(0);
+ }
+
+ // else
+ std::string linebuf;
+ std::vector<double> tmp;
+
+ while (getline(input, linebuf) && tmp.size() == 0)
+ {
+ // strip comments
+ linebuf = linebuf.substr(0, linebuf.find_first_of(m_commt));
+ if (linebuf.length() > 0)
+ tmp = tokenise(linebuf);
+ }
+
+ input.close();
+
+ if (tmp.size() == 0)
+ {
+ std::stringstream obuf; // solely for code readability :)
+ obuf << "File \"" << std::string(filename)
+ << "\" contains no parsable data";
+
+ epix_warning(obuf.str());
+ }
+
+ return tmp.size();
+ } // end of entries(const char*)
+
+
+ // private function:
+ // Tokenise line using our delimiter, return a vector of doubles
+ std::vector<double> data_file::tokenise(std::string line)
+ {
+ size_t pos(line.find(m_delim, 0)); // first delimiter
+ std::string tmpStr; // current chunk of input
+ double tmpDbl; // current parsed chunk
+ std::vector<double> tmpVec; // output found so far
+
+ // read current line into a vector of doubles
+ while(pos != std::string::npos)
+ {
+ tmpStr = line.substr(0, pos);
+ line.erase(0, pos+1);
+ std::istringstream convStr(tmpStr);
+
+ if (!(convStr >> tmpDbl))
+ {
+ tmpDbl = 0;
+ non_parsable(convStr.str());
+ }
+
+ tmpVec.push_back(tmpDbl);
+ pos = line.find(m_delim, 0);
+ }
+
+ if (line.size()) // There's input remaining
+ {
+ std::istringstream convStr(line);
+
+ if (!(convStr >> tmpDbl))
+ {
+ tmpDbl = 0;
+ non_parsable(convStr.str());
+ }
+
+ else
+ tmpVec.push_back(tmpDbl);
+ }
+
+ return tmpVec;
+ }
+
+ //// public data_file functions ////
+ data_file::data_file(unsigned int n)
+ : m_precision(PRECISION), m_data(n),
+ m_delim(default_delim),
+ m_commt(default_commt) { }
+
+ // provide two version to avoid exposing default delim, commt
+ data_file::data_file(const char* filename,
+ const std::string& delim, const std::string& commt )
+ : m_precision(PRECISION), m_delim(delim), m_commt(commt)
+ {
+ // get number of columns by parsing first line of file
+ const unsigned int N(entries(filename));
+ m_data.resize(N);
+
+ if (N > 0) // file contains data
+ read(filename);
+
+ } // end of data_file()
+
+ // filename-only version
+ data_file::data_file(const char* filename)
+ : m_precision(PRECISION), m_delim(default_delim), m_commt(default_commt)
+ {
+ // get number of columns by parsing first line of file
+ const unsigned int N(entries(filename));
+ m_data.resize(N);
+
+ if (N > 0) // file contains data
+ read(filename);
+
+ } // end of data_file(const char*)
+
+
+ // file made from components
+ data_file::data_file(double f(double),
+ double t_min, double t_max, unsigned int num_pts)
+ : m_precision(PRECISION), m_data(1),
+ m_delim(default_delim), m_commt(default_commt)
+ {
+ const double dt((t_max - t_min)/num_pts);
+ for (unsigned int i=0; i<= num_pts; ++i)
+ m_data.at(0).push_back(f(t_min+i*dt));
+ }
+
+ data_file::data_file(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int num_pts)
+ : m_precision(PRECISION), m_data(2),
+ m_delim(default_delim), m_commt(default_commt)
+ {
+ const double dt((t_max - t_min)/num_pts);
+ for (unsigned int i=0; i<= num_pts; ++i)
+ {
+ m_data.at(0).push_back(f1(t_min+i*dt));
+ m_data.at(1).push_back(f2(t_min+i*dt));
+ }
+ }
+
+
+ data_file::data_file(double f1(double), double f2(double), double f3(double),
+ double t_min, double t_max, unsigned int num_pts)
+ : m_precision(PRECISION), m_data(3),
+ m_delim(default_delim), m_commt(default_commt)
+ {
+ const double dt((t_max - t_min)/num_pts);
+ for (unsigned int i=0; i<= num_pts; ++i)
+ {
+ m_data.at(0).push_back(f1(t_min+i*dt));
+ m_data.at(1).push_back(f2(t_min+i*dt));
+ m_data.at(2).push_back(f3(t_min+i*dt));
+ }
+ }
+
+
+ data_file& data_file::read(const char* filename)
+ {
+ unsigned int columns(entries(filename));
+ if (columns != m_data.size())
+ {
+ std::stringstream msg;
+ msg << "Column count mismatch in file " << filename;
+ epix_warning(msg.str());
+ }
+
+ else if (0 < columns)
+ {
+ std::ifstream input(filename);
+ std::string linebuf;
+ std::vector<double> line;
+
+ bool warned(false);
+
+ while (getline(input, linebuf))
+ {
+ // strip comments
+ linebuf = linebuf.substr(0, linebuf.find_first_of(m_commt));
+ if (linebuf.length() > 0)
+ {
+ line = tokenise(linebuf);
+
+ if (line.size() > m_data.size())
+ {
+ if (!warned)
+ {
+ epix_warning("File has more columns than allocated");
+ warned = true;
+ }
+ }
+ else if (line.size() < m_data.size())
+ {
+ if (!warned)
+ {
+ epix_warning("File has fewer columns than allocated");
+ warned = true;
+ }
+ }
+ else
+ {
+ for (unsigned int i = 0; i < m_data.size(); i++)
+ m_data.at(i).push_back(line.at(i));
+ }
+ } // linebuf non-empty
+ } // end of file
+ input.close();
+ }
+ return *this;
+ } // end of data_file::read(const char*, const std::string&)
+
+
+ // transform column(s)
+ data_file& data_file::transform(double f(double), unsigned int col)
+ {
+ unsigned int rows(m_data.at(0).size());
+
+ if (0 < col) // apply to selected column
+ for (unsigned int i=0; i<rows; ++i)
+ m_data.at(col-1).at(i) = f(m_data.at(col-1).at(i));
+
+ else // apply to all columns, default
+ {
+ for (unsigned int j=0; j<m_data.size(); ++j)
+ for (unsigned int i=0; i<rows; ++i)
+ m_data.at(j).at(i) = f(m_data.at(j).at(i));
+ }
+
+ return *this;
+ }
+
+ // apply f to selected columns, components of image go back to columns
+ data_file& data_file::transform(P f(double, double),
+ unsigned int col1, unsigned int col2)
+ {
+ unsigned int rows(m_data.at(0).size());
+
+ for (unsigned int i=0; i<rows; ++i)
+ {
+ P tmp(f(m_data.at(col1 - 1).at(i), m_data.at(col2 - 1).at(i)));
+
+ m_data.at(col1 - 1).at(i) = tmp.x1();
+ m_data.at(col2 - 1).at(i) = tmp.x2();
+ }
+
+ return *this;
+ }
+
+ data_file& data_file::transform(P f(double, double, double),
+ unsigned int col1, unsigned int col2)
+ {
+ unsigned int rows(m_data.at(0).size());
+
+ for (unsigned int i=0; i<rows; ++i)
+ {
+ P tmp(f(m_data.at(col1 - 1).at(i), m_data.at(col2 - 1).at(i), 0));
+
+ m_data.at(col1 - 1).at(i) = tmp.x1();
+ m_data.at(col2 - 1).at(i) = tmp.x2();
+ }
+
+ return *this;
+ }
+
+ data_file& data_file::transform(P f(double, double, double),
+ unsigned int col1,
+ unsigned int col2,
+ unsigned int col3)
+ {
+ unsigned int rows(m_data.at(0).size());
+
+ for (unsigned int i=0; i<rows; ++i)
+ {
+ P tmp(f(m_data.at(col1 - 1).at(i),
+ m_data.at(col2 - 1).at(i),
+ m_data.at(col3 - 1).at(i)));
+
+ m_data.at(col1 - 1).at(i) = tmp.x1();
+ m_data.at(col2 - 1).at(i) = tmp.x2();
+ m_data.at(col3 - 1).at(i) = tmp.x3();
+ }
+
+ return *this;
+ }
+
+ // Erase rows where the data is outside of the specified range
+ data_file& data_file::prune(const data_mask& dm, const unsigned int col)
+ {
+ std::vector<std::vector<double>::iterator> iter(m_data.size());
+ for (unsigned int i = 0; i < m_data.size(); i++)
+ iter.at(i) = m_data.at(i).begin();
+
+ while (iter.at(0) != m_data.at(0).end())
+ {
+ if ( dm.masks(*iter.at(col-1)) )
+ for (unsigned int j = 0; j < m_data.size(); j++)
+ m_data.at(j).erase(iter.at(j));
+
+ else
+ for (unsigned int j = 0; j < m_data.size(); j++)
+ iter.at(j)++;
+ }
+
+ return *this;
+ }
+
+ data_file& data_file::prune(const interval& range, const unsigned int col)
+ {
+ data_mask dm(range);
+ return prune(dm, col);
+ }
+
+ data_file& data_file::prune(double rmin, double rmax,
+ const unsigned int col)
+ {
+ data_mask dm(rmin, rmax);
+ return prune(dm, col);
+ }
+
+
+ // (col1|col2)
+ double data_file::dot(unsigned int col1, unsigned int col2) const
+ {
+ double sum(0);
+
+ if ((col1 > m_data.size()) || (col2 > m_data.size()) )
+ epix_warning("Invalid column index in dot product");
+
+ else
+ for (unsigned int i=0; i < m_data.at(0).size(); ++i)
+ sum += m_data.at(col1-1).at(i)*m_data.at(col2-1).at(i);
+
+ return sum;
+ } // end of dot
+
+ // avg (mean) of col1
+ double data_file::avg(unsigned int col1) const
+ {
+ double sum(0);
+
+ if (col1 > m_data.size())
+ epix_warning("Invalid column index in mean");
+
+ else
+ for (unsigned int i=0; i < m_data.at(0).size(); ++i)
+ sum += m_data.at(col1-1).at(i);
+
+ return sum/m_data.at(0).size();
+ } // end of avg
+
+ // variance (x|x) - n*\bar{x}^2
+ double data_file::var(unsigned int col1) const
+ {
+ double mean(avg(col1));
+
+ return dot(col1, col1) - mean*mean*m_data.at(0).size();
+ } // end of var
+
+ // covariance (x|y) - n*\bar{x}*\bar{y}
+ double data_file::covar(unsigned int col1, unsigned int col2) const
+ {
+ return dot(col1, col2) - (m_data.at(0).size())*avg(col1)*avg(col2);
+ } // end of covar
+
+ void data_file::regression(unsigned int col1, unsigned int col2) const
+ {
+ Line(P(avg(col1), avg(col2)), covar(col1, col2)/var(col1));
+ }
+
+
+ //// Output functions ////
+ // return selected column
+ std::vector<double> data_file::column(unsigned int n) const
+ {
+ if (1 <= n && n <= m_data.size())
+ return m_data.at(n-1);
+ else
+ {
+ if (0 < m_data.size())
+ {
+ epix_warning("Out of range argument to data_file::column()");
+ return m_data.at(0);
+ }
+ else
+ {
+ epix_warning("data_file::column() requested for empty file");
+ std::vector<double> err_val(1, 0);
+ return err_val;
+ }
+ }
+ }
+
+ // apply f to selected column
+ std::vector<double> data_file::column(double f(double), unsigned int n) const
+ {
+ // must copy data
+ std::vector<double> value(m_data.at(0).size());
+ unsigned int col(n);
+
+ if (col < 1 || m_data.size() < col)
+ {
+ if (0 < m_data.size())
+ {
+ epix_warning("Out of range argument to data_file::column()");
+ col=1;
+ }
+ else
+ {
+ epix_warning("data_file::column() requested for empty file");
+ std::vector<double> err_val(1, 0);
+ return err_val;
+ }
+ }
+
+ for (unsigned int i=0; i<m_data.at(0).size(); ++i)
+ value.at(i) = f(m_data.at(col-1).at(i));
+
+ return value;
+ }
+
+
+ // set precision for write()
+ void data_file::precision(const unsigned int n) const
+ {
+ m_precision=n;
+ }
+
+ // write file or selected columns
+ void data_file::write(const char* filename) const
+ {
+ std::ofstream output(filename);
+ if (!output)
+ {
+ epix_warning("data_file::write() cannot open file");
+ return;
+ }
+
+ // else
+ output.precision(m_precision);
+ output.setf(std::ios_base::showpoint); // pad with 0s
+ output.setf(std::ios_base::right); // right-justify
+
+ unsigned int cols(m_data.size());
+
+ for (unsigned int j=0; j < m_data.at(0).size(); ++j)
+ {
+ output << m_data.at(0).at(j);
+ for (unsigned int i=1; i < cols; ++i)
+ output << m_delim << m_data.at(i).at(j);
+
+ output << std::endl;
+ }
+ output.close();
+ }
+
+
+ void data_file::write(const char* fname, std::string pt_out(double, double),
+ unsigned int col1, unsigned int col2) const
+ {
+ std::ofstream output(fname);
+ if (!output)
+ {
+ epix_warning("data_file::write() cannot open file");
+ return;
+ }
+
+ // else
+ output.precision(m_precision);
+
+ for (unsigned int i=0; i < m_data.at(0).size(); ++i)
+ try
+ {
+ output << pt_out(m_data.at(col1-1).at(i), m_data.at(col2-1).at(i));
+ }
+
+ catch (std::out_of_range)
+ {
+ epix_warning("data_file::write(): Invalid column index");
+ return;
+ }
+
+ output.close();
+ } // end of data_file::write(const char*, string function)
+
+ // experimental: LaTeX tabular environment
+ void data_file::tabular(const char* filename,
+ const std::string& alignment,
+ const std::string& legend) const
+ {
+ std::ofstream output(filename);
+ if (!output)
+ {
+ epix_warning("data_file::table() cannot open file");
+ return;
+ }
+
+ // else
+ using std::endl;
+
+ output.precision(m_precision);
+ unsigned int cols(m_data.size());
+
+ output << "\\begin{tabular}{" << alignment << "}" << endl
+ << "\\hline" << endl;
+ if (legend != "")
+ output << legend << endl << "\\hline" << endl;
+
+ for (unsigned int j=0; j < m_data.at(0).size(); ++j)
+ {
+ output << "$" << truncate(m_data.at(0).at(j), m_precision) << "$";
+ for (unsigned int i=1; i < cols; ++i)
+ output << " & $" << truncate(m_data.at(i).at(j), m_precision) << "$";
+
+ output << " \\\\" << endl;
+ }
+
+ output << "\\hline" << endl
+ << "\\end{tabular}" << endl;
+
+ output.close();
+ } // end of data_file::tabular()
+
+
+ void data_file::plot(epix_mark_type TYPE,
+ unsigned int col1, unsigned int col2, unsigned int col3,
+ P f(double, double, double)) const
+ {
+ unsigned int num_entries(m_data.at(0).size());
+
+ std::vector<P> data(num_entries);
+
+ // create path
+ for (unsigned int i=0; i < num_entries; ++i)
+ try
+ {
+ if (col3 == 0)
+ data.at(i) = f(m_data.at(col1-1).at(i),
+ m_data.at(col2-1).at(i),
+ 0);
+
+ else
+ data.at(i) = f(m_data.at(col1-1).at(i),
+ m_data.at(col2-1).at(i),
+ m_data.at(col3-1).at(i));
+ }
+
+ catch (std::out_of_range)
+ {
+ epix_warning("data_file::plot(): Invalid column index");
+ return;
+ }
+
+ // and write it
+ if (PATH == TYPE) // N.B. Unaffected by "select"
+ {
+ path temp(data, false, false); // not closed or filled
+ temp.draw();
+ }
+
+ else
+ for (unsigned int i=0; i < num_entries; ++i)
+ {
+ // if (m_select(data.at(i)))
+ label_data temp(data.at(i), TYPE);
+ temp.draw();
+ }
+ }
+
+ void data_file::plot(epix_mark_type TYPE, P f(double, double, double),
+ unsigned int col1, unsigned int col2,
+ unsigned int col3) const
+ {
+ plot(TYPE, col1, col2, col3, f);
+ }
+
+ //// global functions ////
+ void plot(const char* filename, epix_mark_type TYPE,
+ unsigned int col1, unsigned int col2, unsigned int col3,
+ P f(double, double, double))
+ {
+ data_file temp(filename);
+ temp.plot(TYPE, col1, col2, col3, f);
+ }
+
+ void plot(const char* filename, epix_mark_type TYPE,
+ P f(double, double, double),
+ unsigned int col1, unsigned int col2, unsigned int col3)
+ {
+ data_file temp(filename);
+ temp.plot(TYPE, col1, col2, col3, f);
+ }
+
+ // pass 3rd arg by value
+ void histogram(const char* filename, unsigned int col, data_bins db,
+ double scale)
+ {
+ data_file temp(filename);
+ db.read(temp.column(col));
+ db.histogram(scale);
+ }
+
+ void bar_chart(const char* filename, unsigned int col, data_bins db,
+ double scale)
+ {
+ data_file temp(filename);
+ db.read(temp.column(col));
+ db.bar_chart(scale);
+ }
+} // end of namespace
diff --git a/graphics/epix/data_file.h b/graphics/epix/data_file.h
new file mode 100644
index 0000000000..e5a3af956e
--- /dev/null
+++ b/graphics/epix/data_file.h
@@ -0,0 +1,172 @@
+/*
+ * data_file.h -- ePiX::data_file class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.6
+ * Last Change: July 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_DATA_FILE
+#define EPIX_DATA_FILE
+
+#include <vector>
+#include <list>
+
+#include "enums.h"
+
+namespace ePiX {
+
+ class data_bins;
+ class data_mask;
+ class interval;
+
+ class data_file {
+ public:
+ explicit data_file(unsigned int n=2);
+
+ // get size from first line of file;
+ // provide two versions to avoid exposing default delim/commt strings
+ data_file(const char* filename,
+ const std::string& delim, const std::string& commt);
+ explicit data_file(const char* filename);
+
+ // file made from components
+ data_file(double f(double),
+ double t_min, double t_max, unsigned int num_pts);
+
+ data_file(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int num_pts);
+
+ data_file(double f1(double), double f2(double), double f3(double),
+ double t_min, double t_max, unsigned int num_pts);
+
+ // input
+ data_file& read(const char*);
+
+ // transform column(s)
+ data_file& transform(double f(double), unsigned int col=0);
+
+ // apply f to selected columns; components of image go back to columns
+ data_file& transform(P f(double, double),
+ unsigned int col1=1, unsigned int col2=2);
+
+ data_file& transform(P f(double, double, double),
+ unsigned int col1, unsigned int col2);
+
+ data_file& transform(P f(double, double, double),
+ unsigned int col1,
+ unsigned int col2,
+ unsigned int col3);
+
+ // remove rows where specified entry is masked or outside interval/range
+ data_file& prune(const data_mask&, const unsigned int col);
+ data_file& prune(const interval&, const unsigned int col);
+ data_file& prune(double, double, const unsigned int col);
+
+ // basic statistical operations on columns
+ double dot(unsigned int col1, unsigned int col2) const; // dot product
+ double avg(unsigned int col1) const; // mean
+ double var(unsigned int col1) const; // |x|^2 - n*avg^2
+ double covar(unsigned int col1, unsigned int col2) const;
+ void regression(unsigned int col1, unsigned int col2) const;
+
+
+ // output functions
+ // extract column
+ std::vector<double> column(unsigned int) const;
+ // apply f to values
+ std::vector<double> column(double f(double), unsigned int) const;
+
+ // set C++ output precision for write
+ void precision(unsigned int n=6) const;
+
+ // Setters and getters for delimiter and comment character
+ void delimiter(const char* delim) { m_delim = delim; }
+ std::string delimiter() const { return m_delim; }
+
+ void comment(const char* commt) { m_commt = commt; }
+ std::string comment() const { return m_commt; }
+
+ // write raw data to file
+ void write(const char* filename) const;
+
+ // write selected columns formatted by string-valued function
+ void write(const char* filename, std::string pt_out(double, double),
+ unsigned int col1=1, unsigned int col2=2) const;
+
+ // LaTeX tabular environment
+ void tabular(const char* filename,
+ const std::string& alignment,
+ const std::string& legend="") const;
+
+
+ /*
+ // (un)set cropping criterion for plotting
+ void select(bool Fsel(P));
+ void select(const selection&); // e.g. select(all());
+ */
+
+ // scatter plots; f applied to selected columns
+ void plot(epix_mark_type TYPE,
+ unsigned int col1=1, unsigned int col2=2, unsigned int col3=0,
+ P f(double, double, double) = xyz) const;
+
+ void plot(epix_mark_type TYPE, P f(double, double, double),
+ unsigned int col1=1, unsigned int col2=2,
+ unsigned int col3=0) const;
+
+ private:
+ std::vector<double> tokenise(std::string line);
+ unsigned int entries(const char* filename);
+
+ mutable unsigned int m_precision;
+ // selection m_select;
+
+ std::vector<std::vector<double> > m_data;
+ std::string m_delim; // Field delimiter
+ std::string m_commt; // Comment character
+ }; // end of class data_file
+
+
+ //// Global functions that use file_data, data_bins ////
+ void plot(const char* filename, epix_mark_type TYPE,
+ unsigned int col1=1, unsigned int col2=2, unsigned int col3=0,
+ P f(double, double, double) = xyz);
+
+ void plot(const char* filename, epix_mark_type TYPE,
+ P f(double, double, double),
+ unsigned int col1=1, unsigned int col2=2, unsigned int col3=0);
+
+ // pass 3rd arg by value
+ void histogram(const char* filename, unsigned int col, data_bins,
+ double scale=1);
+ void bar_chart(const char* filename, unsigned int col, data_bins,
+ double scale=1);
+} // end of namespace
+
+#endif /* EPIX_DATA_FILE */
diff --git a/graphics/epix/data_mask.cc b/graphics/epix/data_mask.cc
new file mode 100644
index 0000000000..d2f0290426
--- /dev/null
+++ b/graphics/epix/data_mask.cc
@@ -0,0 +1,76 @@
+/*
+ * data_mask.cc -- ePiX::data_mask class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "functions.h"
+#include "interval.h"
+#include "data_mask.h"
+
+namespace ePiX {
+
+ double identity(double x) { return x; }
+
+ data_mask::data_mask(std::string arg)
+ : m_range(arg), m_filter(identity), m_reverse(false) { }
+
+ data_mask::data_mask(std::string arg, double f(double))
+ : m_range(arg), m_filter(f), m_reverse(false) { }
+
+
+ data_mask::data_mask(const interval& range)
+ : m_range(range), m_filter(identity), m_reverse(false) { }
+
+ data_mask::data_mask(const interval& range, double f(double))
+ : m_range(range), m_filter(f), m_reverse(false) { }
+
+ data_mask::data_mask(double arg1, double arg2)
+ : m_range(arg1, arg2), m_filter(identity), m_reverse(false) { }
+
+ data_mask::data_mask(double arg1, double arg2, double f(double))
+ : m_range(arg1, arg2), m_filter(f), m_reverse(false) { }
+
+ data_mask& data_mask::reverse()
+ {
+ m_reverse = !m_reverse;
+ return *this;
+ }
+
+ bool data_mask::masks(double x) const
+ {
+ bool masked(!m_range.contains(m_filter(x)));
+
+ if (m_reverse)
+ masked = !masked;
+
+ return masked;
+ }
+} // end of namespace
diff --git a/graphics/epix/data_mask.h b/graphics/epix/data_mask.h
new file mode 100644
index 0000000000..e522af0975
--- /dev/null
+++ b/graphics/epix/data_mask.h
@@ -0,0 +1,66 @@
+/*
+ * data_mask.h -- ePiX::data_mask, for selective row removal from data_file
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.6
+ * Last Change: July 3, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_DATA_MASK
+#define EPIX_DATA_MASK
+
+#include <string>
+
+#include "interval.h"
+
+namespace ePiX {
+
+ class data_mask {
+ public:
+ data_mask(std::string);
+ data_mask(std::string, double f(double));
+
+ data_mask(const interval& range);
+ data_mask(const interval& range, double f(double));
+
+ data_mask(double range_min, double range_max);
+ data_mask(double range_min, double range_max,
+ double f(double));
+
+ data_mask& reverse(); // negate mask criterion
+ bool masks(double) const; // true if we mask arg
+
+ private:
+ interval m_range;
+ double (*m_filter)(double); // filter criterion
+ bool m_reverse;
+
+ }; // end of data_mask
+} // end of namespace
+
+#endif /* EPIX_DATA_MASK */
diff --git a/graphics/epix/debug.h b/graphics/epix/debug.h
new file mode 100644
index 0000000000..204063447a
--- /dev/null
+++ b/graphics/epix/debug.h
@@ -0,0 +1,37 @@
+#ifndef EPIX_DEBUG
+#define EPIX_DEBUG
+
+#include <iostream>
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include "pairs.h"
+#include "triples.h"
+
+#include "errors.h"
+
+namespace ePiX
+{
+ inline void debug_msg(const std::string& msg)
+ {
+ std::cerr << msg << std::endl;
+ }
+
+ inline void debug_print(const pair& arg, const std::string& msg="")
+ {
+ std::cerr << msg << " ("
+ << arg.x1() << ", "
+ << arg.x2() << ")" << std::endl;
+ }
+
+ inline void debug_print(const P& arg, const std::string& msg="")
+ {
+ std::cerr << msg << " ("
+ << arg.x1() << ", "
+ << arg.x2() << ", "
+ << arg.x3() << ")" << std::endl;
+ }
+
+}
+#endif /* EPIX_DEBUG */
diff --git a/graphics/epix/depcomp b/graphics/epix/depcomp
new file mode 100644
index 0000000000..04701da536
--- /dev/null
+++ b/graphics/epix/depcomp
@@ -0,0 +1,530 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-07-09.11
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+# This program 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, or (at your option)
+# any later version.
+
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mecanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/graphics/epix/deriv.h b/graphics/epix/deriv.h
new file mode 100644
index 0000000000..56214ef462
--- /dev/null
+++ b/graphics/epix/deriv.h
@@ -0,0 +1,49 @@
+/*
+ * deriv.h -- ePiX derivative function template
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 06, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_DERIV
+#define EPIX_DERIV
+
+#include "constants.h"
+
+namespace ePiX {
+
+ // moved from functions.h to hide global constant EPIX_EPSILON
+ template<class T> T deriv(T f(double), double t, double dt=EPIX_EPSILON)
+ {
+ return (1.0/dt)*(f(t+0.5*dt) - f(t-0.5*dt));
+ }
+} // end of namespace
+
+#endif /* EPIX_DERIV */
diff --git a/graphics/epix/doc/Makefile.am b/graphics/epix/doc/Makefile.am
new file mode 100644
index 0000000000..ec9ac95e5f
--- /dev/null
+++ b/graphics/epix/doc/Makefile.am
@@ -0,0 +1,45 @@
+# Makefile.am for ePiX v1.x "doc" directory
+#
+
+EPIXFLAGS = --no-defaults -I.. -L.. -lepix -v
+
+%.eepic: %.xp
+ ../epix-local $(EPIXFLAGS) $<
+
+XPS := $(wildcard *.xp)
+
+EEPICS = $(XPS:.xp=.eepic)
+
+CLEANFILES = *~ *.aux *.dvi *.log *.out *.idx *.ilg *.ind *.toc \
+ epix.info.bz2 manual_src.tar manual.pdf manual.ps \
+ manual_src.tar.gz manual.pdf.gz manual.ps.gz manual-stamp
+
+MAINTAINERCLEANFILES = *.eepic *.aux *.dvi *.log *.out *.toc *.idx *.ind *.ilg
+
+## Targets ##
+doc_DATA = manual.pdf.gz manual.ps.gz manual_src.tar.gz epix.info.bz2
+
+
+# tar up tex, xp, and eepic files; build ps, pdf
+manual-stamp: manual.tex $(XPS) $(EEPICS)
+ latex -interaction=batchmode manual &>/dev/null
+ latex -interaction=batchmode manual &>/dev/null
+ makeindex manual.idx &>/dev/null
+ ../laps-local --pdf manual.tex
+ touch manual-stamp
+
+manual_src.tar.gz: manual-stamp
+ tar -cf manual_src.tar manual.aux manual.ind manual.tex manual.toc \
+ $(XPS) $(EEPICS)
+ gzip -9 manual_src.tar
+
+#PS
+manual.ps.gz: manual-stamp
+ gzip -9 -c manual.ps > manual.ps.gz
+
+#PDF
+manual.pdf.gz: manual-stamp
+ gzip -9 -c manual.pdf > manual.pdf.gz
+
+epix.info.bz2: manual-stamp epix.info
+ bzip2 -fk epix.info
diff --git a/graphics/epix/doc/Makefile.in b/graphics/epix/doc/Makefile.in
new file mode 100644
index 0000000000..293c547251
--- /dev/null
+++ b/graphics/epix/doc/Makefile.in
@@ -0,0 +1,364 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for ePiX v1.x "doc" directory
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(docdir)"
+docDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASH_PATH = @BASH_PATH@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@
+ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RUNTIME_COMPILER = @RUNTIME_COMPILER@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+EPIXFLAGS = --no-defaults -I.. -L.. -lepix -v
+XPS := $(wildcard *.xp)
+EEPICS = $(XPS:.xp=.eepic)
+CLEANFILES = *~ *.aux *.dvi *.log *.out *.idx *.ilg *.ind *.toc \
+ epix.info.bz2 manual_src.tar manual.pdf manual.ps \
+ manual_src.tar.gz manual.pdf.gz manual.ps.gz manual-stamp
+
+MAINTAINERCLEANFILES = *.eepic *.aux *.dvi *.log *.out *.toc *.idx *.ind *.ilg
+doc_DATA = manual.pdf.gz manual.ps.gz manual_src.tar.gz epix.info.bz2
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+uninstall-info-am:
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(docdir)" || $(mkdir_p) "$(DESTDIR)$(docdir)"
+ @list='$(doc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+ $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(doc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(docdir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(docdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-docDATA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-docDATA uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-docDATA install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-docDATA \
+ uninstall-info-am
+
+
+%.eepic: %.xp
+ ../epix-local $(EPIXFLAGS) $<
+
+# tar up tex, xp, and eepic files; build ps, pdf
+manual-stamp: manual.tex $(XPS) $(EEPICS)
+ latex -interaction=batchmode manual &>/dev/null
+ latex -interaction=batchmode manual &>/dev/null
+ makeindex manual.idx &>/dev/null
+ ../laps-local --pdf manual.tex
+ touch manual-stamp
+
+manual_src.tar.gz: manual-stamp
+ tar -cf manual_src.tar manual.aux manual.ind manual.tex manual.toc \
+ $(XPS) $(EEPICS)
+ gzip -9 manual_src.tar
+
+#PS
+manual.ps.gz: manual-stamp
+ gzip -9 -c manual.ps > manual.ps.gz
+
+#PDF
+manual.pdf.gz: manual-stamp
+ gzip -9 -c manual.pdf > manual.pdf.gz
+
+epix.info.bz2: manual-stamp epix.info
+ bzip2 -fk epix.info
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/graphics/epix/doc/alignment.eepic b/graphics/epix/doc/alignment.eepic
new file mode 100644
index 0000000000..1c5d93bd48
--- /dev/null
+++ b/graphics/epix/doc/alignment.eepic
@@ -0,0 +1,19 @@
+%% Generated from alignment.xp on Fri Jan 7 14:18:43 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 72pt x 24pt
+%% Figure offset: right by 0pt, up by 0pt
+%%
+\setlength{\unitlength}{1pt}
+\begin{picture}(72,24)(-0,-0)
+%% ---
+\path(0.00140226,12)(12.001,12)(24.0006,12)(36.0002,12)(47.9998,12)
+ (59.9994,12)(71.999,12)
+\path(36,0.00046742)(36,12.0001)(36,23.9997)
+\put(36,12){\makebox(0,0)[bl]{\texttt{[tr]}}}
+\put(36,12){\makebox(0,0)[c]{{\circle*{3}}}}
+\put(36,12){\makebox(0,0)[br]{\texttt{[tl]}}}
+\put(36,12){\makebox(0,0)[tl]{\texttt{[br]}}}
+\put(36,12){\makebox(0,0)[tr]{\texttt{[bl]}}}
+\end{picture}
diff --git a/graphics/epix/doc/alignment.xp b/graphics/epix/doc/alignment.xp
new file mode 100644
index 0000000000..e6bfc3c298
--- /dev/null
+++ b/graphics/epix/doc/alignment.xp
@@ -0,0 +1,26 @@
+/* -*-ePiX-*- */
+/* alignment.c -- ePiX's reverse-LaTeX label alignment option */
+#include "epix.h"
+using namespace ePiX;
+
+P O(0,0);
+
+int main()
+{
+ bounding_box(P(-1,-1), P(1,1));
+ picture(P(72,24));
+ unitlength("1pt");
+
+ begin();
+
+ Line(O, E_1);
+ Line(O, E_2);
+
+ font_face("tt");
+ dot(O, P(0,0), "[tr]", tr);
+ label(O, P(0,0), "[tl]", tl);
+ label(O, P(0,0), "[br]", br);
+ label(O, P(0,0), "[bl]", bl);
+
+ end();
+}
diff --git a/graphics/epix/doc/alignment_lr.eepic b/graphics/epix/doc/alignment_lr.eepic
new file mode 100644
index 0000000000..111098caf3
--- /dev/null
+++ b/graphics/epix/doc/alignment_lr.eepic
@@ -0,0 +1,17 @@
+%% Generated from alignment_lr.xp on Fri Jan 7 14:18:31 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 72pt x 24pt
+%% Figure offset: right by 0pt, up by 0pt
+%%
+\setlength{\unitlength}{1pt}
+\begin{picture}(72,24)(-0,-0)
+%% ---
+\put(0,12){\makebox(0,0)[r]{\texttt{[l]}}}
+\put(0,12){\makebox(0,0)[c]{{\circle*{3}}}}
+\put(0,12){\makebox(0,0)[l]{\texttt{[r]}}}
+\put(72,12){\makebox(0,0)[b]{\texttt{[t]}}}
+\put(72,12){\makebox(0,0)[c]{{\circle*{3}}}}
+\put(72,12){\makebox(0,0)[t]{\texttt{[b]}}}
+\end{picture}
diff --git a/graphics/epix/doc/alignment_lr.xp b/graphics/epix/doc/alignment_lr.xp
new file mode 100644
index 0000000000..a6871278e3
--- /dev/null
+++ b/graphics/epix/doc/alignment_lr.xp
@@ -0,0 +1,24 @@
+/* -*-ePiX-*- */
+/* alignment_lr.c -- ePiX's reverse-LaTeX label alignment option */
+#include "epix.h"
+using namespace ePiX;
+
+P p1(-1,0), p2(1,0);
+
+int main()
+{
+ bounding_box(P(-1,-1), P(1,1));
+ picture(P(72,24));
+ unitlength("1pt");
+
+ begin();
+
+ font_face("tt");
+ dot(p1, P(0,0), "[l]", l);
+ label(p1, P(0,0), "[r]", r);
+
+ dot(p2, P(0,0), "[t]", t);
+ label(p2, P(0,0), "[b]", b);
+
+ end();
+}
diff --git a/graphics/epix/doc/arrow.eepic b/graphics/epix/doc/arrow.eepic
new file mode 100644
index 0000000000..98adf21b49
--- /dev/null
+++ b/graphics/epix/doc/arrow.eepic
@@ -0,0 +1,22 @@
+%% Generated from arrows.xp on Mon Jul 2 20:38:11 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 24 x 12pt
+%% Figure offset: left by 0pt, down by 0pt
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\setlength{\unitlength}{1pt}
+\begin{picture}(24,12)(-0,-0)
+\path(0,6)(24,6)
+%%
+\path(17.8125,4.875)(15.75,4.875)
+\path(19.875,5.25)(15.75,5.25)
+\path(21.9375,5.625)(15.75,5.625)
+\path(24,6)(15.75,6)
+\path(21.9375,6.375)(15.75,6.375)
+\path(19.875,6.75)(15.75,6.75)
+\path(17.8125,7.125)(15.75,7.125)
+\path(15.75,6)(15.75,4.5)(24,6)(15.75,7.5)(15.75,6)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/arrow.xp b/graphics/epix/doc/arrow.xp
new file mode 100644
index 0000000000..34c47ad5e0
--- /dev/null
+++ b/graphics/epix/doc/arrow.xp
@@ -0,0 +1,18 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(-2,-1),P(2,1), "24x12pt");
+
+ begin();
+#ifdef CAMBER25
+ arrow_camber(0.25);
+#elif CAMBER50
+ arrow_camber(0.5);
+#endif
+
+ arrow(P(xmin(),0), P(xmax(),0));
+ end();
+}
diff --git a/graphics/epix/doc/arrow25.eepic b/graphics/epix/doc/arrow25.eepic
new file mode 100644
index 0000000000..196889e2b2
--- /dev/null
+++ b/graphics/epix/doc/arrow25.eepic
@@ -0,0 +1,22 @@
+%% Generated from arrows.xp on Mon Jul 2 20:38:23 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 24 x 12pt
+%% Figure offset: left by 0pt, down by 0pt
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\setlength{\unitlength}{1pt}
+\begin{picture}(24,12)(-0,-0)
+\path(0,6)(24,6)
+%%
+\path(17.8125,4.875)(16.2656,4.875)
+\path(19.875,5.25)(16.7813,5.25)
+\path(21.9375,5.625)(17.2969,5.625)
+\path(24,6)(17.8125,6)
+\path(21.9375,6.375)(17.2969,6.375)
+\path(19.875,6.75)(16.7813,6.75)
+\path(17.8125,7.125)(16.2656,7.125)
+\path(17.8125,6)(15.75,4.5)(24,6)(15.75,7.5)(17.8125,6)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/arrow50.eepic b/graphics/epix/doc/arrow50.eepic
new file mode 100644
index 0000000000..e22fec0fd0
--- /dev/null
+++ b/graphics/epix/doc/arrow50.eepic
@@ -0,0 +1,22 @@
+%% Generated from arrows.xp on Mon Jul 2 20:38:34 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 24 x 12pt
+%% Figure offset: left by 0pt, down by 0pt
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\setlength{\unitlength}{1pt}
+\begin{picture}(24,12)(-0,-0)
+\path(0,6)(24,6)
+%%
+\path(17.8125,4.875)(16.7813,4.875)
+\path(19.875,5.25)(17.8125,5.25)
+\path(21.9375,5.625)(18.8438,5.625)
+\path(24,6)(19.875,6)
+\path(21.9375,6.375)(18.8438,6.375)
+\path(19.875,6.75)(17.8125,6.75)
+\path(17.8125,7.125)(16.7813,7.125)
+\path(19.875,6)(15.75,4.5)(24,6)(15.75,7.5)(19.875,6)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/basepoint.eepic b/graphics/epix/doc/basepoint.eepic
new file mode 100644
index 0000000000..efd76dfaa5
--- /dev/null
+++ b/graphics/epix/doc/basepoint.eepic
@@ -0,0 +1,16 @@
+%% Generated from basepoint.xp on Tue Jan 4 15:32:04 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [0,3.75] x [0,1]
+%% Actual size: 3.75pc x 1pc
+%% Figure offset: right by 0pc, up by 0pc
+%%
+\setlength{\unitlength}{1pc}
+\begin{picture}(3.75,1)(-0,-0)
+%% ---
+\path(0,-0.375)(3.75,-0.375)(3.75,1)(0,1)(0,-0.375)
+\allinethickness{0.15pt}%
+\path(0,0)(3.75,0)
+\put(0,0){$y=f(x)$}
+\put(0,0){\makebox(0,0)[c]{{\circle*{0.111111}}}}
+\end{picture}
diff --git a/graphics/epix/doc/basepoint.xp b/graphics/epix/doc/basepoint.xp
new file mode 100644
index 0000000000..7fc15f6cb1
--- /dev/null
+++ b/graphics/epix/doc/basepoint.xp
@@ -0,0 +1,36 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main() {
+ bounding_box(P(0,0),P(3.75,1));
+ unitlength("1pc");
+ picture(3.75,1);
+ // offset(-0.5,0);
+
+ begin();
+
+ rect(P(x_min, y_min-0.375), P(x_max, y_max));
+
+ pen(0.15);
+ line(P(x_min,0), P(x_max,0));
+
+ dot_size(2);
+
+ // std::cout << "\n\\LARGE";
+ /*
+ label(P(0,0), P(0,0), "$b$");
+ ddot(P(0,0));
+
+ label(P(1,0), P(0,0), "$f$");
+ ddot(P(1,0));
+
+ label(P(2,0), P(0,0), "$p$");
+ ddot(P(2,0));
+ */
+
+ label(P(0,0), P(0,0), "$y=f(x)$");
+ ddot(P(0,0));
+
+ end();
+}
diff --git a/graphics/epix/doc/camera.eepic b/graphics/epix/doc/camera.eepic
new file mode 100644
index 0000000000..7da56f9987
--- /dev/null
+++ b/graphics/epix/doc/camera.eepic
@@ -0,0 +1,285 @@
+%% Generated from camera.xp on Sat Sep 22 17:10:34 EDT 2007 by
+%% ePiX-1.2.0
+%%
+%% Cartesian bounding box: [-3.5,3.5] x [-3.5,2.5]
+%% Actual size: 2.625 x 2.25in
+%% Figure offset: left by 0in, down by 0in
+%%
+%% usepackages epic,eepic,xcolor
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}%
+\xdefinecolor{rgb_7f7f7f}{rgb}{0.498039,0.498039,0.498039}%
+\xdefinecolor{rgb_e5e5e5}{rgb}{0.898039,0.898039,0.898039}%
+\xdefinecolor{rgb_ffffff}{rgb}{1,1,1}%
+\setlength{\unitlength}{1in}%
+\begin{picture}(2.625,2.25)(0,0)%
+\path(1.42243,1.30711)(1.4086,1.26997)(1.29561,1.27568)
+\path(1.3125,1.3125)(1.4523,1.30564)(1.59359,1.29871)
+\path(1.3125,1.3125)(1.3125,1.44704)(1.3125,1.58496)
+\path(0.307912,0.721822)(0.173332,2.09409)(2.55902,2.04543)
+ (2.39965,0.566596)(0.307912,0.721822)
+\put(1.58249,0.490175){\makebox(0,0)[l]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Sea}}}}}
+\put(0.937572,1.11972){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Sky}}}}}
+\put(0.735053,0.174015){\makebox(0,0)[r]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Eye}}}}}
+\put(0.929482,0.537641){\makebox(0,0)[r]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Viewpoint}}}}
+\put(0.957156,0.537641){\color{rgb_000000}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(2.476,2.01776){\makebox(0,0)[tr]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Canvas}}}}
+\path(0.957156,0.537641)(1.17567,1.01413)(1.3125,1.3125)
+\color{rgb_7f7f7f}%
+\path(1.83216,0.911179)(1.84054,0.911179)
+\path(1.82052,0.916691)(1.83729,0.916691)
+\path(1.80888,0.922203)(1.83404,0.922203)
+\path(1.79724,0.927715)(1.83079,0.927715)
+\path(1.7856,0.933227)(1.82754,0.933227)
+\path(1.77396,0.938739)(1.82429,0.938739)
+\path(1.76232,0.944251)(1.82104,0.944251)
+\path(1.75068,0.949763)(1.81779,0.949763)
+\path(1.73904,0.955275)(1.81454,0.955275)
+\path(1.7274,0.960787)(1.81129,0.960787)
+\path(1.71576,0.966299)(1.80804,0.966299)
+\path(1.70412,0.971811)(1.80479,0.971811)
+\path(1.69248,0.977323)(1.80154,0.977323)
+\path(1.68084,0.982835)(1.79829,0.982835)
+\path(1.6692,0.988347)(1.79503,0.988347)
+\path(1.65756,0.993859)(1.79178,0.993859)
+\path(1.64592,0.999371)(1.78853,0.999371)
+\path(1.63428,1.00488)(1.78528,1.00488)
+\path(1.62264,1.0104)(1.78203,1.0104)
+\path(1.611,1.01591)(1.77878,1.01591)
+\path(1.60612,1.02142)(1.77553,1.02142)
+\path(1.60892,1.02693)(1.77228,1.02693)
+\path(1.61172,1.03244)(1.76903,1.03244)
+\path(1.61452,1.03796)(1.76578,1.03796)
+\path(1.61732,1.04347)(1.76253,1.04347)
+\path(1.62012,1.04898)(1.75928,1.04898)
+\path(1.62292,1.05449)(1.75603,1.05449)
+\path(1.62572,1.06)(1.75278,1.06)
+\path(1.62852,1.06551)(1.74952,1.06551)
+\path(1.63132,1.07103)(1.74627,1.07103)
+\path(1.63412,1.07654)(1.74302,1.07654)
+\path(1.63692,1.08205)(1.73977,1.08205)
+\path(1.63972,1.08756)(1.73652,1.08756)
+\path(1.64252,1.09307)(1.73327,1.09307)
+\path(1.64532,1.09859)(1.73002,1.09859)
+\path(1.64812,1.1041)(1.72677,1.1041)
+\path(1.65091,1.10961)(1.72352,1.10961)
+\path(1.65371,1.11512)(1.72027,1.11512)
+\path(1.65651,1.12063)(1.71702,1.12063)
+\path(1.65931,1.12615)(1.71377,1.12615)
+\path(1.66211,1.13166)(1.71052,1.13166)
+\path(1.66491,1.13717)(1.70726,1.13717)
+\path(1.66771,1.14268)(1.70401,1.14268)
+\path(1.67051,1.14819)(1.70076,1.14819)
+\path(1.67331,1.15371)(1.69751,1.15371)
+\path(1.67611,1.15922)(1.69426,1.15922)
+\path(1.67891,1.16473)(1.69101,1.16473)
+\path(1.68171,1.17024)(1.68776,1.17024)
+\path(1.83836,0.908239)(1.83836,0.914877)
+\path(1.83293,0.910811)(1.83293,0.924087)
+\path(1.8275,0.913384)(1.8275,0.933297)
+\path(1.82207,0.915956)(1.82207,0.942506)
+\path(1.81664,0.918528)(1.81664,0.951716)
+\path(1.81121,0.9211)(1.81121,0.960926)
+\path(1.80577,0.923672)(1.80577,0.970136)
+\path(1.80034,0.926244)(1.80034,0.979345)
+\path(1.79491,0.928816)(1.79491,0.988555)
+\path(1.78948,0.931388)(1.78948,0.997765)
+\path(1.78405,0.93396)(1.78405,1.00697)
+\path(1.77862,0.936532)(1.77862,1.01618)
+\path(1.77319,0.939104)(1.77319,1.02539)
+\path(1.76775,0.941676)(1.76775,1.0346)
+\path(1.76232,0.944248)(1.76232,1.04381)
+\path(1.75689,0.94682)(1.75689,1.05302)
+\path(1.75146,0.949392)(1.75146,1.06223)
+\path(1.74603,0.951964)(1.74603,1.07144)
+\path(1.7406,0.954536)(1.7406,1.08065)
+\path(1.73517,0.957108)(1.73517,1.08986)
+\path(1.72973,0.95968)(1.72973,1.09907)
+\path(1.7243,0.962252)(1.7243,1.10828)
+\path(1.71887,0.964824)(1.71887,1.11749)
+\path(1.71344,0.967396)(1.71344,1.1267)
+\path(1.70801,0.969968)(1.70801,1.13591)
+\path(1.70258,0.97254)(1.70258,1.14512)
+\path(1.69715,0.975112)(1.69715,1.15433)
+\path(1.69171,0.977684)(1.69171,1.16354)
+\path(1.68628,0.980256)(1.68628,1.17275)
+\path(1.68085,0.982828)(1.68085,1.16855)
+\path(1.67542,0.9854)(1.67542,1.15786)
+\path(1.66999,0.987972)(1.66999,1.14716)
+\path(1.66456,0.990544)(1.66456,1.13647)
+\path(1.65912,0.993116)(1.65912,1.12577)
+\path(1.65369,0.995689)(1.65369,1.11508)
+\path(1.64826,0.998261)(1.64826,1.10439)
+\path(1.64283,1.00083)(1.64283,1.09369)
+\path(1.6374,1.0034)(1.6374,1.083)
+\path(1.63197,1.00598)(1.63197,1.07231)
+\path(1.62654,1.00855)(1.62654,1.06161)
+\path(1.6211,1.01112)(1.6211,1.05092)
+\path(1.61567,1.01369)(1.61567,1.04022)
+\path(1.61024,1.01626)(1.61024,1.02953)
+\color{rgb_000000}%
+\path(1.68451,1.17575)(1.8438,0.905667)(1.60481,1.01884)(1.68451,1.17575)
+\path(1.55858,1.06528)(1.62462,1.12321)(1.68451,1.17575)
+\path(1.64966,0.825085)(1.75291,0.867943)(1.8438,0.905667)
+\path(1.42984,0.888834)(1.52409,0.958865)(1.60481,1.01884)
+\path(0.957156,0.537641)(1.4039,0.929569)(1.68451,1.17575)
+\path(0.957156,0.537641)(1.50556,0.765274)(1.8438,0.905667)
+\path(0.957156,0.537641)(1.35769,0.835234)(1.60481,1.01884)
+\color{rgb_e5e5e5}%
+\path(1.64572,0.826226)(1.5548,1.06009)
+\path(1.63918,0.828123)(1.55101,1.0549)
+\path(1.63264,0.830021)(1.54722,1.04971)
+\path(1.6261,0.831918)(1.54344,1.04452)
+\path(1.61955,0.833815)(1.53965,1.03933)
+\path(1.61301,0.835712)(1.53586,1.03414)
+\path(1.60647,0.837609)(1.53208,1.02895)
+\path(1.59993,0.839507)(1.52829,1.02376)
+\path(1.59339,0.841404)(1.5245,1.01857)
+\path(1.58684,0.843301)(1.52072,1.01338)
+\path(1.5803,0.845198)(1.51693,1.00819)
+\path(1.57376,0.847095)(1.51314,1.003)
+\path(1.56722,0.848993)(1.50936,0.997814)
+\path(1.56068,0.85089)(1.50557,0.992624)
+\path(1.55413,0.852787)(1.50178,0.987435)
+\path(1.54759,0.854684)(1.498,0.982245)
+\path(1.54105,0.856581)(1.49421,0.977056)
+\path(1.53451,0.858479)(1.49042,0.971866)
+\path(1.52797,0.860376)(1.48664,0.966677)
+\path(1.52142,0.862273)(1.48285,0.961487)
+\path(1.51488,0.86417)(1.47906,0.956298)
+\path(1.50834,0.866067)(1.47528,0.951108)
+\path(1.5018,0.867965)(1.47149,0.945919)
+\path(1.49526,0.869862)(1.4677,0.940729)
+\path(1.48871,0.871759)(1.46392,0.93554)
+\path(1.48217,0.873656)(1.46013,0.93035)
+\path(1.47563,0.875553)(1.45634,0.925161)
+\path(1.46909,0.877451)(1.45256,0.919971)
+\path(1.46255,0.879348)(1.44877,0.914781)
+\path(1.456,0.881245)(1.44498,0.909592)
+\path(1.44946,0.883142)(1.4412,0.904402)
+\path(1.44292,0.885039)(1.43741,0.899213)
+\path(1.43638,0.886937)(1.43362,0.894023)
+\path(1.56052,1.06017)(1.55261,1.05709)
+\path(1.56246,1.05506)(1.54664,1.04891)
+\path(1.5644,1.04995)(1.54066,1.04072)
+\path(1.56633,1.04484)(1.53469,1.03253)
+\path(1.56827,1.03973)(1.52872,1.02435)
+\path(1.57021,1.03461)(1.52274,1.01616)
+\path(1.57215,1.0295)(1.51677,1.00797)
+\path(1.57409,1.02439)(1.5108,0.999787)
+\path(1.57602,1.01928)(1.50482,0.991601)
+\path(1.57796,1.01417)(1.49885,0.983414)
+\path(1.5799,1.00906)(1.49288,0.975228)
+\path(1.58184,1.00395)(1.4869,0.967042)
+\path(1.58377,0.998841)(1.48093,0.958855)
+\path(1.58571,0.993731)(1.47496,0.950669)
+\path(1.58765,0.988621)(1.46898,0.942483)
+\path(1.58959,0.98351)(1.46301,0.934296)
+\path(1.59152,0.9784)(1.45704,0.92611)
+\path(1.59346,0.973289)(1.45106,0.917923)
+\path(1.5954,0.968179)(1.44509,0.909737)
+\path(1.59734,0.963068)(1.43911,0.901551)
+\path(1.59928,0.957958)(1.43314,0.893364)
+\path(1.60121,0.952847)(1.43369,0.887715)
+\path(1.60315,0.947737)(1.44233,0.88521)
+\path(1.60509,0.942626)(1.45097,0.882705)
+\path(1.60703,0.937516)(1.45961,0.880199)
+\path(1.60896,0.932405)(1.46825,0.877694)
+\path(1.6109,0.927295)(1.47689,0.875189)
+\path(1.61284,0.922184)(1.48552,0.872684)
+\path(1.61478,0.917074)(1.49416,0.870179)
+\path(1.61672,0.911963)(1.5028,0.867673)
+\path(1.61865,0.906853)(1.51144,0.865168)
+\path(1.62059,0.901742)(1.52008,0.862663)
+\path(1.62253,0.896632)(1.52872,0.860158)
+\path(1.62447,0.891521)(1.53736,0.857653)
+\path(1.6264,0.886411)(1.54599,0.855147)
+\path(1.62834,0.8813)(1.55463,0.852642)
+\path(1.63028,0.87619)(1.56327,0.850137)
+\path(1.63222,0.871079)(1.57191,0.847632)
+\path(1.63416,0.865969)(1.58055,0.845127)
+\path(1.63609,0.860858)(1.58919,0.842621)
+\path(1.63803,0.855748)(1.59783,0.840116)
+\path(1.63997,0.850637)(1.60646,0.837611)
+\path(1.64191,0.845527)(1.6151,0.835106)
+\path(1.64384,0.840416)(1.62374,0.8326)
+\path(1.64578,0.835306)(1.63238,0.830095)
+\path(1.64772,0.830195)(1.64102,0.82759)
+\color{rgb_000000}%
+\path(1.55858,1.06528)(1.64966,0.825085)(1.42984,0.888834)(1.55858,1.06528)
+\path(1.69177,1.3845)(1.6229,1.16677)(1.54714,0.927292)
+\put(1.69177,1.3845){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Object}}}}
+\path(2.05075,0.923554)(1.88188,0.980517)(1.71366,1.03726)
+\put(2.05075,0.923554){\makebox(0,0)[l]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Shadow}}}}
+\put(1.12218,1.68556){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Target}}}}
+\path(1.12218,1.68556)(1.29391,1.34894)
+\path(1.27634,1.40359)(1.2621,1.39054)
+\path(1.27896,1.39892)(1.26528,1.38638)
+\path(1.28062,1.39336)(1.26846,1.38222)
+\path(1.28229,1.38781)(1.27164,1.37806)
+\path(1.28395,1.38226)(1.27482,1.3739)
+\path(1.28561,1.3767)(1.278,1.36974)
+\path(1.28727,1.37115)(1.28118,1.36558)
+\path(1.28893,1.3656)(1.28437,1.36142)
+\path(1.29059,1.36005)(1.28755,1.35726)
+\path(1.29225,1.35449)(1.29073,1.3531)
+\path(1.25949,1.39395)(1.29061,1.35998)
+\path(1.26348,1.39703)(1.28731,1.37102)
+\path(1.26812,1.39939)(1.28401,1.38205)
+\path(1.27276,1.40176)(1.28071,1.39309)
+\path(1.26816,1.39941)(1.25892,1.3947)(1.29391,1.34894)
+ (1.2774,1.40413)(1.26816,1.39941)
+\put(1.3125,1.3125){\color{rgb_000000}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.8pt}%
+\path(0.957156,0.537641)(1.55482,0.490175)
+\allinethickness{0.0055348in}%
+\path(1.4989,0.489651)(1.50786,0.485229)
+\path(1.49933,0.495061)(1.51726,0.486218)
+\path(1.49976,0.500472)(1.52665,0.487207)
+\path(1.50454,0.503736)(1.53604,0.488197)
+\path(1.52968,0.496955)(1.54543,0.489186)
+\path(1.54888,0.489549)(1.54985,0.491516)
+\path(1.54293,0.488923)(1.54487,0.492858)
+\path(1.53699,0.488297)(1.5399,0.494199)
+\path(1.53104,0.487671)(1.53493,0.495541)
+\path(1.5251,0.487045)(1.52995,0.496882)
+\path(1.51916,0.486419)(1.52498,0.498223)
+\path(1.51321,0.485792)(1.52001,0.499565)
+\path(1.50727,0.485166)(1.51504,0.500906)
+\path(1.50133,0.48454)(1.51006,0.502247)
+\path(1.49903,0.491318)(1.50509,0.503589)
+\allinethickness{0.8pt}%
+\path(1.49929,0.494585)(1.49847,0.48424)(1.55482,0.490175)
+ (1.50012,0.50493)(1.49929,0.494585)
+\path(0.957156,0.537641)(0.790401,0.174015)
+\allinethickness{0.0055348in}%
+\path(0.807364,0.192334)(0.808098,0.200697)
+\path(0.80171,0.186228)(0.803178,0.202954)
+\path(0.796055,0.180122)(0.798257,0.20521)
+\path(0.807022,0.201191)(0.793617,0.202367)
+\path(0.810836,0.196084)(0.793081,0.197642)
+\path(0.806749,0.19167)(0.792545,0.192917)
+\path(0.802662,0.187256)(0.792009,0.188191)
+\path(0.798575,0.182843)(0.791473,0.183466)
+\path(0.794488,0.178429)(0.790937,0.178741)
+\allinethickness{0.8pt}%
+\path(0.803586,0.202767)(0.794153,0.207092)(0.790401,0.174015)
+ (0.813019,0.198441)(0.803586,0.202767)
+\path(0.957156,0.537641)(0.937572,1.09205)
+\allinethickness{0.0055348in}%
+\path(0.938782,1.08718)(0.936611,1.08655)
+\path(0.939993,1.08231)(0.935649,1.08104)
+\path(0.941204,1.07743)(0.934688,1.07554)
+\path(0.942414,1.07256)(0.933727,1.07003)
+\path(0.943625,1.06769)(0.932765,1.06453)
+\path(0.944835,1.06282)(0.931804,1.05902)
+\path(0.946046,1.05794)(0.930842,1.05352)
+\path(0.947256,1.05307)(0.929881,1.04801)
+\path(0.948467,1.0482)(0.929251,1.04261)
+\path(0.931094,1.05496)(0.934635,1.0428)
+\path(0.933253,1.06732)(0.940334,1.043)
+\path(0.935413,1.07969)(0.946034,1.0432)
+\allinethickness{0.8pt}%
+\path(0.939306,1.04296)(0.949677,1.04333)(0.937572,1.09205)
+ (0.928935,1.0426)(0.939306,1.04296)
+\end{picture}%
diff --git a/graphics/epix/doc/camera.xp b/graphics/epix/doc/camera.xp
new file mode 100644
index 0000000000..66f8fdb334
--- /dev/null
+++ b/graphics/epix/doc/camera.xp
@@ -0,0 +1,86 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double ht(4);
+
+const P target(0,0,0);
+const P observer(0,-4,0);
+const P dtarg(-0.5,0,1);
+const double dx(0.375);
+
+// location of label
+const P obj_loc(1,0,0.25);
+
+P F(P arg)
+{
+ double x(arg.x2());
+ return (ht/(ht+x))*P(arg.x1(), 0, arg.x3());
+}
+
+P P1(0.75, -1, -0.25);
+P P2(1, -1.25, -0.75);
+P P3(0.5, -1.5, -0.5 );
+P midpt((1.0/3)*(P1+P2+P3));
+
+int main() {
+ bounding_box(P(-3.5,-3.5),P(3.5,2.5));
+ unitlength("0.375in");
+ picture(P(7,6));
+
+ begin();
+
+ camera.at(P(1.5,-10,3.5));
+ camera.range(10);
+
+ font_size("footnotesize");
+ right_angle(target, E_1, -E_2);
+
+ line(target, target+2*dx*E_1);
+ line(target, target+2*dx*E_3);
+
+ // grid(P(-3,0,-2), P(3,0,2), 6, 8);
+ grid(P(-3,0,-2), P(3,0,2));
+
+ masklabel(observer+E_1, P(2,0), "\\textbf{Sea}", r);
+ masklabel(observer+E_3, P(0,2), "\\textbf{Sky}", t);
+ masklabel(observer-E_2, P(-4,0), "\\textbf{Eye}", l);
+
+ masklabel(observer, P(-2,0), "Viewpoint", l);
+ dot(observer);
+
+ masklabel(P(3,0,2), P(-6,-2), "Canvas", bl);
+
+ line(observer, target);
+
+ fill(Black(0.5));
+ triangle(F(P1), F(P2), F(P3));
+
+ line(P1, F(P1));
+ line(P2, F(P2));
+ line(P3, F(P3));
+
+ line(observer, F(P1));
+ line(observer, F(P2));
+ line(observer, F(P3));
+
+ fill(Black(0.1));
+ triangle(P1, P2, P3);
+
+ line(obj_loc, midpt);
+ masklabel(obj_loc, P(0,0), "Object", t);
+
+ line(P(2,0,-1), F(midpt));
+ masklabel(P(2,0,-1), P(0,0), "Shadow", r);
+
+ masklabel(target+dtarg, P(0,0), "Target", t);
+ arrow(target+dtarg, target+0.1*dtarg, 0.5);
+ dot(target);
+
+ bold();
+ arrow(observer, observer+E_1, 0.5);
+ arrow(observer, observer-E_2, 0.5);
+ arrow(observer, observer+E_3, 0.5);
+
+ end();
+}
diff --git a/graphics/epix/doc/cb.eepic b/graphics/epix/doc/cb.eepic
new file mode 100644
index 0000000000..7df0354645
--- /dev/null
+++ b/graphics/epix/doc/cb.eepic
@@ -0,0 +1,25 @@
+%% Generated from cb.xp on Tue Jan 4 15:32:10 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 1.5in x 0.75in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(1.5,0.75)(-0,-0)
+%% ---
+\path(0,0.375)(1.5,0.375)
+\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+%% ---
+\path(0.75,0)(0.75,0.75)
+\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+%% ---
+\thicklines
+\path(0,0.375)(0.375,0.75)(0.75,0.375)(1.125,0.75)(1.5,0.375)
+\put(0.75,-0.055348){\makebox(0,0)[t]{\code{cb}}}
+\end{picture}
diff --git a/graphics/epix/doc/cb.xp b/graphics/epix/doc/cb.xp
new file mode 100644
index 0000000000..e0434b483e
--- /dev/null
+++ b/graphics/epix/doc/cb.xp
@@ -0,0 +1,22 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ bounding_box(P(-2,-1),P(2,1));
+ unitlength("1in");
+ picture(1.5,0.75);
+
+ begin();
+
+ h_axis(4);
+ v_axis(1);
+
+ bold();
+ plot(cb, x_min, x_max, 4);
+
+ label(P(0,y_min), P(0,-4), "\\code{cb}", b);
+
+ end();
+}
diff --git a/graphics/epix/doc/color_density.eepic b/graphics/epix/doc/color_density.eepic
new file mode 100644
index 0000000000..1b0ee79028
--- /dev/null
+++ b/graphics/epix/doc/color_density.eepic
@@ -0,0 +1,139 @@
+%% Generated from color_density.xp on Thu Jul 5 10:01:14 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-2,2] x [0,1.375]
+%% Actual size: 4 x 1.5in
+%% Figure offset: left by 0in, down by 0in
+%%
+\newrgbcolor{rgb_000000}{0 0 0}
+\newrgbcolor{rgb_005454}{0 0.329412 0.329412}
+\newrgbcolor{rgb_00a9a9}{0 0.662745 0.662745}
+\newrgbcolor{rgb_00fefe}{0 0.996078 0.996078}
+\newrgbcolor{rgb_00ffff}{0 1 1}
+\newrgbcolor{rgb_540000}{0.329412 0 0}
+\newrgbcolor{rgb_54ffff}{0.329412 1 1}
+\newrgbcolor{rgb_a90000}{0.662745 0 0}
+\newrgbcolor{rgb_a9ffff}{0.662745 1 1}
+\newrgbcolor{rgb_fe0000}{0.996078 0 0}
+\newrgbcolor{rgb_feffff}{0.996078 1 1}
+\newrgbcolor{rgb_ff0000}{1 0 0}
+\newrgbcolor{rgb_ff5454}{1 0.329412 0.329412}
+\newrgbcolor{rgb_ffa9a9}{1 0.662745 0.662745}
+\newrgbcolor{rgb_fffefe}{1 0.996078 0.996078}
+\psset{unit=1in,linewidth=0.4pt}
+\begin{pspicture}(4,1.5)(-0,-0)
+\psset{fillcolor=rgb_feffff}%
+\psline[fillstyle=solid]
+ (-0.123,1.22727)(0.127,1.22727)(0.127,1.5)(-0.123,1.5)(-0.123,1.22727)
+%%
+\psline(-0.123,1.22727)(0.127,1.22727)(0.127,1.5)(-0.123,1.5)(-0.123,1.22727)
+%%
+\psset{fillcolor=rgb_a9ffff}%
+\psline[fillstyle=solid]
+ (0.21,1.22727)(0.46,1.22727)(0.46,1.5)(0.21,1.5)(0.21,1.22727)
+%%
+\psline(0.21,1.22727)(0.46,1.22727)(0.46,1.5)(0.21,1.5)(0.21,1.22727)
+%%
+\psset{fillcolor=rgb_54ffff}%
+\psline[fillstyle=solid]
+ (0.543,1.22727)(0.793,1.22727)(0.793,1.5)(0.543,1.5)(0.543,1.22727)
+%%
+\psline(0.543,1.22727)(0.793,1.22727)(0.793,1.5)(0.543,1.5)(0.543,1.22727)
+%%
+\psset{fillcolor=rgb_00fefe}%
+\psline[fillstyle=solid]
+ (0.876,1.22727)(1.126,1.22727)(1.126,1.5)(0.876,1.5)(0.876,1.22727)
+%%
+\psline(0.876,1.22727)(1.126,1.22727)(1.126,1.5)(0.876,1.5)(0.876,1.22727)
+%%
+\psset{fillcolor=rgb_00a9a9}%
+\psline[fillstyle=solid]
+ (1.209,1.22727)(1.459,1.22727)(1.459,1.5)(1.209,1.5)(1.209,1.22727)
+%%
+\psline(1.209,1.22727)(1.459,1.22727)(1.459,1.5)(1.209,1.5)(1.209,1.22727)
+%%
+\psset{fillcolor=rgb_005454}%
+\psline[fillstyle=solid]
+ (1.542,1.22727)(1.792,1.22727)(1.792,1.5)(1.542,1.5)(1.542,1.22727)
+%%
+\psline(1.542,1.22727)(1.792,1.22727)(1.792,1.5)(1.542,1.5)(1.542,1.22727)
+%%
+\psset{fillcolor=rgb_000000}%
+\psline[fillstyle=solid]
+ (1.875,1.22727)(2.125,1.22727)(2.125,1.5)(1.875,1.5)(1.875,1.22727)
+%%
+\psline(1.875,1.22727)(2.125,1.22727)(2.125,1.5)(1.875,1.5)(1.875,1.22727)
+%%
+\psset{fillcolor=rgb_540000}%
+\psline[fillstyle=solid]
+ (2.208,1.22727)(2.458,1.22727)(2.458,1.5)(2.208,1.5)(2.208,1.22727)
+%%
+\psline(2.208,1.22727)(2.458,1.22727)(2.458,1.5)(2.208,1.5)(2.208,1.22727)
+%%
+\psset{fillcolor=rgb_a90000}%
+\psline[fillstyle=solid]
+ (2.541,1.22727)(2.791,1.22727)(2.791,1.5)(2.541,1.5)(2.541,1.22727)
+%%
+\psline(2.541,1.22727)(2.791,1.22727)(2.791,1.5)(2.541,1.5)(2.541,1.22727)
+%%
+\psset{fillcolor=rgb_fe0000}%
+\psline[fillstyle=solid]
+ (2.874,1.22727)(3.124,1.22727)(3.124,1.5)(2.874,1.5)(2.874,1.22727)
+%%
+\psline(2.874,1.22727)(3.124,1.22727)(3.124,1.5)(2.874,1.5)(2.874,1.22727)
+%%
+\psset{fillcolor=rgb_ff5454}%
+\psline[fillstyle=solid]
+ (3.207,1.22727)(3.457,1.22727)(3.457,1.5)(3.207,1.5)(3.207,1.22727)
+%%
+\psline(3.207,1.22727)(3.457,1.22727)(3.457,1.5)(3.207,1.5)(3.207,1.22727)
+%%
+\psset{fillcolor=rgb_ffa9a9}%
+\psline[fillstyle=solid]
+ (3.54,1.22727)(3.79,1.22727)(3.79,1.5)(3.54,1.5)(3.54,1.22727)
+%%
+\psline(3.54,1.22727)(3.79,1.22727)(3.79,1.5)(3.54,1.5)(3.54,1.22727)
+%%
+\psset{fillcolor=rgb_fffefe}%
+\psline[fillstyle=solid]
+ (3.873,1.22727)(4.123,1.22727)(4.123,1.5)(3.873,1.5)(3.873,1.22727)
+%%
+\psline(3.873,1.22727)(4.123,1.22727)(4.123,1.5)(3.873,1.5)(3.873,1.22727)
+%%
+\psline(0,0)(4,0)
+%%
+\rput(0,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}}
+\rput(1,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}}
+\rput(2,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}}
+\rput(3,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}}
+\rput(4,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}}
+\psline(2,0)(2,1.09091)
+%%
+\rput(2,0){\makebox(0,0){{$\rule{4pt}{0.5pt}$}}}
+\rput(2,1.09091){\makebox(0,0){{$\rule{4pt}{0.5pt}$}}}
+\rput(0,-0.055348){\makebox(0,0)[t]{{$-2$}}}
+\rput(1,-0.055348){\makebox(0,0)[t]{{$-1$}}}
+\rput(2,-0.055348){\makebox(0,0)[t]{{$\phantom{-}0$}}}
+\rput(3,-0.055348){\makebox(0,0)[t]{{$\phantom{-}1$}}}
+\rput(4,-0.055348){\makebox(0,0)[t]{{$\phantom{-}2$}}}
+\psset{linecolor=rgb_00ffff}%
+\psline(0,1.09091)(1,1.09091)
+%%
+\psline(1,1.09091)(2,0)
+%%
+\psline(2,0)(3,0)
+%%
+\psline(3,0)(4,1.09091)
+%%
+\psset{linewidth=0.8pt}%
+\psset{linecolor=rgb_ff0000}%
+\psline
+ (0,1.09091)(1,0)
+%%
+\psline(1,0)(2,0)
+%%
+\psline(2,0)(3,1.09091)
+%%
+\psline(3,1.09091)(4,1.09091)
+%%
+\end{pspicture}
diff --git a/graphics/epix/doc/color_density.xp b/graphics/epix/doc/color_density.xp
new file mode 100644
index 0000000000..f561fa43e3
--- /dev/null
+++ b/graphics/epix/doc/color_density.xp
@@ -0,0 +1,42 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double dX(0.125), dY(0.25);
+
+int main()
+{
+ picture(P(-2, 0), P(2, 1.125 + dY), "4 x 1.5in");
+
+ begin();
+
+ fill();
+ for (int i=-6; i<=6; ++i)
+ {
+ const double x(0.333*i);
+ fill(Red(x));
+ rect(P(x-dX, 1.125), P(x+dX, 1.125+dY));
+ }
+ nofill();
+
+ h_axis(4);
+ v_axis(P(0,0), P(0,1), 1);
+
+ h_axis_labels(4, P(0,-4), b);
+ red(-1);
+ line(P(-2,1), P(-1,1));
+ line(P(-1,1), P(0,0));
+ line(P(0,0), P(1,0));
+ line(P(1,0), P(2,1));
+
+ red();
+ bold();
+ line(P(-2,1), P(-1,0));
+ line(P(-1,0), P(0,0));
+
+ line(P(0,0), P(1,1));
+ line(P(1,1), P(2,1));
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/doc/dots.eepic b/graphics/epix/doc/dots.eepic
new file mode 100644
index 0000000000..839663481d
--- /dev/null
+++ b/graphics/epix/doc/dots.eepic
@@ -0,0 +1,19 @@
+%% Generated from dots.xp on Tue Jan 4 15:32:12 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [0,8] x [0,1]
+%% Actual size: 72pt x 12pt
+%% Figure offset: right by 10pt, up by 2pt
+%%
+\setlength{\unitlength}{1pt}
+\begin{picture}(72,12)(-10,-2)
+%% ---
+\put(0,0){\makebox(0,0)[c]{{\circle*{4.5}}}}
+\put(9,0){\makebox(0,0)[c]{{\circle*{3}}}}
+\put(18,0){\makebox(0,0)[c]{{\circle*{2}}}}
+\put(36,0){\makebox(0,0)[c]{\rule{3pt}{3pt}}}
+\put(45,0){\makebox(0,0)[c]{\rule{2pt}{2pt}}}
+\path(58.5,0)(78.75,0)
+\put(63,0){\makebox(0,0)[c]{{\circle{4.5}}}}
+\whiten\put(72,0){\makebox(0,0)[c]{{\circle{3}}}}
+\end{picture}
diff --git a/graphics/epix/doc/dots.xp b/graphics/epix/doc/dots.xp
new file mode 100644
index 0000000000..1f13fb6099
--- /dev/null
+++ b/graphics/epix/doc/dots.xp
@@ -0,0 +1,28 @@
+/* -*-ePiX-*- */
+/* dots.c -- Dot primitives */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ unitlength("1pt");
+ bounding_box(P(0,0), P(8,1));
+ picture(P(72,12));
+ offset(P(10,2));
+
+ begin();
+
+ spot(P(0,0));
+ dot(P(1,0));
+ ddot(P(2,0));
+
+ box(P(4,0));
+ bbox(P(5,0));
+
+ line(P(6.5,0), P(8.75,0));
+
+ ring(P(7,0));
+ circ(P(8,0));
+
+ end();
+}
diff --git a/graphics/epix/doc/ePiX.eepic b/graphics/epix/doc/ePiX.eepic
new file mode 100644
index 0000000000..4bdec31118
--- /dev/null
+++ b/graphics/epix/doc/ePiX.eepic
@@ -0,0 +1,1099 @@
+%% Generated from ePiX.xp on Sat Sep 22 20:16:03 EDT 2007 by
+%% ePiX-1.2.0
+%%
+%% Cartesian bounding box: [-0.5,5.75] x [2,10]
+%% Actual size: 4 x 7.5in
+%% Figure offset: left by 0in, down by 0in
+%%
+%% usepackages epic,eepic,xcolor
+%%
+\xdefinecolor{cmy_000019}{cmyk}{0,0,0.0980392,0}%
+\xdefinecolor{rgb_0000ff}{rgb}{0,0,1}%
+\xdefinecolor{rgb_009800}{rgb}{0,0.596078,0}%
+\xdefinecolor{rgb_7f7f7f}{rgb}{0.498039,0.498039,0.498039}%
+\xdefinecolor{rgb_ff0000}{rgb}{1,0,0}%
+\setlength{\unitlength}{1in}%
+\begin{picture}(4,7.5)(0,0)%
+\color{rgb_7f7f7f}%
+\path(0.32,7.03125)(0.96,7.03125)
+\path(0.902922,7.02606)(0.931461,7.02606)
+\path(0.902922,7.03125)(0.96,7.03125)
+\path(0.902922,7.03644)(0.931461,7.03644)
+\path(0.954811,7.03031)(0.954811,7.03219)
+\path(0.949622,7.02936)(0.949622,7.03314)
+\path(0.944433,7.02842)(0.944433,7.03408)
+\path(0.939244,7.02748)(0.939244,7.03502)
+\path(0.934056,7.02653)(0.934056,7.03597)
+\path(0.928867,7.02559)(0.928867,7.03691)
+\path(0.923678,7.02465)(0.923678,7.03785)
+\path(0.918489,7.0237)(0.918489,7.0388)
+\path(0.9133,7.02276)(0.9133,7.03974)
+\path(0.908111,7.02182)(0.908111,7.04068)
+\path(0.902922,7.02087)(0.902922,7.04163)
+\path(0.902922,7.03125)(0.902922,7.02087)(0.96,7.03125)
+ (0.902922,7.04163)(0.902922,7.03125)
+\put(0.32,7.0866){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{xp}, \texttt{flx}}}}
+\put(0.32,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(0.97999,7.08981){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{eepic}}}}
+\put(0.96,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(0.96,7.03125)(0.963187,7.03115)(0.966347,7.03086)
+ (0.969482,7.03039)(0.972591,7.02972)(0.975676,7.02888)
+ (0.978736,7.02785)(0.981772,7.02665)(0.984785,7.02528)
+ (0.987774,7.02374)(0.990741,7.02203)(0.993685,7.02016)
+ (0.996608,7.01813)(0.999509,7.01594)(1.00239,7.0136)
+ (1.00525,7.01111)(1.00809,7.00847)(1.01091,7.00569)
+ (1.01371,7.00277)(1.01649,6.99972)(1.01926,6.99653)
+ (1.02201,6.99321)(1.02474,6.98976)(1.02745,6.98619)(1.03014,6.9825)
+ (1.03282,6.97869)(1.03549,6.97477)(1.03814,6.97074)(1.04077,6.9666)
+ (1.04339,6.96235)(1.046,6.95801)(1.04859,6.95356)(1.05117,6.94903)
+ (1.05374,6.9444)(1.0563,6.93968)(1.05884,6.93488)(1.06138,6.93)
+ (1.0639,6.92504)(1.06641,6.92)(1.06891,6.9149)(1.07141,6.90972)
+ (1.07389,6.90448)(1.07637,6.89918)(1.07884,6.89382)(1.0813,6.8884)
+ (1.08375,6.88293)(1.0862,6.87742)(1.08864,6.87185)(1.09107,6.86625)
+ (1.0935,6.86061)(1.09593,6.85493)(1.09835,6.84921)(1.10076,6.84347)
+ (1.10317,6.8377)(1.10558,6.83191)(1.10799,6.8261)(1.1104,6.82028)
+ (1.1128,6.81444)(1.1152,6.80859)(1.1176,6.80273)(1.12,6.79688)
+ (1.1224,6.79102)(1.1248,6.78516)(1.1272,6.77931)(1.1296,6.77347)
+ (1.13201,6.76765)(1.13442,6.76184)(1.13683,6.75605)
+ (1.13924,6.75028)(1.14165,6.74454)(1.14407,6.73882)(1.1465,6.73314)
+ (1.14893,6.7275)(1.15136,6.7219)(1.1538,6.71633)(1.15625,6.71082)
+ (1.1587,6.70535)(1.16116,6.69993)(1.16363,6.69457)(1.16611,6.68927)
+ (1.16859,6.68403)(1.17109,6.67885)(1.17359,6.67375)(1.1761,6.66871)
+ (1.17862,6.66375)(1.18116,6.65887)(1.1837,6.65407)(1.18626,6.64935)
+ (1.18883,6.64472)(1.19141,6.64019)(1.194,6.63574)(1.19661,6.6314)
+ (1.19923,6.62715)(1.20186,6.62301)(1.20451,6.61898)
+ (1.20718,6.61506)(1.20986,6.61125)(1.21255,6.60756)
+ (1.21526,6.60399)(1.21799,6.60054)(1.22074,6.59722)
+ (1.22351,6.59403)(1.22629,6.59098)(1.22909,6.58806)
+ (1.23191,6.58528)(1.23475,6.58264)(1.23761,6.58015)
+ (1.24049,6.57781)(1.24339,6.57562)(1.24631,6.57359)
+ (1.24926,6.57172)(1.25223,6.57001)(1.25522,6.56847)(1.25823,6.5671)
+ (1.26126,6.5659)(1.26432,6.56487)(1.26741,6.56403)(1.27052,6.56336)
+ (1.27365,6.56289)(1.27681,6.5626)(1.28,6.5625)
+\path(1.28,6.5625)(1.6,6.5625)
+\allinethickness{0.0055348in}%
+\path(1.59481,6.56156)(1.59402,6.56359)
+\path(1.58962,6.56061)(1.58804,6.56467)
+\path(1.58443,6.55967)(1.58207,6.56576)
+\path(1.57924,6.55873)(1.57609,6.56685)
+\path(1.57406,6.55778)(1.57011,6.56793)
+\path(1.56887,6.55684)(1.56413,6.56902)
+\path(1.56368,6.5559)(1.55815,6.57011)
+\path(1.55849,6.55495)(1.55217,6.5712)
+\path(1.5533,6.55401)(1.5462,6.57228)
+\path(1.54811,6.55307)(1.54292,6.56641)
+\path(1.55244,6.57115)(1.54292,6.56745)
+\path(1.56195,6.56942)(1.54292,6.56202)
+\path(1.57146,6.56769)(1.54292,6.55659)
+\path(1.58097,6.56596)(1.54755,6.55296)
+\path(1.59049,6.56423)(1.57377,6.55773)
+\allinethickness{1.2pt}%
+\path(1.54292,6.5625)(1.54292,6.55212)(1.6,6.5625)(1.54292,6.57288)(1.54292,6.5625)
+\path(1.6,6.5625)(2.24,6.5625)
+\allinethickness{0.0055348in}%
+\path(2.18926,6.57172)(2.18292,6.56591)
+\path(2.19561,6.57057)(2.18292,6.55895)
+\path(2.20195,6.56942)(2.1831,6.55216)
+\path(2.20829,6.56827)(2.19259,6.55388)
+\path(2.21463,6.56711)(2.20207,6.5556)
+\path(2.22097,6.56596)(2.21155,6.55733)
+\path(2.22732,6.56481)(2.22103,6.55905)
+\path(2.23366,6.56365)(2.23052,6.56078)
+\path(2.18292,6.5602)(2.18926,6.55328)
+\path(2.18292,6.56827)(2.19561,6.55443)
+\path(2.18674,6.57218)(2.20195,6.55558)
+\path(2.19562,6.57057)(2.20829,6.55673)
+\path(2.20449,6.56896)(2.21463,6.55789)
+\path(2.21337,6.56734)(2.22097,6.55904)
+\path(2.22225,6.56573)(2.22732,6.56019)
+\path(2.23112,6.56411)(2.23366,6.56135)
+\allinethickness{1.2pt}%
+\path(2.18292,6.5625)(2.18292,6.55212)(2.24,6.5625)
+ (2.18292,6.57288)(2.18292,6.5625)
+\put(1.6,6.61785){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{dvi}}}}}
+\put(1.6,6.5625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(2.21793,6.59482){\makebox(0,0)[br]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{ps}}}}}
+\put(2.24,6.5625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(0.96,6.09375)(0.963187,6.09385)(0.966347,6.09414)
+ (0.969482,6.09461)(0.972591,6.09528)(0.975676,6.09612)
+ (0.978736,6.09715)(0.981772,6.09835)(0.984785,6.09972)
+ (0.987774,6.10126)(0.990741,6.10297)(0.993685,6.10484)
+ (0.996608,6.10687)(0.999509,6.10906)(1.00239,6.1114)
+ (1.00525,6.11389)(1.00809,6.11653)(1.01091,6.11931)
+ (1.01371,6.12223)(1.01649,6.12528)(1.01926,6.12847)
+ (1.02201,6.13179)(1.02474,6.13524)(1.02745,6.13881)(1.03014,6.1425)
+ (1.03282,6.14631)(1.03549,6.15023)(1.03814,6.15426)(1.04077,6.1584)
+ (1.04339,6.16265)(1.046,6.16699)(1.04859,6.17144)(1.05117,6.17597)
+ (1.05374,6.1806)(1.0563,6.18532)(1.05884,6.19012)(1.06138,6.195)
+ (1.0639,6.19996)(1.06641,6.205)(1.06891,6.2101)(1.07141,6.21528)
+ (1.07389,6.22052)(1.07637,6.22582)(1.07884,6.23118)(1.0813,6.2366)
+ (1.08375,6.24207)(1.0862,6.24758)(1.08864,6.25315)(1.09107,6.25875)
+ (1.0935,6.26439)(1.09593,6.27007)(1.09835,6.27579)(1.10076,6.28153)
+ (1.10317,6.2873)(1.10558,6.29309)(1.10799,6.2989)(1.1104,6.30472)
+ (1.1128,6.31056)(1.1152,6.31641)(1.1176,6.32227)(1.12,6.32812)
+ (1.1224,6.33398)(1.1248,6.33984)(1.1272,6.34569)(1.1296,6.35153)
+ (1.13201,6.35735)(1.13442,6.36316)(1.13683,6.36895)
+ (1.13924,6.37472)(1.14165,6.38046)(1.14407,6.38618)(1.1465,6.39186)
+ (1.14893,6.3975)(1.15136,6.4031)(1.1538,6.40867)(1.15625,6.41418)
+ (1.1587,6.41965)(1.16116,6.42507)(1.16363,6.43043)(1.16611,6.43573)
+ (1.16859,6.44097)(1.17109,6.44615)(1.17359,6.45125)(1.1761,6.45629)
+ (1.17862,6.46125)(1.18116,6.46613)(1.1837,6.47093)(1.18626,6.47565)
+ (1.18883,6.48028)(1.19141,6.48481)(1.194,6.48926)(1.19661,6.4936)
+ (1.19923,6.49785)(1.20186,6.50199)(1.20451,6.50602)
+ (1.20718,6.50994)(1.20986,6.51375)(1.21255,6.51744)
+ (1.21526,6.52101)(1.21799,6.52446)(1.22074,6.52778)
+ (1.22351,6.53097)(1.22629,6.53402)(1.22909,6.53694)
+ (1.23191,6.53972)(1.23475,6.54236)(1.23761,6.54485)
+ (1.24049,6.54719)(1.24339,6.54938)(1.24631,6.55141)
+ (1.24926,6.55328)(1.25223,6.55499)(1.25522,6.55653)(1.25823,6.5579)
+ (1.26126,6.5591)(1.26432,6.56013)(1.26741,6.56097)(1.27052,6.56164)
+ (1.27365,6.56211)(1.27681,6.5624)(1.28,6.5625)
+\put(0.97999,6.03519){\makebox(0,0)[t]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{tex}}}}}
+\put(0.96,6.09375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.24,6.5625)(2.24533,6.55472)(2.25067,6.54701)(2.256,6.53936)
+ (2.26133,6.53177)(2.26667,6.52425)(2.272,6.5168)(2.27733,6.50941)
+ (2.28267,6.50208)(2.288,6.49482)(2.29333,6.48763)(2.29867,6.4805)
+ (2.304,6.47344)(2.30933,6.46644)(2.31467,6.45951)(2.32,6.45264)
+ (2.32533,6.44583)(2.33067,6.4391)(2.336,6.43242)(2.34133,6.42581)
+ (2.34667,6.41927)(2.352,6.41279)(2.35733,6.40638)(2.36267,6.40003)
+ (2.368,6.39375)(2.37333,6.38753)(2.37867,6.38138)(2.384,6.37529)
+ (2.38933,6.36927)(2.39467,6.36331)(2.4,6.35742)(2.40533,6.3516)
+ (2.41067,6.34583)(2.416,6.34014)(2.42133,6.33451)(2.42667,6.32894)
+ (2.432,6.32344)(2.43733,6.318)(2.44267,6.31263)(2.448,6.30732)
+ (2.45333,6.30208)(2.45867,6.29691)(2.464,6.2918)(2.46933,6.28675)
+ (2.47467,6.28177)(2.48,6.27686)(2.48533,6.27201)(2.49067,6.26722)
+ (2.496,6.2625)(2.50133,6.25785)(2.50667,6.25326)(2.512,6.24873)
+ (2.51733,6.24427)(2.52267,6.23988)(2.528,6.23555)(2.53333,6.23128)
+ (2.53867,6.22708)(2.544,6.22295)(2.54933,6.21888)(2.55467,6.21488)
+ (2.56,6.21094)(2.56533,6.20706)(2.57067,6.20326)(2.576,6.19951)
+ (2.58133,6.19583)(2.58667,6.19222)(2.592,6.18867)(2.59733,6.18519)
+ (2.60267,6.18177)(2.608,6.17842)(2.61333,6.17513)(2.61867,6.17191)
+ (2.624,6.16875)(2.62933,6.16566)(2.63467,6.16263)(2.64,6.15967)
+ (2.64533,6.15677)(2.65067,6.15394)(2.656,6.15117)(2.66133,6.14847)
+ (2.66667,6.14583)(2.672,6.14326)(2.67733,6.14076)(2.68267,6.13831)
+ (2.688,6.13594)(2.69333,6.13363)(2.69867,6.13138)(2.704,6.1292)
+ (2.70933,6.12708)(2.71467,6.12503)(2.72,6.12305)(2.72533,6.12113)
+ (2.73067,6.11927)(2.736,6.11748)(2.74133,6.11576)(2.74667,6.1141)
+ (2.752,6.1125)(2.75733,6.11097)(2.76267,6.10951)(2.768,6.10811)
+ (2.77333,6.10677)(2.77867,6.1055)(2.784,6.1043)(2.78933,6.10316)
+ (2.79467,6.10208)(2.8,6.10107)(2.80533,6.10013)(2.81067,6.09925)
+ (2.816,6.09844)(2.82133,6.09769)(2.82667,6.09701)(2.832,6.09639)
+ (2.83733,6.09583)(2.84267,6.09535)(2.848,6.09492)(2.85333,6.09456)
+ (2.85867,6.09427)(2.864,6.09404)(2.86933,6.09388)(2.87467,6.09378)(2.88,6.09375)
+\allinethickness{0.0055348in}%
+\path(2.82289,6.08916)(2.83102,6.08515)
+\path(2.82293,6.09461)(2.83919,6.08659)
+\path(2.82296,6.10005)(2.84735,6.08802)
+\path(2.82634,6.10385)(2.85551,6.08945)
+\path(2.84423,6.10048)(2.86367,6.09088)
+\path(2.86211,6.09712)(2.87184,6.09232)
+\path(2.8738,6.09266)(2.87482,6.09473)
+\path(2.8676,6.09157)(2.86963,6.0957)
+\path(2.8614,6.09048)(2.86445,6.09668)
+\path(2.8552,6.0894)(2.85927,6.09765)
+\path(2.84899,6.08831)(2.85408,6.09863)
+\path(2.84279,6.08722)(2.8489,6.0996)
+\path(2.83659,6.08613)(2.84372,6.10058)
+\path(2.83039,6.08504)(2.83854,6.10155)
+\path(2.82419,6.08395)(2.83335,6.10253)
+\path(2.82292,6.09285)(2.82817,6.1035)
+\allinethickness{1.2pt}%
+\path(2.82292,6.0941)(2.82286,6.08372)(2.88,6.09375)
+ (2.82299,6.10448)(2.82292,6.0941)
+\put(2.93535,6.09375){\makebox(0,0)[l]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{pdf}}}}}
+\put(2.88,6.09375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.4pt}%
+\color{rgb_7f7f7f}%
+\path(2.24,6.5625)(2.24533,6.57028)(2.25067,6.57799)(2.256,6.58564)
+ (2.26133,6.59323)(2.26667,6.60075)(2.272,6.6082)(2.27733,6.61559)
+ (2.28267,6.62292)(2.288,6.63018)(2.29333,6.63737)(2.29867,6.6445)
+ (2.304,6.65156)(2.30933,6.65856)(2.31467,6.66549)(2.32,6.67236)
+ (2.32533,6.67917)(2.33067,6.6859)(2.336,6.69258)(2.34133,6.69919)
+ (2.34667,6.70573)(2.352,6.71221)(2.35733,6.71862)(2.36267,6.72497)
+ (2.368,6.73125)(2.37333,6.73747)(2.37867,6.74362)(2.384,6.74971)
+ (2.38933,6.75573)(2.39467,6.76169)(2.4,6.76758)(2.40533,6.7734)
+ (2.41067,6.77917)(2.416,6.78486)(2.42133,6.79049)(2.42667,6.79606)
+ (2.432,6.80156)(2.43733,6.807)(2.44267,6.81237)(2.448,6.81768)
+ (2.45333,6.82292)(2.45867,6.82809)(2.464,6.8332)(2.46933,6.83825)
+ (2.47467,6.84323)(2.48,6.84814)(2.48533,6.85299)(2.49067,6.85778)
+ (2.496,6.8625)(2.50133,6.86715)(2.50667,6.87174)(2.512,6.87627)
+ (2.51733,6.88073)(2.52267,6.88512)(2.528,6.88945)(2.53333,6.89372)
+ (2.53867,6.89792)(2.544,6.90205)(2.54933,6.90612)(2.55467,6.91012)
+ (2.56,6.91406)(2.56533,6.91794)(2.57067,6.92174)(2.576,6.92549)
+ (2.58133,6.92917)(2.58667,6.93278)(2.592,6.93633)(2.59733,6.93981)
+ (2.60267,6.94323)(2.608,6.94658)(2.61333,6.94987)(2.61867,6.95309)
+ (2.624,6.95625)(2.62933,6.95934)(2.63467,6.96237)(2.64,6.96533)
+ (2.64533,6.96823)(2.65067,6.97106)(2.656,6.97383)(2.66133,6.97653)
+ (2.66667,6.97917)(2.672,6.98174)(2.67733,6.98424)(2.68267,6.98669)
+ (2.688,6.98906)(2.69333,6.99137)(2.69867,6.99362)(2.704,6.9958)
+ (2.70933,6.99792)(2.71467,6.99997)(2.72,7.00195)(2.72533,7.00387)
+ (2.73067,7.00573)(2.736,7.00752)(2.74133,7.00924)(2.74667,7.0109)
+ (2.752,7.0125)(2.75733,7.01403)(2.76267,7.01549)(2.768,7.01689)
+ (2.77333,7.01823)(2.77867,7.0195)(2.784,7.0207)(2.78933,7.02184)
+ (2.79467,7.02292)(2.8,7.02393)(2.80533,7.02487)(2.81067,7.02575)
+ (2.816,7.02656)(2.82133,7.02731)(2.82667,7.02799)(2.832,7.02861)
+ (2.83733,7.02917)(2.84267,7.02965)(2.848,7.03008)(2.85333,7.03044)
+ (2.85867,7.03073)(2.864,7.03096)(2.86933,7.03112)(2.87467,7.03122)(2.88,7.03125)
+\path(2.87464,7.03024)(2.87481,7.03216)
+\path(2.86927,7.02923)(2.86961,7.03307)
+\path(2.86391,7.02822)(2.86442,7.03399)
+\path(2.85855,7.02721)(2.85922,7.0349)
+\path(2.85318,7.02621)(2.85403,7.03581)
+\path(2.84782,7.0252)(2.84883,7.03672)
+\path(2.84246,7.02419)(2.84364,7.03763)
+\path(2.8371,7.02318)(2.83844,7.03854)
+\path(2.83173,7.02217)(2.83325,7.03946)
+\path(2.82637,7.02116)(2.82805,7.04037)
+\path(2.87938,7.03113)(2.82289,7.03609)
+\path(2.86058,7.0276)(2.82292,7.0309)
+\path(2.84178,7.02406)(2.82296,7.02571)
+\path(2.82292,7.0309)(2.82299,7.02052)(2.88,7.03125)
+ (2.82286,7.04128)(2.82292,7.0309)
+\put(2.86001,7.08981){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{eps}}}}
+\put(2.88,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.88,7.03125)(3.52,7.03125)
+\path(3.47434,7.03955)(3.46292,7.03623)
+\path(3.48575,7.03748)(3.46292,7.03083)
+\path(3.49717,7.0354)(3.46292,7.02543)
+\path(3.50858,7.03333)(3.4706,7.02227)
+\path(3.46292,7.03964)(3.46811,7.02182)
+\path(3.46808,7.04069)(3.4733,7.02276)
+\path(3.47385,7.03964)(3.47849,7.0237)
+\path(3.47962,7.03859)(3.48368,7.02465)
+\path(3.48539,7.03754)(3.48887,7.02559)
+\path(3.49116,7.03649)(3.49406,7.02653)
+\path(3.49692,7.03545)(3.49924,7.02748)
+\path(3.50269,7.0344)(3.50443,7.02842)
+\path(3.50846,7.03335)(3.50962,7.02936)
+\path(3.51423,7.0323)(3.51481,7.03031)
+\path(3.46292,7.03125)(3.46292,7.02087)(3.52,7.03125)
+ (3.46292,7.04163)(3.46292,7.03125)
+\put(3.57535,7.03125){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}
+\put(3.52,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(1.92,6.09375){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large laps}}}}
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(0.32,5.15625)(0.96,5.15625)
+\allinethickness{0.0055348in}%
+\path(0.902922,5.15435)(0.90863,5.14691)
+\path(0.902922,5.16284)(0.914338,5.14795)
+\path(0.907102,5.16587)(0.920046,5.14899)
+\path(0.914659,5.16449)(0.925753,5.15002)
+\path(0.922216,5.16312)(0.931461,5.15106)
+\path(0.929773,5.16175)(0.937169,5.1521)
+\path(0.93733,5.16037)(0.942877,5.15314)
+\path(0.944886,5.159)(0.948584,5.15417)
+\path(0.952443,5.15762)(0.954292,5.15521)
+\path(0.948429,5.15415)(0.952865,5.15755)
+\path(0.936859,5.15204)(0.945731,5.15884)
+\path(0.925288,5.14994)(0.938596,5.16014)
+\path(0.913717,5.14783)(0.931461,5.16144)
+\path(0.902922,5.14633)(0.924326,5.16274)
+\path(0.902922,5.15309)(0.917192,5.16403)
+\path(0.902922,5.15986)(0.910057,5.16533)
+\allinethickness{1.2pt}%
+\path(0.902922,5.15625)(0.902922,5.14587)(0.96,5.15625)
+ (0.902922,5.16663)(0.902922,5.15625)
+\put(0.32,5.2116){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}}
+\put(0.32,5.15625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(0.97999,5.21481){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}}
+\put(0.96,5.15625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.4pt}%
+\color{rgb_7f7f7f}%
+\path(0.96,5.15625)(0.963187,5.15615)(0.966347,5.15586)
+ (0.969482,5.15539)(0.972591,5.15472)(0.975676,5.15388)
+ (0.978736,5.15285)(0.981772,5.15165)(0.984785,5.15028)
+ (0.987774,5.14874)(0.990741,5.14703)(0.993685,5.14516)
+ (0.996608,5.14313)(0.999509,5.14094)(1.00239,5.1386)
+ (1.00525,5.13611)(1.00809,5.13347)(1.01091,5.13069)
+ (1.01371,5.12777)(1.01649,5.12472)(1.01926,5.12153)
+ (1.02201,5.11821)(1.02474,5.11476)(1.02745,5.11119)(1.03014,5.1075)
+ (1.03282,5.10369)(1.03549,5.09977)(1.03814,5.09574)(1.04077,5.0916)
+ (1.04339,5.08735)(1.046,5.08301)(1.04859,5.07856)(1.05117,5.07403)
+ (1.05374,5.0694)(1.0563,5.06468)(1.05884,5.05988)(1.06138,5.055)
+ (1.0639,5.05004)(1.06641,5.045)(1.06891,5.0399)(1.07141,5.03472)
+ (1.07389,5.02948)(1.07637,5.02418)(1.07884,5.01882)(1.0813,5.0134)
+ (1.08375,5.00793)(1.0862,5.00242)(1.08864,4.99685)(1.09107,4.99125)
+ (1.0935,4.98561)(1.09593,4.97993)(1.09835,4.97421)(1.10076,4.96847)
+ (1.10317,4.9627)(1.10558,4.95691)(1.10799,4.9511)(1.1104,4.94528)
+ (1.1128,4.93944)(1.1152,4.93359)(1.1176,4.92773)(1.12,4.92188)
+ (1.1224,4.91602)(1.1248,4.91016)(1.1272,4.90431)(1.1296,4.89847)
+ (1.13201,4.89265)(1.13442,4.88684)(1.13683,4.88105)
+ (1.13924,4.87528)(1.14165,4.86954)(1.14407,4.86382)(1.1465,4.85814)
+ (1.14893,4.8525)(1.15136,4.8469)(1.1538,4.84133)(1.15625,4.83582)
+ (1.1587,4.83035)(1.16116,4.82493)(1.16363,4.81957)(1.16611,4.81427)
+ (1.16859,4.80903)(1.17109,4.80385)(1.17359,4.79875)(1.1761,4.79371)
+ (1.17862,4.78875)(1.18116,4.78387)(1.1837,4.77907)(1.18626,4.77435)
+ (1.18883,4.76972)(1.19141,4.76519)(1.194,4.76074)(1.19661,4.7564)
+ (1.19923,4.75215)(1.20186,4.74801)(1.20451,4.74398)
+ (1.20718,4.74006)(1.20986,4.73625)(1.21255,4.73256)
+ (1.21526,4.72899)(1.21799,4.72554)(1.22074,4.72222)
+ (1.22351,4.71903)(1.22629,4.71598)(1.22909,4.71306)
+ (1.23191,4.71028)(1.23475,4.70764)(1.23761,4.70515)
+ (1.24049,4.70281)(1.24339,4.70063)(1.24631,4.69859)
+ (1.24926,4.69672)(1.25223,4.69501)(1.25522,4.69347)(1.25823,4.6921)
+ (1.26126,4.6909)(1.26432,4.68987)(1.26741,4.68903)(1.27052,4.68836)
+ (1.27365,4.68789)(1.27681,4.6876)(1.28,4.6875)
+\path(1.28,4.6875)(1.6,4.6875)
+\path(1.59287,4.6862)(1.59429,4.68854)
+\path(1.58575,4.68491)(1.58858,4.68958)
+\path(1.57862,4.68361)(1.58288,4.69061)
+\path(1.5715,4.68232)(1.57717,4.69165)
+\path(1.56437,4.68102)(1.57146,4.69269)
+\path(1.55725,4.67973)(1.56575,4.69373)
+\path(1.55012,4.67843)(1.56005,4.69476)
+\path(1.543,4.67714)(1.55434,4.6958)
+\path(1.54292,4.68744)(1.54863,4.69684)
+\path(1.59185,4.68602)(1.58488,4.69025)
+\path(1.58369,4.68453)(1.56976,4.693)
+\path(1.57554,4.68305)(1.55464,4.69575)
+\path(1.56738,4.68157)(1.54292,4.69643)
+\path(1.55923,4.68009)(1.54292,4.68999)
+\path(1.55108,4.6786)(1.54292,4.68356)
+\path(1.54292,4.6875)(1.54292,4.67712)(1.6,4.6875)(1.54292,4.69788)(1.54292,4.6875)
+\path(1.6,4.6875)(2.24,4.6875)
+\path(2.22632,4.68501)(2.18292,4.69269)
+\path(2.21185,4.68238)(2.18292,4.6875)
+\path(2.19739,4.67975)(2.18292,4.68231)
+\path(2.18811,4.69693)(2.18466,4.67744)
+\path(2.1933,4.69599)(2.1902,4.67844)
+\path(2.19849,4.69505)(2.19573,4.67945)
+\path(2.20368,4.6941)(2.20126,4.68046)
+\path(2.20887,4.69316)(2.2068,4.68146)
+\path(2.21406,4.69222)(2.21233,4.68247)
+\path(2.21924,4.69127)(2.21787,4.68348)
+\path(2.22443,4.69033)(2.2234,4.68448)
+\path(2.22962,4.68939)(2.22893,4.68549)
+\path(2.23481,4.68844)(2.23447,4.68649)
+\path(2.18292,4.6875)(2.18292,4.67712)(2.24,4.6875)
+ (2.18292,4.69788)(2.18292,4.6875)
+\put(1.6,4.74285){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{dvi}}}}}
+\put(1.6,4.6875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(2.21793,4.71982){\makebox(0,0)[br]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{ps}}}}}
+\put(2.24,4.6875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(0.96,4.21875)(0.963187,4.21885)(0.966347,4.21914)
+ (0.969482,4.21961)(0.972591,4.22028)(0.975676,4.22112)
+ (0.978736,4.22215)(0.981772,4.22335)(0.984785,4.22472)
+ (0.987774,4.22626)(0.990741,4.22797)(0.993685,4.22984)
+ (0.996608,4.23188)(0.999509,4.23406)(1.00239,4.2364)
+ (1.00525,4.23889)(1.00809,4.24153)(1.01091,4.24431)
+ (1.01371,4.24723)(1.01649,4.25028)(1.01926,4.25347)
+ (1.02201,4.25679)(1.02474,4.26024)(1.02745,4.26381)(1.03014,4.2675)
+ (1.03282,4.27131)(1.03549,4.27523)(1.03814,4.27926)(1.04077,4.2834)
+ (1.04339,4.28765)(1.046,4.29199)(1.04859,4.29644)(1.05117,4.30097)
+ (1.05374,4.3056)(1.0563,4.31032)(1.05884,4.31512)(1.06138,4.32)
+ (1.0639,4.32496)(1.06641,4.33)(1.06891,4.3351)(1.07141,4.34028)
+ (1.07389,4.34552)(1.07637,4.35082)(1.07884,4.35618)(1.0813,4.3616)
+ (1.08375,4.36707)(1.0862,4.37258)(1.08864,4.37815)(1.09107,4.38375)
+ (1.0935,4.38939)(1.09593,4.39507)(1.09835,4.40079)(1.10076,4.40653)
+ (1.10317,4.4123)(1.10558,4.41809)(1.10799,4.4239)(1.1104,4.42972)
+ (1.1128,4.43556)(1.1152,4.44141)(1.1176,4.44727)(1.12,4.45312)
+ (1.1224,4.45898)(1.1248,4.46484)(1.1272,4.47069)(1.1296,4.47653)
+ (1.13201,4.48235)(1.13442,4.48816)(1.13683,4.49395)
+ (1.13924,4.49972)(1.14165,4.50546)(1.14407,4.51118)(1.1465,4.51686)
+ (1.14893,4.5225)(1.15136,4.5281)(1.1538,4.53367)(1.15625,4.53918)
+ (1.1587,4.54465)(1.16116,4.55007)(1.16363,4.55543)(1.16611,4.56073)
+ (1.16859,4.56597)(1.17109,4.57115)(1.17359,4.57625)(1.1761,4.58129)
+ (1.17862,4.58625)(1.18116,4.59113)(1.1837,4.59593)(1.18626,4.60065)
+ (1.18883,4.60528)(1.19141,4.60981)(1.194,4.61426)(1.19661,4.6186)
+ (1.19923,4.62285)(1.20186,4.62699)(1.20451,4.63102)
+ (1.20718,4.63494)(1.20986,4.63875)(1.21255,4.64244)
+ (1.21526,4.64601)(1.21799,4.64946)(1.22074,4.65278)
+ (1.22351,4.65597)(1.22629,4.65902)(1.22909,4.66194)
+ (1.23191,4.66472)(1.23475,4.66736)(1.23761,4.66985)
+ (1.24049,4.67219)(1.24339,4.67437)(1.24631,4.67641)
+ (1.24926,4.67828)(1.25223,4.67999)(1.25522,4.68153)(1.25823,4.6829)
+ (1.26126,4.6841)(1.26432,4.68513)(1.26741,4.68597)(1.27052,4.68664)
+ (1.27365,4.68711)(1.27681,4.6874)(1.28,4.6875)
+\put(0.97999,4.16019){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}}
+\put(0.96,4.21875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.24,4.6875)(2.24533,4.67972)(2.25067,4.67201)(2.256,4.66436)
+ (2.26133,4.65677)(2.26667,4.64925)(2.272,4.6418)(2.27733,4.63441)
+ (2.28267,4.62708)(2.288,4.61982)(2.29333,4.61263)(2.29867,4.6055)
+ (2.304,4.59844)(2.30933,4.59144)(2.31467,4.58451)(2.32,4.57764)
+ (2.32533,4.57083)(2.33067,4.5641)(2.336,4.55742)(2.34133,4.55081)
+ (2.34667,4.54427)(2.352,4.53779)(2.35733,4.53138)(2.36267,4.52503)
+ (2.368,4.51875)(2.37333,4.51253)(2.37867,4.50638)(2.384,4.50029)
+ (2.38933,4.49427)(2.39467,4.48831)(2.4,4.48242)(2.40533,4.4766)
+ (2.41067,4.47083)(2.416,4.46514)(2.42133,4.45951)(2.42667,4.45394)
+ (2.432,4.44844)(2.43733,4.443)(2.44267,4.43763)(2.448,4.43232)
+ (2.45333,4.42708)(2.45867,4.42191)(2.464,4.4168)(2.46933,4.41175)
+ (2.47467,4.40677)(2.48,4.40186)(2.48533,4.39701)(2.49067,4.39222)
+ (2.496,4.3875)(2.50133,4.38285)(2.50667,4.37826)(2.512,4.37373)
+ (2.51733,4.36927)(2.52267,4.36488)(2.528,4.36055)(2.53333,4.35628)
+ (2.53867,4.35208)(2.544,4.34795)(2.54933,4.34388)(2.55467,4.33988)
+ (2.56,4.33594)(2.56533,4.33206)(2.57067,4.32826)(2.576,4.32451)
+ (2.58133,4.32083)(2.58667,4.31722)(2.592,4.31367)(2.59733,4.31019)
+ (2.60267,4.30677)(2.608,4.30342)(2.61333,4.30013)(2.61867,4.29691)
+ (2.624,4.29375)(2.62933,4.29066)(2.63467,4.28763)(2.64,4.28467)
+ (2.64533,4.28177)(2.65067,4.27894)(2.656,4.27617)(2.66133,4.27347)
+ (2.66667,4.27083)(2.672,4.26826)(2.67733,4.26576)(2.68267,4.26331)
+ (2.688,4.26094)(2.69333,4.25863)(2.69867,4.25638)(2.704,4.2542)
+ (2.70933,4.25208)(2.71467,4.25003)(2.72,4.24805)(2.72533,4.24613)
+ (2.73067,4.24427)(2.736,4.24248)(2.74133,4.24076)(2.74667,4.2391)
+ (2.752,4.2375)(2.75733,4.23597)(2.76267,4.23451)(2.768,4.23311)
+ (2.77333,4.23177)(2.77867,4.2305)(2.784,4.2293)(2.78933,4.22816)
+ (2.79467,4.22708)(2.8,4.22607)(2.80533,4.22513)(2.81067,4.22425)
+ (2.816,4.22344)(2.82133,4.22269)(2.82667,4.22201)(2.832,4.22139)
+ (2.83733,4.22083)(2.84267,4.22035)(2.848,4.21992)(2.85333,4.21956)
+ (2.85867,4.21927)(2.864,4.21904)(2.86933,4.21888)(2.87467,4.21878)(2.88,4.21875)
+\path(2.82416,4.22925)(2.82805,4.20963)
+\path(2.82975,4.2282)(2.83325,4.21054)
+\path(2.83533,4.22715)(2.83844,4.21146)
+\path(2.84091,4.2261)(2.84364,4.21237)
+\path(2.8465,4.22505)(2.84883,4.21328)
+\path(2.85208,4.224)(2.85403,4.21419)
+\path(2.85767,4.22295)(2.85922,4.2151)
+\path(2.86325,4.2219)(2.86442,4.21601)
+\path(2.86883,4.22085)(2.86961,4.21693)
+\path(2.87442,4.2198)(2.87481,4.21784)
+\path(2.82289,4.21293)(2.86575,4.22143)
+\path(2.82292,4.21845)(2.85149,4.22411)
+\path(2.82295,4.22396)(2.83724,4.22679)
+\path(2.82292,4.2191)(2.82286,4.20872)(2.88,4.21875)
+ (2.82299,4.22948)(2.82292,4.2191)
+\put(2.93535,4.21875){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{pdf}}}}}
+\put(2.88,4.21875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.24,4.6875)(2.24533,4.69528)(2.25067,4.70299)(2.256,4.71064)
+ (2.26133,4.71823)(2.26667,4.72575)(2.272,4.7332)(2.27733,4.74059)
+ (2.28267,4.74792)(2.288,4.75518)(2.29333,4.76237)(2.29867,4.7695)
+ (2.304,4.77656)(2.30933,4.78356)(2.31467,4.79049)(2.32,4.79736)
+ (2.32533,4.80417)(2.33067,4.8109)(2.336,4.81758)(2.34133,4.82419)
+ (2.34667,4.83073)(2.352,4.83721)(2.35733,4.84362)(2.36267,4.84997)
+ (2.368,4.85625)(2.37333,4.86247)(2.37867,4.86862)(2.384,4.87471)
+ (2.38933,4.88073)(2.39467,4.88669)(2.4,4.89258)(2.40533,4.8984)
+ (2.41067,4.90417)(2.416,4.90986)(2.42133,4.91549)(2.42667,4.92106)
+ (2.432,4.92656)(2.43733,4.932)(2.44267,4.93737)(2.448,4.94268)
+ (2.45333,4.94792)(2.45867,4.95309)(2.464,4.9582)(2.46933,4.96325)
+ (2.47467,4.96823)(2.48,4.97314)(2.48533,4.97799)(2.49067,4.98278)
+ (2.496,4.9875)(2.50133,4.99215)(2.50667,4.99674)(2.512,5.00127)
+ (2.51733,5.00573)(2.52267,5.01012)(2.528,5.01445)(2.53333,5.01872)
+ (2.53867,5.02292)(2.544,5.02705)(2.54933,5.03112)(2.55467,5.03512)
+ (2.56,5.03906)(2.56533,5.04294)(2.57067,5.04674)(2.576,5.05049)
+ (2.58133,5.05417)(2.58667,5.05778)(2.592,5.06133)(2.59733,5.06481)
+ (2.60267,5.06823)(2.608,5.07158)(2.61333,5.07487)(2.61867,5.07809)
+ (2.624,5.08125)(2.62933,5.08434)(2.63467,5.08737)(2.64,5.09033)
+ (2.64533,5.09323)(2.65067,5.09606)(2.656,5.09883)(2.66133,5.10153)
+ (2.66667,5.10417)(2.672,5.10674)(2.67733,5.10924)(2.68267,5.11169)
+ (2.688,5.11406)(2.69333,5.11637)(2.69867,5.11862)(2.704,5.1208)
+ (2.70933,5.12292)(2.71467,5.12497)(2.72,5.12695)(2.72533,5.12887)
+ (2.73067,5.13073)(2.736,5.13252)(2.74133,5.13424)(2.74667,5.1359)
+ (2.752,5.1375)(2.75733,5.13903)(2.76267,5.14049)(2.768,5.14189)
+ (2.77333,5.14323)(2.77867,5.1445)(2.784,5.1457)(2.78933,5.14684)
+ (2.79467,5.14792)(2.8,5.14893)(2.80533,5.14987)(2.81067,5.15075)
+ (2.816,5.15156)(2.82133,5.15231)(2.82667,5.15299)(2.832,5.15361)
+ (2.83733,5.15417)(2.84267,5.15465)(2.848,5.15508)(2.85333,5.15544)
+ (2.85867,5.15573)(2.864,5.15596)(2.86933,5.15612)(2.87467,5.15622)(2.88,5.15625)
+\path(2.86706,5.15382)(2.87286,5.1575)
+\path(2.85412,5.15138)(2.86572,5.15876)
+\path(2.84118,5.14895)(2.85857,5.16001)
+\path(2.82824,5.14651)(2.85143,5.16126)
+\path(2.82297,5.14896)(2.84429,5.16252)
+\path(2.82293,5.15473)(2.83715,5.16377)
+\path(2.8229,5.1605)(2.83,5.16503)
+\path(2.8743,5.15518)(2.87281,5.15751)
+\path(2.8686,5.1541)(2.86563,5.15877)
+\path(2.8629,5.15303)(2.85844,5.16003)
+\path(2.85719,5.15196)(2.85126,5.1613)
+\path(2.85149,5.15089)(2.84407,5.16256)
+\path(2.84579,5.14981)(2.83688,5.16382)
+\path(2.84009,5.14874)(2.8297,5.16508)
+\path(2.83439,5.14767)(2.82286,5.16579)
+\path(2.82869,5.1466)(2.82292,5.15566)
+\path(2.82292,5.1559)(2.82299,5.14552)(2.88,5.15625)
+ (2.82286,5.16628)(2.82292,5.1559)
+\put(2.86001,5.21481){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{eps}}}}}
+\put(2.88,5.15625){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.88,5.15625)(3.52,5.15625)
+\path(3.51287,5.15495)(3.50817,5.1584)
+\path(3.50573,5.15366)(3.49634,5.16055)
+\path(3.4986,5.15236)(3.48451,5.1627)
+\path(3.49146,5.15106)(3.47268,5.16485)
+\path(3.48433,5.14976)(3.46292,5.16548)
+\path(3.47719,5.14847)(3.46292,5.15895)
+\path(3.47006,5.14717)(3.46292,5.15241)
+\path(3.46863,5.16559)(3.46292,5.15782)
+\path(3.47434,5.16455)(3.46292,5.14901)
+\path(3.48005,5.16351)(3.46773,5.14675)
+\path(3.48575,5.16248)(3.4752,5.1481)
+\path(3.49146,5.16144)(3.48267,5.14946)
+\path(3.49717,5.1604)(3.49013,5.15082)
+\path(3.50288,5.15936)(3.4976,5.15218)
+\path(3.50858,5.15833)(3.50507,5.15353)
+\path(3.51429,5.15729)(3.51253,5.15489)
+\path(3.46292,5.15625)(3.46292,5.14587)(3.52,5.15625)
+ (3.46292,5.16663)(3.46292,5.15625)
+\put(3.57535,5.15625){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}}
+\put(3.52,5.15625){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(1.92,4.21875){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large epix}}}}
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(0.32,3.28125)(0.96,3.28125)
+\allinethickness{0.0055348in}%
+\path(0.908111,3.29068)(0.902922,3.27138)
+\path(0.9133,3.28974)(0.9085,3.27189)
+\path(0.918489,3.2888)(0.914223,3.27293)
+\path(0.923678,3.28785)(0.919945,3.27397)
+\path(0.928867,3.28691)(0.925667,3.27501)
+\path(0.934056,3.28597)(0.931389,3.27605)
+\path(0.939244,3.28502)(0.937111,3.27709)
+\path(0.944433,3.28408)(0.942833,3.27813)
+\path(0.949622,3.28314)(0.948556,3.27917)
+\path(0.954811,3.28219)(0.954278,3.28021)
+\path(0.902922,3.27602)(0.914338,3.27295)
+\path(0.902922,3.28116)(0.925753,3.27502)
+\path(0.902922,3.28631)(0.937169,3.2771)
+\path(0.902922,3.29145)(0.948584,3.27917)
+\allinethickness{1.2pt}%
+\path(0.902922,3.28125)(0.902922,3.27087)(0.96,3.28125)
+ (0.902922,3.29163)(0.902922,3.28125)
+\put(0.32,3.3366){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}}
+\put(0.32,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(0.97999,3.33981){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}}
+\put(0.96,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(0.96,3.28125)(0.963187,3.28115)(0.966347,3.28086)
+ (0.969482,3.28039)(0.972591,3.27972)(0.975676,3.27888)
+ (0.978736,3.27785)(0.981772,3.27665)(0.984785,3.27528)
+ (0.987774,3.27374)(0.990741,3.27203)(0.993685,3.27016)
+ (0.996608,3.26813)(0.999509,3.26594)(1.00239,3.2636)
+ (1.00525,3.26111)(1.00809,3.25847)(1.01091,3.25569)
+ (1.01371,3.25277)(1.01649,3.24972)(1.01926,3.24653)
+ (1.02201,3.24321)(1.02474,3.23976)(1.02745,3.23619)(1.03014,3.2325)
+ (1.03282,3.22869)(1.03549,3.22477)(1.03814,3.22074)(1.04077,3.2166)
+ (1.04339,3.21235)(1.046,3.20801)(1.04859,3.20356)(1.05117,3.19903)
+ (1.05374,3.1944)(1.0563,3.18968)(1.05884,3.18488)(1.06138,3.18)
+ (1.0639,3.17504)(1.06641,3.17)(1.06891,3.1649)(1.07141,3.15972)
+ (1.07389,3.15448)(1.07637,3.14918)(1.07884,3.14382)(1.0813,3.1384)
+ (1.08375,3.13293)(1.0862,3.12742)(1.08864,3.12185)(1.09107,3.11625)
+ (1.0935,3.11061)(1.09593,3.10493)(1.09835,3.09921)(1.10076,3.09347)
+ (1.10317,3.0877)(1.10558,3.08191)(1.10799,3.0761)(1.1104,3.07028)
+ (1.1128,3.06444)(1.1152,3.05859)(1.1176,3.05273)(1.12,3.04688)
+ (1.1224,3.04102)(1.1248,3.03516)(1.1272,3.02931)(1.1296,3.02347)
+ (1.13201,3.01765)(1.13442,3.01184)(1.13683,3.00605)
+ (1.13924,3.00028)(1.14165,2.99454)(1.14407,2.98882)(1.1465,2.98314)
+ (1.14893,2.9775)(1.15136,2.9719)(1.1538,2.96633)(1.15625,2.96082)
+ (1.1587,2.95535)(1.16116,2.94993)(1.16363,2.94457)(1.16611,2.93927)
+ (1.16859,2.93403)(1.17109,2.92885)(1.17359,2.92375)(1.1761,2.91871)
+ (1.17862,2.91375)(1.18116,2.90887)(1.1837,2.90407)(1.18626,2.89935)
+ (1.18883,2.89472)(1.19141,2.89019)(1.194,2.88574)(1.19661,2.8814)
+ (1.19923,2.87715)(1.20186,2.87301)(1.20451,2.86898)
+ (1.20718,2.86506)(1.20986,2.86125)(1.21255,2.85756)
+ (1.21526,2.85399)(1.21799,2.85054)(1.22074,2.84722)
+ (1.22351,2.84403)(1.22629,2.84098)(1.22909,2.83806)
+ (1.23191,2.83528)(1.23475,2.83264)(1.23761,2.83015)
+ (1.24049,2.82781)(1.24339,2.82563)(1.24631,2.82359)
+ (1.24926,2.82172)(1.25223,2.82001)(1.25522,2.81847)(1.25823,2.8171)
+ (1.26126,2.8159)(1.26432,2.81487)(1.26741,2.81403)(1.27052,2.81336)
+ (1.27365,2.81289)(1.27681,2.8126)(1.28,2.8125)
+\path(1.28,2.8125)(1.6,2.8125)
+\allinethickness{0.0055348in}%
+\path(1.54292,2.80731)(1.59652,2.81313)
+\path(1.54292,2.8125)(1.57865,2.81638)
+\path(1.54292,2.81769)(1.56079,2.81963)
+\path(1.59481,2.81156)(1.5946,2.81348)
+\path(1.58962,2.81061)(1.5892,2.81446)
+\path(1.58443,2.80967)(1.58381,2.81544)
+\path(1.57924,2.80873)(1.57841,2.81643)
+\path(1.57406,2.80778)(1.57301,2.81741)
+\path(1.56887,2.80684)(1.56761,2.81839)
+\path(1.56368,2.8059)(1.56221,2.81937)
+\path(1.55849,2.80495)(1.55682,2.82035)
+\path(1.5533,2.80401)(1.55142,2.82133)
+\path(1.54811,2.80307)(1.54602,2.82231)
+\allinethickness{1.2pt}%
+\path(1.54292,2.8125)(1.54292,2.80212)(1.6,2.8125)(1.54292,2.82288)(1.54292,2.8125)
+\path(1.6,2.8125)(2.24,2.8125)
+\allinethickness{0.0055348in}%
+\path(2.23481,2.81156)(2.23373,2.81364)
+\path(2.22962,2.81061)(2.22746,2.81478)
+\path(2.22443,2.80967)(2.22119,2.81592)
+\path(2.21924,2.80873)(2.21492,2.81706)
+\path(2.21406,2.80778)(2.20864,2.8182)
+\path(2.20887,2.80684)(2.20237,2.81934)
+\path(2.20368,2.8059)(2.1961,2.82048)
+\path(2.19849,2.80495)(2.18983,2.82162)
+\path(2.1933,2.80401)(2.18356,2.82276)
+\path(2.18811,2.80307)(2.18292,2.81306)
+\path(2.19108,2.8214)(2.18292,2.81716)
+\path(2.19923,2.81991)(2.18292,2.81144)
+\path(2.20738,2.81843)(2.18292,2.80573)
+\path(2.21554,2.81695)(2.18919,2.80326)
+\path(2.22369,2.81547)(2.20612,2.80634)
+\path(2.23185,2.81398)(2.22306,2.80942)
+\allinethickness{1.2pt}%
+\path(2.18292,2.8125)(2.18292,2.80212)(2.24,2.8125)
+ (2.18292,2.82288)(2.18292,2.8125)
+\put(1.6,2.86785){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{dvi}}}}}}
+\put(1.6,2.8125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(2.21793,2.84482){\makebox(0,0)[br]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{ps}}}}}}
+\put(2.24,2.8125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.4pt}%
+\color{rgb_7f7f7f}%
+\path(0.96,2.34375)(0.963187,2.34385)(0.966347,2.34414)
+ (0.969482,2.34461)(0.972591,2.34528)(0.975676,2.34612)
+ (0.978736,2.34715)(0.981772,2.34835)(0.984785,2.34972)
+ (0.987774,2.35126)(0.990741,2.35297)(0.993685,2.35484)
+ (0.996608,2.35688)(0.999509,2.35906)(1.00239,2.3614)
+ (1.00525,2.36389)(1.00809,2.36653)(1.01091,2.36931)
+ (1.01371,2.37223)(1.01649,2.37528)(1.01926,2.37847)
+ (1.02201,2.38179)(1.02474,2.38524)(1.02745,2.38881)(1.03014,2.3925)
+ (1.03282,2.39631)(1.03549,2.40023)(1.03814,2.40426)(1.04077,2.4084)
+ (1.04339,2.41265)(1.046,2.41699)(1.04859,2.42144)(1.05117,2.42597)
+ (1.05374,2.4306)(1.0563,2.43532)(1.05884,2.44012)(1.06138,2.445)
+ (1.0639,2.44996)(1.06641,2.455)(1.06891,2.4601)(1.07141,2.46528)
+ (1.07389,2.47052)(1.07637,2.47582)(1.07884,2.48118)(1.0813,2.4866)
+ (1.08375,2.49207)(1.0862,2.49758)(1.08864,2.50315)(1.09107,2.50875)
+ (1.0935,2.51439)(1.09593,2.52007)(1.09835,2.52579)(1.10076,2.53153)
+ (1.10317,2.5373)(1.10558,2.54309)(1.10799,2.5489)(1.1104,2.55472)
+ (1.1128,2.56056)(1.1152,2.56641)(1.1176,2.57227)(1.12,2.57812)
+ (1.1224,2.58398)(1.1248,2.58984)(1.1272,2.59569)(1.1296,2.60153)
+ (1.13201,2.60735)(1.13442,2.61316)(1.13683,2.61895)
+ (1.13924,2.62472)(1.14165,2.63046)(1.14407,2.63618)(1.1465,2.64186)
+ (1.14893,2.6475)(1.15136,2.6531)(1.1538,2.65867)(1.15625,2.66418)
+ (1.1587,2.66965)(1.16116,2.67507)(1.16363,2.68043)(1.16611,2.68573)
+ (1.16859,2.69097)(1.17109,2.69615)(1.17359,2.70125)(1.1761,2.70629)
+ (1.17862,2.71125)(1.18116,2.71613)(1.1837,2.72093)(1.18626,2.72565)
+ (1.18883,2.73028)(1.19141,2.73481)(1.194,2.73926)(1.19661,2.7436)
+ (1.19923,2.74785)(1.20186,2.75199)(1.20451,2.75602)
+ (1.20718,2.75994)(1.20986,2.76375)(1.21255,2.76744)
+ (1.21526,2.77101)(1.21799,2.77446)(1.22074,2.77778)
+ (1.22351,2.78097)(1.22629,2.78402)(1.22909,2.78694)
+ (1.23191,2.78972)(1.23475,2.79236)(1.23761,2.79485)
+ (1.24049,2.79719)(1.24339,2.79937)(1.24631,2.80141)
+ (1.24926,2.80328)(1.25223,2.80499)(1.25522,2.80653)(1.25823,2.8079)
+ (1.26126,2.8091)(1.26432,2.81013)(1.26741,2.81097)(1.27052,2.81164)
+ (1.27365,2.81211)(1.27681,2.8124)(1.28,2.8125)
+\put(0.97999,2.28519){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}}
+\put(0.96,2.34375){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(2.24,2.8125)(2.24533,2.80472)(2.25067,2.79701)(2.256,2.78936)
+ (2.26133,2.78177)(2.26667,2.77425)(2.272,2.7668)(2.27733,2.75941)
+ (2.28267,2.75208)(2.288,2.74482)(2.29333,2.73763)(2.29867,2.7305)
+ (2.304,2.72344)(2.30933,2.71644)(2.31467,2.70951)(2.32,2.70264)
+ (2.32533,2.69583)(2.33067,2.6891)(2.336,2.68242)(2.34133,2.67581)
+ (2.34667,2.66927)(2.352,2.66279)(2.35733,2.65638)(2.36267,2.65003)
+ (2.368,2.64375)(2.37333,2.63753)(2.37867,2.63138)(2.384,2.62529)
+ (2.38933,2.61927)(2.39467,2.61331)(2.4,2.60742)(2.40533,2.6016)
+ (2.41067,2.59583)(2.416,2.59014)(2.42133,2.58451)(2.42667,2.57894)
+ (2.432,2.57344)(2.43733,2.568)(2.44267,2.56263)(2.448,2.55732)
+ (2.45333,2.55208)(2.45867,2.54691)(2.464,2.5418)(2.46933,2.53675)
+ (2.47467,2.53177)(2.48,2.52686)(2.48533,2.52201)(2.49067,2.51722)
+ (2.496,2.5125)(2.50133,2.50785)(2.50667,2.50326)(2.512,2.49873)
+ (2.51733,2.49427)(2.52267,2.48988)(2.528,2.48555)(2.53333,2.48128)
+ (2.53867,2.47708)(2.544,2.47295)(2.54933,2.46888)(2.55467,2.46488)
+ (2.56,2.46094)(2.56533,2.45706)(2.57067,2.45326)(2.576,2.44951)
+ (2.58133,2.44583)(2.58667,2.44222)(2.592,2.43867)(2.59733,2.43519)
+ (2.60267,2.43177)(2.608,2.42842)(2.61333,2.42513)(2.61867,2.42191)
+ (2.624,2.41875)(2.62933,2.41566)(2.63467,2.41263)(2.64,2.40967)
+ (2.64533,2.40677)(2.65067,2.40394)(2.656,2.40117)(2.66133,2.39847)
+ (2.66667,2.39583)(2.672,2.39326)(2.67733,2.39076)(2.68267,2.38831)
+ (2.688,2.38594)(2.69333,2.38363)(2.69867,2.38138)(2.704,2.3792)
+ (2.70933,2.37708)(2.71467,2.37503)(2.72,2.37305)(2.72533,2.37113)
+ (2.73067,2.36927)(2.736,2.36748)(2.74133,2.36576)(2.74667,2.3641)
+ (2.752,2.3625)(2.75733,2.36097)(2.76267,2.35951)(2.768,2.35811)
+ (2.77333,2.35677)(2.77867,2.3555)(2.784,2.3543)(2.78933,2.35316)
+ (2.79467,2.35208)(2.8,2.35107)(2.80533,2.35013)(2.81067,2.34925)
+ (2.816,2.34844)(2.82133,2.34769)(2.82667,2.34701)(2.832,2.34639)
+ (2.83733,2.34583)(2.84267,2.34535)(2.848,2.34492)(2.85333,2.34456)
+ (2.85867,2.34427)(2.864,2.34404)(2.86933,2.34388)(2.87467,2.34378)(2.88,2.34375)
+\allinethickness{0.0055348in}%
+\path(2.82869,2.3534)(2.82294,2.34686)
+\path(2.83439,2.35233)(2.82289,2.33925)
+\path(2.84009,2.35126)(2.82501,2.3341)
+\path(2.84579,2.35019)(2.83287,2.33548)
+\path(2.85149,2.34911)(2.84072,2.33686)
+\path(2.85719,2.34804)(2.84858,2.33823)
+\path(2.8629,2.34697)(2.85643,2.33961)
+\path(2.8686,2.3459)(2.86429,2.34099)
+\path(2.8743,2.34482)(2.87214,2.34237)
+\path(2.8229,2.34038)(2.82921,2.33484)
+\path(2.82294,2.34704)(2.83556,2.33595)
+\path(2.82298,2.35369)(2.84191,2.33706)
+\path(2.83154,2.35287)(2.84826,2.33818)
+\path(2.84123,2.35104)(2.8546,2.33929)
+\path(2.85092,2.34922)(2.86095,2.34041)
+\path(2.86062,2.3474)(2.8673,2.34152)
+\path(2.87031,2.34557)(2.87365,2.34264)
+\allinethickness{1.2pt}%
+\path(2.82292,2.3441)(2.82286,2.33372)(2.88,2.34375)
+ (2.82299,2.35448)(2.82292,2.3441)
+\put(2.93535,2.34375){\makebox(0,0)[l]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{pdf}}}}}}
+\put(2.88,2.34375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.24,2.8125)(2.24533,2.82028)(2.25067,2.82799)(2.256,2.83564)
+ (2.26133,2.84323)(2.26667,2.85075)(2.272,2.8582)(2.27733,2.86559)
+ (2.28267,2.87292)(2.288,2.88018)(2.29333,2.88737)(2.29867,2.8945)
+ (2.304,2.90156)(2.30933,2.90856)(2.31467,2.91549)(2.32,2.92236)
+ (2.32533,2.92917)(2.33067,2.9359)(2.336,2.94258)(2.34133,2.94919)
+ (2.34667,2.95573)(2.352,2.96221)(2.35733,2.96862)(2.36267,2.97497)
+ (2.368,2.98125)(2.37333,2.98747)(2.37867,2.99362)(2.384,2.99971)
+ (2.38933,3.00573)(2.39467,3.01169)(2.4,3.01758)(2.40533,3.0234)
+ (2.41067,3.02917)(2.416,3.03486)(2.42133,3.04049)(2.42667,3.04606)
+ (2.432,3.05156)(2.43733,3.057)(2.44267,3.06237)(2.448,3.06768)
+ (2.45333,3.07292)(2.45867,3.07809)(2.464,3.0832)(2.46933,3.08825)
+ (2.47467,3.09323)(2.48,3.09814)(2.48533,3.10299)(2.49067,3.10778)
+ (2.496,3.1125)(2.50133,3.11715)(2.50667,3.12174)(2.512,3.12627)
+ (2.51733,3.13073)(2.52267,3.13512)(2.528,3.13945)(2.53333,3.14372)
+ (2.53867,3.14792)(2.544,3.15205)(2.54933,3.15612)(2.55467,3.16012)
+ (2.56,3.16406)(2.56533,3.16794)(2.57067,3.17174)(2.576,3.17549)
+ (2.58133,3.17917)(2.58667,3.18278)(2.592,3.18633)(2.59733,3.18981)
+ (2.60267,3.19323)(2.608,3.19658)(2.61333,3.19987)(2.61867,3.20309)
+ (2.624,3.20625)(2.62933,3.20934)(2.63467,3.21237)(2.64,3.21533)
+ (2.64533,3.21823)(2.65067,3.22106)(2.656,3.22383)(2.66133,3.22653)
+ (2.66667,3.22917)(2.672,3.23174)(2.67733,3.23424)(2.68267,3.23669)
+ (2.688,3.23906)(2.69333,3.24137)(2.69867,3.24362)(2.704,3.2458)
+ (2.70933,3.24792)(2.71467,3.24997)(2.72,3.25195)(2.72533,3.25387)
+ (2.73067,3.25573)(2.736,3.25752)(2.74133,3.25924)(2.74667,3.2609)
+ (2.752,3.2625)(2.75733,3.26403)(2.76267,3.26549)(2.768,3.26689)
+ (2.77333,3.26823)(2.77867,3.2695)(2.784,3.2707)(2.78933,3.27184)
+ (2.79467,3.27292)(2.8,3.27393)(2.80533,3.27487)(2.81067,3.27575)
+ (2.816,3.27656)(2.82133,3.27731)(2.82667,3.27799)(2.832,3.27861)
+ (2.83733,3.27917)(2.84267,3.27965)(2.848,3.28008)(2.85333,3.28044)
+ (2.85867,3.28073)(2.864,3.28096)(2.86933,3.28112)(2.87467,3.28122)(2.88,3.28125)
+\allinethickness{0.0055348in}%
+\path(2.82295,3.27579)(2.83249,3.27231)
+\path(2.82292,3.28106)(2.84199,3.2741)
+\path(2.82289,3.28633)(2.85149,3.27589)
+\path(2.82456,3.29098)(2.861,3.27767)
+\path(2.85228,3.28612)(2.8705,3.27946)
+\path(2.87406,3.28013)(2.87481,3.28216)
+\path(2.86813,3.27902)(2.86961,3.28307)
+\path(2.86219,3.2779)(2.86442,3.28399)
+\path(2.85626,3.27678)(2.85922,3.2849)
+\path(2.85032,3.27567)(2.85403,3.28581)
+\path(2.84439,3.27455)(2.84883,3.28672)
+\path(2.83845,3.27343)(2.84364,3.28763)
+\path(2.83252,3.27232)(2.83844,3.28854)
+\path(2.82658,3.2712)(2.83325,3.28946)
+\path(2.82295,3.27639)(2.82805,3.29037)
+\allinethickness{1.2pt}%
+\path(2.82292,3.2809)(2.82299,3.27052)(2.88,3.28125)
+ (2.82286,3.29128)(2.82292,3.2809)
+\put(2.86001,3.33981){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eps}}}}}}
+\put(2.88,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.4pt}%
+\color{rgb_7f7f7f}%
+\path(2.88,3.28125)(3.52,3.28125)
+\path(3.51481,3.28031)(3.51477,3.2822)
+\path(3.50962,3.27936)(3.50954,3.28315)
+\path(3.50443,3.27842)(3.50432,3.2841)
+\path(3.49924,3.27748)(3.49909,3.28505)
+\path(3.49406,3.27653)(3.49386,3.286)
+\path(3.48887,3.27559)(3.48863,3.28695)
+\path(3.48368,3.27465)(3.4834,3.2879)
+\path(3.47849,3.2737)(3.47818,3.28885)
+\path(3.4733,3.27276)(3.47295,3.2898)
+\path(3.46811,3.27182)(3.46772,3.29076)
+\path(3.48855,3.28697)(3.46292,3.28644)
+\path(3.51417,3.28231)(3.46292,3.28125)
+\path(3.49512,3.27673)(3.46292,3.27606)
+\path(3.46292,3.28125)(3.46292,3.27087)(3.52,3.28125)
+ (3.46292,3.29163)(3.46292,3.28125)
+\put(3.57535,3.28125){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}}
+\put(3.52,3.28125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(1.92,2.34375){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large elaps}}}}
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(0.32,1.40625)(0.96,1.40625)
+\allinethickness{0.0055348in}%
+\path(0.912435,1.4149)(0.902922,1.41097)
+\path(0.921948,1.41317)(0.902922,1.40531)
+\path(0.931461,1.41144)(0.902922,1.39966)
+\path(0.940974,1.40971)(0.91102,1.39734)
+\path(0.950487,1.40798)(0.93551,1.4018)
+\path(0.902922,1.40939)(0.908111,1.39682)
+\path(0.905721,1.41612)(0.9133,1.39776)
+\path(0.911752,1.41502)(0.918489,1.3987)
+\path(0.917783,1.41393)(0.923678,1.39965)
+\path(0.923814,1.41283)(0.928867,1.40059)
+\path(0.929845,1.41173)(0.934056,1.40153)
+\path(0.935876,1.41064)(0.939244,1.40248)
+\path(0.941907,1.40954)(0.944433,1.40342)
+\path(0.947938,1.40844)(0.949622,1.40436)
+\path(0.953969,1.40735)(0.954811,1.40531)
+\allinethickness{1.2pt}%
+\path(0.902922,1.40625)(0.902922,1.39587)(0.96,1.40625)
+ (0.902922,1.41663)(0.902922,1.40625)
+\put(0.32,1.4616){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}}
+\put(0.32,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(0.97999,1.46481){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}}
+\put(0.96,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(0.96,1.40625)(0.963187,1.40615)(0.966347,1.40586)
+ (0.969482,1.40539)(0.972591,1.40472)(0.975676,1.40388)
+ (0.978736,1.40285)(0.981772,1.40165)(0.984785,1.40028)
+ (0.987774,1.39874)(0.990741,1.39703)(0.993685,1.39516)
+ (0.996608,1.39313)(0.999509,1.39094)(1.00239,1.3886)
+ (1.00525,1.38611)(1.00809,1.38347)(1.01091,1.38069)
+ (1.01371,1.37777)(1.01649,1.37472)(1.01926,1.37153)
+ (1.02201,1.36821)(1.02474,1.36476)(1.02745,1.36119)(1.03014,1.3575)
+ (1.03282,1.35369)(1.03549,1.34977)(1.03814,1.34574)(1.04077,1.3416)
+ (1.04339,1.33735)(1.046,1.33301)(1.04859,1.32856)(1.05117,1.32403)
+ (1.05374,1.3194)(1.0563,1.31468)(1.05884,1.30988)(1.06138,1.305)
+ (1.0639,1.30004)(1.06641,1.295)(1.06891,1.2899)(1.07141,1.28472)
+ (1.07389,1.27948)(1.07637,1.27418)(1.07884,1.26882)(1.0813,1.2634)
+ (1.08375,1.25793)(1.0862,1.25242)(1.08864,1.24685)(1.09107,1.24125)
+ (1.0935,1.23561)(1.09593,1.22993)(1.09835,1.22421)(1.10076,1.21847)
+ (1.10317,1.2127)(1.10558,1.20691)(1.10799,1.2011)(1.1104,1.19528)
+ (1.1128,1.18944)(1.1152,1.18359)(1.1176,1.17773)(1.12,1.17188)
+ (1.1224,1.16602)(1.1248,1.16016)(1.1272,1.15431)(1.1296,1.14847)
+ (1.13201,1.14265)(1.13442,1.13684)(1.13683,1.13105)
+ (1.13924,1.12528)(1.14165,1.11954)(1.14407,1.11382)(1.1465,1.10814)
+ (1.14893,1.1025)(1.15136,1.0969)(1.1538,1.09133)(1.15625,1.08582)
+ (1.1587,1.08035)(1.16116,1.07493)(1.16363,1.06957)(1.16611,1.06427)
+ (1.16859,1.05903)(1.17109,1.05385)(1.17359,1.04875)(1.1761,1.04371)
+ (1.17862,1.03875)(1.18116,1.03387)(1.1837,1.02907)(1.18626,1.02435)
+ (1.18883,1.01972)(1.19141,1.01519)(1.194,1.01074)(1.19661,1.0064)
+ (1.19923,1.00215)(1.20186,0.998013)(1.20451,0.99398)
+ (1.20718,0.990058)(1.20986,0.98625)(1.21255,0.982559)
+ (1.21526,0.978989)(1.21799,0.975542)(1.22074,0.972222)
+ (1.22351,0.969033)(1.22629,0.965977)(1.22909,0.963057)
+ (1.23191,0.960278)(1.23475,0.957642)(1.23761,0.955152)
+ (1.24049,0.952812)(1.24339,0.950625)(1.24631,0.948594)
+ (1.24926,0.946723)(1.25223,0.945015)(1.25522,0.943472)
+ (1.25823,0.942099)(1.26126,0.940898)(1.26432,0.939874)
+ (1.26741,0.939028)(1.27052,0.938364)(1.27365,0.937886)
+ (1.27681,0.937597)(1.28,0.9375)
+\path(1.28,0.9375)(1.6,0.9375)
+\allinethickness{0.0055348in}%
+\path(1.54292,0.934917)(1.54926,0.928275)
+\path(1.54292,0.942712)(1.55561,0.929428)
+\path(1.54596,0.947325)(1.56195,0.930581)
+\path(1.55497,0.945688)(1.56829,0.931735)
+\path(1.56397,0.94405)(1.57463,0.932888)
+\path(1.57298,0.942413)(1.58097,0.934041)
+\path(1.58199,0.940775)(1.58732,0.935194)
+\path(1.59099,0.939138)(1.59366,0.936347)
+\path(1.59067,0.935804)(1.59366,0.938653)
+\path(1.58135,0.934109)(1.58732,0.939806)
+\path(1.57202,0.932413)(1.58097,0.940959)
+\path(1.5627,0.930718)(1.57463,0.942112)
+\path(1.55337,0.929022)(1.56829,0.943265)
+\path(1.54405,0.927327)(1.56195,0.944419)
+\path(1.54292,0.933461)(1.55561,0.945572)
+\path(1.54292,0.940669)(1.54926,0.946725)
+\allinethickness{1.2pt}%
+\path(1.54292,0.9375)(1.54292,0.927122)(1.6,0.9375)
+ (1.54292,0.947878)(1.54292,0.9375)
+\path(1.6,0.9375)(2.24,0.9375)
+\allinethickness{0.0055348in}%
+\path(2.23385,0.936381)(2.23481,0.938443)
+\path(2.22769,0.935262)(2.22962,0.939387)
+\path(2.22154,0.934143)(2.22443,0.94033)
+\path(2.21538,0.933024)(2.21924,0.941274)
+\path(2.20923,0.931905)(2.21406,0.942217)
+\path(2.20308,0.930787)(2.20887,0.943161)
+\path(2.19692,0.929668)(2.20368,0.944104)
+\path(2.19077,0.928549)(2.19849,0.945047)
+\path(2.18461,0.92743)(2.1933,0.945991)
+\path(2.18292,0.935846)(2.18811,0.946934)
+\path(2.23185,0.936017)(2.22148,0.940867)
+\path(2.22369,0.934535)(2.20297,0.944233)
+\path(2.21554,0.933052)(2.18445,0.9476)
+\path(2.20738,0.93157)(2.18292,0.943017)
+\path(2.19923,0.930087)(2.18292,0.937719)
+\path(2.19108,0.928605)(2.18292,0.93242)
+\allinethickness{1.2pt}%
+\path(2.18292,0.9375)(2.18292,0.927122)(2.24,0.9375)
+ (2.18292,0.947878)(2.18292,0.9375)
+\put(1.6,0.992848){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{dvi}}}}}}
+\put(1.6,0.9375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(2.21793,0.969823){\makebox(0,0)[br]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{ps}}}}}}
+\put(2.24,0.9375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{0.4pt}%
+\color{rgb_7f7f7f}%
+\path(0.96,0.46875)(0.963187,0.468847)(0.966347,0.469136)
+ (0.969482,0.469614)(0.972591,0.470278)(0.975676,0.471124)
+ (0.978736,0.472148)(0.981772,0.473349)(0.984785,0.474722)
+ (0.987774,0.476265)(0.990741,0.477973)(0.993685,0.479844)
+ (0.996608,0.481875)(0.999509,0.484062)(1.00239,0.486402)
+ (1.00525,0.488892)(1.00809,0.491528)(1.01091,0.494307)
+ (1.01371,0.497227)(1.01649,0.500283)(1.01926,0.503472)
+ (1.02201,0.506792)(1.02474,0.510239)(1.02745,0.513809)
+ (1.03014,0.5175)(1.03282,0.521308)(1.03549,0.52523)
+ (1.03814,0.529263)(1.04077,0.533403)(1.04339,0.537647)
+ (1.046,0.541992)(1.04859,0.546435)(1.05117,0.550972)
+ (1.05374,0.555601)(1.0563,0.560317)(1.05884,0.565118)(1.06138,0.57)
+ (1.0639,0.57496)(1.06641,0.579996)(1.06891,0.585103)
+ (1.07141,0.590278)(1.07389,0.595518)(1.07637,0.60082)
+ (1.07884,0.606181)(1.0813,0.611597)(1.08375,0.617065)
+ (1.0862,0.622582)(1.08864,0.628145)(1.09107,0.63375)
+ (1.0935,0.639394)(1.09593,0.645074)(1.09835,0.650786)
+ (1.10076,0.656528)(1.10317,0.662295)(1.10558,0.668086)
+ (1.10799,0.673896)(1.1104,0.679722)(1.1128,0.685562)
+ (1.1152,0.691411)(1.1176,0.697266)(1.12,0.703125)(1.1224,0.708984)
+ (1.1248,0.714839)(1.1272,0.720688)(1.1296,0.726528)
+ (1.13201,0.732354)(1.13442,0.738164)(1.13683,0.743955)
+ (1.13924,0.749722)(1.14165,0.755464)(1.14407,0.761176)
+ (1.1465,0.766856)(1.14893,0.7725)(1.15136,0.778105)
+ (1.1538,0.783668)(1.15625,0.789185)(1.1587,0.794653)
+ (1.16116,0.800069)(1.16363,0.80543)(1.16611,0.810732)
+ (1.16859,0.815972)(1.17109,0.821147)(1.17359,0.826254)
+ (1.1761,0.83129)(1.17862,0.83625)(1.18116,0.841132)
+ (1.1837,0.845933)(1.18626,0.850649)(1.18883,0.855278)
+ (1.19141,0.859815)(1.194,0.864258)(1.19661,0.868603)
+ (1.19923,0.872847)(1.20186,0.876987)(1.20451,0.88102)
+ (1.20718,0.884942)(1.20986,0.88875)(1.21255,0.892441)
+ (1.21526,0.896011)(1.21799,0.899458)(1.22074,0.902778)
+ (1.22351,0.905967)(1.22629,0.909023)(1.22909,0.911943)
+ (1.23191,0.914722)(1.23475,0.917358)(1.23761,0.919848)
+ (1.24049,0.922188)(1.24339,0.924375)(1.24631,0.926406)
+ (1.24926,0.928277)(1.25223,0.929985)(1.25522,0.931528)
+ (1.25823,0.932901)(1.26126,0.934102)(1.26432,0.935126)
+ (1.26741,0.935972)(1.27052,0.936636)(1.27365,0.937114)
+ (1.27681,0.937403)(1.28,0.9375)
+\put(0.97999,0.410187){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}}
+\put(0.96,0.46875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.24,0.9375)(2.24533,0.92972)(2.25067,0.922005)
+ (2.256,0.914355)(2.26133,0.906771)(2.26667,0.899251)
+ (2.272,0.891797)(2.27733,0.884408)(2.28267,0.877083)
+ (2.288,0.869824)(2.29333,0.86263)(2.29867,0.855501)(2.304,0.848438)
+ (2.30933,0.841439)(2.31467,0.834505)(2.32,0.827637)
+ (2.32533,0.820833)(2.33067,0.814095)(2.336,0.807422)
+ (2.34133,0.800814)(2.34667,0.794271)(2.352,0.787793)
+ (2.35733,0.78138)(2.36267,0.775033)(2.368,0.76875)
+ (2.37333,0.762533)(2.37867,0.75638)(2.384,0.750293)
+ (2.38933,0.744271)(2.39467,0.738314)(2.4,0.732422)
+ (2.40533,0.726595)(2.41067,0.720833)(2.416,0.715137)
+ (2.42133,0.709505)(2.42667,0.703939)(2.432,0.698438)
+ (2.43733,0.693001)(2.44267,0.68763)(2.448,0.682324)
+ (2.45333,0.677083)(2.45867,0.671908)(2.464,0.666797)
+ (2.46933,0.661751)(2.47467,0.656771)(2.48,0.651855)
+ (2.48533,0.647005)(2.49067,0.64222)(2.496,0.6375)(2.50133,0.632845)
+ (2.50667,0.628255)(2.512,0.62373)(2.51733,0.619271)
+ (2.52267,0.614876)(2.528,0.610547)(2.53333,0.606283)
+ (2.53867,0.602083)(2.544,0.597949)(2.54933,0.59388)
+ (2.55467,0.589876)(2.56,0.585938)(2.56533,0.582064)
+ (2.57067,0.578255)(2.576,0.574512)(2.58133,0.570833)
+ (2.58667,0.56722)(2.592,0.563672)(2.59733,0.560189)
+ (2.60267,0.556771)(2.608,0.553418)(2.61333,0.55013)
+ (2.61867,0.546908)(2.624,0.54375)(2.62933,0.540658)
+ (2.63467,0.53763)(2.64,0.534668)(2.64533,0.531771)
+ (2.65067,0.528939)(2.656,0.526172)(2.66133,0.52347)
+ (2.66667,0.520833)(2.672,0.518262)(2.67733,0.515755)
+ (2.68267,0.513314)(2.688,0.510937)(2.69333,0.508626)
+ (2.69867,0.50638)(2.704,0.504199)(2.70933,0.502083)
+ (2.71467,0.500033)(2.72,0.498047)(2.72533,0.496126)
+ (2.73067,0.494271)(2.736,0.49248)(2.74133,0.490755)
+ (2.74667,0.489095)(2.752,0.4875)(2.75733,0.48597)(2.76267,0.484505)
+ (2.768,0.483105)(2.77333,0.481771)(2.77867,0.480501)
+ (2.784,0.479297)(2.78933,0.478158)(2.79467,0.477083)(2.8,0.476074)
+ (2.80533,0.47513)(2.81067,0.474251)(2.816,0.473437)
+ (2.82133,0.472689)(2.82667,0.472005)(2.832,0.471387)
+ (2.83733,0.470833)(2.84267,0.470345)(2.848,0.469922)
+ (2.85333,0.469564)(2.85867,0.469271)(2.864,0.469043)
+ (2.86933,0.46888)(2.87467,0.468783)(2.88,0.46875)
+\path(2.86583,0.471416)(2.82296,0.474287)
+\path(2.86567,0.466235)(2.82292,0.469098)
+\path(2.84427,0.462478)(2.82289,0.46391)
+\path(2.82817,0.478501)(2.82689,0.459429)
+\path(2.83335,0.477526)(2.8322,0.460361)
+\path(2.83854,0.476551)(2.83751,0.461293)
+\path(2.84372,0.475576)(2.84282,0.462225)
+\path(2.8489,0.474601)(2.84814,0.463157)
+\path(2.85408,0.473625)(2.85345,0.464089)
+\path(2.85927,0.47265)(2.85876,0.465021)
+\path(2.86445,0.471675)(2.86407,0.465954)
+\path(2.86963,0.4707)(2.86938,0.466886)
+\path(2.87482,0.469725)(2.87469,0.467818)
+\path(2.82292,0.469098)(2.82286,0.458721)(2.88,0.46875)
+ (2.82299,0.479476)(2.82292,0.469098)
+\put(2.93535,0.46875){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{pdf}}}}}
+\put(2.88,0.46875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\allinethickness{1.2pt}%
+\color{rgb_ff0000}%
+\path(2.24,0.9375)(2.24533,0.94528)(2.25067,0.952995)
+ (2.256,0.960645)(2.26133,0.968229)(2.26667,0.975749)
+ (2.272,0.983203)(2.27733,0.990592)(2.28267,0.997917)(2.288,1.00518)
+ (2.29333,1.01237)(2.29867,1.0195)(2.304,1.02656)(2.30933,1.03356)
+ (2.31467,1.04049)(2.32,1.04736)(2.32533,1.05417)(2.33067,1.0609)
+ (2.336,1.06758)(2.34133,1.07419)(2.34667,1.08073)(2.352,1.08721)
+ (2.35733,1.09362)(2.36267,1.09997)(2.368,1.10625)(2.37333,1.11247)
+ (2.37867,1.11862)(2.384,1.12471)(2.38933,1.13073)(2.39467,1.13669)
+ (2.4,1.14258)(2.40533,1.1484)(2.41067,1.15417)(2.416,1.15986)
+ (2.42133,1.16549)(2.42667,1.17106)(2.432,1.17656)(2.43733,1.182)
+ (2.44267,1.18737)(2.448,1.19268)(2.45333,1.19792)(2.45867,1.20309)
+ (2.464,1.2082)(2.46933,1.21325)(2.47467,1.21823)(2.48,1.22314)
+ (2.48533,1.22799)(2.49067,1.23278)(2.496,1.2375)(2.50133,1.24215)
+ (2.50667,1.24674)(2.512,1.25127)(2.51733,1.25573)(2.52267,1.26012)
+ (2.528,1.26445)(2.53333,1.26872)(2.53867,1.27292)(2.544,1.27705)
+ (2.54933,1.28112)(2.55467,1.28512)(2.56,1.28906)(2.56533,1.29294)
+ (2.57067,1.29674)(2.576,1.30049)(2.58133,1.30417)(2.58667,1.30778)
+ (2.592,1.31133)(2.59733,1.31481)(2.60267,1.31823)(2.608,1.32158)
+ (2.61333,1.32487)(2.61867,1.32809)(2.624,1.33125)(2.62933,1.33434)
+ (2.63467,1.33737)(2.64,1.34033)(2.64533,1.34323)(2.65067,1.34606)
+ (2.656,1.34883)(2.66133,1.35153)(2.66667,1.35417)(2.672,1.35674)
+ (2.67733,1.35924)(2.68267,1.36169)(2.688,1.36406)(2.69333,1.36637)
+ (2.69867,1.36862)(2.704,1.3708)(2.70933,1.37292)(2.71467,1.37497)
+ (2.72,1.37695)(2.72533,1.37887)(2.73067,1.38073)(2.736,1.38252)
+ (2.74133,1.38424)(2.74667,1.3859)(2.752,1.3875)(2.75733,1.38903)
+ (2.76267,1.39049)(2.768,1.39189)(2.77333,1.39323)(2.77867,1.3945)
+ (2.784,1.3957)(2.78933,1.39684)(2.79467,1.39792)(2.8,1.39893)
+ (2.80533,1.39987)(2.81067,1.40075)(2.816,1.40156)(2.82133,1.40231)
+ (2.82667,1.40299)(2.832,1.40361)(2.83733,1.40417)(2.84267,1.40465)
+ (2.848,1.40508)(2.85333,1.40544)(2.85867,1.40573)(2.864,1.40596)
+ (2.86933,1.40612)(2.87467,1.40622)(2.88,1.40625)
+\allinethickness{0.0055348in}%
+\path(2.82288,1.41337)(2.82817,1.3965)
+\path(2.82772,1.41543)(2.83335,1.39747)
+\path(2.83353,1.41441)(2.83854,1.39845)
+\path(2.83934,1.41339)(2.84372,1.39942)
+\path(2.84515,1.41237)(2.8489,1.4004)
+\path(2.85096,1.41135)(2.85408,1.40137)
+\path(2.85677,1.41033)(2.85927,1.40235)
+\path(2.86257,1.40931)(2.86445,1.40332)
+\path(2.86838,1.40829)(2.86963,1.4043)
+\path(2.87419,1.40727)(2.87482,1.40527)
+\path(2.83547,1.39787)(2.86857,1.40826)
+\path(2.82296,1.39954)(2.85714,1.41026)
+\path(2.82293,1.40512)(2.84572,1.41227)
+\path(2.82289,1.4107)(2.83429,1.41427)
+\allinethickness{1.2pt}%
+\path(2.82292,1.4059)(2.82299,1.39552)(2.88,1.40625)
+ (2.82286,1.41628)(2.82292,1.4059)
+\put(2.86001,1.46481){\makebox(0,0)[b]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eps}}}}}}
+\put(2.88,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\path(2.88,1.40625)(3.52,1.40625)
+\allinethickness{0.0055348in}%
+\path(3.50867,1.40419)(3.51287,1.40755)
+\path(3.49734,1.40213)(3.50573,1.40884)
+\path(3.48601,1.40007)(3.4986,1.41014)
+\path(3.47467,1.39801)(3.49146,1.41144)
+\path(3.46334,1.39595)(3.48433,1.41274)
+\path(3.46292,1.40262)(3.47719,1.41403)
+\path(3.46292,1.40962)(3.47006,1.41533)
+\path(3.51429,1.40521)(3.51235,1.40764)
+\path(3.50858,1.40417)(3.5047,1.40903)
+\path(3.50288,1.40314)(3.49705,1.41042)
+\path(3.49717,1.4021)(3.4894,1.41181)
+\path(3.49146,1.40106)(3.48175,1.41321)
+\path(3.48575,1.40002)(3.47409,1.4146)
+\path(3.48005,1.39899)(3.46644,1.41599)
+\path(3.47434,1.39795)(3.46292,1.41222)
+\path(3.46863,1.39691)(3.46292,1.40404)
+\allinethickness{1.2pt}%
+\path(3.46292,1.40625)(3.46292,1.39587)(3.52,1.40625)
+ (3.46292,1.41663)(3.46292,1.40625)
+\put(3.57535,1.40625){\makebox(0,0)[l]{\fboxrule0.1pt%
+\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}}}
+\put(3.52,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}%
+\put(1.92,0.46875){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large flix}}}}
+\end{picture}%
diff --git a/graphics/epix/doc/ePiX.xp b/graphics/epix/doc/ePiX.xp
new file mode 100644
index 0000000000..c39e6b2ac0
--- /dev/null
+++ b/graphics/epix/doc/ePiX.xp
@@ -0,0 +1,156 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+void emph(const std::string& prog)
+{
+ if (prog == "all")
+ black();
+ else
+ {
+ bbold(Red());
+ label_color(Blue());
+ label_mask(Yellow(0.1));
+ label_border(Red(), "0.1pt");
+ }
+}
+
+void restore(const std::string& prog)
+{
+ if (prog == "all")
+ emph(prog);
+
+ else
+ {
+ plain();
+ black(0.5);
+ label_mask(Neutral());
+ }
+}
+
+void diagram(const std::string& prog)
+{
+ font_size("footnotesize");
+ arrow_width(1.5);
+ restore(prog);
+
+ if (prog != "laps")
+ emph(prog);
+
+ arrow(P(0,1), P(1,1));
+
+ dot(P(0,1), P(0,4), "\\texttt{xp}, \\texttt{flx}", t);
+ dot(P(1,1), P(2,4), "\\texttt{eepic}", t);
+ restore(prog);
+
+ if (prog != "epix")
+ emph(prog);
+
+ spline(P(1,1), P(1.2,1), P(1.3,0.5), P(1.5,0.5));
+ arrow(P(1.5,0.5), P(2,0.5));
+ arrow(P(2,0.5), P(3,0.5));
+
+ dot(P(2,0.5), P(0,4), "\\texttt{dvi}", t);
+ dot(P(3,0.5), P(-2,2), "\\texttt{ps}", tl);
+ restore(prog);
+
+ if(prog == "laps")
+ emph(prog);
+
+ spline(P(1,0), P(1.2,0), P(1.3,0.5), P(1.5,0.5));
+
+ dot(P(1,0), P(2,-4), "\\texttt{tex}", b);
+
+ if (prog == "elaps") // and laps
+ emph(prog);
+
+ arrow(P(3,0.5), P(3.5,0), P(4,0));
+
+ dot(P(4,0), P(4,0), "\\texttt{pdf}", r);
+ restore(prog);
+
+ if (prog == "elaps" || prog == "flix")
+ emph(prog);
+
+ arrow(P(3,0.5), P(3.5,1), P(4,1));
+
+ dot(P(4,1), P(-2,4), "\\texttt{eps}", t);
+ restore(prog);
+
+ if(prog == "flix")
+ emph(prog);
+
+ arrow(P(4,1), P(5,1));
+
+ dot(P(5,1), P(4,0),
+ "\\begin{minipage}{0.225in}\\texttt{png mng gif}\\end{minipage}", r);
+ restore(prog);
+
+ if (prog != "all")
+ {
+ font_size("Large");
+ font_face("tt");
+ label_color(Green(0.6));
+ label(P(2.5,0), prog);
+ }
+
+}
+
+int main()
+{
+#ifdef SHOW_ALL
+ picture(P(-0.5,0), P(5.75,10), "4 x 7.5 in");
+#else
+ picture(P(-0.5,2), P(5.75,10), "4 x 7.5 in");
+#endif
+
+ begin();
+ // border();
+
+ screen laps(P(0,0), P(5,1));
+ activate(laps);
+
+ diagram("laps");
+ laps.v_scale(0.5, P(0,0.5));
+ inset(laps, P(0,8), P(5,10));
+ deactivate(laps);
+
+
+ screen epix(P(0,0), P(5,1));
+ activate(epix);
+
+ diagram("epix");
+ epix.v_scale(0.5, P(0,0.5));
+ inset(epix, P(0,6), P(5,8));
+ deactivate(epix);
+
+
+ screen elaps(P(0,0), P(5,1));
+ activate(elaps);
+
+ diagram("elaps");
+ elaps.v_scale(0.5, P(0,0.5));
+ inset(elaps, P(0,4), P(5,6));
+ deactivate(elaps);
+
+
+ screen flix(P(0,0), P(5,1));
+ activate(flix);
+
+ diagram("flix");
+ flix.v_scale(0.5, P(0,0.5));
+ inset(flix, P(0,2), P(5,4));
+ deactivate(flix);
+
+#ifdef SHOW_ALL
+ screen all(P(0,0), P(5,1));
+ activate(all);
+
+ diagram("all");
+ all.v_scale(0.5, P(0,0.5));
+ inset(all, P(0,0), P(5,2));
+ deactivate(all);
+#endif
+
+ end();
+}
diff --git a/graphics/epix/doc/epix.info b/graphics/epix/doc/epix.info
new file mode 100644
index 0000000000..3b30c42c39
--- /dev/null
+++ b/graphics/epix/doc/epix.info
@@ -0,0 +1,4696 @@
+This is epix.info, produced by makeinfo version 4.9 from epix.texi.
+
+ This is the manual for ePiX, Version 1.2 Copyright (C) 2001, 2002,
+2003, 2004, 2005, 2006, 2007 Andrew D. Hwang
+
+
+File: epix.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
+
+ePiX manual
+***********
+
+This is the manual for ePiX, Version 1.2 Copyright (C) 2001, 2002,
+2003, 2004, 2005, 2006, 2007 Andrew D. Hwang
+
+* Menu:
+
+* Introduction ::
+* Getting Started ::
+* Reference Manual ::
+* Advanced Topics ::
+* Software Freedom::
+* Acknowledgments::
+* Function Index::
+* Concept Index::
+
+ --- The Detailed Node Listing ---
+
+Introduction
+
+* Changes in Version 1.2::
+* Software Dependencies::
+* Installation::
+
+Getting Started
+
+* Running `ePiX'::
+* The Drawing Model::
+* Tutorial::
+* `C++' Basics::
+* Animation::
+* Layout Tricks::
+
+Reference Manual
+
+* File Structure::
+* Picture Size and Aspect Ratio::
+* Color::
+* Scene Attributes::
+* Drawing Attributes::
+* Creating and Drawing Objects::
+* More About `C++'::
+* Attribute Quick Reference::
+
+Advanced Topics
+
+* Hidden Object Removal::
+* Extensions::
+* Programmer's Guide::
+
+
+File: epix.info, Node: Introduction, Next: Getting Started, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+`ePiX', a collection of batch utilities, creates mathematically
+accurate figures, plots, and animations containing `LaTeX' typography.
+The input syntax is easy to learn, and the user interface resembles
+that of `LaTeX' itself: You prepare a scene description in a text
+editor, then "compile" the input file into a picture. `LaTeX'- and
+web-compatible output types include a `LaTeX' picture-like environment
+written with `PSTricks', `tikz', or `eepic' macros; vector images
+(`eps', `ps', and `pdf'); and bitmapped images and movies (`png',
+`mng', and `gif').
+
+ `ePiX''s strengths include:
+
+ * Quality of output: `ePiX' creates 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: Objects are described by 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 command-line switches or 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 a
+ 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.
+
+
+ `ePiX' facilitates logical, as opposed to visual, structuring of
+mathematical figures, analogous to the relationship between `LaTeX' and
+a word processor. A few stylistic defaults streamline the creation of
+simple figures, but there are few internal restrictions on the contents
+or appearance of a figure; aesthetic and practical decisions are left
+to you.
+
+ 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 *Note chapter:started::, , or return to the
+ manual as needed.
+
+ * More advanced user, browse at will, probably starting with
+ Chapter *Note chapter:ref-man::, .
+
+
+ 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.
+
+* Menu:
+
+* Changes in Version 1.2::
+* Software Dependencies::
+* Installation::
+
+
+File: epix.info, Node: Changes in Version 1.2, Next: Software Dependencies, Prev: Introduction, Up: Introduction
+
+1.1 Changes in Version 1.2
+==========================
+
+`ePiX' 1.2.x has been written almost entirely from scratch. The
+conceptual model is unchanged, but there are a few changes of syntax.
+If you're new to `ePiX', please skip straight to Section *Note
+section:software_deps::, .
+
+
+
+Except as noted below, `ePiX' 1.0 files will compile under Version 1.2.
+Generally, 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).
+
+ * (Mandatory) The global variable tix in a `flix' file must be
+ manipulated through the function tix().
+
+ * (Mandatory) The command `use_pstricks()' is obsolete. PSTricks
+ output is obtained systematically as an output format.
+
+ * (Mandatory) Deprecated "aliases" no longer exist: `triple' (for
+ the `P' class), `D' (for `Deriv'), and `I' (for `Integral').
+ Lowercase trig function names conflicted with the standard
+ namespace and have been removed.
+
+ * (Mandatory) Geometric object commands (`circle', `plane',
+ `segment', and `sphere'), which formerly created class objects,
+ now perform drawing just as `ellipse', `line', `rect', etc., do.
+ The classes are available with capitalized names (`Circle',
+ etc.).
+
+ * (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.
+
+ * (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.)
+
+ * (Suggested) The camera may be accessed through the function
+ `cam()'.
+
+ * (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.
+
+
+
+
+ * Output is cleanly separated from the internal representation.
+ Figures may be written with a choice of macros--`PSTricks',
+ `tikz', and `eepic' at present--and new output types are easily
+ coded so long as the format supports arbitrary line segments,
+ color, and the ability to place a `LaTeX' box at a specified
+ location.
+
+ * Colors are 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. Filters performing CMYK separation are provided.
+
+ * Color filling is controlled with declarations, similarly to line
+ colors in `ePiX' 1.0. Arrows and markers of type spot, dot, ddot,
+ and circ are now colored like other markers. Parametric surfaces
+ may be color-shaded.
+
+ If a figure contains many shaded elements, a color-capable output
+ format (e.g.\ `PSTricks' or `tikz') should be used for
+ efficiency. Filled regions are implemented as fine hatching in
+ `eepic'.
+
+ * An `axis' class provides coordinate axes with labels in a
+ variety of styles: decimals or scientific notation of specified
+ precision, fractions, trig fractions, logarithmic labels in
+ arbitrary (integer) base, and user-supplied styles.
+
+ * `ePiX' 1.2.x performs page layout. Sub-figures may be manipulated
+ flexibly. The sample files give several applications.
+
+ * 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.
+
+
+
+File: epix.info, Node: Software Dependencies, Next: Installation, Prev: Changes in Version 1.2, Up: Introduction
+
+1.2 Software Dependencies
+=========================
+
+If you run GNU/Linux, a BSD, or Solaris, you probably have (and can
+surely install) all the external software needed to use `ePiX'. On Mac
+OS X, you will need the Apple developer tools and an X server (XCode
+and XDarwin on the Tiger disks), and the free `fink' package manager to
+build a GNU 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 a
+`LaTeX' picture; `dvi'; PostScript, `pdf' or `eps'; and if desired, to
+a bitmapped image or movie. Four shell scripts--`epix', `laps',
+`elaps', and `flix'--automate the various file format conversions.
+
+ `ePiX' consists of a `C++' library, header, and shell scripts, and
+requires GNU `bash' and a compiler _for normal use_. For complete
+functionality, you need `g++' (Version 3.2 or later), `bash', a text
+editor (`ePiX' works particularly well with `emacs'), a `LaTeX'
+distribution, `Ghostscript', `gv' (or your favorite PS/PDF previewer),
+and `ImageMagick'. GNU `grep' and `sed' are good to have. You may need
+additional "developer packages" (`binutils', `make') in order to build
+`ePiX'. The more up to date your software is, the better your
+experience is likely to be, but bleeding edge versions are not
+necessary, or even always desirable.
+
+ 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 GNU environment.
+
+ Jay Belanger's `emacs' mode allows you to write, compile, and view
+`ePiX' figures without leaving `emacs'. If you use another editor,
+you'll want to create template source files so you don't have to type
+boilerplate code each time you write a new figure.
+
+
+
+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
+
+
+
+File: epix.info, Node: Installation, Prev: Software Dependencies, Up: Introduction
+
+1.3 Installation
+================
+
+`ePiX' is distributed over the World-Wide Web as source code. Packages
+may be found at `http://mathcs.holycross.edu/~ahwang/epix/ePiX.html'
+The latest stable release is also on the CTAN mirrors, in the
+`graphics' directory. (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.tar.gz
+ tar -jxvf epix-x.y.z.tar.bz2
+ (`x.y.z' is the version number) or, if your `tar' doesn't do
+decompression,
+
+ gunzip -c epix-x.y.z.tar.gz | tar -xvf -
+ bzcat epix-x.y.z.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'. 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'.
+
+
+
+There are two mailing lists, one for user questions, one for
+development discussion. Please visit
+`http://savannah.nongnu.org/mail/?group=epix' to subscribe.
+
+
+File: epix.info, Node: Getting Started, Next: Reference Manual, Prev: Introduction, Up: Top
+
+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 *Note section:running::, describes the commands (shell
+scripts) comprising `ePiX', and explains how to set up a graphical
+environment using standard *nix programs. Section *Note
+section:overview::, briefly describes figure creation. Section *Note
+section:tutorial::, presents a few files side-by-side with their
+output, and should be read at a computer so you can run the exercises.
+
+* Menu:
+
+* Running `ePiX'::
+* The Drawing Model::
+* Tutorial::
+* `C++' Basics::
+* Animation::
+* Layout Tricks::
+
+
+File: epix.info, Node: Running `ePiX', Next: The Drawing Model, Prev: Getting Started, Up: Getting Started
+
+2.1 Running `ePiX'
+==================
+
+An "input file" is a human-written figure specification containing
+`ePiX' commands. An "output file" is machine-created, and is included
+directly into a `LaTeX' document with the appropriate packages.
+
+ Conversion ("compiling" a figure) is accomplished with four shell
+scripts, `laps', `epix', `elaps', and `flix'. Each script has a
+preferred extension for its input files, and is invoked with a command
+of the form
+
+ <script> [options] <input file(s)>
+ Often, no options are necessary. `<script> --help' describes
+`<script>''s options.
+
+ By default, output file names are constructed by replacing the input
+extension with the (preferred) output extension. For brevity,
+extensions may be omitted. If the script has doubts about your intent,
+it proceeds with default behavior and prints a warning message.
+
+ The author is a great fan of <TAB> completion, under which a shell,
+based on what has been typed so far, automatically fills in a command
+when the <TAB> key is pressed. `ePiX' comes with code snippets that
+complete intelligently when the first part of a command is one of the
+shell scripts. For example, if command completion is active, typing
+`epix' <TAB> prints only names of `epix' input files. To use this
+feature, you must install Ian MacDonald's `bash completion' package.
+The `INSTALL' and `POST_INSTALL' files contain details.
+
+
+
+`laps' performs `LaTeX' to PostScript/PDF conversion, and is
+independent of the rest of `ePiX'. By default, `laps' invokes `LaTeX'
+and `dvips'. The option `--pdf' creates a PDF file by post-processing
+the PostScript with `ps2pdf'. Other `TeX'-family processors
+(`pslatex', `pdftex', etc.) may be used instead of `LaTeX' by invoking
+`laps' with an appropriate option.
+
+
+
+`epix' compiles an input file into a `LaTeX' picture. The input file
+should have extension `xp' (for eXtended Picture). Jay Belanger's
+`emacs' mode is Highly Recommended; the installation procedure can be
+found in the `POST_INSTALL' file. When this mode is active, `emacs'
+automatically inserts a preamble template when a new `xp' file is
+created. In addition, you can peruse `ePiX''s info file, or format,
+compile, and preview files, all from within `emacs'.
+
+ Output files from the script `epix' have extension `eepic', after
+Conrad Kwok's enhancements to the `LaTeX' picture environment. In
+Version 1.2, however, an output file need not contain `eepic' macros at
+all.
+
+ An output file is `input' directly into a `LaTeX' document whose
+preamble contains appropriate `usepackage' lines. Rotated text
+requires the `rotating' package.
+
+
+
+`elaps' creates stand-alone vector images (`eps' or `pdf') from `epix'
+input files or `eepic' figures, even those not produced with `epix'.
+`elaps' automatically loads the `LaTeX' packages needed for features
+described in this manual. Additional `LaTeX' packages and `dvips'
+options may be specified on the command line.
+
+
+
+`flix' creates bitmapped images and movies, Section *Note
+section:animation::, . Input files should have extension `flx', and
+must contain a valid `epix' header as well as additional code. Jay
+Belanger's `emacs' mode facilitates creation of `flix' files.
+
+
+File: epix.info, Node: The Drawing Model, Next: Tutorial, Prev: Running `ePiX', Up: Getting Started
+
+2.2 The Drawing Model
+=====================
+
+To draw a figure manually, you select a sheet of paper of appropriate
+size and add paths, markers, and labels. These scene elements have
+attributes (line color, line width, fill color, font size, etc.)
+affecting their appearance.
+
+ `ePiX''s drawing model behaves similarly. A `picture' command sets
+the _canvas_ (or logical drawing area, a Cartesian rectangle) and the
+true size of the final figure. A `begin' command initializes the
+"virtual paper" for drawing. Subsequent _drawing commands_ add objects
+to the scene: lines, curves, function plots, labels, and the like. The
+printed appearance of scene elements is determined by the current
+"attribute state" and controlled by _style declaration_ which remain in
+effect until superseded. Finally, an `end' command closes the figure and
+prints it to the output file.
+
+ In this manual, command descriptions follow a few conventions.
+Optional arguments are enclosed in square brackets. A `len' argument is
+either a number (representing a length in `pt') or 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.), or a `Color' specified by
+densities (`RGB(r,g,b)', `CMY(c,m,y)', etc.)
+
+ * Fill color: `fill(color)', `nofill()'.
+
+ * Line color and width: `plain([color])', `bold([color])'.
+
+ * Text size: `font_size([size])', returns to `normalsize' if no
+ argument is given.
+
+
+ \noindent A complete list of style commands is found in Section
+*Note section:quickref::, , starting on page *Note section:quickref::.
+
+ To handle three-dimensional scenes, a `camera' performs point
+projection from a selected spatial location to the canvas. As a user,
+you'll need to control relatively few of the `camera''s parameters.
+Keep in mind, however, that elements are added to a scene in the same
+order their commands appear in the output file, and that later elements
+generally cover earlier ones. Some three-dimensional scenes require
+manual ordering of the input file; such ordering is dependent on the
+`camera''s location.
+
+ By default, `ePiX' draws thin, solid, black lines, performs no
+filling of regions, prints text in a 12 pt Roman font, and looks down
+the z axis from a large distance, giving orthogonal projection on the
+(x,y) plane. When the `camera' is moved, the z axis points vertically
+up on the page.
+
+
+File: epix.info, Node: Tutorial, Next: `C++' Basics, Prev: The Drawing Model, Up: Getting Started
+
+2.3 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. 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. 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 path 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 from the drop-down menu
+(or with the keyboard command), 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 code needed to specify the
+figure's size, 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" // These lines are analogous
+using namespace ePiX; // to a usepackage command.
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "2 x 1in"); // corners, true size
+
+ begin(); // ---- Figure body starts here ----
+
+ border(Black(), "1pt"); // color, line width
+
+ font_size("Huge"); // May be any font size, e.g. "scriptsize"
+ label(P(0,0), "Hello, world!");
+
+ end(); // ---- End figure; write output file ----
+}
+
+
+[Image]
+
+ * Change the color and width of the border. (`RGB(r,g,b);' creates
+ an RGB color, CMY colors are analogous. Named primaries are
+ available. The densities should be between 0 and 1 for
+ "expected" behavior.)
+
+ * Add `backing(Cyan());' after the `border' command.
+
+ * Put the command `crop_ellipse();' before the `border' command.
+ Permute the `crop_ellipse' command with the `border' and
+ `backing' lines, and note how the attribute (`crop') affects
+ objects (`border', `backing').
+
+
+
+
+Our next file uses simple objects to draw a 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)); // the door
+ nofill();
+
+ bold(); // draw thicker lines
+ 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]
+
+ * Add declarations such as `bold(RGB(1,0.9,0.5))' or
+ `fill(Yellow())' to color the scene. (Color and filling are
+ orthogonal attributes.)
+
+ \noindent The sample file `house.flx' uses loops to draw gradient
+fills of the lawn, sky, and sun, and animates a sunset.
+
+
+
+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), "5 x 1in"); // [-2,2] x [-1,1]
+
+ begin();
+ revolutions(); // set angle units, [0,1] = one turn
+
+ h_axis(16); // axes w/default endpts
+ v_axis(4);
+ h_axis_labels(4, P(0,-4), b); // shift down 4pt, align below
+
+ plain(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.
+ The `polarplot' command graphs r=f(\theta).)
+
+ * 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.
+
+
+
+
+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), "2 x 1in");
+ begin();
+ pst_format(); // use PSTricks macros for output
+
+ // 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));
+
+ plain(Blue(1.2)); // line color and width
+ fill(Yellow()); // shading color
+ surface(f, R);
+
+ 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)); // convert n to an index bound
+ 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); // return (x, y)
+}
+
+int main()
+{
+ picture(P(0, -1), P(6*M_PI, 1), "5 x 1in");
+
+ begin();
+
+ set_crop();
+ bold(Green());
+ plot(Sin, 0, xmax(), 120);
+
+ domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40));
+ for (int i=3; 0 <= i; --i) // print in descending degree
+ {
+ bold(RGB(0.25*i, 0, 1-0.25*i)); // degree-dependent color
+ plot(sin_n, R.slice2(5*i+1)); // plot for n = 5i+1
+ }
+ end();
+}
+
+
+[Image]
+
+
+
+Page layout can be composed from sub-pages with `screen' objects. In
+the loop body below, objects are added to the "active" `screen', 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"); // overall size
+
+ 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]
+
+
+File: epix.info, Node: `C++' Basics, Next: Animation, Prev: Tutorial, Up: Getting Started
+
+2.4 `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 ("commands"). Plain declarations are
+relatively rare in user files, since a definition serves to declare any
+new names that it contains.
+
+ Every statement ends with a semicolon, and conventionally a file
+contains at most one statement per line. The compiler ignores nearly
+all whitespace (spaces, tabs, and newlines), which should be used
+freely 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
+loads the contents of the "header" file `epix.h', 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, var2, MY_var, aLongVariableName; // valid
+my-var, 2var, \v@@riable, $x, ${MY_VARIABLE}; // not valid
+ Variable names are case-sensitive, and numerous (non-universal)
+conventions govern the significance of capitalization. Generally, make
+names descriptive but not unwieldy, and avoid language keywords (such
+as `const', `true', `double', `class', or `public') and names that
+begin with an underscore.
+
+ 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. The code block
+
+double f(double x)
+{
+ return sqrt(1-x*x);
+}
+ specifies the `double'-valued function f of one `double' variable
+defined by the formula f(x)=\sqrt1-x^2.
+
+
+
+`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 multi-line comment, but a
+`C'-style comment may not; the compiler will mistake the first `*/' it
+encounters as the end of the current multi-line 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. The contents of the output file
+start with `begin()' and terminate with `end()'. 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.
+
+
+
+In `C++', a `string' is a sequence of characters. Most `string's in
+`ePiX' input files are _literals_, double-quoted `string's whose value
+is read from the input. In a string literal, backslash is an escape
+character; 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" literally represents a
+`LaTeX' command, while "\textwidth" is read "`TABextwidth'" by the
+compiler.
+
+ Though not commonly needed, raw text can be printed to the output
+file. The functions `write', `pre_write', and `post_write' accept
+`string' arguments. `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. As an application, a complete `LaTeX' `figure'
+environment (with caption and label) can be produced by an `ePiX' file,
+Figure *Note fig:captioned::, .
+
+
+#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 internal state. A
+_conditional statement_ causes blocks of code to be executed according
+to criteria. 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.
+
+
+File: epix.info, Node: Animation, Next: Layout Tricks, Prev: `C++' Basics, Up: Getting Started
+
+2.5 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.
+
+ By default, `flix' creates movies with 24 frames, in which `tix()'
+runs from 0 to 1, and animates at 0.08 sec/frame. These and other
+parameters can be changed with command-line options.
+
+ A "typical" `.flx' file may take 30 seconds to a few minutes to
+compile, depending on the number of frames and the complexity of each
+frame. 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. While running, `flix' prints
+a 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
+assembles the movie.
+
+
+File: epix.info, Node: Layout Tricks, Prev: Animation, Up: Getting Started
+
+2.6 Layout Tricks
+=================
+
+
+
+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 are
+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.
+
+
+
+`ePiX' can place external images into a figure, similarly to Rolf
+Niepraschk's `overpic' package. You provide the Cartesian center point,
+the file name, and optionally the true height and/or width of the image:
+
+ label(P(a,b), "\\includegraphics[width=w,height=h]{file}");
+ This effect requires the `graphicx' package. When compiling a
+stand-alone graphic containing an external image, you must specify the
+`graphicx' package on the command line: `elaps -p graphicx <file>'
+
+
+File: epix.info, Node: Reference Manual, Next: Advanced Topics, Prev: Getting Started, Up: Top
+
+3 Reference Manual
+******************
+
+This chapter details `ePiX''s capabilities, discussing attributes and
+data types, and listing available commands in the form
+
+ label(P posn, [P offset], string text, [align]);
+ circle(P ctr, double rad=1, normal=P(0,0,1));
+ As in Chapter *Note chapter:started::, , function arguments are given
+by type (`P', `double', `string', etc.)\ and name, or by name alone if
+the type is clear. Optional arguments are enclosed in square brackets.
+A few argument types, such as `[align]' above, admit only a small
+number of values; these cases are explained when the corresponding
+command is first introduced.
+
+ A name followed by an equals sign and a value indicates a default
+argument; if omitted in an input file, the compiler substitutes the
+default value. Only trailing arguments may be specified this way. For
+example, if the `rad' argument of the `circle' command is omitted, the
+`normal' argument _must_ be omitted as well.
+
+ In an input file, only an argument's value is given, not the type:
+
+ label(P(0,0), P(0,-4), "Hello world", b);
+ circle(P(0,-0.25), sqrt(2)); // use default normal
+
+ Generally, `len' signifies either a number (representing a length in
+`pt') or a double-quoted string containing a number and a two-letter
+`LaTeX' length unit, such as `"1.5pt"' or `"6cm"'. `color' represents a
+`Color' object constructed from a named primary (`Blue()',
+`Magenta(0.7)', etc.), a color specification (`RGB(r,g,b)',
+`CMY(c,m,y)', etc.), or an operator applied to an existing `Color'.
+
+* Menu:
+
+* File Structure::
+* Picture Size and Aspect Ratio::
+* Color::
+* Scene Attributes::
+* Drawing Attributes::
+* Creating and Drawing Objects::
+* More About `C++'::
+* Attribute Quick Reference::
+
+
+File: epix.info, Node: File Structure, Next: Picture Size and Aspect Ratio, Prev: Reference Manual, Up: Reference Manual
+
+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" // N.B. no semicolon
+using namespace ePiX;
+
+int main() {
+ picture(P(a1,b1), P(a2,b2), "n1 [unit1] x n2 unit2");
+ begin(); // end of preamble, start of body
+ end(); // end of body
+}
+ `ePiX' commands are of four general types: drawing, attribute setting,
+definitions (of data and functions), and operations on existing
+objects. 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
+in the preamble or body.
+
+
+
+The `end()' command writes the output file to `stdout', using `eepic'
+macros by default. The shell scripts redirect `stdout' to an
+appropriate disk file.
+
+ The attribute-setting command `pst_format()' causes the output file
+to be written using `PSTricks' macros when `end' is called. Similarly,
+`tikz_format()' causes the file to be written using `tikz' macros, and
+`eepic_format()' causes the file to be written using `eepic' macros.
+These commands may appear anywhere in the figure body. There is no
+reason for a file to contain more than one such command.
+
+ The output format may be selected on the command line, overriding any
+explicit request in the input file. Supplying `epix', `elaps', or
+`flix' with one of the options `--pst', `--tikz', or `--eepic' is
+tantamount to issuing a `pst_format()' (etc.)\ command just before the
+end of the file. These options are listed in decreasing precedence. If
+more than one is given, the "strongest" applies, regardless of the
+command line order.
+
+ A figure may be written directly to a specified disk file, in a
+format unaffected by the command line flags above. The command
+
+ print_eepic("file.tex");
+ writes the figure to the named file using `eepic' macros. Analogous
+commands exist for the formats `pst' and `tikz'. These commands perform
+an immediate action. Consequently, the command's location in the input
+file is significant, and multiple commands may appear in a single file,
+so long as distinct file name arguments are provided. Applications
+include writing the same figure in multiple formats, or creating
+successive "snapshots" of a lengthy computation.
+
+
+File: epix.info, Node: Picture Size and Aspect Ratio, Next: Color, Prev: File Structure, Up: Reference Manual
+
+3.2 Picture Size and Aspect Ratio
+=================================
+
+The `picture' command specifies a figure's logical and true sizes. In
+the "minimal file" snippet above, the _canvas_ 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.
+
+ The true (printed) width and height are read from `picture''s third
+argument, a "size `string'" such as "4cm x 1in", containing a number
+and optional `LaTeX' length unit, an `x', another number, and a
+mandatory length unit. Spaces may be used for legibility. The
+mandatory length unit becomes the `LaTeX' `unitlength'. The argument
+"4cm x 1in" creates a picture 4 cm wide and 1 in high, but internally
+converts 4 cm to inches. Recognized length units are `pt' (points, the
+default), `cm' (centimeters), `in' (inches), `mm' (millimeters), `pc'
+(picas), and `bp' (big points). (`1in = 2.54cm = 72bp = 72.27pt', `1pc
+= 12pt'.)
+
+ The logical and true sizes may be defined separately with the
+commands
+
+ bounding_box(P(a1,b1), P(a2,b2));
+ picture(n1, n2);
+ unitlength(len); // len a length string, not a double
+ One way or another, the logical and true dimensions _must_ have
+positive values when the `begin()' command is issued.
+
+ `LaTeX' treats the contents of a picture environment as a single box,
+aligned by default on its lower left corner. An `offset' command
+accepts two `double' arguments or a size `string' and shifts the page
+location accordingly. The command `offset("0.25 x -0.5cm")' shifts the
+picture right 0.25 cm and down 0.5 cm. If the `unitlength' is 1 cm,
+the command `offset(0.25, -0.5)' has the same effect.
+
+ A non-zero `offset' causes a picture's contents to appear in a
+location where `LaTeX' does not expect them. This can be useful in a
+`LaTeX' document, but should be avoided when compiling a stand-alone
+image, since `dvips' may crop according to rules of its own.
+
+ The canvas's corners are `(xmin(),ymin())' and `(xmax(),ymax())',
+while its width and height are `xsize()' and `ysize()'. The canvas is a
+virtual, advisory data structure; its dimensions are not directly
+related to the figure's printed size, and picture elements may lie
+outside the canvas. Affine scaling maps the canvas to the page when the
+output file is written.
+[Image]
+
+ The figure's aspect ratio is controlled by sizing the canvas. The
+aspect ratio is "true" if the canvas and page rectangles are
+geometrically similar, e.g., if both boxes are 1.5 times as wide as
+they are tall.
+
+
+File: epix.info, Node: Color, Next: Scene Attributes, Prev: Picture Size and Aspect Ratio, Up: Reference Manual
+
+3.3 Color
+=========
+
+`ePiX' provides a `Color' data type. Four models are implemented:
+`RGB', `CMY', `CMYK', and `Gray'. A `Color' holds primary color
+"channels", each carrying an intensity between 0 (no color) and 1 (full
+saturation). "No color" means black in `RGB' and `Gray', white in
+`CMY(K)'. `RGB', `CMY', and `CMYK' colors are written to the output
+file as commands in the corresponding model. `Gray' shades are written
+in `RGB'.
+
+ Operations on red-green-blue colors are described below.
+Functionally, colors are converted to `RGB', operated upon, then
+converted back to the original model. Conversions are as described in
+Uwe Kern's `xcolor' manual `xcolor'.
+
+
+
+Each color model has a "constructor" creating 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 *Note fig:densities::, . Other primary
+constructors work analogously.
+
+
+[Image]
+
+Figure[hbt]
+
+ Let \delta:[-2,2]\to[0,1] be the piecewise-linear function that
+converts real numbers to primary color densities, \clip:R\to[0,1] the
+clipping function. The non-primary constructor `RGB(r, g, b)' computes
+the density of the red channel as
+\clip\bigl(\delta(r)+\delta(-g)+\delta(-b)\bigr); the green and blue
+channel densities are computed similarly. Every color can be created
+with arguments between 0 and 1, but the constructor accepts arbitrary
+real arguments and returns colors varying "continuously and
+periodically".
+
+ Colors possess an "alpha-channel" for transparency. Except as
+supported by the output format, this feature is a stub.
+
+
+
+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 channels by c, rebuild
+ 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.alpha(double d); // set alpha channel to clip(d)
+
+ tint.filter(col); // return min density in each channel
+ Except for `filter', these operators modify their object. `filter'
+simulates the effect of viewing `col' through a transparent sheet of
+`tint', and returns a new `Color' object having the same model as
+`tint' without modifying `tint' itself.
+
+
+File: epix.info, Node: Scene Attributes, Next: Drawing Attributes, Prev: Color, Up: Reference Manual
+
+3.4 Scene Attributes
+====================
+
+Objects in a scene sit in 3-dimensional space. A _camera_ maps objects
+to the _active screen_. The active `screen' may, in turn crop its
+contents. Each drawing command creates an object, "photographs" it, and
+adds the image to the active `screen'. This section describes the
+`Camera' and `screen' classes and a few associated concepts.
+
+
+
+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()'. The
+current angular mode affects all trigonometric functions and operations.
+
+
+
+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, Figure *Note fig:camera::, .
+
+
+[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 _camera sphere_ is centered at the viewpoint and passes through the
+target. 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 the camera sphere, then maps the sphere to the screen plane; the
+fisheye lens does orthogonal projection (so the entire image lies
+inside the disk centered at the target whose radius is the range) while
+the bubble lens does stereographic projection from the target's
+antipode.
+
+ An input file normally uses a single camera, so a global object named
+`camera' is defined automatically. 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_ through which all scene `Color's pass. For
+uniformity, the filter should only be set at the start of the file
+body, before any visible elements have been placed in the scene. The
+filter has two primary uses--model conversion and color separation--but
+can also be used for special effects.
+
+ There is a `Neutral' color, for which filtering has no effect at
+all. The `camera''s default filter is `Neutral'. In addition, each
+color model has a _neutral_ representative, `RGB_Neutral', etc. Passing
+`Color's through a neutral filter preserves their appearance but
+converts them to the neutral `Color''s model.
+
+ Filtering can be used to "split" a `Color' into primary
+constituents. For `RGB' channels, the primaries themselves are suitable
+filters. For `CMYK' channels, there are special _process_ filters,
+named C_Process, etc.
+
+ camera.filter(CMY_Neutral()); // convert all colors to CMY
+ camera.filter(Gray_Neutral()); // black and white photography
+ camera.filter(Green()); // the green channel
+ camera.filter(M_Process()); // the magenta channel
+ camera.filter(Red(1.4)); // la vie en rose?
+
+
+
+
+Two operations handle elements lying far from the target. _Cropping_
+culls elements based on their screen location, and is described later.
+_Clipping_ removes objects whose spatial location lies outside the
+"clip region".
+
+ Initially, the clip region is a very large box centered at the
+origin. Commands are provided to resize this box, keeping the faces
+parallel to coordinate planes.
+
+ 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)
+ clip_box(); // very large box
+ Additional "clippers" may be added manually. Individual clipping
+planes are specified by a point and inward-pointing normal vector.
+Parallel planes cutting a "slice" or "slab" are described by a
+location, direction, and a distance. The location lies halfway between
+the clipping planes, and the planes' normals point toward the location.
+
+ clip_face(P loc, P perp); // perp points inward
+ clip_slice(loc, perp); // very close parallel planes
+ clip_slice(loc, perp, dist); // planes separated by dist
+ clip_restore(); // remove manually-added clip planes
+ Like `clip_restore', the `clip_box' and `clip_to' commands remove all
+user-specified half spaces.
+
+
+
+By default, drawing occurs in the Cartesian coordinate system of the
+`canvas'. However, insets and subfigures are most naturally composed in
+"local" coordinates, then placed into their final location as a unit, a
+process called _layout_. `ePiX' implements layout with the `screen'
+class.
+
+
+
+A `screen' is a Cartesian plane containing a distinguished coordinate
+rectangle, its _bounding box_. The `canvas' of a figure is a `screen',
+as is the internal representation of the printed page. 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
+ deactivate(subfig); // re-activate the previous screen
+
+ The `canvas' is automatically drawn at the `end' of the input file.
+The contents of other `screen's must be incorporated into the `canvas'
+explicitly with an `import' or `inset' command. `import' affinely
+scales the bounding box of the "child" `screen' to the `canvas'. `inset'
+specifies corners in the "parent" where the child 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
+
+
+
+The portion of a `screen' enclosed by a specified rectangle can be
+_extracted_. Each of the commands
+
+ subfig.extract(P sw, P ne);
+ canvas().extract(P sw, P ne);
+ returns the `screen' having stated corners and containing part of
+`subfig' or the `canvas', respectively. Elliptical and diamond-shaped
+portions of a `screen' may be extracted. The contents occupy the
+ellipse or diamond inscribed in the given rectangle.
+
+ subfig.extract_ellipse(sw, ne);
+ canvas().extract_diamond(sw, ne);
+ The `screen' returned by `extract' (or its variants) may be used just
+like a manually-constructed `screen', for example to construct a
+magnified inset.
+
+
+
+On occasion, it is necessary to draw at known page size, independently
+of the unit length. For 2-dimensional drawing in the (x_1,x_2)-plane
+with the `camera' in its default location, the coordinates (horizontal,
+vertical, or both) of a `screen' may be interpreted as true pt offsets
+relative to a specified point rather than as Cartesian coordinates.
+
+ inlay(subfig, P loc);
+ inlay_horizontal(subfig, loc);
+ inlay_vertical(subfig, loc);
+ Each command maps the origin of `subfig' to the specified location in
+the active `screen'. The first performs affine scaling so that one
+Cartesian unit in `subfig' maps to one true pt on the page. The second
+and third commands perform this scaling only in the named direction.
+
+ The `inlay' functions are suitable only for 2-dimensional effects.
+For 3-dimensional true-size drawing, the function `pt_to_screen'
+converts a true length of 1 pt into Cartesian coordinates in the active
+`screen'. For example, the command `line(P(0,0),
+P(pt_to_screen(12),0))' draws a line segment 12 pt long with its left
+endpoint at the Cartesian origin. True size drawing is unusual in an
+input file, but has definite uses in library code; `ePiX''s right angle
+marker is a typical application.
+
+ Either type of true-size drawing works as described when drawing in
+the `canvas', and _only_ when drawing in a `screen' imported to the
+`canvas' at "true Cartesian" size (one `screen' unit maps to one
+Cartesian unit in the `canvas'). In other situations, the true size
+coordinate(s) will be scaled by additional affine transformation(s).
+
+
+
+A `screen' has a _crop mask_: rectangular (default), elliptical, or
+diamond-shaped. If cropping is switched on in the active `screen',
+added elements are cropped to the crop mask. For example, cropping by
+the default crop mask in the `canvas' ensures the figure lies inside
+the printed region allocated by `LaTeX'.
+
+ The `crop' commands below affect the active `screen' only. Cropping
+is not a "global" attribute, but must be set or unset explicitly for
+each `screen'. By default, cropping is switched off.
+
+ set_crop(); // activate cropping
+ set_crop(false); // deactivate cropping
+ crop_diamond(); // <>-shaped mask, set crop state
+ crop_ellipse(); // etc...
+ crop(); // crop active screen's contents
+ Normally the crop mask is inscribed in the `screen''s bounding box.
+The commands `crop_diamond' and `crop_ellipse' also accept a pair of
+`P' arguments, which are treated as corners of the crop box.
+
+ The active `screen' may be decorated with a `border' (outline of
+specified color and line width) and `backing' (solid fill color). The
+crop mask determines the shape of the `border' and `backing'.
+
+ border(color, len);
+ backing(color);
+ Identically-named member functions can be applied to an arbitrary
+`screen' whether or not it is active:
+
+ scr.crop_rectangle().backing(Blue(1.8));
+ canvas().crop();
+
+
+
+A _plane affine map_ has the form T(x) = Ax+b for some invertible
+2\times2 matrix A and a constant vector b. `ePiX''s `affine' class
+allows affine maps to be built and applied to `screen's' contents.
+
+ An affine map is uniquely determined by the images of three
+non-collinear points. The constructor returns the affine map sending
+the points (1,0), (0,1), and (0,0) to `pt1', `pt2', and `pt0',
+respectively.
+
+ affine af(P pt1, P pt2, P pt0=P(0,0));
+ To emphasize, the arguments are locations, not displacements, and the
+image of the origin comes last. There is also a `void' constructor
+(taking no arguments) which returns the identity map.
+
+ To facilitate construction of affine maps, an existing `affine' may
+be post-composed with a variety of "elementary" affine transformations.
+In the commands below, `th' is an angle (in current units), `sc' is a
+non-zero `double', and `ctr' is a point fixed by the composing
+transformation. In each command, `ctr' defaults to (0,0).
+
+ affine af; // the identity map
+ af.shift(P arg); // translate by arg
+ af.rotate(th, [ctr]); // counterclockwise rotation about ctr
+ af.reflect(th, [ctr]); // reflect across line through ctr
+
+ af.h_scale(sc, [ctr]); // horizontal scaling
+ af.v_scale(sc, [ctr]); // vertical scaling
+ af.scale(sc, [ctr]); // dilatation
+
+ af.h_shear(sc, [ctr]); // shear preserving horizontals
+ af.v_shear(sc, [ctr]); // shear preserving verticals
+
+ af.invert(); // the inverse
+ af.postcomp(affine f); // post-compose with f
+ af(f); // pre-compose, af not modified
+ A non-invertible `affine' can be created _only_ by shearing or scaling
+with an extremely large or extremely small argument, or by supplying
+three collinear points to the constructor. Calling `invert' on a
+non-invertible map merely issues a warning and performs no action.
+
+ An `affine' may be applied to a `screen''s current contents. The
+`screen' class has eight member functions (`shift' through `shear')
+with syntax identical to the affine map functions. In addition, an
+arbitrary `affine' may be applied to a `screen':
+
+ scr.shift(arg); // shift scr's contents by arg; etc.
+ scr.apply(f); // apply f to scr's contents
+ To apply a composition of several maps to a `screen', it's best to
+build an `affine' map by composition, then `apply' the map. Composing
+`affine's is cheap; `apply'ing an `affine' is costly in proportion to
+the number of elements in the `screen'.
+
+ Applying an `affine' to a `screen' has no effect on the bounding
+box, `border', or `backing', and may move elements outside the bounding
+box even if cropping is active. To ensure a `screen''s contents lie
+inside the bounding box, `crop' the `screen' _after_ `apply'ing the
+`affine'(s).
+
+ The sample file `inverse.xp' uses `affine' maps to depict branches
+of inverse functions in one variable, `symmetry.xp' depicts the
+permutation group S_3 by its action on a regular hexagon.
+
+
+File: epix.info, Node: Drawing Attributes, Next: Creating and Drawing Objects, Prev: Scene Attributes, Up: Reference Manual
+
+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); // turn filling on, specify color
+ 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(len); // set line pen width
+ pen(color); // set line color, keep width
+ pen(color, len); // set color and width
+ As usual, `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([color]); // 0.4pt
+ bold([color]); // 0.8pt
+ bbold([color]); // 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. In the
+sample styles below, the repeating units have the same page size, 12 pt.
+[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 ith character is a dash or space, the ith subinterval is drawn
+solid or empty, respectively. If the ith character is a period, a dot is
+placed at the midpoint of the ith 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 *Note section:extensions::, 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 (counterclockwise) angle is set in current
+angle units with the command `label_angle(theta)'. For example, a
+rotation angle of 90 degrees prints labels along a vertical axis.
+Though label rotation has legitimate uses, it can make labels more
+difficult to read, defeating their purpose. Do not use rotated labels
+merely because they are available. As a practical matter, if an output
+file contains rotated labels, the enclosing document must use the
+`rotating' package. `elaps' automatically loads this package.
+
+ An `affine' behaves moderately intelligently when acting on a marker
+or label. The mapping is applied to the label's location, and the
+"linear part" is used to adjust the offset and label angle. No attempt
+is made to treat alignment. For best results, if a `screen' will have
+an `affine' applied to it, label positions should be fine-tuned only
+with offsets, not alignment arguments. In all situations, the font
+itself is unchanged; no attempt is made to print sheared, scaled, or
+reflected text. The sample file `inverse.xp' illustrates the effect of
+affine maps on labels.
+
+
+
+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. If no argument is
+given, `normalsize' is understood. font_face accepts a two-letter
+string, appended to the string "`text'" to give a `LaTeX' font
+declaration command ("`textsc'" above). Finer-grained control is
+accomplished by placing `LaTeX' commands into the label text.
+
+
+
+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 text color
+ label_mask(color=White()); // set mask color
+ label_pad(string len);
+
+ label_border(color, [len]); // set color (and line width)
+ label_border(len); // set line width only
+ no_label_border(); // turn off label borders
+
+
+
+`ePiX''s marker types, listed in Table *Note table:marker::, , 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); ---
+ A `circ' is filled with the current `mask_color', and a `ring' is
+"hollow". 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 4 pt in diameter; `dot', `box',
+and `circ' are 3 pt in diameter; `ddot' and `bbox' are 2 pt in
+diameter. At arbitrary diameter, a `spot' is 4/3 the diameter of a `dot'
+and a `ddot' is 2/3 the diameter. The command `dot_size(diam=3)' sets
+the diameter of a `dot', and hence the size of all dot-like markers.
+
+
+[Image]
+
+Table[tb]
+
+
+
+When constructing and placing a label,
+ * Offsets are specified in `pt' (true length), not Cartesian
+ units: A label's location relative to its 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 set 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
+
+
+
+File: epix.info, Node: Creating and Drawing Objects, Next: More About `C++', Prev: Drawing Attributes, Up: Reference Manual
+
+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.
+
+ Depending on context, a `P' may represent either a _location_
+(point) or a _displacement_ (vector). Almost all `ePiX' functions treat
+a `P' as a point. However, algebraic operators and commands that plot
+vector fields treat `P' arguments as displacements.
+
+ 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;
+scalar, cross, and componentwise products; 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); // scalar 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. *Note non-eucl::ff.
+
+ 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.
+
+ 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 met. The constructors return well-formed objects
+with two exceptions: `Circle' and `Plane' 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. Malformedness is benign: Calling
+`draw()' on a malformed object does nothing.
+
+
+
+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'.
+
+ The elements of a `frame' are named `sea', `sky', and `eye', just as
+for the `camera'. A `frame' can be rotated through an arbitrary angle
+about any of its elements.
+
+ frame(); // the standard basis {E_1, E_2, E_3}
+ frame fr(v1, v2, v3); // orthonormalize {v1, v2, v3}
+ fr.sea(); // the first element of fr, etc.
+ fr.rot1(theta); // rotate fr through theta about sea, etc.
+
+
+
+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.
+
+ Two commands are available to mark off right angles or a subtended
+angle. Each accepts a spatial location and two non-zero directions, and
+draws a scene element in the plane spanned by the vectors.
+
+ right_angle(P loc, P v1, P v2, scale=8);
+ arc_measure(P loc, P v1, P v2, scale=8);
+ arc_measure(P loc, P v1, P v2, offset, text, align, scale=8);
+ The `right_angle' command does not check its arguments for
+perpendicularity. The `arc_measure' commands mark the _small_ angle
+subtended by the directions; the label form places a label at the
+midpoint of the arc. The (optional) `scale' argument is the true size
+in `pt' of the marker.
+
+
+
+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, Figure *Note
+fig:fractal::, . 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_inset(c=0); // base indent as frac of ht
+ [Image]\qquad [Image]\qquad [Image] \\ The `inset' 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.
+
+
+
+`ePiX' provides an `axis' class for coordinate axes. Labels are
+generated automatically in a variety of styles: decimal, scientific
+notation, fraction, and trigonometric fraction. Logarithmic axes and
+labels are available. Axis and labeling commands from Version 1.0 have
+been retained.
+
+
+
+An `axis' consists of a line segment divided into a specified number of
+equal-length subintervals by "major" (long) tick marks. Each
+subinterval may be divided further by "minor" (short) tick marks.
+Minor ticks may be equally-spaced ("Cartesian") or logarithmically
+placed. Finally, a label is written at each major tick mark with
+specified offset and alignment. Labels are generated automatically from
+the endpoints, so the line should be parallel to a coordinate axis.
+Label attributes (masking, borders, font size and face, rotation angle)
+are determined by the current label style, not by the `axis'.
+
+ The command
+
+ axis(P tail, P head, int n, P offset=P(0,0), [align = none]);
+ creates an axis joining `tail' to `head', divided into `n' segments of
+equal length, with a major tick mark and label at each division point
+and endpoint. The `offset' and `align' arguments have the same meaning
+as for ordinary labels.
+
+ The number and length of minor ticks, and the alignment of ticks, are
+controlled with member functions:
+
+ axis Ax(P(a,c), P(b,c), n);
+ Ax.subdivide(n); // put n-1 minor ticks in each axis segment
+ Ax.tick_ratio(r); // minor length = r*major length
+ Ax.align(AL=c); // align all ticks; AL = t, b, l, r, or c
+ By default, major ticks are `6pt' long and twice the length of minor
+ticks. The global declaration `tick_size(len)' sets the major length,
+subject to "reasonable stylistic limits". For visual consistency, tick
+lengths should not be changed casually.
+
+ Labels on an `axis' may be drawn in several styles, selected with
+member functions:
+
+ Ax.dec(); // decimals (default)
+ Ax.frac(); // fractions, e.g. 0.5 -> \frac{1}{2}
+ Ax.trig(); // fractional multiples of \pi
+ Ax.sci(); // scientific notation, k\times base^N
+
+ Ax.unmark(double); // remove label at selected location
+ Ax.precision(p); // set number of digits for decimal labels
+ Ax.align_labels(AL); // re-align labels
+ Arbitrary textual labels depending on one coordinate are obtained by
+writing a `string'-valued function of `double' and "registering" it:
+
+ // f represents x as a string in given precision and base
+ std::string f(double x, unsigned int prec, unsigned int base);
+ Ax.label_rep(f);
+ For example, textual tags can be printed instead of numeric labels.
+
+ By default, an `axis' is Cartesian. The member function `log(int
+b=10)' converts an `axis' to "log mode" with specified base; this
+affects both tick marks and labeling. If `b' is at least 3, minor tick
+marks appropriate for a logarithmic axis base `b' are drawn. Second,
+labels are written in decimal or scientific notation appropriately for
+a logarithmic axis; that is, "k\times b^N" (or its decimal value) is
+written at location N+\log_b k.
+
+ Minor ticks of a log `axis' may be labeled individually; again, this
+is controlled with member functions:
+
+ Ax.tag(d); // labels at N+log_b(d)
+ Ax.tag235(); // tag 2, 3, and 5 if b=10
+ Ax.tags(); // tag 1, ..., b-1
+ Ax.untag(); // remove all tags, including 1
+ Ax.untag(double); // remove one tag, e.g. Ax.untag(9);
+
+ For convenience, an `axis' object along an edge of the active
+`screen' can be created with a named command:
+
+ top_axis(n, offset, align);
+ bottom_axis(n, offset, align);
+ left_axis(n, offset, align);
+ right_axis(n, offset, align);
+ The ticks automatically point into the bounding box.
+
+ The functions above create objects or set `axis' attributes, but
+write no output. Tick marks and labels can be printed separately, or at
+once:
+
+ Ax.draw(); // axis, tick marks, and labels
+ Ax.draw_ticks(); // axis and ticks only
+ Ax.draw_labels();
+
+
+
+`ePiX' formerly supplied commands for drawing simple axes and their
+labels. These commands have been kept for compatibility. 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. 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 endpoint 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, [n], offset, [align], base=10);
+ h_axis_log_masklabels(p1, p2, [n], 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.
+
+
+
+Broken axes are best drawn using page layout, especially if axis labels
+are to be drawn. To accomplish the task, create a screen for each piece
+of axis, using appropriate Cartesian coordinates for the corners, then
+`inset' the screens so the axis pieces are nearly end to end. A zig-zag
+glyph signifies the break:
+
+ axis_break(P, P, scale=12);
+ The `P' arguments are the screen coordinates of the ends to be joined;
+the optional third argument is the true height and width in `pt' of the
+glyph. The sample file `coord_tricks.xp' uses layout and axis breaks.
+
+
+
+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:
+
+ pen(0.25);
+ grid(10*xsize(), 10*ysize());
+ pen(0.5);
+ grid(2*xsize(), 2*ysize());
+ pen(1);
+ grid(xsize(), ysize());
+
+
+
+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:
+
+ path ngon; // declare new path
+ for (int i=0; i<=n; ++i)
+ ngon.pt(cis(i*full_turn()/n)); // works in all angle modes
+ 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 grid square sizes.
+Generally, though, integer truncation occurs: If `R=domain(P(0,0),
+P(1,1), mesh(10,6))', then `R.resize1(0,0.25)' is the rectangle
+[0,0.25]\times[0,1] subdivided into 2\times6 subrectangles, since
+10\div4=2 in integer arithmetic. For expected behavior, choose mesh
+sizes to avoid 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 *Note fig:plot::, 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'.
+
+
+
+`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 time steps. 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 2-dimensional, the plot is a planar slice of the field, even
+if the field depends on three variables. If the domain is
+3-dimensional, the field is drawn in successive slices x_3=const,
+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.
+
+
+
+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 *Note table:marker::, . 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 divided at specified
+locations into "bins", not necessarily of equal length. Numerical data
+is read in and the number of points in each bin counted. The lifetime
+of a `data_bins' object has two stages. First, "cuts" (endpoints of
+subintervals) are added. Then, 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 in the bin; thus,
+the total area over an interval [a,b] does not depend on how [a,b] has
+been subdivided. The sample files `dataplot.xp' and `histogram.xp'
+illustrate use.
+
+ Statistical convention dictates cuts be chosen distinctly from data
+values; that is, values should all fall strictly within a bin, not at a
+boundary point. With large, unknown data sets, this convention may be
+difficult to uphold. `ePiX' attempts to handle anomalous data
+intelligently, by keeping counts of values "out-of-range" or "on-cut".
+
+ In detail, if x<a or x>b is a data value, it is counted as
+out-of-range and does not contribute to the histogram population. If
+x=a or x=b, the value counts as both out-of-range and on-cut but is
+added to the population of the lowest or highest bin, respectively. Any
+other cut appearing as a data input is flagged as on-cut, and
+increments the population of each adjacent bin by one-half. When a
+histogram or bar chart is written, `ePiX' prints a warning message
+summarizing the number of anomalous data seen.
+
+
+
+Simple horizontal and vertical error bars are provided. The final
+(optional) argument is the true height or width (respectively) in pt.
+
+ h_error_bar(P location, double error, <mark type>, ht=6);
+ v_error_bar(P location, double error, <mark type>, wd=6);
+
+ To create more complex elements, such as asymmetric bars, whisker
+plots, labeled error bars, and the like, write a custom function using
+true-size drawing, see page *Note truesize::. For example, a fillable,
+labeled, asymmetric, vertical rectangular error bar can be implemented
+(entirely in `ePiX') like this:
+
+ void error_bar(P loc, double lo, double hi, P offset,
+ std::string text, align, double wd=6)
+ {
+ const double width(pt_to_screen(0.5*wd)); // converts to 3pt
+ rect(loc - P(width, lo), loc + P(width, hi));
+ line(loc - P(width, 0), loc + P(width, 0));
+ label(loc + P(width, 0), offset, text, align);
+ }
+ For stylistic uniformity, functions such as this should be put into a
+library and used systematically. Section *Note section:extensions::,
+outlines the process of writing, compiling, and using a custom library.
+
+
+
+A `legend' systematically labels different parts of a plot by
+associating visual "keys" with explanatory text. This tends to be most
+useful for plots containing several distinct but conceptually related
+graphs requiring contrast.
+
+ Visually, a `legend' is represented as an aligned list of rows, each
+containing a box (the key), a gap (the label skip), and some text.
+These rows are printed in a (usually large) masked label. By default,
+keys are `12pt' squares bordered in black, the label skip is `6pt', the
+background is white, and the border is plain black. These attributes
+are controlled (simultaneously for all items) with member functions.
+Parameters of type `double' represent lengths in `pt'.
+
+ legend L;
+ L.backing(color); // set background
+ L.border(color, [double]); // set border color [and width]
+ L.border(double); // border width
+
+ L.item_border(color, [double]);
+ L.item_border(double); // same, for item borders
+
+ L.label_skip(double);
+ L.key_size(double);
+
+
+
+There are three types of legend key, representing filled regions,
+paths, and markers. Fill and path keys get their visual attributes from
+the current drawing state. A mark key must be told the marker type.
+Each is created by specifying the item text.
+
+ L.fill_item(text);
+ L.path_item(text);
+ L.mark_item(<mark type>, text);
+ Keys in the printed legend appear in the same order they are created
+in the input file.
+
+
+
+Normally, a `legend' is defined near the start of a file, and an item
+is added at the point in the file where the corresponding object or
+plot is drawn, so that the item receives the correct attributes. A
+`legend' is placed into the figure with the `draw' function. The
+arguments have the same meaning as for ordinary `label's.
+
+ L.draw(P location, P offset, align);
+ All three arguments are mandatory. "Global" `legend' settings
+(border, backing, etc.) may be changed anywhere between the `legend''s
+creation and `draw' function. The sample file `legend.xp' revisits the
+example on page *Note taylor_poly::, including a trig-labeled axis and a
+legend. The file `shadeplot.xp' contains filled keys, and `dataplot.xp'
+contains a `legend' with items of mixed type.
+
+
+File: epix.info, Node: More About `C++', Next: Attribute Quick Reference, Prev: Creating and Drawing Objects, Up: Reference Manual
+
+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 Kernighan and Ritchie `KnR', is an excellent, manageable resource
+for the basics of procedural programming. _C++ Primer Plus_, by Stephen
+Prata `Prata', clearly lays out the extensive details of `C++'.
+Marshall Cline's _`C++' FAQ Lite_ `Cline' engagingly discusses common
+points of confusion and furnishes tips on good design and programming.
+
+ `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 a
+`LaTeX' picture 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_ variable holds the memory address of
+another variable. Pointers are useful for manipulating (possibly large)
+data structures through "handles" of fixed small size. `C++' also
+provides _references_, which bind an additional name to an existing
+object and allow the object to be manipulated through this alias. 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.
+
+
+
+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.
+
+
+
+`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:
+
+ Cos Sin Tan
+ Sec Csc Cot
+ Acos Asin Atan
+ 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 Arg(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
+ `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. For more details, please
+consult a book, such as Prata `Prata' or Stroustrup `S', or Cline's
+on-line FAQ `Cline'.
+
+
+
+`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 an object from being altered unexpectedly by
+a function call in a different part of the program. Calling by value
+helps localize the logic of a program, and circumvents easy-to-write
+but extremely hard-to-find bugs.
+
+ In `C++', a function may accept reference arguments. Passing an
+object by reference grants the calling function access to the object
+itself, not to a copy. There are two common applications: The object is
+a large data structure for which copying is "expensive", or the
+function _needs_ to modify its arguments (e.g., a function `swap(x,y)'
+that exchanges the values of `x' and `y').
+
+ For the first situation, `C++' provides the `const' keyword, which
+ensures the function does not modify its arguments, but accepts a
+reference merely for efficiency. Any attempt to modify a `const'
+argument will be caught by the compiler. Most `ePiX' commands accept
+`const' reference arguments.
+
+ The ability to pass function arguments by reference is sometimes
+touted as a feature in `C++' texts. However, the technique 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.
+
+ 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.
+
+
+
+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
+which variable names may be re-used without ambiguity. Function bodies
+are code blocks, as are the alternatives associated to control
+statements. 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. Variables should be declared in the smallest scope
+possible.
+
+ The compiler is not picky about spaces, tabs, and newlines, so an
+input file should be formatted to make local scopes visually apparent.
+`emacs' automatically indents code to reflect scope, though the default
+behavior does not please all users. As with variable naming, clarity
+and consistency are paramount.
+
+
+
+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 <iostream>
+ #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.
+
+
+File: epix.info, Node: Attribute Quick Reference, Prev: More About `C++', Up: Reference Manual
+
+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_border(len)'. The command `no_label_border()'
+ turns off label borders.
+
+ * Font size: `font_size(LaTeX size)', no argument means
+ `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, the single command `red()' has the same
+effect as the three commands `pen(Red())', `fill(Red())', and
+`label_color(Red())'.
+
+
+File: epix.info, Node: Advanced Topics, Next: Software Freedom, Prev: Reference Manual, Up: Top
+
+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.
+
+* Menu:
+
+* Hidden Object Removal::
+* Extensions::
+* Programmer's Guide::
+
+
+File: epix.info, Node: Hidden Object Removal, Next: Extensions, Prev: Advanced Topics, Up: Advanced Topics
+
+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.)
+
+
+File: epix.info, Node: Extensions, Next: Programmer's Guide, Prev: Hidden Object Removal, Up: Advanced Topics
+
+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 *Note section:programmers::, .
+
+
+
+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 extensively-commented sample files `std_F.cc' and `std_F.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 class and 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 1.0.0, 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-1.0.h
+# install -m 644 libepix.a /usr/local/lib/libepix-1.0.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-1.0 file.xp
+
+
+File: epix.info, Node: Programmer's Guide, Prev: Extensions, Up: Advanced Topics
+
+4.3 Programmer's Guide
+======================
+
+This section briefly surveys `ePiX''s implementation, and is intended
+for (potential) programmers. The source code 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. For example, the
+user-visible classes defined in `Color.h', `path.h', and `screen.h'
+contain only a pointer to the implementation class, and style data is
+hidden behind global commands.
+
+ Functionally, the code consists of the user interface; implementation
+class\-es comprising drawing attributes, spatial objects, screens and
+representations of their elements, and output; and miscellaneous
+utility functions. The headers in each group, and their contents, are
+described in Section *Note section:interface::, .
+
+ The user interface headers are assembled into a single file,
+`epix.h', and installed in `/usr/local/include' by default. In normal
+use, the shell scripts read only the user interface header. The
+individual headers, including the components of `epix.h', are installed
+in `/usr/local/include/epix'. These are provided for authors of
+external libraries, who may need access to implementation details.
+
+
+
+`ePiX' harnesses the computational power of `C++' to the typographical
+capabilities of `LaTeX'. Consequently, `ePiX' should be viewed in part
+as a framework for expressing numerical data visually.
+
+ In the course of your work, you may develop specialized code filling
+a gap in `ePiX''s functionality. If your code seems likely to be of
+interest to other users, please consider bundling it as an external
+package and notifying the `ePiX' community so your work can be linked
+from the project pages and distributed to interested users.
+
+ There are no formal requirements for external packages, but in the
+interest of uniformity contributed code should follow the GNU Coding
+Standards `GNUCoding'. At a minimum, an external package should build
+with the standard `./configure; make; make install' commands, and the
+`configure' script should accept an option `--with-epix' for the user
+to specify a non-default `ePiX' install directory.
+
+ If an external package builds a static library, it should provide a
+single header containing all the package's entry points, and enclose
+its interface in a namespace. Entry points should not collide with
+`ePiX' functions. Naming the package "`epix-<...>'" is a good idea, but
+not essential. For example, a package providing textual nodes and
+diagram layout might be named `epix-nodes'. Input files would use the
+package with the lines
+
+ #include "epix-nodes.h"
+ using namespace ePiX-nodes;
+ and be compiled with
+
+ epix -lepix-nodes <file>
+
+ The user and internal interfaces of `ePiX'-1.2 are not likely to
+change. Still, it's prudent to rely only on the user interface in
+contributed code whenever possible. Doing so also simplifies your work
+as an author; your library can simply `include' the user header file,
+and deal only with high-level objects and drawing attributes.
+
+
+
+These files (in order) comprise the global header `epix.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.
+
+ `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.
+
+ `axis.h' Coordinate axes and labels in various styles.
+
+ `legend.h' Plot legends.
+
+ `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 "model-less" 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' Simple manipulator for the active screen.
+
+ `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.
+
+
+
+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 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.
+
+ `legend_item.h' Items for `legend' s.
+
+ `path_data.h' Path implementation.
+
+ `spline.h' The natural spline class.
+
+ `spline_data.h' Templates for quadratic and cubic splines.
+
+
+
+Elements in a `screen' are represented polymorphically as "`tile's", of
+which there are six types: `glyph' (textual elements), `pen_arrow'
+(arrows), `pen_fill' (filled regions), `pen_line' (path-like elements),
+`verbatim' (raw text), and `legend_tile' (legends).
+
+ Border and background shape are dictated by the `screen_mask' class.
+The cropping algorithm assumes the contour of a screen mask is convex.
+
+ `affine.h' Affine maps.
+
+ `cropping.h' Screen mask cropping.
+
+ `glyph.h' Markers and labels.
+
+ `legend_tile.h' Screen representation of a `legend' .
+
+ `mask_diamond.h' Screen diamond mask.
+
+ `mask_ellipse.h' Screen elliptical mask.
+
+ `mask_rectangle.h' Screen rectangular mask.
+
+ `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 a couple of high-level operations and several
+"atomic" low-level operations. To create a new output format, one need
+only implement the `format' interface for the desired file type. Paths
+and filled regions may be implemented however the output type dictates.
+
+ `eepic.h' eepic macros.
+
+ `fmt_template.h' "skeleton" header for new output formats.
+
+ `format.h' The output interface.
+
+ `pst.h' PSTricks macros.
+
+ `tikz.h' tikz 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.
+
+ `frac.h' Rational numbers and operators.
+
+ `halfspace.h' Halfspace cutting.
+
+ `hatching.h' Filling regions in eepic.
+
+ `lens.h' Camera lenses.
+
+ `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.
+
+
+File: epix.info, Node: Software Freedom, Next: Acknowledgments, Prev: Advanced Topics, Up: Top
+
+Appendix A Software Freedom
+***************************
+
+Academics in general, and mathematicians in particular, depend on free
+exchange of information. We prove theorems or establish experimental
+results, write up formal accounts, place preprints on public file
+servers, and submit papers to peer-reviewed journals. If accepted, the
+results--data, techniques, methods of reasoning, citations, and
+conclusions--are published in print and become part of the public
+record, governed by copyright law. Libraries purchase journal
+subscriptions, but researchers and scholars may use ideas from the
+literature merely by giving appropriate citations in their own work.
+"Theft" arises from false claims of authorship.
+
+ Carried over to software, the academic process would guarantee rights
+similar to those provided by the GNU General Public License (GPL):
+
+ * (GPL 0) To run a program for any purpose.
+
+ * (GPL 1) To study how the program works, and adapt it to your
+ needs.
+
+ * (GPL 2) To redistribute copies of the program.
+
+ * (GPL 3) To improve the program, and release improvements to the
+ public, so that the whole community benefits.
+
+
+ In reality, attitudes toward software differ markedly. Most academics
+work on a proprietary platform, use proprietary software for research
+and teaching, and share information with colleagues and students in
+proprietary, even obfuscated, data formats. Contrary to the academic
+ethic, proprietary software licenses restrict access to information:
+preventing users from learning how a program works internally ("reverse
+engineering"), limiting the number of users who may run a piece of
+software, and forbidding users from running (or sometimes even
+installing) a purchased copy on multiple machines.
+
+ Restrictions on use aside, if one cannot examine a program's source
+code, one cannot fully trust the output, any more than one can trust
+(for purposes of scientific publication) results of a commercial
+testing lab.
+
+ Consider a hypothetical future world in which scholarly results are
+disseminated like software. Instead of subscriptions, journals sell
+licenses granting readership to a specified number of individuals.
+Photocopying an article for a class or research seminar constitutes
+"piracy", though if the institution has purchased a sufficiently large
+site license the teacher or speaker may bring the physical volume to
+class and project the pages onto a screen.
+
+ Of course, reading an article is scarcely enlightening. Mathematics
+papers contain only the statements of theorems. Merely opening the
+journal binds the reader to a lengthy legal agreement, stating that
+theorems be used only for specific purposes and threatening serious
+legal consequences for attempting to discover the author's proofs.
+
+ The actions of a single student, employee, or faculty member can
+expose an institution to a costly "journal audit" from the Mathematical
+Society of America (MSA), with the institution responsible for legal
+costs if the audit reveals license violations anywhere in the
+organization.
+
+ Mathematicians who long for the Old Days when papers contained
+proofs and were shared freely are dismissed as idealistic cranks or
+labeled anti-business communists. Common knowledge asserts the obvious
+superiority of proprietary journals, and the necessity of licenses for
+keeping mathematicians gainfully employed.
+
+ Back in our world, some vendors have attempted to placate opponents
+of closed source with "shared source" licenses, under which one may
+sign a non-disclosure agreement and subsequently examine source code.
+In the future world analogy, a shared source agreement would allow
+journal licensees to sign an NDA, then see the proofs of theorems.
+Readers could thereby correct errors in proofs (benefitting the
+publisher by improving the reliability of the journal), but would be
+legally forbidden from using the ideas elsewhere (denying benefit to
+other mathematicians).
+
+ Legally and conceptually codifying software as a commodity ignores a
+fundamental reality: Like an idea or recipe, software can be copied
+without loss of the original. The perception of "theft" by copying
+arises from an artificial belief that software has an owner who must be
+monetarily compensated each time a person acquires a copy. The nature
+of software does not enforce the "sale" model in the way services and
+physical commodities do. It therefore seems philosophically
+inappropriate to treat software as a commodity, and perilous to conform
+the legal system to the enforcement of such a model.
+
+ At its best, software enhances our productivity and creativity.
+Sharing software, like sharing ideas, benefits a larger number of
+people without detriment to existing users. I hope 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.
+
+
+File: epix.info, Node: Acknowledgments, Next: Function Index, Prev: Software Freedom, Up: Top
+
+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:
+
+ *Infrastructure* Donald Knuth, Conrad Kwok, Leslie Lamport, Tim
+Morgan, Piet van Oostrum, Sunil Podar, Richard Stallman, Till Tantau,
+Herbert Voss, Timothy van Zandt
+
+ *Enhancements* Jay Belanger, Robin Blume-Kohout, Julian Gilbey,
+Marcus Hanwell, Yvon Henel, Svend Daugaard Pedersen, Andrew Sterian
+
+ *Porting and packaging* Julian Gilbey (Debian); Tsuguru Kato
+(FreeBSD); Markus Dittrich, Danny van Dyk, Christian Faulhammer,
+Olivier Fisette, Chris Gianelloni, Michael Hanselmann, Marcus Hanwell,
+David Holm, Peter Johanson, Patrick Kursawe, Tobias Scherbaum, Markus
+Ullmann (Gentoo); Guido Gonzato (RPM); Rene Rebe (T2)
+
+ *Debugging, 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
+
+
+File: epix.info, Node: Function Index, Next: Concept Index, Prev: Acknowledgments, Up: Top
+
+Function Index
+**************
+
+
+* Menu:
+
+* aarrow: Creating and Drawing Objects.
+ (line 248)
+* Acos: More About C++. (line 112)
+* activate: Scene Attributes. (line 161)
+* affine: Scene Attributes. (line 271)
+* apply: Scene Attributes. (line 307)
+* arc: Creating and Drawing Objects.
+ (line 167)
+* arc_arrow: Creating and Drawing Objects.
+ (line 248)
+* arc_measure: Creating and Drawing Objects.
+ (line 193)
+* arrow: Creating and Drawing Objects.
+ (line 242)
+* arrow_inset: Creating and Drawing Objects.
+ (line 235)
+* arrow_ratio: Creating and Drawing Objects.
+ (line 235)
+* arrow_width: Creating and Drawing Objects.
+ (line 235)
+* Asin: More About C++. (line 112)
+* Atan: More About C++. (line 112)
+* axis: Creating and Drawing Objects.
+ (line 275)
+* axis.align: Creating and Drawing Objects.
+ (line 284)
+* axis.align_labels: Creating and Drawing Objects.
+ (line 296)
+* axis.dec: Creating and Drawing Objects.
+ (line 296)
+* axis.draw: Creating and Drawing Objects.
+ (line 342)
+* axis.draw_labels: Creating and Drawing Objects.
+ (line 342)
+* axis.draw_ticks: Creating and Drawing Objects.
+ (line 342)
+* axis.frac: Creating and Drawing Objects.
+ (line 296)
+* axis.label_rep: Creating and Drawing Objects.
+ (line 307)
+* axis.precision: Creating and Drawing Objects.
+ (line 296)
+* axis.sci: Creating and Drawing Objects.
+ (line 296)
+* axis.subdivide: Creating and Drawing Objects.
+ (line 284)
+* axis.tag: Creating and Drawing Objects.
+ (line 323)
+* axis.tag235: Creating and Drawing Objects.
+ (line 323)
+* axis.tags: Creating and Drawing Objects.
+ (line 323)
+* axis.tick_ratio: Creating and Drawing Objects.
+ (line 284)
+* axis.trig: Creating and Drawing Objects.
+ (line 296)
+* axis.unmark: Creating and Drawing Objects.
+ (line 296)
+* axis.untag: Creating and Drawing Objects.
+ (line 323)
+* axis_break: Creating and Drawing Objects.
+ (line 394)
+* back_arc: Creating and Drawing Objects.
+ (line 851)
+* back_arc2: Creating and Drawing Objects.
+ (line 851)
+* back_cube: Creating and Drawing Objects.
+ (line 857)
+* back_dodeca: Creating and Drawing Objects.
+ (line 857)
+* back_icosa: Creating and Drawing Objects.
+ (line 857)
+* back_latitude: Creating and Drawing Objects.
+ (line 837)
+* back_line: Creating and Drawing Objects.
+ (line 851)
+* back_longitude: Creating and Drawing Objects.
+ (line 837)
+* back_octa: Creating and Drawing Objects.
+ (line 857)
+* back_tetra: Creating and Drawing Objects.
+ (line 857)
+* back_triangle: Creating and Drawing Objects.
+ (line 857)
+* backing: Scene Attributes. (line 252)
+* backplot_N: Creating and Drawing Objects.
+ (line 879)
+* backplot_R: Creating and Drawing Objects.
+ (line 879)
+* backplot_S: Creating and Drawing Objects.
+ (line 879)
+* bbold: Drawing Attributes. (line 33)
+* bbox: Drawing Attributes. (line 174)
+* begin: File Structure. (line 12)
+* Black: Color. (line 23)
+* Blue: Color. (line 23)
+* bold: Drawing Attributes. (line 33)
+* border: Scene Attributes. (line 252)
+* bottom_axis: Creating and Drawing Objects.
+ (line 332)
+* bounding_box: Picture Size and Aspect Ratio.
+ (line 24)
+* box: Drawing Attributes. (line 174)
+* Camera.at: Scene Attributes. (line 75)
+* Camera.clip_range: Scene Attributes. (line 75)
+* Camera.focus: Scene Attributes. (line 75)
+* Camera.look_at: Scene Attributes. (line 75)
+* Camera.pan: Scene Attributes. (line 75)
+* Camera.range: Scene Attributes. (line 75)
+* Camera.roll: Scene Attributes. (line 75)
+* Camera.tilt: Scene Attributes. (line 75)
+* canvas: Scene Attributes. (line 183)
+* cb: More About C++. (line 123)
+* circ: Drawing Attributes. (line 174)
+* circle: Creating and Drawing Objects.
+ (line 145)
+* Circle: Creating and Drawing Objects.
+ (line 70)
+* cis: Creating and Drawing Objects.
+ (line 27)
+* clip_box: Scene Attributes. (line 127)
+* clip_face: Scene Attributes. (line 137)
+* clip_restore: Scene Attributes. (line 137)
+* clip_slice: Scene Attributes. (line 137)
+* clip_to: Scene Attributes. (line 127)
+* CMY: Color. (line 29)
+* CMY_Black: Color. (line 29)
+* CMY_White: Color. (line 29)
+* cmyk: Drawing Attributes. (line 210)
+* CMYK: Color. (line 29)
+* Color.alpha: Color. (line 73)
+* Color.blend: Color. (line 73)
+* Color.filter: Color. (line 73)
+* Color.invert: Color. (line 73)
+* Color.superpose: Color. (line 73)
+* Cos: More About C++. (line 112)
+* Cot: More About C++. (line 112)
+* crop: Scene Attributes. (line 239)
+* crop_diamond: Scene Attributes. (line 239)
+* crop_ellipse: Scene Attributes. (line 239)
+* Csc: More About C++. (line 112)
+* Cyan: Color. (line 29)
+* cyl: Creating and Drawing Objects.
+ (line 27)
+* dart: Creating and Drawing Objects.
+ (line 248)
+* dart_field: Creating and Drawing Objects.
+ (line 793)
+* dash_size: Drawing Attributes. (line 44)
+* dashed: Drawing Attributes. (line 53)
+* data_bins: Creating and Drawing Objects.
+ (line 1006)
+* data_bins.bar_chart: Creating and Drawing Objects.
+ (line 1016)
+* data_bins.cut: Creating and Drawing Objects.
+ (line 1006)
+* data_bins.histogram: Creating and Drawing Objects.
+ (line 1016)
+* data_bins.plot: Creating and Drawing Objects.
+ (line 1016)
+* data_bins.read: Creating and Drawing Objects.
+ (line 1006)
+* data_file: Creating and Drawing Objects.
+ (line 931)
+* data_file.avg: Creating and Drawing Objects.
+ (line 950)
+* data_file.column: Creating and Drawing Objects.
+ (line 973)
+* data_file.covar: Creating and Drawing Objects.
+ (line 950)
+* data_file.dot: Creating and Drawing Objects.
+ (line 950)
+* data_file.plot: Creating and Drawing Objects.
+ (line 958)
+* data_file.precision: Creating and Drawing Objects.
+ (line 967)
+* data_file.read: Creating and Drawing Objects.
+ (line 931)
+* data_file.regression: Creating and Drawing Objects.
+ (line 950)
+* data_file.transform: Creating and Drawing Objects.
+ (line 945)
+* data_file.var: Creating and Drawing Objects.
+ (line 950)
+* data_file.write: Creating and Drawing Objects.
+ (line 967)
+* data_mask: Creating and Drawing Objects.
+ (line 988)
+* data_mask.prune: Creating and Drawing Objects.
+ (line 996)
+* ddot: Drawing Attributes. (line 174)
+* deactivate: Scene Attributes. (line 161)
+* Deriv: Creating and Drawing Objects.
+ (line 745)
+* Deriv.eval: Creating and Drawing Objects.
+ (line 745)
+* Deriv.left: Creating and Drawing Objects.
+ (line 745)
+* Deriv.right: Creating and Drawing Objects.
+ (line 745)
+* disk_line: Creating and Drawing Objects.
+ (line 826)
+* domain: Creating and Drawing Objects.
+ (line 512)
+* domain.resize: Creating and Drawing Objects.
+ (line 531)
+* domain.slice: Creating and Drawing Objects.
+ (line 531)
+* domain.slices: Creating and Drawing Objects.
+ (line 531)
+* domain_list: Creating and Drawing Objects.
+ (line 668)
+* domain_list.add: Creating and Drawing Objects.
+ (line 668)
+* dot: Drawing Attributes. (line 174)
+* dot_size: Drawing Attributes. (line 185)
+* dotted: Drawing Attributes. (line 53)
+* draw: Creating and Drawing Objects.
+ (line 59)
+* ellipse: Creating and Drawing Objects.
+ (line 167)
+* ellipse_bottom: Creating and Drawing Objects.
+ (line 180)
+* ellipse_left: Creating and Drawing Objects.
+ (line 180)
+* ellipse_right: Creating and Drawing Objects.
+ (line 180)
+* ellipse_top: Creating and Drawing Objects.
+ (line 180)
+* end: File Structure. (line 12)
+* envelope: Creating and Drawing Objects.
+ (line 768)
+* extract: Scene Attributes. (line 183)
+* extract_diamond: Scene Attributes. (line 190)
+* extract_ellipse: Scene Attributes. (line 190)
+* fill: Drawing Attributes. (line 12)
+* flow: Creating and Drawing Objects.
+ (line 778)
+* font_face: Drawing Attributes. (line 144)
+* font_size: Drawing Attributes. (line 144)
+* fractal: Creating and Drawing Objects.
+ (line 214)
+* frame: Creating and Drawing Objects.
+ (line 134)
+* front_arc: Creating and Drawing Objects.
+ (line 851)
+* front_arc2: Creating and Drawing Objects.
+ (line 851)
+* front_cube: Creating and Drawing Objects.
+ (line 857)
+* front_dodeca: Creating and Drawing Objects.
+ (line 857)
+* front_icosa: Creating and Drawing Objects.
+ (line 857)
+* front_line: Creating and Drawing Objects.
+ (line 851)
+* front_octa: Creating and Drawing Objects.
+ (line 857)
+* front_tetra: Creating and Drawing Objects.
+ (line 857)
+* front_triangle: Creating and Drawing Objects.
+ (line 857)
+* frontplot_N: Creating and Drawing Objects.
+ (line 879)
+* frontplot_R: Creating and Drawing Objects.
+ (line 879)
+* frontplot_S: Creating and Drawing Objects.
+ (line 879)
+* Gray: Color. (line 29)
+* Green: Color. (line 23)
+* grid: Creating and Drawing Objects.
+ (line 405)
+* h_axis: Creating and Drawing Objects.
+ (line 352)
+* h_axis_labels: Creating and Drawing Objects.
+ (line 368)
+* h_axis_log_labels: Creating and Drawing Objects.
+ (line 368)
+* h_axis_log_masklabels: Creating and Drawing Objects.
+ (line 368)
+* h_axis_masklabels: Creating and Drawing Objects.
+ (line 368)
+* h_error_bar: Creating and Drawing Objects.
+ (line 1047)
+* h_log_axis: Creating and Drawing Objects.
+ (line 352)
+* h_scale: Scene Attributes. (line 282)
+* h_shear: Scene Attributes. (line 282)
+* hyperbolic_line: Creating and Drawing Objects.
+ (line 826)
+* import: Scene Attributes. (line 172)
+* include: C++ Basics. (line 37)
+* inf: Creating and Drawing Objects.
+ (line 731)
+* inlay: Scene Attributes. (line 204)
+* inlay_horizontal: Scene Attributes. (line 204)
+* inlay_vertical: Scene Attributes. (line 204)
+* inset: Scene Attributes. (line 172)
+* Integral: Creating and Drawing Objects.
+ (line 745)
+* Integral.eval: Creating and Drawing Objects.
+ (line 745)
+* J: Creating and Drawing Objects.
+ (line 38)
+* label <1>: Drawing Attributes. (line 99)
+* label: Layout Tricks. (line 46)
+* label_border: Drawing Attributes. (line 160)
+* label_color: Drawing Attributes. (line 160)
+* label_mask: Drawing Attributes. (line 160)
+* label_pad: Drawing Attributes. (line 160)
+* latitude: Creating and Drawing Objects.
+ (line 837)
+* left_axis: Creating and Drawing Objects.
+ (line 332)
+* legend: Creating and Drawing Objects.
+ (line 1083)
+* legend.backing: Creating and Drawing Objects.
+ (line 1083)
+* legend.border: Creating and Drawing Objects.
+ (line 1083)
+* legend.draw: Creating and Drawing Objects.
+ (line 1115)
+* legend.fill_item: Creating and Drawing Objects.
+ (line 1101)
+* legend.item_border: Creating and Drawing Objects.
+ (line 1083)
+* legend.key_size: Creating and Drawing Objects.
+ (line 1083)
+* legend.label_skip: Creating and Drawing Objects.
+ (line 1083)
+* legend.mark_item: Creating and Drawing Objects.
+ (line 1101)
+* legend.path_item: Creating and Drawing Objects.
+ (line 1101)
+* Line: Creating and Drawing Objects.
+ (line 145)
+* line: Creating and Drawing Objects.
+ (line 145)
+* line_style: Drawing Attributes. (line 44)
+* log1_grid: Creating and Drawing Objects.
+ (line 411)
+* log2_grid: Creating and Drawing Objects.
+ (line 411)
+* log_grid: Creating and Drawing Objects.
+ (line 411)
+* longitude: Creating and Drawing Objects.
+ (line 837)
+* Magenta: Color. (line 29)
+* move_to: Creating and Drawing Objects.
+ (line 59)
+* newton: Creating and Drawing Objects.
+ (line 731)
+* no_label_border: Drawing Attributes. (line 160)
+* nofill: Drawing Attributes. (line 12)
+* ode_plot: Creating and Drawing Objects.
+ (line 778)
+* P: Creating and Drawing Objects.
+ (line 27)
+* P.x1: Creating and Drawing Objects.
+ (line 38)
+* P.x2: Creating and Drawing Objects.
+ (line 38)
+* P.x3: Creating and Drawing Objects.
+ (line 38)
+* path: Creating and Drawing Objects.
+ (line 437)
+* path.close: Creating and Drawing Objects.
+ (line 468)
+* path.draw: Creating and Drawing Objects.
+ (line 468)
+* path.fill: Creating and Drawing Objects.
+ (line 468)
+* pen <1>: Creating and Drawing Objects.
+ (line 422)
+* pen: Drawing Attributes. (line 23)
+* picture <1>: Picture Size and Aspect Ratio.
+ (line 24)
+* picture: File Structure. (line 12)
+* plain: Drawing Attributes. (line 33)
+* Plane: Creating and Drawing Objects.
+ (line 85)
+* plot: Creating and Drawing Objects.
+ (line 495)
+* polar: Creating and Drawing Objects.
+ (line 27)
+* polar_grid: Creating and Drawing Objects.
+ (line 405)
+* polarplot: Creating and Drawing Objects.
+ (line 495)
+* post_write: C++ Basics. (line 122)
+* postcomp: Scene Attributes. (line 282)
+* pre_write: C++ Basics. (line 122)
+* pt_to_screen: Scene Attributes. (line 214)
+* quad: Creating and Drawing Objects.
+ (line 145)
+* rect: Creating and Drawing Objects.
+ (line 145)
+* Red: Color. (line 23)
+* reflect: Scene Attributes. (line 282)
+* rgb: Drawing Attributes. (line 210)
+* RGB: Color. (line 23)
+* riemann_sum: Creating and Drawing Objects.
+ (line 756)
+* right_angle: Creating and Drawing Objects.
+ (line 193)
+* right_axis: Creating and Drawing Objects.
+ (line 332)
+* ring: Drawing Attributes. (line 174)
+* rotate: Scene Attributes. (line 282)
+* scale <1>: Creating and Drawing Objects.
+ (line 59)
+* scale: Scene Attributes. (line 282)
+* scenery: Creating and Drawing Objects.
+ (line 680)
+* scenery.add: Creating and Drawing Objects.
+ (line 680)
+* scenery.draw: Creating and Drawing Objects.
+ (line 680)
+* Sec: More About C++. (line 112)
+* Segment: Creating and Drawing Objects.
+ (line 90)
+* set_crop: Scene Attributes. (line 239)
+* sgn: More About C++. (line 123)
+* shadeplot: Creating and Drawing Objects.
+ (line 495)
+* shift <1>: Creating and Drawing Objects.
+ (line 59)
+* shift: Scene Attributes. (line 282)
+* Sin: More About C++. (line 112)
+* sinx: More About C++. (line 123)
+* slope_field: Creating and Drawing Objects.
+ (line 793)
+* solid: Drawing Attributes. (line 53)
+* sph: Creating and Drawing Objects.
+ (line 27)
+* Sphere: Creating and Drawing Objects.
+ (line 93)
+* spline: Creating and Drawing Objects.
+ (line 167)
+* spot: Drawing Attributes. (line 174)
+* sup: Creating and Drawing Objects.
+ (line 731)
+* surface: Creating and Drawing Objects.
+ (line 616)
+* surface_rev: Creating and Drawing Objects.
+ (line 627)
+* Tan: More About C++. (line 112)
+* tan_field: Creating and Drawing Objects.
+ (line 768)
+* tan_line: Creating and Drawing Objects.
+ (line 768)
+* top_axis: Creating and Drawing Objects.
+ (line 332)
+* triangle: Creating and Drawing Objects.
+ (line 145)
+* unitlength: Picture Size and Aspect Ratio.
+ (line 24)
+* v_axis: Creating and Drawing Objects.
+ (line 352)
+* v_axis_labels: Creating and Drawing Objects.
+ (line 368)
+* v_axis_log_labels: Creating and Drawing Objects.
+ (line 368)
+* v_axis_log_masklabels: Creating and Drawing Objects.
+ (line 368)
+* v_axis_masklabels: Creating and Drawing Objects.
+ (line 368)
+* v_error_bar: Creating and Drawing Objects.
+ (line 1047)
+* v_log_axis: Creating and Drawing Objects.
+ (line 352)
+* v_scale: Scene Attributes. (line 282)
+* v_shear: Scene Attributes. (line 282)
+* vector_field: Creating and Drawing Objects.
+ (line 793)
+* White: Color. (line 23)
+* write: C++ Basics. (line 122)
+* Yellow: Color. (line 29)
+* zero: More About C++. (line 123)
+
+
+File: epix.info, Node: Concept Index, Prev: Function Index, Up: Top
+
+Concept Index
+*************
+
+
+* Menu:
+
+* Affine map: Scene Attributes. (line 264)
+* Affine map!action on labels: Drawing Attributes. (line 130)
+* Angle units <1>: Drawing Attributes. (line 121)
+* Angle units: Scene Attributes. (line 14)
+* Angular mode <1>: More About C++. (line 112)
+* Angular mode: Creating and Drawing Objects.
+ (line 27)
+* Animation: Animation. (line 6)
+* Arrow: Creating and Drawing Objects.
+ (line 231)
+* Axes: Creating and Drawing Objects.
+ (line 257)
+* Axes!broken: Creating and Drawing Objects.
+ (line 390)
+* Axes!labeling: Creating and Drawing Objects.
+ (line 257)
+* Axes!logarithmic: Creating and Drawing Objects.
+ (line 350)
+* Bar Charts: Creating and Drawing Objects.
+ (line 1013)
+* Bounding box: Scene Attributes. (line 156)
+* Camera <1>: Hidden Object Removal.
+ (line 13)
+* Camera: Scene Attributes. (line 21)
+* Camera!color separation: Scene Attributes. (line 94)
+* Camera!lens: Scene Attributes. (line 57)
+* Camera!manipulation: Scene Attributes. (line 69)
+* Camera!manipulation of: Scene Attributes. (line 116)
+* Camera!viewpoint: Scene Attributes. (line 31)
+* canvas: The Drawing Model. (line 11)
+* Circle: Creating and Drawing Objects.
+ (line 69)
+* Classes: More About C++. (line 149)
+* Clipping: Scene Attributes. (line 120)
+* Color <1>: Drawing Attributes. (line 215)
+* Color: Color. (line 6)
+* Color!separation: Scene Attributes. (line 94)
+* Color!surface plotting: Creating and Drawing Objects.
+ (line 700)
+* Color!transparency: Color. (line 65)
+* Conditional statement: More About C++. (line 22)
+* Cplusplus@C++ <1>: More About C++. (line 6)
+* Cplusplus@C++: C++ Basics. (line 6)
+* Cropping: Scene Attributes. (line 231)
+* Data plotting: Creating and Drawing Objects.
+ (line 897)
+* Domain: Creating and Drawing Objects.
+ (line 509)
+* Emacs@emacs <1>: Animation. (line 19)
+* Emacs@emacs <2>: C++ Basics. (line 16)
+* Emacs@emacs <3>: Running ePiX. (line 50)
+* Emacs@emacs: Software Dependencies.
+ (line 36)
+* Error bars: Creating and Drawing Objects.
+ (line 1046)
+* Filling: Drawing Attributes. (line 11)
+* Fonts: Drawing Attributes. (line 142)
+* Free software <1>: Software Freedom. (line 6)
+* Free software: Introduction. (line 42)
+* Function: More About C++. (line 22)
+* Function!call syntax: More About C++. (line 186)
+* Function!class member: More About C++. (line 156)
+* Function!mathematical: More About C++. (line 108)
+* Function!overloaded: More About C++. (line 229)
+* Function!returning void: More About C++. (line 84)
+* Graph paper: Creating and Drawing Objects.
+ (line 422)
+* Graphical interface: Tutorial. (line 13)
+* Hidden object removal: Hidden Object Removal.
+ (line 6)
+* Histograms: Creating and Drawing Objects.
+ (line 1013)
+* Input file!comment in: More About C++. (line 337)
+* Input file!conditional compilation: More About C++. (line 281)
+* Installation <1>: Installation. (line 31)
+* Installation: Software Dependencies.
+ (line 6)
+* Intersection: Creating and Drawing Objects.
+ (line 109)
+* Labels <1>: More About C++. (line 310)
+* Labels: Drawing Attributes. (line 80)
+* Labels!alignment: Drawing Attributes. (line 80)
+* Labels!axis: Creating and Drawing Objects.
+ (line 257)
+* Labels!backslash in: Drawing Attributes. (line 205)
+* Labels!fonts in: Drawing Attributes. (line 142)
+* Labels!in double quotes: Drawing Attributes. (line 205)
+* Labels!rotated: Drawing Attributes. (line 121)
+* Layout <1>: Scene Attributes. (line 148)
+* Layout: Layout Tricks. (line 6)
+* Legends: Creating and Drawing Objects.
+ (line 1072)
+* Mac OS X: Software Dependencies.
+ (line 6)
+* Marker types: Drawing Attributes. (line 172)
+* Output format: File Structure. (line 31)
+* Path: Drawing Attributes. (line 11)
+* Path!class: Creating and Drawing Objects.
+ (line 433)
+* Path!filled: Drawing Attributes. (line 11)
+* Path!fractal: Creating and Drawing Objects.
+ (line 206)
+* Path!style: Drawing Attributes. (line 41)
+* Picture!aspect ratio: Picture Size and Aspect Ratio.
+ (line 44)
+* Picture!bounding box: Picture Size and Aspect Ratio.
+ (line 44)
+* Picture!offset: Picture Size and Aspect Ratio.
+ (line 6)
+* Picture!size: Picture Size and Aspect Ratio.
+ (line 6)
+* Plane: Creating and Drawing Objects.
+ (line 85)
+* Plotting: Creating and Drawing Objects.
+ (line 480)
+* Plotting!calculus: Creating and Drawing Objects.
+ (line 721)
+* Plotting!data: Creating and Drawing Objects.
+ (line 897)
+* Plotting!spherical: Creating and Drawing Objects.
+ (line 833)
+* Plotting!surface: Creating and Drawing Objects.
+ (line 605)
+* Point: Creating and Drawing Objects.
+ (line 14)
+* Pointer: More About C++. (line 52)
+* post_write: C++ Basics. (line 122)
+* pre_write: C++ Basics. (line 122)
+* Preamble: File Structure. (line 10)
+* Screen: Scene Attributes. (line 21)
+* Screen!active: Scene Attributes. (line 148)
+* Segment: Creating and Drawing Objects.
+ (line 90)
+* Sphere: Creating and Drawing Objects.
+ (line 93)
+* Stereograms: Layout Tricks. (line 8)
+* Variable!local: More About C++. (line 239)
+* Variable!names: More About C++. (line 34)
+* Variable!pointer: More About C++. (line 52)
+* Variable!reference: More About C++. (line 186)
+* Variable!type of: More About C++. (line 45)
+* Viewpoint: Scene Attributes. (line 31)
+* Windows operating system: Software Dependencies.
+ (line 40)
+* write: C++ Basics. (line 122)
+
+
+
+Tag Table:
+Node: Top185
+Node: Introduction1105
+Node: Changes in Version 1.24664
+Node: Software Dependencies8541
+Ref: section:software_deps8714
+Node: Installation11086
+Node: Getting Started12670
+Ref: chapter:started12806
+Node: Running `ePiX'13556
+Ref: section:running13709
+Node: The Drawing Model16861
+Ref: section:overview17013
+Node: Tutorial19428
+Ref: section:tutorial19560
+Ref: taylor_poly24927
+Node: `C++' Basics26756
+Ref: fig:captioned32767
+Node: Animation33131
+Ref: section:animation33262
+Node: Layout Tricks34998
+Ref: section:layout35116
+Node: Reference Manual37114
+Ref: chapter:ref-man37255
+Node: File Structure38952
+Node: Picture Size and Aspect Ratio41705
+Ref: page:scaling44202
+Node: Color44417
+Ref: section:color44557
+Ref: fig:densities46382
+Node: Scene Attributes47847
+Ref: fig:camera48882
+Ref: truesize56642
+Node: Drawing Attributes62495
+Ref: table:marker70626
+Node: Creating and Drawing Objects71285
+Ref: fig:fractal81596
+Ref: fig:plot96868
+Ref: non-eucl107182
+Node: More About `C++'121128
+Ref: references130049
+Node: Attribute Quick Reference137418
+Ref: section:quickref137580
+Node: Advanced Topics140341
+Ref: chapter:adv140481
+Node: Hidden Object Removal140765
+Ref: section:hidden140932
+Node: Extensions142805
+Ref: section:extensions142953
+Node: Programmer's Guide149302
+Ref: section:programmers149436
+Ref: section:interface152502
+Node: Software Freedom158743
+Node: Acknowledgments164009
+Node: Function Index165447
+Node: Concept Index200200
+
+End Tag Table
diff --git a/graphics/epix/doc/graphpaper.eepic b/graphics/epix/doc/graphpaper.eepic
new file mode 100644
index 0000000000..94a18e8085
--- /dev/null
+++ b/graphics/epix/doc/graphpaper.eepic
@@ -0,0 +1,101 @@
+%% Generated from graphpaper.xp on Tue Jan 4 15:32:14 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 2in x 1in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{0.01in}
+\begin{picture}(200,100)(-0,-0)
+%% ---
+\allinethickness{0.25pt}%
+\path(0,0)(0,100)
+\path(5,0)(5,100)
+\path(10,0)(10,100)
+\path(15,0)(15,100)
+\path(20,0)(20,100)
+\path(25,0)(25,100)
+\path(30,0)(30,100)
+\path(35,0)(35,100)
+\path(40,0)(40,100)
+\path(45,0)(45,100)
+\path(50,0)(50,100)
+\path(55,0)(55,100)
+\path(60,0)(60,100)
+\path(65,0)(65,100)
+\path(70,0)(70,100)
+\path(75,0)(75,100)
+\path(80,0)(80,100)
+\path(85,0)(85,100)
+\path(90,0)(90,100)
+\path(95,0)(95,100)
+\path(100,0)(100,100)
+\path(105,0)(105,100)
+\path(110,0)(110,100)
+\path(115,0)(115,100)
+\path(120,0)(120,100)
+\path(125,0)(125,100)
+\path(130,0)(130,100)
+\path(135,0)(135,100)
+\path(140,0)(140,100)
+\path(145,0)(145,100)
+\path(150,0)(150,100)
+\path(155,0)(155,100)
+\path(160,0)(160,100)
+\path(165,0)(165,100)
+\path(170,0)(170,100)
+\path(175,0)(175,100)
+\path(180,0)(180,100)
+\path(185,0)(185,100)
+\path(190,0)(190,100)
+\path(195,0)(195,100)
+\path(200,0)(200,100)
+\path(0,0)(200,0)
+\path(0,5)(200,5)
+\path(0,10)(200,10)
+\path(0,15)(200,15)
+\path(0,20)(200,20)
+\path(0,25)(200,25)
+\path(0,30)(200,30)
+\path(0,35)(200,35)
+\path(0,40)(200,40)
+\path(0,45)(200,45)
+\path(0,50)(200,50)
+\path(0,55)(200,55)
+\path(0,60)(200,60)
+\path(0,65)(200,65)
+\path(0,70)(200,70)
+\path(0,75)(200,75)
+\path(0,80)(200,80)
+\path(0,85)(200,85)
+\path(0,90)(200,90)
+\path(0,95)(200,95)
+\path(0,100)(200,100)
+%% ---
+\allinethickness{0.5pt}%
+\path(0,0)(0,100)
+\path(25,0)(25,100)
+\path(50,0)(50,100)
+\path(75,0)(75,100)
+\path(100,0)(100,100)
+\path(125,0)(125,100)
+\path(150,0)(150,100)
+\path(175,0)(175,100)
+\path(200,0)(200,100)
+\path(0,0)(200,0)
+\path(0,25)(200,25)
+\path(0,50)(200,50)
+\path(0,75)(200,75)
+\path(0,100)(200,100)
+%% ---
+\allinethickness{1pt}%
+\path(0,0)(0,100)
+\path(50,0)(50,100)
+\path(100,0)(100,100)
+\path(150,0)(150,100)
+\path(200,0)(200,100)
+\path(0,0)(200,0)
+\path(0,50)(200,50)
+\path(0,100)(200,100)
+%% ---
+\end{picture}
diff --git a/graphics/epix/doc/graphpaper.xp b/graphics/epix/doc/graphpaper.xp
new file mode 100644
index 0000000000..795c499d4d
--- /dev/null
+++ b/graphics/epix/doc/graphpaper.xp
@@ -0,0 +1,24 @@
+/* -*-ePiX-*- */
+/* graphpaper.c -- July 6, 2002 */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ bounding_box(P(-2,-1), P(2,1));
+ picture(P(200,100));
+ unitlength("0.01in");
+
+ begin();
+
+ pen(0.25);
+ grid(10*x_size, 10*y_size);
+
+ pen(0.5);
+ grid(2*x_size, 2*y_size);
+
+ pen(1);
+ grid(x_size, y_size);
+
+ end();
+}
diff --git a/graphics/epix/doc/hello.eepic b/graphics/epix/doc/hello.eepic
new file mode 100644
index 0000000000..9b58fefc81
--- /dev/null
+++ b/graphics/epix/doc/hello.eepic
@@ -0,0 +1,15 @@
+%% Generated from hello.xp on Thu Jun 28 11:33:40 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 2 x 1in
+%% Figure offset: left by 0in, down by 0in
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\setlength{\unitlength}{1in}
+\begin{picture}(2,1)(-0,-0)
+\put(1,0.5){\makebox(0,0)[c]{{\Huge Hello, world!}}}
+\allinethickness{1pt}%
+\path(2,0)(2,1)(0,1)(0,0)(2,0)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/hello.xp b/graphics/epix/doc/hello.xp
new file mode 100644
index 0000000000..c8bd3739b9
--- /dev/null
+++ b/graphics/epix/doc/hello.xp
@@ -0,0 +1,20 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(-1,-1),P(1,1), "2x1in");
+
+ begin();
+
+ // uncomment and permute these lines
+ // crop_ellipse();
+ // backing(Yellow());
+ border(Black(), "1pt");
+
+ font_size("Huge");
+ label(P(0,0), "Hello, world!");
+
+ end();
+}
diff --git a/graphics/epix/doc/koch.eepic b/graphics/epix/doc/koch.eepic
new file mode 100644
index 0000000000..1f949958c0
--- /dev/null
+++ b/graphics/epix/doc/koch.eepic
@@ -0,0 +1,160 @@
+%% Generated from koch.xp on Tue Jan 4 15:32:16 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [0,3] x [0,0.5]
+%% Actual size: 3in x 0.5in
+%% Figure offset: right by 0in, up by 0.25in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(3,0.5)(-0,-0.25)
+%% ---
+\path(0,0)(0.25,0)(0.25,0.25)(0.5,0.25)(0.5,0)(0.5,-0.25)(0.75,-0.25)
+ (0.75,0)(1,0)
+%% ---
+\path(1,0)(1.0625,0)(1.0625,0.0625)(1.125,0.0625)(1.125,0)(1.125,-0.0625)
+ (1.1875,-0.0625)(1.1875,0)(1.25,0)(1.25,0.0625)(1.1875,0.0625)
+ (1.1875,0.125)(1.25,0.125)(1.3125,0.125)(1.3125,0.1875)(1.25,0.1875)
+ (1.25,0.25)(1.3125,0.25)(1.3125,0.3125)(1.375,0.3125)(1.375,0.25)
+ (1.375,0.1875)(1.4375,0.1875)(1.4375,0.25)(1.5,0.25)(1.5,0.1875)
+ (1.5625,0.1875)(1.5625,0.125)(1.5,0.125)(1.4375,0.125)(1.4375,0.0625)
+ (1.5,0.0625)(1.5,0)(1.5,-0.0625)(1.5625,-0.0625)(1.5625,-0.125)
+ (1.5,-0.125)(1.4375,-0.125)(1.4375,-0.1875)(1.5,-0.1875)(1.5,-0.25)
+ (1.5625,-0.25)(1.5625,-0.1875)(1.625,-0.1875)(1.625,-0.25)(1.625,-0.3125)
+ (1.6875,-0.3125)(1.6875,-0.25)(1.75,-0.25)(1.75,-0.1875)(1.6875,-0.1875)
+ (1.6875,-0.125)(1.75,-0.125)(1.8125,-0.125)(1.8125,-0.0625)(1.75,-0.0625)
+ (1.75,0)(1.8125,0)(1.8125,0.0625)(1.875,0.0625)(1.875,0)
+\path(1.875,0)(1.875,-0.0625)(1.9375,-0.0625)(1.9375,0)(2,0)
+%% ---
+\path(2,0)(2.01562,0)(2.01562,0.015625)(2.03125,0.015625)(2.03125,0)
+ (2.03125,-0.015625)(2.04688,-0.015625)(2.04688,0)(2.0625,0)
+ (2.0625,0.015625)(2.04688,0.015625)(2.04688,0.03125)(2.0625,0.03125)
+ (2.07812,0.03125)(2.07812,0.046875)(2.0625,0.046875)(2.0625,0.0625)
+ (2.07812,0.0625)(2.07812,0.078125)(2.09375,0.078125)(2.09375,0.0625)
+ (2.09375,0.046875)(2.10938,0.046875)(2.10938,0.0625)(2.125,0.0625)
+ (2.125,0.046875)(2.14062,0.046875)(2.14062,0.03125)(2.125,0.03125)
+ (2.10938,0.03125)(2.10938,0.015625)(2.125,0.015625)(2.125,0)
+ (2.125,-0.015625)(2.14062,-0.015625)(2.14062,-0.03125)(2.125,-0.03125)
+ (2.10938,-0.03125)(2.10938,-0.046875)(2.125,-0.046875)(2.125,-0.0625)
+ (2.14062,-0.0625)(2.14062,-0.046875)(2.15625,-0.046875)(2.15625,-0.0625)
+ (2.15625,-0.078125)(2.17188,-0.078125)(2.17188,-0.0625)(2.1875,-0.0625)
+ (2.1875,-0.046875)(2.17188,-0.046875)(2.17188,-0.03125)(2.1875,-0.03125)
+ (2.20312,-0.03125)(2.20312,-0.015625)(2.1875,-0.015625)(2.1875,0)
+ (2.20312,0)(2.20312,0.015625)(2.21875,0.015625)(2.21875,0)
+\path(2.21875,0)(2.21875,-0.015625)(2.23438,-0.015625)(2.23438,0)(2.25,0)
+ (2.25,0.015625)(2.23438,0.015625)(2.23438,0.03125)(2.25,0.03125)
+ (2.26562,0.03125)(2.26562,0.046875)(2.25,0.046875)(2.25,0.0625)
+ (2.23438,0.0625)(2.23438,0.046875)(2.21875,0.046875)(2.21875,0.0625)
+ (2.21875,0.078125)(2.20312,0.078125)(2.20312,0.0625)(2.1875,0.0625)
+ (2.1875,0.078125)(2.17188,0.078125)(2.17188,0.09375)(2.1875,0.09375)
+ (2.20312,0.09375)(2.20312,0.109375)(2.1875,0.109375)(2.1875,0.125)
+ (2.20312,0.125)(2.20312,0.140625)(2.21875,0.140625)(2.21875,0.125)
+ (2.21875,0.109375)(2.23438,0.109375)(2.23438,0.125)(2.25,0.125)
+ (2.26562,0.125)(2.26562,0.140625)(2.28125,0.140625)(2.28125,0.125)
+ (2.28125,0.109375)(2.29688,0.109375)(2.29688,0.125)(2.3125,0.125)
+ (2.3125,0.140625)(2.29688,0.140625)(2.29688,0.15625)(2.3125,0.15625)
+ (2.32812,0.15625)(2.32812,0.171875)(2.3125,0.171875)(2.3125,0.1875)
+ (2.29688,0.1875)(2.29688,0.171875)(2.28125,0.171875)(2.28125,0.1875)
+ (2.28125,0.203125)(2.26562,0.203125)(2.26562,0.1875)
+\path(2.26562,0.1875)(2.25,0.1875)(2.25,0.203125)(2.23438,0.203125)
+ (2.23438,0.21875)(2.25,0.21875)(2.26562,0.21875)(2.26562,0.234375)
+ (2.25,0.234375)(2.25,0.25)(2.26562,0.25)(2.26562,0.265625)
+ (2.28125,0.265625)(2.28125,0.25)(2.28125,0.234375)(2.29688,0.234375)
+ (2.29688,0.25)(2.3125,0.25)(2.3125,0.265625)(2.29688,0.265625)
+ (2.29688,0.28125)(2.3125,0.28125)(2.32812,0.28125)(2.32812,0.296875)
+ (2.3125,0.296875)(2.3125,0.3125)(2.32812,0.3125)(2.32812,0.328125)
+ (2.34375,0.328125)(2.34375,0.3125)(2.34375,0.296875)(2.35938,0.296875)
+ (2.35938,0.3125)(2.375,0.3125)(2.375,0.296875)(2.39062,0.296875)
+ (2.39062,0.28125)(2.375,0.28125)(2.35938,0.28125)(2.35938,0.265625)
+ (2.375,0.265625)(2.375,0.25)(2.375,0.234375)(2.39062,0.234375)
+ (2.39062,0.21875)(2.375,0.21875)(2.35938,0.21875)(2.35938,0.203125)
+ (2.375,0.203125)(2.375,0.1875)(2.39062,0.1875)(2.39062,0.203125)
+ (2.40625,0.203125)(2.40625,0.1875)(2.40625,0.171875)(2.42188,0.171875)
+ (2.42188,0.1875)(2.4375,0.1875)(2.4375,0.203125)(2.42188,0.203125)
+\path(2.42188,0.203125)(2.42188,0.21875)(2.4375,0.21875)(2.45312,0.21875)
+ (2.45312,0.234375)(2.4375,0.234375)(2.4375,0.25)(2.45312,0.25)
+ (2.45312,0.265625)(2.46875,0.265625)(2.46875,0.25)(2.46875,0.234375)
+ (2.48438,0.234375)(2.48438,0.25)(2.5,0.25)(2.5,0.234375)
+ (2.51562,0.234375)(2.51562,0.21875)(2.5,0.21875)(2.48438,0.21875)
+ (2.48438,0.203125)(2.5,0.203125)(2.5,0.1875)(2.51562,0.1875)
+ (2.51562,0.203125)(2.53125,0.203125)(2.53125,0.1875)(2.53125,0.171875)
+ (2.54688,0.171875)(2.54688,0.1875)(2.5625,0.1875)(2.5625,0.171875)
+ (2.57812,0.171875)(2.57812,0.15625)(2.5625,0.15625)(2.54688,0.15625)
+ (2.54688,0.140625)(2.5625,0.140625)(2.5625,0.125)(2.54688,0.125)
+ (2.54688,0.109375)(2.53125,0.109375)(2.53125,0.125)(2.53125,0.140625)
+ (2.51562,0.140625)(2.51562,0.125)(2.5,0.125)(2.48438,0.125)
+ (2.48438,0.109375)(2.46875,0.109375)(2.46875,0.125)(2.46875,0.140625)
+ (2.45312,0.140625)(2.45312,0.125)(2.4375,0.125)(2.4375,0.109375)
+ (2.45312,0.109375)(2.45312,0.09375)(2.4375,0.09375)(2.42188,0.09375)
+\path(2.42188,0.09375)(2.42188,0.078125)(2.4375,0.078125)(2.4375,0.0625)
+ (2.45312,0.0625)(2.45312,0.078125)(2.46875,0.078125)(2.46875,0.0625)
+ (2.46875,0.046875)(2.48438,0.046875)(2.48438,0.0625)(2.5,0.0625)
+ (2.5,0.046875)(2.51562,0.046875)(2.51562,0.03125)(2.5,0.03125)
+ (2.48438,0.03125)(2.48438,0.015625)(2.5,0.015625)(2.5,0)(2.5,-0.015625)
+ (2.51562,-0.015625)(2.51562,-0.03125)(2.5,-0.03125)(2.48438,-0.03125)
+ (2.48438,-0.046875)(2.5,-0.046875)(2.5,-0.0625)(2.51562,-0.0625)
+ (2.51562,-0.046875)(2.53125,-0.046875)(2.53125,-0.0625)
+ (2.53125,-0.078125)(2.54688,-0.078125)(2.54688,-0.0625)(2.5625,-0.0625)
+ (2.5625,-0.078125)(2.57812,-0.078125)(2.57812,-0.09375)(2.5625,-0.09375)
+ (2.54688,-0.09375)(2.54688,-0.109375)(2.5625,-0.109375)(2.5625,-0.125)
+ (2.54688,-0.125)(2.54688,-0.140625)(2.53125,-0.140625)(2.53125,-0.125)
+ (2.53125,-0.109375)(2.51562,-0.109375)(2.51562,-0.125)(2.5,-0.125)
+ (2.48438,-0.125)(2.48438,-0.140625)(2.46875,-0.140625)(2.46875,-0.125)
+ (2.46875,-0.109375)(2.45312,-0.109375)(2.45312,-0.125)(2.4375,-0.125)
+\path(2.4375,-0.125)(2.4375,-0.140625)(2.45312,-0.140625)(2.45312,-0.15625)
+ (2.4375,-0.15625)(2.42188,-0.15625)(2.42188,-0.171875)(2.4375,-0.171875)
+ (2.4375,-0.1875)(2.45312,-0.1875)(2.45312,-0.171875)(2.46875,-0.171875)
+ (2.46875,-0.1875)(2.46875,-0.203125)(2.48438,-0.203125)(2.48438,-0.1875)
+ (2.5,-0.1875)(2.5,-0.203125)(2.51562,-0.203125)(2.51562,-0.21875)
+ (2.5,-0.21875)(2.48438,-0.21875)(2.48438,-0.234375)(2.5,-0.234375)
+ (2.5,-0.25)(2.51562,-0.25)(2.51562,-0.234375)(2.53125,-0.234375)
+ (2.53125,-0.25)(2.53125,-0.265625)(2.54688,-0.265625)(2.54688,-0.25)
+ (2.5625,-0.25)(2.5625,-0.234375)(2.54688,-0.234375)(2.54688,-0.21875)
+ (2.5625,-0.21875)(2.57812,-0.21875)(2.57812,-0.203125)(2.5625,-0.203125)
+ (2.5625,-0.1875)(2.57812,-0.1875)(2.57812,-0.171875)(2.59375,-0.171875)
+ (2.59375,-0.1875)(2.59375,-0.203125)(2.60938,-0.203125)(2.60938,-0.1875)
+ (2.625,-0.1875)(2.625,-0.203125)(2.64062,-0.203125)(2.64062,-0.21875)
+ (2.625,-0.21875)(2.60938,-0.21875)(2.60938,-0.234375)(2.625,-0.234375)
+ (2.625,-0.25)(2.625,-0.265625)(2.64062,-0.265625)(2.64062,-0.28125)
+\path(2.64062,-0.28125)(2.625,-0.28125)(2.60938,-0.28125)
+ (2.60938,-0.296875)(2.625,-0.296875)(2.625,-0.3125)(2.64062,-0.3125)
+ (2.64062,-0.296875)(2.65625,-0.296875)(2.65625,-0.3125)
+ (2.65625,-0.328125)(2.67188,-0.328125)(2.67188,-0.3125)(2.6875,-0.3125)
+ (2.6875,-0.296875)(2.67188,-0.296875)(2.67188,-0.28125)(2.6875,-0.28125)
+ (2.70312,-0.28125)(2.70312,-0.265625)(2.6875,-0.265625)(2.6875,-0.25)
+ (2.70312,-0.25)(2.70312,-0.234375)(2.71875,-0.234375)(2.71875,-0.25)
+ (2.71875,-0.265625)(2.73438,-0.265625)(2.73438,-0.25)(2.75,-0.25)
+ (2.75,-0.234375)(2.73438,-0.234375)(2.73438,-0.21875)(2.75,-0.21875)
+ (2.76562,-0.21875)(2.76562,-0.203125)(2.75,-0.203125)(2.75,-0.1875)
+ (2.73438,-0.1875)(2.73438,-0.203125)(2.71875,-0.203125)(2.71875,-0.1875)
+ (2.71875,-0.171875)(2.70312,-0.171875)(2.70312,-0.1875)(2.6875,-0.1875)
+ (2.6875,-0.171875)(2.67188,-0.171875)(2.67188,-0.15625)(2.6875,-0.15625)
+ (2.70312,-0.15625)(2.70312,-0.140625)(2.6875,-0.140625)(2.6875,-0.125)
+ (2.70312,-0.125)(2.70312,-0.109375)(2.71875,-0.109375)(2.71875,-0.125)
+ (2.71875,-0.140625)(2.73438,-0.140625)
+\path(2.73438,-0.140625)(2.73438,-0.125)(2.75,-0.125)(2.76562,-0.125)
+ (2.76562,-0.109375)(2.78125,-0.109375)(2.78125,-0.125)(2.78125,-0.140625)
+ (2.79688,-0.140625)(2.79688,-0.125)(2.8125,-0.125)(2.8125,-0.109375)
+ (2.79688,-0.109375)(2.79688,-0.09375)(2.8125,-0.09375)(2.82812,-0.09375)
+ (2.82812,-0.078125)(2.8125,-0.078125)(2.8125,-0.0625)(2.79688,-0.0625)
+ (2.79688,-0.078125)(2.78125,-0.078125)(2.78125,-0.0625)
+ (2.78125,-0.046875)(2.76562,-0.046875)(2.76562,-0.0625)(2.75,-0.0625)
+ (2.75,-0.046875)(2.73438,-0.046875)(2.73438,-0.03125)(2.75,-0.03125)
+ (2.76562,-0.03125)(2.76562,-0.015625)(2.75,-0.015625)(2.75,0)(2.76562,0)
+ (2.76562,0.015625)(2.78125,0.015625)(2.78125,0)(2.78125,-0.015625)
+ (2.79688,-0.015625)(2.79688,0)(2.8125,0)(2.8125,0.015625)
+ (2.79688,0.015625)(2.79688,0.03125)(2.8125,0.03125)(2.82812,0.03125)
+ (2.82812,0.046875)(2.8125,0.046875)(2.8125,0.0625)(2.82812,0.0625)
+ (2.82812,0.078125)(2.84375,0.078125)(2.84375,0.0625)(2.84375,0.046875)
+ (2.85938,0.046875)(2.85938,0.0625)(2.875,0.0625)(2.875,0.046875)
+\path(2.875,0.046875)(2.89062,0.046875)(2.89062,0.03125)(2.875,0.03125)
+ (2.85938,0.03125)(2.85938,0.015625)(2.875,0.015625)(2.875,0)
+ (2.875,-0.015625)(2.89062,-0.015625)(2.89062,-0.03125)(2.875,-0.03125)
+ (2.85938,-0.03125)(2.85938,-0.046875)(2.875,-0.046875)(2.875,-0.0625)
+ (2.89062,-0.0625)(2.89062,-0.046875)(2.90625,-0.046875)(2.90625,-0.0625)
+ (2.90625,-0.078125)(2.92188,-0.078125)(2.92188,-0.0625)(2.9375,-0.0625)
+ (2.9375,-0.046875)(2.92188,-0.046875)(2.92188,-0.03125)(2.9375,-0.03125)
+ (2.95312,-0.03125)(2.95312,-0.015625)(2.9375,-0.015625)(2.9375,0)
+ (2.95312,0)(2.95312,0.015625)(2.96875,0.015625)(2.96875,0)
+ (2.96875,-0.015625)(2.98438,-0.015625)(2.98438,0)(3,0)
+%% ---
+\end{picture}
diff --git a/graphics/epix/doc/koch.xp b/graphics/epix/doc/koch.xp
new file mode 100644
index 0000000000..d1a04e1c0f
--- /dev/null
+++ b/graphics/epix/doc/koch.xp
@@ -0,0 +1,24 @@
+/* -*-ePiX-*- */
+/* koch.c -- Simple fractal "curve" generation. -- June 6, 2002 */
+
+#include "epix.h"
+using namespace ePiX;
+
+// const int koch_seed[] = {6, 4, 0, 1, -1, 0};
+const int seed[] = {4, 8, 0, 1, 0, 3, 3, 0, 1, 0};
+
+int main()
+{
+ bounding_box(P(0,0), P(3, 0.5));
+ picture(P(3, 0.5));
+ unitlength("1in");
+ offset(P(0,0.25));
+
+ begin();
+
+ for (int i=1; i <= 3; ++i)
+ fractal(P(i-1,0), P(i,0), i, seed);
+
+ end();
+}
+
diff --git a/graphics/epix/doc/layout.eepic b/graphics/epix/doc/layout.eepic
new file mode 100644
index 0000000000..07eec3fcb6
--- /dev/null
+++ b/graphics/epix/doc/layout.eepic
@@ -0,0 +1,1511 @@
+%% Generated from layout.xp on Sat Jun 30 12:16:41 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [0,2] x [0,3]
+%% Actual size: 5 x 7.5in
+%% Figure offset: left by 0in, down by 0in
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\xdefinecolor{rgb_980000}{rgb}{0.596078,0,0}
+\setlength{\unitlength}{1in}
+\begin{picture}(5,7.5)(-0,-0)
+\path(1.95438,5.77398)(1.9095,5.84756)(1.86459,5.91634)
+ (1.81949,5.98073)(1.77406,6.04108)(1.72817,6.09772)
+ (1.68169,6.15093)(1.63449,6.20095)(1.58643,6.24802)
+ (1.53738,6.29233)(1.4872,6.33406)(1.43575,6.37337)(1.38287,6.41039)
+ (1.32843,6.44527)(1.27224,6.4781)(1.21415,6.50899)(1.15394,6.53802)
+ (1.09144,6.56528)(1.02641,6.59083)(0.958625,6.61472)
+ (0.887817,6.63701)(0.813702,6.65773)(0.735966,6.67692)
+ (0.654259,6.69459)(0.568192,6.71076)
+%%
+\path(1.7999,5.73751)(1.76689,5.81018)(1.7333,5.87809)
+ (1.69903,5.94164)(1.66399,6.00118)(1.6281,6.05703)(1.59125,6.10945)
+ (1.55336,6.15868)(1.51431,6.20496)(1.47401,6.24846)
+ (1.43234,6.28936)(1.38918,6.32782)(1.34441,6.36396)
+ (1.29789,6.39792)(1.24946,6.4298)(1.19898,6.45968)(1.14626,6.48766)
+ (1.09112,6.5138)(1.03334,6.53816)(0.972699,6.5608)
+ (0.908939,6.58175)(0.841779,6.60103)(0.770903,6.61868)
+ (0.69596,6.6347)(0.616556,6.64908)
+%%
+\path(1.64758,5.71257)(1.62656,5.78375)(1.60445,5.85027)
+ (1.5812,5.91251)(1.55677,5.97079)(1.53112,6.02543)(1.50418,6.07667)
+ (1.4759,6.12475)(1.4462,6.16989)(1.41501,6.21226)(1.38225,6.25204)
+ (1.34781,6.28935)(1.31159,6.32435)(1.27348,6.35712)
+ (1.23334,6.38779)(1.19104,6.41643)(1.14642,6.44311)(1.09929,6.4679)
+ (1.04947,6.49085)(0.996736,6.512)(0.940842,6.53138)(0.881517,6.549)
+ (0.818452,6.56488)(0.7513,6.579)(0.679669,6.59135)
+%%
+\path(1.49959,5.69983)(1.49052,5.76899)(1.47988,5.83363)
+ (1.46769,5.89408)(1.45395,5.95068)(1.43865,6.00371)(1.42178,6.0534)
+ (1.4033,6.09999)(1.38319,6.14367)(1.36138,6.18461)(1.33782,6.22297)
+ (1.31245,6.25888)(1.28517,6.29246)(1.2559,6.32381)(1.22453,6.35304)
+ (1.19093,6.3802)(1.15497,6.40538)(1.11648,6.42861)(1.0753,6.44994)
+ (1.03121,6.4694)(0.983998,6.48701)(0.933394,6.50277)
+ (0.879107,6.51667)(0.820805,6.52869)(0.758105,6.53879)
+%%
+\path(1.35808,5.69964)(1.36071,5.7663)(1.36137,5.82859)
+ (1.36012,5.88685)(1.35701,5.94137)(1.35206,5.99243)
+ (1.34528,6.04024)(1.33669,6.08502)(1.32628,6.12695)
+ (1.31402,6.16618)(1.29989,6.20287)(1.28384,6.23713)(1.2658,6.26908)
+ (1.24573,6.2988)(1.22352,6.32638)(1.19908,6.35188)(1.17229,6.37536)
+ (1.14301,6.39686)(1.1111,6.41641)(1.07637,6.43402)(1.03861,6.4497)
+ (0.997597,6.46343)(0.953048,6.47519)(0.904656,6.48495)(0.852063,6.49264)
+%%
+\path(1.22499,5.71201)(1.23894,5.77574)(1.25058,5.83529)
+ (1.26001,5.89099)(1.26732,5.94311)(1.27257,5.99188)
+ (1.27581,6.03753)(1.27707,6.08023)(1.27637,6.12016)
+ (1.27372,6.15746)(1.26912,6.19226)(1.26255,6.22468)(1.25398,6.2548)
+ (1.24336,6.28272)(1.23063,6.30849)(1.21572,6.33218)
+ (1.19853,6.35383)(1.17897,6.37346)(1.1569,6.3911)(1.13216,6.40674)
+ (1.10459,6.42038)(1.07398,6.43198)(1.04008,6.44151)
+ (1.00263,6.44891)(0.961291,6.45409)
+%%
+\path(1.10205,5.73661)(1.12678,5.79705)(1.14894,5.85356)
+ (1.16867,5.90641)(1.18608,5.95585)(1.20126,6.00209)(1.2143,6.04534)
+ (1.22526,6.08575)(1.23418,6.12348)(1.2411,6.15867)(1.24604,6.19142)
+ (1.24901,6.22184)(1.25,6.25)(1.249,6.27598)(1.24597,6.29984)
+ (1.24087,6.32162)(1.23364,6.34134)(1.22419,6.35903)
+ (1.21243,6.37468)(1.19825,6.3883)(1.1815,6.39984)(1.16202,6.40927)
+ (1.13961,6.41653)(1.11404,6.42153)(1.08505,6.42418)
+%%
+\path(0.990653,5.77275)(1.02551,5.82968)(1.05762,5.88291)
+ (1.08714,5.93269)(1.11422,5.97925)(1.13897,6.02279)(1.1615,6.06346)
+ (1.18189,6.10143)(1.20023,6.13683)(1.21656,6.16978)
+ (1.23095,6.20036)(1.24341,6.22868)(1.25398,6.2548)(1.26266,6.27878)
+ (1.26945,6.30066)(1.27433,6.32047)(1.27727,6.33823)
+ (1.27824,6.35395)(1.27716,6.36761)(1.27397,6.37919)
+ (1.26857,6.38865)(1.26084,6.39593)(1.25063,6.40095)
+ (1.23778,6.40361)(1.22209,6.40378)
+%%
+\path(0.891818,5.81952)(0.936069,5.87276)(0.977467,5.92257)
+ (1.01619,5.96916)(1.05241,6.01272)(1.08626,6.05343)
+ (1.11788,6.09143)(1.14736,6.12687)(1.17482,6.15986)
+ (1.20032,6.19049)(1.22395,6.21886)(1.24576,6.24504)(1.2658,6.26908)
+ (1.28412,6.29103)(1.30073,6.31092)(1.31565,6.32877)
+ (1.32889,6.34458)(1.34044,6.35836)(1.35028,6.37006)
+ (1.35839,6.37967)(1.36472,6.38712)(1.3692,6.39234)(1.37176,6.39522)
+ (1.3723,6.39566)(1.37069,6.39349)
+%%
+\path(0.806183,5.87573)(0.85904,5.92524)(0.909007,5.97156)
+ (0.956284,6.01489)(1.00105,6.0554)(1.04347,6.09324)
+ (1.08369,6.12855)(1.12183,6.16142)(1.15802,6.19198)
+ (1.19236,6.22029)(1.22494,6.24644)(1.25585,6.27048)
+ (1.28517,6.29246)(1.31296,6.31241)(1.33928,6.33035)
+ (1.36418,6.34629)(1.3877,6.36022)(1.40988,6.37214)(1.43074,6.38199)
+ (1.4503,6.38973)(1.46858,6.3953)(1.48558,6.3986)(1.50128,6.39953)
+ (1.51567,6.39793)(1.52872,6.39365)
+%%
+\path(0.734,5.94009)(0.794644,5.98587)(0.852427,6.02873)
+ (0.907559,6.06882)(0.960235,6.1063)(1.01063,6.14129)
+ (1.05891,6.17391)(1.10521,6.20425)(1.14968,6.2324)(1.19244,6.25843)
+ (1.23361,6.28241)(1.27329,6.30437)(1.31159,6.32435)(1.3486,6.34237)
+ (1.38441,6.35845)(1.41911,6.37258)(1.45277,6.38474)
+ (1.48548,6.39492)(1.5173,6.40305)(1.54832,6.40909)(1.57859,6.41296)
+ (1.6082,6.41454)(1.63721,6.41373)(1.6657,6.41035)(1.69373,6.40423)
+%%
+\path(0.675166,6.01119)(0.742777,6.05334)(0.807609,6.09281)
+ (0.869881,6.12974)(0.929796,6.16426)(0.987543,6.19647)
+ (1.0433,6.22648)(1.09722,6.25436)(1.14946,6.28019)(1.20016,6.30402)
+ (1.24947,6.32591)(1.29751,6.34588)(1.34441,6.36396)
+ (1.39029,6.38017)(1.43528,6.39451)(1.47948,6.40696)(1.52302,6.4175)
+ (1.56602,6.42609)(1.60861,6.43269)(1.65091,6.43722)(1.69305,6.4396)
+ (1.73517,6.4397)(1.77744,6.43741)(1.82002,6.43255)(1.86308,6.42493)
+%%
+\path(0.62927,6.08763)(0.703045,6.12629)(0.774167,6.1625)
+ (0.842861,6.1964)(0.909337,6.22808)(0.973792,6.25763)
+ (1.03641,6.28514)(1.09737,6.31068)(1.15683,6.3343)(1.21496,6.35605)
+ (1.27191,6.37597)(1.32783,6.39408)(1.38287,6.41039)
+ (1.43719,6.42493)(1.49093,6.43766)(1.54425,6.44859)
+ (1.59729,6.45768)(1.65023,6.46488)(1.70324,6.47014)
+ (1.75649,6.47337)(1.81019,6.4745)(1.86455,6.47339)(1.9198,6.46991)
+ (1.97622,6.46388)(2.03409,6.4551)
+%%
+\path(1.95438,5.77398)(1.877,5.75436)(1.7999,5.73751)
+ (1.72333,5.72355)(1.64758,5.71257)(1.57291,5.70464)
+ (1.49959,5.69983)(1.4279,5.69816)(1.35808,5.69964)(1.29037,5.70427)
+ (1.22499,5.71201)(1.16216,5.72282)(1.10205,5.73661)
+ (1.04484,5.75329)(0.990653,5.77275)(0.939616,5.79488)
+ (0.891818,5.81952)(0.847326,5.84652)(0.806183,5.87573)
+ (0.768408,5.90698)(0.734,5.94009)(0.702933,5.97489)
+ (0.675166,6.01119)(0.650637,6.04883)(0.62927,6.08763)
+%%
+\path(1.86459,5.91634)(1.79875,5.89596)(1.7333,5.87809)
+ (1.66845,5.86282)(1.60445,5.85027)(1.54151,5.84052)
+ (1.47988,5.83363)(1.41976,5.82964)(1.36137,5.82859)
+ (1.30491,5.83047)(1.25058,5.83529)(1.19853,5.843)(1.14894,5.85356)
+ (1.10193,5.86689)(1.05762,5.88291)(1.01611,5.90151)
+ (0.977467,5.92257)(0.941756,5.94597)(0.909007,5.97156)
+ (0.879232,5.9992)(0.852427,6.02873)(0.828566,6.05999)
+ (0.807609,6.09281)(0.789499,6.12704)(0.774167,6.1625)
+%%
+\path(1.77406,6.04108)(1.71877,6.02)(1.66399,6.00118)
+ (1.60993,5.98475)(1.55677,5.97079)(1.50471,5.95942)
+ (1.45395,5.95068)(1.40465,5.94465)(1.35701,5.94137)
+ (1.31118,5.94086)(1.26732,5.94311)(1.22558,5.94812)
+ (1.18608,5.95585)(1.14892,5.96625)(1.11422,5.97925)
+ (1.08203,5.99478)(1.05241,6.01272)(1.02541,6.03297)(1.00105,6.0554)
+ (0.97933,6.07989)(0.960235,6.1063)(0.943738,6.13447)
+ (0.929796,6.16426)(0.918352,6.19551)(0.909337,6.22808)
+%%
+\path(1.68169,6.15093)(1.63613,6.12916)(1.59125,6.10945)
+ (1.54721,6.09191)(1.50418,6.07667)(1.46232,6.0638)(1.42178,6.0534)
+ (1.38272,6.04553)(1.34528,6.04024)(1.3096,6.03757)(1.27581,6.03753)
+ (1.24401,6.04012)(1.2143,6.04534)(1.18677,6.05313)(1.1615,6.06346)
+ (1.13852,6.07626)(1.11788,6.09143)(1.0996,6.1089)(1.08369,6.12855)
+ (1.07013,6.15026)(1.05891,6.17391)(1.04998,6.19936)(1.0433,6.22648)
+ (1.0388,6.25512)(1.03641,6.28514)
+%%
+\path(1.58643,6.24802)(1.54994,6.22555)(1.51431,6.20496)
+ (1.47969,6.18637)(1.4462,6.16989)(1.41399,6.15563)(1.38319,6.14367)
+ (1.35391,6.13409)(1.32628,6.12695)(1.3004,6.12229)(1.27637,6.12016)
+ (1.25427,6.12056)(1.23418,6.12348)(1.21615,6.12892)
+ (1.20023,6.13683)(1.18644,6.14717)(1.17482,6.15986)
+ (1.16535,6.17483)(1.15802,6.19198)(1.15281,6.21121)(1.14968,6.2324)
+ (1.14858,6.25544)(1.14946,6.28019)(1.15223,6.30652)(1.15683,6.3343)
+%%
+\path(1.4872,6.33406)(1.45923,6.31085)(1.43234,6.28936)
+ (1.40664,6.26972)(1.38225,6.25204)(1.35927,6.23642)
+ (1.33782,6.22297)(1.318,6.21176)(1.29989,6.20287)(1.28357,6.19636)
+ (1.26912,6.19226)(1.2566,6.19061)(1.24604,6.19142)(1.23748,6.19468)
+ (1.23095,6.20036)(1.22644,6.20844)(1.22395,6.21886)
+ (1.22346,6.23156)(1.22494,6.24644)(1.22834,6.26342)
+ (1.23361,6.28241)(1.24068,6.30328)(1.24947,6.32591)
+ (1.25991,6.35018)(1.27191,6.37597)
+%%
+\path(1.38287,6.41039)(1.36299,6.38639)(1.34441,6.36396)
+ (1.32725,6.34324)(1.31159,6.32435)(1.29754,6.30738)
+ (1.28517,6.29246)(1.27457,6.27966)(1.2658,6.26908)(1.25892,6.26077)
+ (1.25398,6.2548)(1.251,6.2512)(1.25,6.25)(1.251,6.2512)
+ (1.25398,6.2548)(1.25892,6.26077)(1.2658,6.26908)(1.27457,6.27966)
+ (1.28517,6.29246)(1.29754,6.30738)(1.31159,6.32435)
+ (1.32725,6.34324)(1.34441,6.36396)(1.36299,6.38639)(1.38287,6.41039)
+%%
+\path(1.27224,6.4781)(1.26007,6.45322)(1.24946,6.4298)
+ (1.24053,6.40794)(1.23334,6.38779)(1.22799,6.36945)
+ (1.22453,6.35304)(1.22302,6.33865)(1.22352,6.32638)
+ (1.22604,6.31631)(1.23063,6.30849)(1.23727,6.30299)
+ (1.24597,6.29984)(1.25671,6.29906)(1.26945,6.30066)
+ (1.28414,6.30462)(1.30073,6.31092)(1.31913,6.31951)
+ (1.33928,6.33035)(1.36108,6.34335)(1.38441,6.35845)
+ (1.40918,6.37553)(1.43528,6.39451)(1.46257,6.41526)(1.49093,6.43766)
+%%
+\path(1.15394,6.53802)(1.14916,6.51218)(1.14626,6.48766)
+ (1.14532,6.46459)(1.14642,6.44311)(1.14962,6.42333)
+ (1.15497,6.40538)(1.16252,6.38935)(1.17229,6.37536)(1.18429,6.3635)
+ (1.19853,6.35383)(1.21499,6.34643)(1.23364,6.34134)(1.25442,6.3386)
+ (1.27727,6.33823)(1.30213,6.34023)(1.32889,6.34458)
+ (1.35745,6.35126)(1.3877,6.36022)(1.41952,6.37141)(1.45277,6.38474)
+ (1.48732,6.40014)(1.52302,6.4175)(1.55973,6.43672)(1.59729,6.45768)
+%%
+\path(1.02641,6.59083)(1.02876,6.56389)(1.03334,6.53816)
+ (1.04022,6.51377)(1.04947,6.49085)(1.06115,6.46953)(1.0753,6.44994)
+ (1.09195,6.4322)(1.1111,6.41641)(1.13276,6.40268)(1.1569,6.3911)
+ (1.18348,6.38175)(1.21243,6.37468)(1.24369,6.36996)
+ (1.27716,6.36761)(1.31274,6.36764)(1.35028,6.37006)
+ (1.38967,6.37486)(1.43074,6.38199)(1.47334,6.39141)(1.5173,6.40305)
+ (1.56245,6.41685)(1.60861,6.43269)(1.6556,6.45049)(1.70324,6.47014)
+%%
+\path(0.887817,6.63701)(0.897069,6.60884)(0.908939,6.58175)
+ (0.923508,6.55588)(0.940842,6.53138)(0.960994,6.50838)
+ (0.983998,6.48701)(1.00987,6.46741)(1.03861,6.4497)(1.0702,6.43398)
+ (1.10459,6.42038)(1.14172,6.40897)(1.1815,6.39984)(1.22383,6.39305)
+ (1.26857,6.38865)(1.31559,6.38667)(1.36472,6.38712)
+ (1.41578,6.39001)(1.46858,6.3953)(1.52292,6.40297)(1.57859,6.41296)
+ (1.63537,6.42519)(1.69305,6.4396)(1.75139,6.45607)(1.81019,6.4745)
+%%
+\path(0.735966,6.67692)(0.7519,6.64732)(0.770903,6.61868)
+ (0.793063,6.59115)(0.818452,6.56488)(0.847122,6.54)
+ (0.879107,6.51667)(0.91442,6.49502)(0.953048,6.47519)
+ (0.994955,6.45732)(1.04008,6.44151)(1.08834,6.42788)
+ (1.13961,6.41653)(1.19376,6.40753)(1.25063,6.40095)
+ (1.31003,6.39684)(1.37176,6.39522)(1.43559,6.39612)
+ (1.50128,6.39953)(1.56857,6.40541)(1.63721,6.41373)
+ (1.70692,6.42442)(1.77744,6.43741)(1.84849,6.45261)(1.9198,6.46991)
+%%
+\path(0.568192,6.71076)(0.590579,6.67951)(0.616556,6.64908)
+ (0.646225,6.61965)(0.679669,6.59135)(0.716949,6.56435)
+ (0.758105,6.53879)(0.803148,6.51484)(0.852063,6.49264)
+ (0.904803,6.47235)(0.961291,6.45409)(1.02142,6.43799)
+ (1.08505,6.42418)(1.15201,6.41274)(1.22209,6.40378)
+ (1.29507,6.39734)(1.37069,6.39349)(1.44868,6.39226)
+ (1.52872,6.39365)(1.61052,6.39765)(1.69373,6.40423)
+ (1.77803,6.41335)(1.86308,6.42493)(1.94854,6.43888)(2.03409,6.4551)
+%%
+\path(1.25,6.25)(0.90831,5.83754)
+%%
+\path(0.929086,5.88702)(0.940008,5.90021)
+\path(0.922161,5.87053)(0.944004,5.8969)
+\path(0.915235,5.85404)(0.947999,5.89359)
+\path(0.90831,5.83754)(0.951995,5.89028)
+\path(0.923227,5.84742)(0.955991,5.88697)
+\path(0.938144,5.85729)(0.959987,5.88366)
+\path(0.953061,5.86716)(0.963983,5.88035)
+\path(0.951995,5.89028)(0.936012,5.90352)(0.90831,5.83754)
+ (0.967979,5.87704)(0.951995,5.89028)
+%%
+\path(1.25,6.25)(1.9921,6.09631)
+%%
+\path(1.90984,6.09745)(1.88348,6.10291)
+\path(1.93726,6.09707)(1.88453,6.10799)
+\path(1.96468,6.09669)(1.88558,6.11307)
+\path(1.9921,6.09631)(1.88663,6.11815)
+\path(1.96678,6.10685)(1.88768,6.12323)
+\path(1.94147,6.11739)(1.88874,6.12831)
+\path(1.91616,6.12793)(1.88979,6.13339)
+\path(1.88663,6.11815)(1.88242,6.09782)(1.9921,6.09631)
+ (1.89084,6.13847)(1.88663,6.11815)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(2.375,5.125)
+ (2.375,7.375)(0.125,7.375)(0.125,5.125)(2.375,5.125)
+%%
+\allinethickness{0.4pt}%
+\color{rgb_000000}%
+\path(1.57249,2.99581)
+ (1.60208,3.08238)(1.62568,3.16486)(1.6436,3.24353)(1.65613,3.31869)
+ (1.66348,3.39059)(1.66589,3.45945)(1.66353,3.52548)
+ (1.65656,3.58888)(1.64515,3.64982)(1.6294,3.70847)(1.60943,3.76497)
+ (1.58534,3.81945)(1.5572,3.87205)(1.52509,3.92289)(1.48905,3.97206)
+ (1.44912,4.01968)(1.40534,4.06584)(1.35773,4.11062)(1.3063,4.15411)
+ (1.25104,4.19638)(1.19195,4.23751)(1.129,4.27756)(1.06218,4.3166)(0.991435,4.35469)
+%%
+\path(1.39706,3.04908)(1.43364,3.12654)(1.46419,3.20061)
+ (1.48899,3.27155)(1.50828,3.33955)(1.52226,3.40482)
+ (1.53114,3.46754)(1.53508,3.52788)(1.53423,3.58598)(1.5287,3.64199)
+ (1.51863,3.69603)(1.50409,3.74824)(1.48518,3.79871)
+ (1.46195,3.84755)(1.43447,3.89487)(1.40276,3.94074)
+ (1.36687,3.98526)(1.3268,4.02851)(1.28256,4.07055)(1.23414,4.11145)
+ (1.18153,4.1513)(1.12471,4.19013)(1.06363,4.22802)
+ (0.998248,4.26502)(0.928503,4.30119)
+%%
+\path(1.24877,3.10605)(1.29092,3.17474)(1.32712,3.24068)
+ (1.3576,3.30403)(1.38257,3.36496)(1.40221,3.42363)(1.41669,3.48018)
+ (1.42614,3.53473)(1.43068,3.5874)(1.43043,3.6383)(1.42548,3.68755)
+ (1.4159,3.73523)(1.40174,3.78143)(1.38307,3.82624)(1.35991,3.86973)
+ (1.33228,3.91199)(1.3002,3.95308)(1.26366,3.99306)(1.22265,4.03201)
+ (1.17713,4.06997)(1.12708,4.107)(1.07245,4.14315)(1.01316,4.17848)
+ (0.94915,4.21303)(0.88033,4.24685)
+%%
+\path(1.12691,3.16617)(1.17344,3.22652)(1.21419,3.28463)
+ (1.24934,3.34063)(1.27907,3.39466)(1.30353,3.44682)
+ (1.32285,3.49721)(1.33713,3.54595)(1.34648,3.59312)
+ (1.35097,3.63881)(1.35067,3.68311)(1.34564,3.72607)(1.3359,3.76779)
+ (1.32149,3.80832)(1.30242,3.84773)(1.27869,3.88608)
+ (1.25028,3.92343)(1.21716,3.95982)(1.17931,3.99531)
+ (1.13666,4.02995)(1.08914,4.06378)(1.0367,4.09685)(0.979215,4.1292)
+ (0.916597,4.16087)(0.848721,4.19189)
+%%
+\path(1.03051,3.22888)(1.08046,3.28136)(1.12486,3.33203)
+ (1.16386,3.38098)(1.1976,3.42832)(1.22618,3.47411)(1.24971,3.51846)
+ (1.26827,3.56143)(1.28193,3.60309)(1.29073,3.64351)
+ (1.29472,3.68275)(1.29392,3.72088)(1.28835,3.75794)(1.27801,3.794)
+ (1.26288,3.82909)(1.24294,3.86327)(1.21815,3.89658)
+ (1.18844,3.92907)(1.15376,3.96077)(1.11403,3.99173)
+ (1.06914,4.02198)(1.01898,4.05155)(0.963433,4.08048)
+ (0.902342,4.10881)(0.835544,4.13656)
+%%
+\path(0.958412,3.29368)(1.01103,3.3388)(1.05838,3.38244)
+ (1.10059,3.42468)(1.13773,3.4656)(1.1699,3.50525)(1.19715,3.54369)
+ (1.21956,3.58099)(1.23714,3.61719)(1.24993,3.65234)(1.25794,3.6865)
+ (1.26117,3.7197)(1.25961,3.75199)(1.25324,3.78341)(1.242,3.814)
+ (1.22584,3.84379)(1.20471,3.87282)(1.1785,3.90111)(1.14713,3.92871)
+ (1.11049,3.95563)(1.06842,3.98191)(1.02079,4.00758)
+ (0.967431,4.03266)(0.90814,4.05717)(0.842708,4.08114)
+%%
+\path(0.909289,3.36006)(0.964025,3.39834)(1.01381,3.43541)
+ (1.05873,3.47132)(1.09883,3.50614)(1.13418,3.5399)(1.16481,3.57265)
+ (1.19075,3.60442)(1.212,3.63526)(1.22857,3.66521)(1.24045,3.69429)
+ (1.2476,3.72255)(1.25,3.75)(1.24758,3.77668)(1.24029,3.80262)
+ (1.22803,3.82784)(1.21071,3.85236)(1.18821,3.87622)(1.1604,3.89941)
+ (1.12714,3.92198)(1.08825,3.94394)(1.04353,3.9653)
+ (0.992768,3.98607)(0.935726,4.00629)(0.872128,4.02595)
+%%
+\path(0.881704,3.42756)(0.938175,3.45953)(0.990033,3.4905)
+ (1.03733,3.5205)(1.08009,3.54957)(1.11835,3.57774)(1.15212,3.60504)
+ (1.1814,3.63149)(1.20618,3.65713)(1.22644,3.68198)(1.24213,3.70606)
+ (1.25321,3.72939)(1.25961,3.75199)(1.26127,3.77388)
+ (1.25808,3.79508)(1.24993,3.8156)(1.2367,3.83545)(1.21824,3.85464)
+ (1.19439,3.87319)(1.16495,3.89111)(1.12973,3.9084)(1.08847,3.92506)
+ (1.04091,3.94111)(0.986766,3.95654)(0.92569,3.97136)
+%%
+\path(0.874138,3.49573)(0.93211,3.52194)(0.985819,3.54729)
+ (1.03529,3.5718)(1.08054,3.5955)(1.12156,3.61841)(1.15836,3.64055)
+ (1.19091,3.66193)(1.21917,3.68256)(1.24311,3.70247)
+ (1.26267,3.72167)(1.27778,3.74015)(1.28835,3.75794)
+ (1.29429,3.77504)(1.29547,3.79146)(1.29177,3.80719)
+ (1.28303,3.82225)(1.26907,3.83662)(1.2497,3.85032)(1.22469,3.86333)
+ (1.1938,3.87564)(1.15674,3.88726)(1.1132,3.89816)(1.06282,3.90834)(1.0052,3.91777)
+%%
+\path(0.885031,3.56419)(0.944391,3.58516)(0.999849,3.60537)
+ (1.05141,3.62484)(1.09907,3.64357)(1.14282,3.66157)
+ (1.18263,3.67886)(1.21846,3.69544)(1.25027,3.71131)(1.278,3.72648)
+ (1.30157,3.74095)(1.32091,3.75472)(1.3359,3.76779)(1.34643,3.78015)
+ (1.35237,3.7918)(1.35356,3.80272)(1.34982,3.81291)(1.34096,3.82236)
+ (1.32674,3.83103)(1.30692,3.83893)(1.28121,3.84601)
+ (1.24929,3.85226)(1.21078,3.85763)(1.16529,3.8621)(1.11235,3.86562)
+%%
+\path(0.912807,3.63258)(0.973544,3.64883)(1.03075,3.66437)
+ (1.0844,3.67923)(1.1345,3.69339)(1.18102,3.70686)(1.22391,3.71963)
+ (1.26313,3.73171)(1.29863,3.74309)(1.33033,3.75376)
+ (1.35815,3.76372)(1.38199,3.77294)(1.40174,3.78143)
+ (1.41728,3.78915)(1.42844,3.7961)(1.43507,3.80224)(1.43696,3.80755)
+ (1.43391,3.812)(1.42567,3.81556)(1.41195,3.81818)(1.39244,3.81982)
+ (1.36679,3.82042)(1.33458,3.81993)(1.29537,3.81827)(1.24863,3.81537)
+%%
+\path(0.955906,3.70059)(1.01809,3.7126)(1.0771,3.72394)
+ (1.13294,3.73461)(1.18557,3.74461)(1.23497,3.75392)
+ (1.28108,3.76253)(1.32387,3.77044)(1.36326,3.77762)
+ (1.39918,3.78406)(1.43155,3.78974)(1.46025,3.79463)
+ (1.48518,3.79871)(1.5062,3.80194)(1.52314,3.8043)(1.53585,3.80574)
+ (1.54411,3.80622)(1.54771,3.80568)(1.54637,3.80407)
+ (1.53982,3.80133)(1.52771,3.79737)(1.50967,3.79211)
+ (1.48526,3.78546)(1.45399,3.7773)(1.4153,3.76751)
+%%
+\path(1.0128,3.76793)(1.07655,3.77617)(1.13751,3.78375)
+ (1.19566,3.79067)(1.25098,3.7969)(1.30343,3.80242)(1.35296,3.80723)
+ (1.39954,3.81129)(1.44308,3.81459)(1.48353,3.81709)
+ (1.52079,3.81875)(1.55477,3.81956)(1.58534,3.81945)
+ (1.61238,3.81839)(1.63574,3.81633)(1.65524,3.8132)(1.67069,3.80894)
+ (1.68186,3.80347)(1.68849,3.79671)(1.6903,3.78856)(1.68695,3.77892)
+ (1.67805,3.76764)(1.66317,3.7546)(1.64178,3.73963)(1.61332,3.72254)
+%%
+\path(1.57249,2.99581)(1.48135,3.02195)(1.39706,3.04908)
+ (1.31956,3.07714)(1.24877,3.10605)(1.1846,3.13575)(1.12691,3.16617)
+ (1.0756,3.19723)(1.03051,3.22888)(0.991504,3.26105)
+ (0.958412,3.29368)(0.931066,3.3267)(0.909289,3.36006)
+ (0.892898,3.3937)(0.881704,3.42756)(0.875516,3.46158)
+ (0.874138,3.49573)(0.877376,3.52995)(0.885031,3.56419)
+ (0.896906,3.59842)(0.912807,3.63258)(0.932537,3.66665)
+ (0.955906,3.70059)(0.982723,3.73436)(1.0128,3.76793)
+%%
+\path(1.62568,3.16486)(1.54188,3.18217)(1.46419,3.20061)
+ (1.39261,3.22013)(1.32712,3.24068)(1.26766,3.26219)
+ (1.21419,3.28463)(1.16661,3.30793)(1.12486,3.33203)
+ (1.08882,3.35689)(1.05838,3.38244)(1.03343,3.40863)
+ (1.01381,3.43541)(0.999398,3.46271)(0.990033,3.4905)
+ (0.985561,3.51871)(0.985819,3.54729)(0.990638,3.57619)
+ (0.999849,3.60537)(1.01328,3.63478)(1.03075,3.66437)
+ (1.05208,3.69411)(1.0771,3.72394)(1.10564,3.75384)(1.13751,3.78375)
+%%
+\path(1.65613,3.31869)(1.57945,3.32854)(1.50828,3.33955)
+ (1.44265,3.3517)(1.38257,3.36496)(1.32805,3.37929)(1.27907,3.39466)
+ (1.2356,3.41101)(1.1976,3.42832)(1.165,3.44653)(1.13773,3.4656)
+ (1.11571,3.48548)(1.09883,3.50614)(1.087,3.52752)(1.08009,3.54957)
+ (1.07798,3.57225)(1.08054,3.5955)(1.08762,3.61929)(1.09907,3.64357)
+ (1.11475,3.66828)(1.1345,3.69339)(1.15816,3.71885)(1.18557,3.74461)
+ (1.21656,3.77064)(1.25098,3.7969)
+%%
+\path(1.66589,3.45945)(1.59601,3.46292)(1.53114,3.46754)
+ (1.47135,3.4733)(1.41669,3.48018)(1.36718,3.48816)(1.32285,3.49721)
+ (1.2837,3.50732)(1.24971,3.51846)(1.22088,3.53059)(1.19715,3.54369)
+ (1.17849,3.55772)(1.16481,3.57265)(1.15605,3.58843)
+ (1.15212,3.60504)(1.15293,3.62242)(1.15836,3.64055)(1.1683,3.65937)
+ (1.18263,3.67886)(1.20121,3.69896)(1.22391,3.71963)
+ (1.25058,3.74084)(1.28108,3.76253)(1.31526,3.78468)(1.35296,3.80723)
+%%
+\path(1.65656,3.58888)(1.59309,3.58689)(1.53423,3.58598)
+ (1.48007,3.58615)(1.43068,3.5874)(1.38614,3.58973)(1.34648,3.59312)
+ (1.31173,3.59758)(1.28193,3.60309)(1.25706,3.60963)
+ (1.23714,3.61719)(1.22213,3.62574)(1.212,3.63526)(1.2067,3.64574)
+ (1.20618,3.65713)(1.21037,3.66942)(1.21917,3.68256)
+ (1.23251,3.69654)(1.25027,3.71131)(1.27235,3.72684)
+ (1.29863,3.74309)(1.32898,3.76003)(1.36326,3.77762)
+ (1.40135,3.79582)(1.44308,3.81459)
+%%
+\path(1.6294,3.70847)(1.57186,3.70176)(1.51863,3.69603)
+ (1.4698,3.69129)(1.42548,3.68755)(1.38575,3.68482)(1.35067,3.68311)
+ (1.32031,3.68242)(1.29472,3.68275)(1.27392,3.68411)(1.25794,3.6865)
+ (1.24679,3.68989)(1.24045,3.69429)(1.23891,3.69969)
+ (1.24213,3.70606)(1.25007,3.71339)(1.26267,3.72167)
+ (1.27987,3.73086)(1.30157,3.74095)(1.3277,3.75191)(1.35815,3.76372)
+ (1.3928,3.77634)(1.43155,3.78974)(1.47426,3.80389)(1.52079,3.81875)
+%%
+\path(1.58534,3.81945)(1.53323,3.80866)(1.48518,3.79871)
+ (1.44131,3.78962)(1.40174,3.78143)(1.36658,3.77414)(1.3359,3.76779)
+ (1.3098,3.76239)(1.28835,3.75794)(1.27161,3.75448)(1.25961,3.75199)
+ (1.25241,3.7505)(1.25,3.75)(1.25241,3.7505)(1.25961,3.75199)
+ (1.27161,3.75448)(1.28835,3.75794)(1.3098,3.76239)(1.3359,3.76779)
+ (1.36658,3.77414)(1.40174,3.78143)(1.44131,3.78962)
+ (1.48518,3.79871)(1.53323,3.80866)(1.58534,3.81945)
+%%
+\path(1.52509,3.92289)(1.47784,3.90853)(1.43447,3.89487)
+ (1.39512,3.88192)(1.35991,3.86973)(1.32897,3.85833)
+ (1.30242,3.84773)(1.28036,3.83798)(1.26288,3.82909)
+ (1.25007,3.82109)(1.242,3.814)(1.23872,3.80784)(1.24029,3.80262)
+ (1.24673,3.79836)(1.25808,3.79508)(1.27433,3.79277)
+ (1.29547,3.79146)(1.3215,3.79113)(1.35237,3.7918)(1.38804,3.79345)
+ (1.42844,3.7961)(1.47351,3.79972)(1.52314,3.8043)(1.57726,3.80985)(1.63574,3.81633)
+%%
+\path(1.44912,4.01968)(1.40612,4.00221)(1.36687,3.98526)
+ (1.33151,3.96887)(1.3002,3.95308)(1.27308,3.93792)(1.25028,3.92343)
+ (1.23193,3.90964)(1.21815,3.89658)(1.20904,3.8843)(1.20471,3.87282)
+ (1.20524,3.86216)(1.21071,3.85236)(1.22118,3.84345)(1.2367,3.83545)
+ (1.25731,3.82837)(1.28303,3.82225)(1.31387,3.81709)
+ (1.34982,3.81291)(1.39086,3.80973)(1.43696,3.80755)
+ (1.48807,3.80638)(1.54411,3.80622)(1.60502,3.80707)(1.67069,3.80894)
+%%
+\path(1.35773,4.11062)(1.31832,4.09041)(1.28256,4.07055)
+ (1.25061,4.05107)(1.22265,4.03201)(1.19883,4.01341)
+ (1.17931,3.99531)(1.16424,3.97775)(1.15376,3.96077)
+ (1.14802,3.94441)(1.14713,3.92871)(1.15123,3.91369)(1.1604,3.89941)
+ (1.17476,3.8859)(1.19439,3.87319)(1.21935,3.86132)(1.2497,3.85032)
+ (1.28549,3.84021)(1.32674,3.83103)(1.37347,3.82281)
+ (1.42567,3.81556)(1.48331,3.80931)(1.54637,3.80407)
+ (1.61479,3.79987)(1.68849,3.79671)
+%%
+\path(1.25104,4.19638)(1.2145,4.17376)(1.18153,4.1513)
+ (1.15234,4.12903)(1.12708,4.107)(1.10596,4.08523)(1.08914,4.06378)
+ (1.07681,4.04268)(1.06914,4.02198)(1.06629,4.00171)
+ (1.06842,3.98191)(1.07569,3.96264)(1.08825,3.94394)
+ (1.10622,3.92584)(1.12973,3.9084)(1.15889,3.89165)(1.1938,3.87564)
+ (1.23455,3.86042)(1.28121,3.84601)(1.33383,3.83246)
+ (1.39244,3.81982)(1.45707,3.80811)(1.52771,3.79737)
+ (1.60435,3.78763)(1.68695,3.77892)
+%%
+\path(1.129,4.27756)(1.09455,4.25281)(1.06363,4.22802)
+ (1.03643,4.20324)(1.01316,4.17848)(0.994019,4.15379)
+ (0.979215,4.1292)(0.968952,4.10475)(0.963433,4.08048)
+ (0.96286,4.05644)(0.967431,4.03266)(0.977337,4.00919)
+ (0.992768,3.98607)(1.0139,3.96337)(1.04091,3.94111)
+ (1.07396,3.91936)(1.1132,3.89816)(1.15877,3.87757)(1.21078,3.85763)
+ (1.26936,3.8384)(1.33458,3.81993)(1.40653,3.80226)(1.48526,3.78546)
+ (1.5708,3.76955)(1.66317,3.7546)
+%%
+\path(0.991435,4.35469)(0.958234,4.32805)(0.928503,4.30119)
+ (0.902461,4.27411)(0.88033,4.24685)(0.862339,4.21944)
+ (0.848721,4.19189)(0.83971,4.16426)(0.835544,4.13656)
+ (0.836464,4.10884)(0.842708,4.08114)(0.854517,4.05349)
+ (0.872128,4.02595)(0.895776,3.99856)(0.92569,3.97136)
+ (0.962093,3.94442)(1.0052,3.91777)(1.05522,3.89149)
+ (1.11235,3.86562)(1.17676,3.84023)(1.24863,3.81537)(1.3281,3.79111)
+ (1.4153,3.76751)(1.51034,3.74463)(1.61332,3.72254)
+%%
+\path(1.25,3.75)(0.507902,3.59631)
+%%
+\path(0.583844,3.62793)(0.610211,3.63339)
+\path(0.55853,3.61739)(0.611263,3.62831)
+\path(0.533216,3.60685)(0.612315,3.62323)
+\path(0.507902,3.59631)(0.613368,3.61815)
+\path(0.535321,3.59669)(0.61442,3.61307)
+\path(0.56274,3.59707)(0.615472,3.60799)
+\path(0.590158,3.59745)(0.616525,3.60291)
+\path(0.613368,3.61815)(0.609159,3.63847)(0.507902,3.59631)
+ (0.617577,3.59782)(0.613368,3.61815)
+%%
+\path(1.25,3.75)(1.59169,3.33754)
+%%
+\path(1.54694,3.36716)(1.53602,3.38035)
+\path(1.56186,3.35729)(1.54001,3.38366)
+\path(1.57677,3.34742)(1.54401,3.38697)
+\path(1.59169,3.33754)(1.548,3.39028)
+\path(1.58476,3.35404)(1.552,3.39359)
+\path(1.57784,3.37053)(1.556,3.3969)
+\path(1.57091,3.38702)(1.55999,3.40021)
+\path(1.548,3.39028)(1.53202,3.37704)(1.59169,3.33754)
+ (1.56399,3.40352)(1.548,3.39028)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(2.375,2.625)
+ (2.375,4.875)(0.125,4.875)(0.125,2.625)(2.375,2.625)
+%%
+\allinethickness{0.4pt}%
+\color{rgb_000000}%
+\path
+ (0.927506,0.495809)(1.01757,0.548834)(1.10157,0.602843)
+ (1.17947,0.657739)(1.25125,0.713425)(1.3169,0.769804)
+ (1.37643,0.826777)(1.42989,0.884247)(1.47732,0.94212)
+ (1.51879,1.0003)(1.55438,1.0587)(1.58419,1.11722)(1.60833,1.17579)
+ (1.62692,1.23431)(1.64008,1.2927)(1.64797,1.35089)(1.65074,1.40881)
+ (1.64854,1.46638)(1.64154,1.52354)(1.62991,1.58023)
+ (1.61383,1.63639)(1.59347,1.69196)(1.56902,1.7469)(1.54066,1.80115)(1.50857,1.85469)
+%%
+\path(0.8777,0.611715)(0.959433,0.655571)(1.03581,0.700614)
+ (1.10675,0.74677)(1.17219,0.793961)(1.2321,0.842109)
+ (1.28645,0.891132)(1.33522,0.940947)(1.37842,0.991473)
+ (1.41609,1.04262)(1.44824,1.09432)(1.47494,1.14647)(1.49626,1.199)
+ (1.51227,1.25182)(1.52307,1.30486)(1.52876,1.35804)
+ (1.52946,1.41127)(1.52529,1.46449)(1.51639,1.51763)(1.5029,1.57062)
+ (1.48496,1.62339)(1.46273,1.67588)(1.43637,1.72802)
+ (1.40604,1.77978)(1.37192,1.83108)
+%%
+\path(0.850911,0.713606)(0.924836,0.749547)(0.993963,0.786789)
+ (1.05819,0.825281)(1.11743,0.864964)(1.17161,0.905781)
+ (1.22068,0.947667)(1.26458,0.990557)(1.3033,1.03438)
+ (1.33682,1.07908)(1.36514,1.12456)(1.38829,1.17077)
+ (1.40628,1.21763)(1.41917,1.26507)(1.42702,1.313)(1.42989,1.36136)
+ (1.42787,1.41007)(1.42105,1.45906)(1.40954,1.50826)
+ (1.39346,1.55759)(1.37292,1.607)(1.34805,1.6564)(1.31901,1.70574)
+ (1.28592,1.75496)(1.24895,1.80399)
+%%
+\path(0.844563,0.803527)(0.911256,0.832549)(0.97359,0.862922)
+ (1.03145,0.894614)(1.08472,0.927588)(1.13332,0.961802)
+ (1.17715,0.997213)(1.21616,1.03377)(1.25029,1.07143)
+ (1.27949,1.11013)(1.30374,1.14982)(1.32302,1.19043)
+ (1.33734,1.23191)(1.3467,1.27419)(1.35115,1.31721)(1.35071,1.3609)
+ (1.34544,1.40519)(1.33541,1.45002)(1.32069,1.49531)
+ (1.30138,1.54101)(1.27758,1.58703)(1.24938,1.63332)(1.21692,1.6798)
+ (1.18032,1.72642)(1.13972,1.7731)
+%%
+\path(0.856643,0.883119)(0.916712,0.906022)(0.972764,0.930277)
+ (1.02467,0.955868)(1.0723,0.982778)(1.11556,1.01098)
+ (1.15433,1.04046)(1.18853,1.07117)(1.21807,1.10309)
+ (1.24291,1.13617)(1.26297,1.17038)(1.27822,1.20567)(1.28864,1.242)
+ (1.2942,1.27931)(1.29492,1.31754)(1.29079,1.35666)(1.28185,1.39658)
+ (1.26815,1.43727)(1.24972,1.47865)(1.22664,1.52067)
+ (1.19897,1.56326)(1.16682,1.60635)(1.13027,1.64988)
+ (1.08945,1.69379)(1.04445,1.73802)
+%%
+\path(0.885577,0.953717)(0.93965,0.971145)(0.989968,0.989888)
+ (1.03639,1.00995)(1.07878,1.03132)(1.11702,1.05399)
+ (1.15098,1.07797)(1.18055,1.10322)(1.20565,1.12975)
+ (1.22618,1.15751)(1.24206,1.1865)(1.25323,1.21667)(1.25963,1.24801)
+ (1.26123,1.28046)(1.258,1.314)(1.24993,1.34858)(1.23701,1.38415)
+ (1.21926,1.42067)(1.1967,1.45809)(1.16937,1.49635)(1.13734,1.5354)
+ (1.10065,1.57517)(1.0594,1.61562)(1.01366,1.65667)(0.963551,1.69828)
+%%
+\path(0.930139,1.01641)(0.97886,1.02889)(1.02402,1.04261)
+ (1.06548,1.05759)(1.10308,1.07385)(1.13669,1.09139)
+ (1.16618,1.11021)(1.19141,1.13032)(1.21227,1.15172)(1.22866,1.1744)
+ (1.24046,1.19834)(1.2476,1.22355)(1.25,1.25)(1.24758,1.27767)
+ (1.2403,1.30654)(1.22812,1.33658)(1.211,1.36775)(1.18893,1.40004)
+ (1.16191,1.43338)(1.12996,1.46775)(1.0931,1.50311)(1.05137,1.53939)
+ (1.00483,1.57655)(0.95355,1.61455)(0.897604,1.65331)
+%%
+\path(0.989383,1.07211)(1.03341,1.08005)(1.07402,1.08915)
+ (1.11107,1.09943)(1.14439,1.11092)(1.17383,1.12362)
+ (1.19925,1.13757)(1.22049,1.15278)(1.23743,1.16926)
+ (1.24993,1.18702)(1.25787,1.20606)(1.26114,1.22639)
+ (1.25963,1.24801)(1.25325,1.2709)(1.24192,1.29508)(1.22557,1.32052)
+ (1.20414,1.3472)(1.17758,1.37511)(1.14587,1.40423)(1.10898,1.43452)
+ (1.06692,1.46596)(1.0197,1.49852)(0.967353,1.53214)
+ (0.909912,1.5668)(0.84744,1.60244)
+%%
+\path(1.0626,1.12156)(1.1026,1.12531)(1.1393,1.1301)
+ (1.17253,1.13598)(1.20212,1.14296)(1.22791,1.15108)
+ (1.24973,1.16037)(1.26742,1.17086)(1.28083,1.18256)(1.2898,1.19551)
+ (1.29418,1.20972)(1.29384,1.22521)(1.28864,1.242)(1.27846,1.26009)
+ (1.26319,1.27949)(1.24272,1.30021)(1.21697,1.32225)(1.18585,1.3456)
+ (1.14931,1.37026)(1.10728,1.39622)(1.05973,1.42347)
+ (1.00664,1.45198)(0.948007,1.48173)(0.883841,1.51269)(0.81417,1.54484)
+%%
+\path(1.14927,1.16539)(1.18593,1.16521)(1.21938,1.16596)
+ (1.24942,1.16766)(1.27589,1.17035)(1.2986,1.17407)(1.31737,1.17886)
+ (1.33202,1.18475)(1.34238,1.19178)(1.34825,1.19998)
+ (1.34948,1.20938)(1.3459,1.22002)(1.33734,1.23191)(1.32364,1.2451)
+ (1.30466,1.25959)(1.28026,1.27541)(1.2503,1.29259)(1.21467,1.31112)
+ (1.17326,1.33103)(1.12598,1.35233)(1.07274,1.375)(1.01349,1.39906)
+ (0.948177,1.4245)(0.876769,1.45131)(0.799255,1.47948)
+%%
+\path(1.24904,1.20411)(1.28307,1.20023)(1.31396,1.19712)
+ (1.3415,1.19483)(1.3655,1.19339)(1.38577,1.19284)(1.4021,1.19323)
+ (1.41431,1.19461)(1.42218,1.197)(1.42551,1.20046)(1.4241,1.20502)
+ (1.41776,1.21074)(1.40628,1.21763)(1.38947,1.22576)
+ (1.36714,1.23514)(1.33911,1.24583)(1.3052,1.25784)(1.26524,1.27122)
+ (1.21907,1.28599)(1.16656,1.30219)(1.10756,1.31982)
+ (1.04196,1.33891)(0.969654,1.35948)(0.890556,1.38154)(0.804598,1.4051)
+%%
+\path(1.3617,1.23817)(1.39385,1.23075)(1.4229,1.22394)
+ (1.44865,1.21779)(1.47089,1.21232)(1.48943,1.2076)(1.50402,1.20365)
+ (1.51446,1.20053)(1.52052,1.19829)(1.52196,1.19696)
+ (1.51856,1.19661)(1.51007,1.19727)(1.49626,1.199)(1.47689,1.20184)
+ (1.45173,1.20585)(1.42053,1.21107)(1.38308,1.21755)
+ (1.33914,1.22534)(1.28849,1.23448)(1.23092,1.24502)
+ (1.16623,1.25701)(1.09423,1.27047)(1.01474,1.28546)
+ (0.927602,1.30199)(0.83267,1.32012)
+%%
+\path(1.4872,1.26793)(1.51821,1.2571)(1.5462,1.2467)
+ (1.57093,1.23677)(1.5922,1.22735)(1.60978,1.21849)(1.62342,1.21022)
+ (1.63288,1.20259)(1.6379,1.19565)(1.63823,1.18945)(1.6336,1.18404)
+ (1.62373,1.17947)(1.60833,1.17579)(1.58713,1.17306)
+ (1.55982,1.17134)(1.52613,1.17068)(1.48574,1.17114)
+ (1.43836,1.17279)(1.3837,1.17569)(1.32146,1.17988)(1.25135,1.18545)
+ (1.17308,1.19243)(1.08639,1.20091)(0.99101,1.21092)(0.886683,1.22254)
+%%
+\path(0.927506,0.495809)(0.899539,0.55566)(0.8777,0.611715)
+ (0.861604,0.664274)(0.850911,0.713606)(0.845319,0.759952)
+ (0.844563,0.803527)(0.848407,0.844524)(0.856643,0.883119)
+ (0.869088,0.919469)(0.885577,0.953717)(0.90597,0.985993)
+ (0.930139,1.01641)(0.957975,1.04509)(0.989383,1.07211)
+ (1.02428,1.09758)(1.0626,1.12156)(1.10428,1.14414)(1.14927,1.16539)
+ (1.19753,1.18536)(1.24904,1.20411)(1.30377,1.2217)(1.3617,1.23817)
+ (1.42285,1.25356)(1.4872,1.26793)
+%%
+\path(1.10157,0.602843)(1.06552,0.653288)(1.03581,0.700614)
+ (1.01206,0.745046)(0.993963,0.786789)(0.981224,0.826026)
+ (0.97359,0.862922)(0.970837,0.897627)(0.972764,0.930277)
+ (0.979193,0.960993)(0.989968,0.989888)(1.00495,1.01706)
+ (1.02402,1.04261)(1.04708,1.06661)(1.07402,1.08915)
+ (1.10479,1.11029)(1.1393,1.1301)(1.17751,1.14864)(1.21938,1.16596)
+ (1.26487,1.1821)(1.31396,1.19712)(1.36664,1.21106)(1.4229,1.22394)
+ (1.48275,1.23581)(1.5462,1.2467)
+%%
+\path(1.25125,0.713425)(1.20852,0.754966)(1.17219,0.793961)
+ (1.14193,0.830577)(1.11743,0.864964)(1.09844,0.89726)
+ (1.08472,0.927588)(1.07607,0.95606)(1.0723,0.982778)
+ (1.07325,1.00784)(1.07878,1.03132)(1.08876,1.0533)(1.10308,1.07385)
+ (1.12165,1.09304)(1.14439,1.11092)(1.17123,1.12754)
+ (1.20212,1.14296)(1.23702,1.15721)(1.27589,1.17035)
+ (1.31872,1.18239)(1.3655,1.19339)(1.41622,1.20335)(1.47089,1.21232)
+ (1.52955,1.22032)(1.5922,1.22735)
+%%
+\path(1.37643,0.826777)(1.32827,0.85999)(1.28645,0.891132)
+ (1.25067,0.920321)(1.22068,0.947667)(1.19624,0.973268)
+ (1.17715,0.997213)(1.16324,1.01959)(1.15433,1.04046)
+ (1.15028,1.0599)(1.15098,1.07797)(1.15631,1.09472)(1.16618,1.11021)
+ (1.18051,1.12448)(1.19925,1.13757)(1.22233,1.14953)
+ (1.24973,1.16037)(1.28142,1.17014)(1.31737,1.17886)(1.3576,1.18655)
+ (1.4021,1.19323)(1.4509,1.19893)(1.50402,1.20365)(1.56151,1.20741)(1.62342,1.21022)
+%%
+\path(1.47732,0.94212)(1.42478,0.967642)(1.37842,0.991473)
+ (1.338,1.01369)(1.3033,1.03438)(1.27412,1.05361)(1.25029,1.07143)
+ (1.23165,1.08791)(1.21807,1.10309)(1.20944,1.11702)
+ (1.20565,1.12975)(1.20662,1.1413)(1.21227,1.15172)(1.22256,1.16103)
+ (1.23743,1.16926)(1.25686,1.17643)(1.28083,1.18256)
+ (1.30933,1.18768)(1.34238,1.19178)(1.37998,1.19488)(1.42218,1.197)
+ (1.469,1.19814)(1.52052,1.19829)(1.57679,1.19746)(1.6379,1.19565)
+%%
+\path(1.55438,1.0587)(1.49833,1.07721)(1.44824,1.09432)
+ (1.4039,1.11009)(1.36514,1.12456)(1.3318,1.13779)(1.30374,1.14982)
+ (1.28083,1.16067)(1.26297,1.17038)(1.25007,1.17898)(1.24206,1.1865)
+ (1.23887,1.19294)(1.24046,1.19834)(1.2468,1.20271)(1.25787,1.20606)
+ (1.27366,1.20839)(1.29418,1.20972)(1.31944,1.21005)
+ (1.34948,1.20938)(1.38435,1.20771)(1.4241,1.20502)(1.46881,1.20133)
+ (1.51856,1.19661)(1.57345,1.19085)(1.6336,1.18404)
+%%
+\path(1.60833,1.17579)(1.54946,1.18798)(1.49626,1.199)
+ (1.44858,1.20887)(1.40628,1.21763)(1.36924,1.22531)
+ (1.33734,1.23191)(1.3105,1.23747)(1.28864,1.242)(1.2717,1.24551)
+ (1.25963,1.24801)(1.25241,1.2495)(1.25,1.25)(1.25241,1.2495)
+ (1.25963,1.24801)(1.2717,1.24551)(1.28864,1.242)(1.3105,1.23747)
+ (1.33734,1.23191)(1.36924,1.22531)(1.40628,1.21763)
+ (1.44858,1.20887)(1.49626,1.199)(1.54946,1.18798)(1.60833,1.17579)
+%%
+\path(1.64008,1.2927)(1.5789,1.29929)(1.52307,1.30486)
+ (1.47248,1.30943)(1.42702,1.313)(1.3866,1.31559)(1.35115,1.31721)
+ (1.3206,1.31786)(1.29492,1.31754)(1.27406,1.31626)(1.258,1.314)
+ (1.24675,1.31076)(1.2403,1.30654)(1.23868,1.30132)(1.24192,1.29508)
+ (1.25007,1.28781)(1.26319,1.27949)(1.28135,1.27009)
+ (1.30466,1.25959)(1.33321,1.24795)(1.36714,1.23514)
+ (1.40659,1.22112)(1.45173,1.20585)(1.50274,1.18927)(1.55982,1.17134)
+%%
+\path(1.65074,1.40881)(1.5876,1.4105)(1.52946,1.41127)
+ (1.47624,1.41113)(1.42787,1.41007)(1.38428,1.40809)
+ (1.34544,1.40519)(1.3113,1.40136)(1.28185,1.39658)(1.25709,1.39085)
+ (1.23701,1.38415)(1.22163,1.37646)(1.211,1.36775)(1.20515,1.35801)
+ (1.20414,1.3472)(1.20805,1.33529)(1.21697,1.32225)(1.23101,1.30803)
+ (1.2503,1.29259)(1.27497,1.27588)(1.3052,1.25784)(1.34116,1.23842)
+ (1.38308,1.21755)(1.43118,1.19515)(1.48574,1.17114)
+%%
+\path(1.64154,1.52354)(1.57665,1.52102)(1.51639,1.51763)
+ (1.4607,1.51338)(1.40954,1.50826)(1.36288,1.50224)(1.32069,1.49531)
+ (1.28297,1.48746)(1.24972,1.47865)(1.22095,1.46887)(1.1967,1.45809)
+ (1.177,1.44627)(1.16191,1.43338)(1.15151,1.41938)(1.14587,1.40423)
+ (1.14509,1.38787)(1.14931,1.37026)(1.15864,1.35134)
+ (1.17326,1.33103)(1.19333,1.30928)(1.21907,1.28599)(1.2507,1.26109)
+ (1.28849,1.23448)(1.33271,1.20605)(1.3837,1.17569)
+%%
+\path(1.61383,1.63639)(1.54727,1.6303)(1.48496,1.62339)
+ (1.42684,1.61563)(1.37292,1.607)(1.32316,1.59747)(1.27758,1.58703)
+ (1.23617,1.57563)(1.19897,1.56326)(1.16601,1.54986)(1.13734,1.5354)
+ (1.11301,1.51983)(1.0931,1.50311)(1.0777,1.48517)(1.06692,1.46596)
+ (1.06088,1.44542)(1.05973,1.42347)(1.06362,1.40002)(1.07274,1.375)
+ (1.08731,1.3483)(1.10756,1.31982)(1.13377,1.28943)(1.16623,1.25701)
+ (1.20529,1.2224)(1.25135,1.18545)
+%%
+\path(1.56902,1.7469)(1.50078,1.73787)(1.43637,1.72802)
+ (1.37578,1.71732)(1.31901,1.70574)(1.26605,1.69325)(1.21692,1.6798)
+ (1.17165,1.66536)(1.13027,1.64988)(1.09284,1.63332)(1.0594,1.61562)
+ (1.03003,1.59672)(1.00483,1.57655)(0.983899,1.55505)
+ (0.967353,1.53214)(0.955336,1.50773)(0.948007,1.48173)
+ (0.945551,1.45402)(0.948177,1.4245)(0.956122,1.39304)
+ (0.969654,1.35948)(0.989078,1.32368)(1.01474,1.28546)
+ (1.04703,1.24461)(1.08639,1.20091)
+%%
+\path(1.50857,1.85469)(1.43853,1.8433)(1.37192,1.83108)
+ (1.30872,1.81799)(1.24895,1.80399)(1.1926,1.78904)(1.13972,1.7731)
+ (1.09032,1.75611)(1.04445,1.73802)(1.00217,1.71876)
+ (0.963551,1.69828)(0.928663,1.67649)(0.897604,1.65331)
+ (0.870487,1.62866)(0.84744,1.60244)(0.828611,1.57454)
+ (0.81417,1.54484)(0.80431,1.5132)(0.799255,1.47948)
+ (0.799255,1.44351)(0.804598,1.4051)(0.815612,1.36405)
+ (0.83267,1.32012)(0.856198,1.27305)(0.886683,1.22254)
+%%
+\path(1.25,1.25)(0.600163,1.38459)
+%%
+\path(0.68242,1.38345)(0.708786,1.37799)
+\path(0.655001,1.38383)(0.707734,1.37291)
+\path(0.627582,1.38421)(0.706681,1.36782)
+\path(0.600163,1.38459)(0.705629,1.36274)
+\path(0.625477,1.37404)(0.704577,1.35766)
+\path(0.650792,1.3635)(0.703524,1.35258)
+\path(0.676106,1.35296)(0.702472,1.3475)
+\path(0.705629,1.36274)(0.709838,1.38307)(0.600163,1.38459)
+ (0.70142,1.34242)(0.705629,1.36274)
+%%
+\path(1.25,1.25)(0.90831,0.837544)
+%%
+\path(0.929086,0.887024)(0.940008,0.900207)
+\path(0.922161,0.870531)(0.944004,0.896897)
+\path(0.915235,0.854037)(0.947999,0.893587)
+\path(0.90831,0.837544)(0.951995,0.890277)
+\path(0.923227,0.847417)(0.955991,0.886966)
+\path(0.938144,0.85729)(0.959987,0.883656)
+\path(0.953061,0.867163)(0.963983,0.880346)
+\path(0.951995,0.890277)(0.936012,0.903518)(0.90831,0.837544)
+ (0.967979,0.877035)(0.951995,0.890277)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(2.375,0.125)
+ (2.375,2.375)(0.125,2.375)(0.125,0.125)(2.375,0.125)
+%%
+\allinethickness{0.4pt}%
+\color{rgb_000000}%
+\path(4.32177,5.61398)
+ (4.31023,5.69921)(4.29571,5.77929)(4.27832,5.85466)
+ (4.25813,5.92574)(4.23521,5.99286)(4.20959,6.05635)(4.1813,6.11649)
+ (4.15036,6.17352)(4.11676,6.22769)(4.0805,6.27919)(4.04155,6.32822)
+ (3.99986,6.37493)(3.9554,6.41949)(3.90809,6.46204)(3.85786,6.50269)
+ (3.80463,6.54158)(3.7483,6.5788)(3.68874,6.61445)(3.62584,6.64863)
+ (3.55945,6.68142)(3.48941,6.71289)(3.41554,6.74311)
+ (3.33764,6.77214)(3.25551,6.80006)
+%%
+\path(4.13841,5.61911)(4.13845,5.69921)(4.13499,5.7746)
+ (4.12815,5.84568)(4.11806,5.91278)(4.10479,5.97624)
+ (4.08842,6.03631)(4.06899,6.09326)(4.04655,6.14732)
+ (4.02109,6.19867)(3.99263,6.24751)(3.96116,6.29401)
+ (3.92663,6.33832)(3.88902,6.38056)(3.84826,6.42088)
+ (3.80428,6.45939)(3.75699,6.49618)(3.70631,6.53136)
+ (3.65209,6.56502)(3.59422,6.59722)(3.53254,6.62806)
+ (3.46687,6.65758)(3.39703,6.68587)(3.32279,6.71296)(3.24391,6.73891)
+%%
+\path(3.97074,5.63438)(3.98145,5.70897)(3.98827,5.77929)
+ (3.99133,5.84568)(3.99078,5.90844)(3.98672,5.96784)
+ (3.97923,6.02413)(3.96839,6.07752)(3.95423,6.12822)
+ (3.93678,6.17639)(3.91605,6.22222)(3.89204,6.26583)
+ (3.86473,6.30736)(3.83407,6.34695)(3.80002,6.38469)(3.7625,6.42068)
+ (3.72142,6.45502)(3.67668,6.4878)(3.62816,6.51909)(3.57571,6.54895)
+ (3.51917,6.57745)(3.45835,6.60465)(3.39303,6.63059)
+ (3.32299,6.65533)(3.24794,6.6789)
+%%
+\path(3.82031,5.65946)(3.84076,5.72828)(3.85704,5.79325)
+ (3.8693,5.85466)(3.87769,5.91278)(3.88234,5.96784)(3.88333,6.02004)
+ (3.88074,6.06957)(3.87462,6.1166)(3.86501,6.16129)(3.85192,6.20378)
+ (3.83536,6.24419)(3.81529,6.28265)(3.79169,6.31924)
+ (3.76451,6.35408)(3.73366,6.38723)(3.69906,6.41879)
+ (3.66061,6.44883)(3.61816,6.47739)(3.57157,6.50455)
+ (3.52065,6.53035)(3.46521,6.55484)(3.40502,6.57805)
+ (3.33981,6.60002)(3.26928,6.62077)
+%%
+\path(3.68828,5.69383)(3.71752,5.75673)(3.74242,5.81619)
+ (3.76316,5.87245)(3.77989,5.92574)(3.79272,5.97624)
+ (3.80176,6.02413)(3.80708,6.06957)(3.80875,6.1127)(3.80678,6.15367)
+ (3.80122,6.19257)(3.79205,6.22953)(3.77926,6.26463)
+ (3.76282,6.29797)(3.74266,6.32962)(3.71872,6.35966)
+ (3.69089,6.38814)(3.65907,6.41512)(3.62312,6.44066)
+ (3.58287,6.46478)(3.53814,6.48754)(3.4887,6.50895)(3.43432,6.52905)
+ (3.37469,6.54785)(3.3095,6.56536)
+%%
+\path(3.57536,5.73678)(3.61246,5.79374)(3.64519,5.84764)
+ (3.6737,5.89868)(3.69814,5.94703)(3.71864,5.99286)(3.73529,6.03631)
+ (3.74816,6.07752)(3.75733,6.1166)(3.76282,6.15367)(3.76466,6.18881)
+ (3.76284,6.22212)(3.75735,6.25368)(3.74816,6.28355)(3.7352,6.3118)
+ (3.71839,6.33848)(3.69766,6.36364)(3.67286,6.38731)
+ (3.64387,6.40955)(3.6105,6.43036)(3.57256,6.44976)(3.52982,6.46778)
+ (3.48202,6.48442)(3.42884,6.49968)(3.36994,6.51354)
+%%
+\path(3.48182,5.78746)(3.52593,5.83858)(3.5657,5.88698)
+ (3.6013,5.93282)(3.63287,5.97624)(3.66052,6.01738)(3.68434,6.05635)
+ (3.70443,6.09326)(3.72082,6.12822)(3.73357,6.16129)
+ (3.74268,6.19257)(3.74817,6.22212)(3.75,6.25)(3.74815,6.27626)
+ (3.74256,6.30096)(3.73315,6.32411)(3.71983,6.34577)
+ (3.70247,6.36595)(3.68092,6.38466)(3.65502,6.40193)
+ (3.62455,6.41774)(3.58928,6.43209)(3.54893,6.44498)
+ (3.50317,6.45637)(3.45165,6.46623)
+%%
+\path(3.40754,5.84494)(3.45785,5.89041)(3.50396,5.93346)
+ (3.54601,5.97421)(3.58414,6.0128)(3.61846,6.04931)(3.64906,6.08384)
+ (3.67601,6.11649)(3.69937,6.14732)(3.71917,6.17639)
+ (3.73544,6.20378)(3.74817,6.22953)(3.75735,6.25368)
+ (3.76295,6.27626)(3.76491,6.29732)(3.76315,6.31686)(3.75758,6.3349)
+ (3.74809,6.35145)(3.73451,6.36651)(3.71669,6.38006)(3.69441,6.3921)
+ (3.66744,6.40258)(3.63549,6.41148)(3.59823,6.41875)(3.55529,6.42432)
+%%
+\path(3.352,5.90822)(3.40781,5.9483)(3.45961,5.98623)
+ (3.50754,6.0221)(3.55172,6.05601)(3.59226,6.08804)(3.62924,6.11826)
+ (3.66274,6.14674)(3.69281,6.17352)(3.71948,6.19867)
+ (3.74278,6.22222)(3.76271,6.24419)(3.77926,6.26463)(3.7924,6.28355)
+ (3.80208,6.30096)(3.80823,6.31686)(3.81077,6.33125)
+ (3.80957,6.34412)(3.8045,6.35546)(3.79539,6.36522)(3.78206,6.37338)
+ (3.76426,6.37987)(3.74171,6.38464)(3.7141,6.3876)(3.68106,6.38866)
+%%
+\path(3.31441,5.97626)(3.37509,6.01129)(3.432,6.04439)
+ (3.48528,6.07564)(3.53504,6.10512)(3.58139,6.13288)(3.6244,6.15897)
+ (3.66415,6.18345)(3.70069,6.20635)(3.73405,6.22769)
+ (3.76427,6.24751)(3.79135,6.26583)(3.81529,6.28265)
+ (3.83606,6.29797)(3.85363,6.3118)(3.86794,6.32411)(3.8789,6.3349)
+ (3.88643,6.34412)(3.89039,6.35175)(3.89064,6.35772)
+ (3.88701,6.36198)(3.87927,6.36444)(3.86717,6.36501)
+ (3.85042,6.36359)(3.82865,6.36003)
+%%
+\path(3.29368,6.04807)(3.35869,6.07842)(3.42021,6.10703)
+ (3.47839,6.13398)(3.53332,6.1593)(3.5851,6.18306)(3.63381,6.20527)
+ (3.67954,6.22597)(3.72232,6.24518)(3.7622,6.26292)(3.79922,6.27919)
+ (3.8334,6.29401)(3.86473,6.30736)(3.89321,6.31924)(3.91881,6.32962)
+ (3.94149,6.33848)(3.9612,6.34577)(3.97785,6.35145)(3.99135,6.35546)
+ (4.00158,6.35772)(4.00838,6.35815)(4.01158,6.35663)
+ (4.01096,6.35306)(4.00627,6.34727)(3.99719,6.33908)
+%%
+\path(3.28857,6.12268)(3.35743,6.14874)(3.42314,6.17324)
+ (3.4858,6.19622)(3.54552,6.21772)(3.60241,6.23776)(3.65653,6.25637)
+ (3.70797,6.27356)(3.75678,6.28934)(3.80302,6.30372)
+ (3.84672,6.31668)(3.88792,6.32822)(3.92663,6.33832)
+ (3.96287,6.34695)(3.99662,6.35408)(4.02787,6.35966)
+ (4.05658,6.36364)(4.08272,6.36595)(4.10621,6.36651)
+ (4.12697,6.36522)(4.14491,6.36198)(4.15988,6.35663)
+ (4.17173,6.34904)(4.18026,6.33901)(4.18525,6.32631)
+%%
+\path(3.29768,6.19917)(3.37001,6.22136)(3.43952,6.24213)
+ (3.50631,6.26151)(3.57051,6.27953)(3.63219,6.29619)
+ (3.69145,6.31151)(3.74836,6.32549)(3.80299,6.33812)(3.85541,6.3494)
+ (3.90567,6.35932)(3.95381,6.36784)(3.99986,6.37493)
+ (4.04387,6.38056)(4.08585,6.38469)(4.1258,6.38723)(4.16374,6.38814)
+ (4.19966,6.38731)(4.23353,6.38466)(4.26532,6.38006)
+ (4.29499,6.37338)(4.32247,6.36444)(4.34769,6.35306)
+ (4.37053,6.33901)(4.39086,6.32202)
+%%
+\path(4.32177,5.61398)(4.22824,5.61526)(4.13841,5.61911)
+ (4.0525,5.62549)(3.97074,5.63438)(3.89329,5.64572)(3.82031,5.65946)
+ (3.75194,5.67553)(3.68828,5.69383)(3.6294,5.71428)(3.57536,5.73678)
+ (3.52617,5.76121)(3.48182,5.78746)(3.4423,5.81541)(3.40754,5.84494)
+ (3.37747,5.87592)(3.352,5.90822)(3.33103,5.94171)(3.31441,5.97626)
+ (3.30201,6.01176)(3.29368,6.04807)(3.28926,6.08509)
+ (3.28857,6.12268)(3.29144,6.16074)(3.29768,6.19917)
+%%
+\path(4.29571,5.77929)(4.2137,5.77577)(4.13499,5.7746)
+ (4.05978,5.77577)(3.98827,5.77929)(3.92064,5.78512)
+ (3.85704,5.79325)(3.79759,5.80362)(3.74242,5.81619)(3.6916,5.83089)
+ (3.64519,5.84764)(3.60322,5.86637)(3.5657,5.88698)(3.53263,5.90938)
+ (3.50396,5.93346)(3.47965,5.95911)(3.45961,5.98623)
+ (3.44377,6.01469)(3.432,6.04439)(3.42419,6.07521)(3.42021,6.10703)
+ (3.41991,6.13974)(3.42314,6.17324)(3.42973,6.2074)(3.43952,6.24213)
+%%
+\path(4.25813,5.92574)(4.18659,5.9182)(4.11806,5.91278)
+ (4.05273,5.90952)(3.99078,5.90844)(3.93239,5.90952)
+ (3.87769,5.91278)(3.82683,5.9182)(3.77989,5.92574)(3.73697,5.93537)
+ (3.69814,5.94703)(3.66343,5.96068)(3.63287,5.97624)
+ (3.60644,5.99364)(3.58414,6.0128)(3.56592,6.03362)(3.55172,6.05601)
+ (3.54146,6.07988)(3.53504,6.10512)(3.53237,6.13163)(3.53332,6.1593)
+ (3.53775,6.18804)(3.54552,6.21772)(3.55649,6.24825)(3.57051,6.27953)
+%%
+\path(4.20959,6.05635)(4.1476,6.04537)(4.08842,6.03631)
+ (4.03224,6.02922)(3.97923,6.02413)(3.92955,6.02106)
+ (3.88333,6.02004)(3.8407,6.02106)(3.80176,6.02413)(3.7666,6.02922)
+ (3.73529,6.03631)(3.70786,6.04537)(3.68434,6.05635)(3.66475,6.0692)
+ (3.64906,6.08384)(3.63724,6.10022)(3.62924,6.11826)
+ (3.62499,6.13787)(3.6244,6.15897)(3.62738,6.18147)(3.63381,6.20527)
+ (3.64358,6.23027)(3.65653,6.25637)(3.67254,6.28349)(3.69145,6.31151)
+%%
+\path(4.15036,6.17352)(4.0971,6.15956)(4.04655,6.14732)
+ (3.99887,6.13685)(3.95423,6.12822)(3.91277,6.12146)(3.87462,6.1166)
+ (3.83992,6.11368)(3.80875,6.1127)(3.7812,6.11368)(3.75733,6.1166)
+ (3.7372,6.12146)(3.72082,6.12822)(3.70822,6.13685)(3.69937,6.14732)
+ (3.69425,6.15956)(3.69281,6.17352)(3.69498,6.18914)
+ (3.70069,6.20635)(3.70984,6.22505)(3.72232,6.24518)
+ (3.73801,6.26664)(3.75678,6.28934)(3.77849,6.3132)(3.80299,6.33812)
+%%
+\path(4.0805,6.27919)(4.03524,6.26259)(3.99263,6.24751)
+ (3.95285,6.23403)(3.91605,6.22222)(3.88236,6.21212)
+ (3.85192,6.20378)(3.82484,6.19726)(3.80122,6.19257)
+ (3.78114,6.18975)(3.76466,6.18881)(3.75183,6.18975)
+ (3.74268,6.19257)(3.73722,6.19726)(3.73544,6.20378)
+ (3.73731,6.21212)(3.74278,6.22222)(3.7518,6.23403)(3.76427,6.24751)
+ (3.78012,6.26259)(3.79922,6.27919)(3.82147,6.29725)
+ (3.84672,6.31668)(3.87484,6.3374)(3.90567,6.35932)
+%%
+\path(3.99986,6.37493)(3.96191,6.35595)(3.92663,6.33832)
+ (3.89419,6.32209)(3.86473,6.30736)(3.83839,6.29419)
+ (3.81529,6.28265)(3.79555,6.27278)(3.77926,6.26463)
+ (3.76651,6.25825)(3.75735,6.25368)(3.75184,6.25092)(3.75,6.25)
+ (3.75184,6.25092)(3.75735,6.25368)(3.76651,6.25825)
+ (3.77926,6.26463)(3.79555,6.27278)(3.81529,6.28265)
+ (3.83839,6.29419)(3.86473,6.30736)(3.89419,6.32209)
+ (3.92663,6.33832)(3.96191,6.35595)(3.99986,6.37493)
+%%
+\path(3.90809,6.46204)(3.8768,6.44088)(3.84826,6.42088)
+ (3.82261,6.40212)(3.80002,6.38469)(3.78061,6.36864)
+ (3.76451,6.35408)(3.75182,6.34105)(3.74266,6.32962)(3.7371,6.31986)
+ (3.7352,6.3118)(3.73701,6.30549)(3.74256,6.30096)(3.75186,6.29823)
+ (3.76491,6.29732)(3.78166,6.29823)(3.80208,6.30096)(3.8261,6.30549)
+ (3.85363,6.3118)(3.88457,6.31986)(3.91881,6.32962)(3.9562,6.34105)
+ (3.99662,6.35408)(4.03989,6.36864)(4.08585,6.38469)
+%%
+\path(3.80463,6.54158)(3.77938,6.5184)(3.75699,6.49618)
+ (3.73762,6.47503)(3.72142,6.45502)(3.70853,6.43625)
+ (3.69906,6.41879)(3.69315,6.40273)(3.69089,6.38814)
+ (3.69237,6.37509)(3.69766,6.36364)(3.7068,6.35385)(3.71983,6.34577)
+ (3.73676,6.33944)(3.75758,6.3349)(3.78227,6.33216)(3.81077,6.33125)
+ (3.84301,6.33216)(3.8789,6.3349)(3.91834,6.33944)(3.9612,6.34577)
+ (4.00733,6.35385)(4.05658,6.36364)(4.10878,6.37509)(4.16374,6.38814)
+%%
+\path(3.68874,6.61445)(3.66891,6.58934)(3.65209,6.56502)
+ (3.63846,6.54157)(3.62816,6.51909)(3.62135,6.49766)
+ (3.61816,6.47739)(3.61871,6.45836)(3.62312,6.44066)
+ (3.63148,6.42436)(3.64387,6.40955)(3.66033,6.39629)
+ (3.68092,6.38466)(3.70565,6.37472)(3.73451,6.36651)
+ (3.76748,6.36008)(3.8045,6.35546)(3.8455,6.35268)(3.89039,6.35175)
+ (3.93905,6.35268)(3.99135,6.35546)(4.04713,6.36008)
+ (4.10621,6.36651)(4.16841,6.37472)(4.23353,6.38466)
+%%
+\path(3.55945,6.68142)(3.54439,6.65444)(3.53254,6.62806)
+ (3.52408,6.60236)(3.51917,6.57745)(3.51798,6.55341)
+ (3.52065,6.53035)(3.52733,6.50836)(3.53814,6.48754)
+ (3.55319,6.46798)(3.57256,6.44976)(3.59633,6.43299)
+ (3.62455,6.41774)(3.65725,6.40408)(3.69441,6.3921)(3.73603,6.38184)
+ (3.78206,6.37338)(3.83242,6.36674)(3.88701,6.36198)
+ (3.94571,6.35911)(4.00838,6.35815)(4.07484,6.35911)
+ (4.14491,6.36198)(4.21837,6.36674)(4.29499,6.37338)
+%%
+\path(3.41554,6.74311)(3.40457,6.71429)(3.39703,6.68587)
+ (3.39312,6.65793)(3.39303,6.63059)(3.39694,6.60393)
+ (3.40502,6.57805)(3.41743,6.55306)(3.43432,6.52905)
+ (3.45581,6.50614)(3.48202,6.48442)(3.51304,6.464)(3.54893,6.44498)
+ (3.58974,6.42744)(3.63549,6.41148)(3.68616,6.39719)
+ (3.74171,6.38464)(3.80208,6.37389)(3.86717,6.36501)
+ (3.93685,6.35806)(4.01096,6.35306)(4.08932,6.35005)
+ (4.17173,6.34904)(4.25793,6.35005)(4.34769,6.35306)
+%%
+\path(3.25551,6.80006)(3.24787,6.76939)(3.24391,6.73891)
+ (3.24387,6.70872)(3.24794,6.6789)(3.25635,6.64955)(3.26928,6.62077)
+ (3.28694,6.59267)(3.3095,6.56536)(3.33712,6.53894)(3.36994,6.51354)
+ (3.40808,6.48927)(3.45165,6.46623)(3.5007,6.44454)(3.55529,6.42432)
+ (3.61541,6.40566)(3.68106,6.38866)(3.75217,6.37343)
+ (3.82865,6.36003)(3.91038,6.34856)(3.99719,6.33908)
+ (4.08889,6.33165)(4.18525,6.32631)(4.286,6.32309)(4.39086,6.32202)
+%%
+\path(3.75,6.25)(3.14565,5.94783)
+%%
+\path(3.19923,5.99202)(3.21941,6.00211)
+\path(3.18137,5.97729)(3.22173,5.99747)
+\path(3.16351,5.96256)(3.22405,5.99283)
+\path(3.14565,5.94783)(3.22637,5.98819)
+\path(3.16815,5.95328)(3.22869,5.98355)
+\path(3.19065,5.95872)(3.23101,5.9789)
+\path(3.21315,5.96417)(3.23333,5.97426)
+\path(3.22637,5.98819)(3.21709,6.00675)(3.14565,5.94783)
+ (3.23565,5.96962)(3.22637,5.98819)
+%%
+\path(3.75,6.25)(4.35435,5.94783)
+%%
+\path(4.28685,5.96417)(4.26667,5.97426)
+\path(4.30935,5.95872)(4.26899,5.9789)
+\path(4.33185,5.95328)(4.27131,5.98355)
+\path(4.35435,5.94783)(4.27363,5.98819)
+\path(4.33649,5.96256)(4.27595,5.99283)
+\path(4.31863,5.97729)(4.27827,5.99747)
+\path(4.30077,5.99202)(4.28059,6.00211)
+\path(4.27363,5.98819)(4.26435,5.96962)(4.35435,5.94783)
+ (4.28291,6.00675)(4.27363,5.98819)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(4.875,5.125)
+ (4.875,7.375)(2.625,7.375)(2.625,5.125)(4.875,5.125)
+%%
+\allinethickness{0.4pt}%
+\color{rgb_000000}%
+\path(3.75,2.95191)
+ (3.81752,3.02689)(3.87769,3.10015)(3.93077,3.17175)
+ (3.97698,3.24175)(4.01655,3.3102)(4.04971,3.37715)(4.07667,3.44266)
+ (4.09761,3.50676)(4.11274,3.5695)(4.12223,3.63093)(4.12626,3.69108)
+ (4.125,3.75)(4.11861,3.80772)(4.10725,3.86428)(4.09106,3.91971)
+ (4.07018,3.97405)(4.04476,4.02733)(4.01493,4.07958)
+ (3.98081,4.13082)(3.94252,4.1811)(3.90018,4.23043)(3.85391,4.27884)
+ (3.80382,4.32635)(3.75,4.373)
+%%
+\path(3.62348,3.04636)(3.69014,3.11055)(3.75,3.17364)
+ (3.80325,3.23566)(3.85004,3.29665)(3.89055,3.35662)(3.92492,3.4156)
+ (3.9533,3.47361)(3.97585,3.53068)(3.9927,3.58684)(4.00399,3.64209)
+ (4.00986,3.69647)(4.01042,3.75)(4.0058,3.80269)(3.99613,3.85457)
+ (3.98152,3.90564)(3.96208,3.95594)(3.93793,4.00548)
+ (3.90916,4.05428)(3.87589,4.10235)(3.8382,4.1497)(3.79621,4.19636)
+ (3.75,4.24234)(3.69967,4.28766)(3.64529,4.33232)
+%%
+\path(3.52707,3.13497)(3.59209,3.1895)(3.65084,3.24339)
+ (3.70344,3.29667)(3.75,3.34934)(3.79061,3.40141)(3.82538,3.45289)
+ (3.85441,3.5038)(3.87779,3.55414)(3.89561,3.60392)(3.90797,3.65315)
+ (3.91496,3.70184)(3.91667,3.75)(3.91317,3.79764)(3.90456,3.84476)
+ (3.89092,3.89138)(3.87233,3.93749)(3.84887,3.98312)
+ (3.82061,4.02827)(3.78763,4.07294)(3.75,4.11715)(3.7078,4.16089)
+ (3.6611,4.20419)(3.60997,4.24703)(3.55447,4.28944)
+%%
+\path(3.45806,3.21828)(3.52096,3.26413)(3.57809,3.30969)
+ (3.6295,3.35496)(3.67526,3.39995)(3.71541,3.44466)(3.75,3.4891)
+ (3.77909,3.53325)(3.80273,3.57714)(3.82096,3.62075)(3.83384,3.6641)
+ (3.84142,3.70718)(3.84375,3.75)(3.84087,3.79256)(3.83283,3.83486)
+ (3.81967,3.8769)(3.80146,3.91869)(3.77822,3.96024)(3.75,4.00153)
+ (3.71685,4.04257)(3.67882,4.08337)(3.63594,4.12393)
+ (3.58827,4.16425)(3.53583,4.20433)(3.47868,4.24417)
+%%
+\path(3.41407,3.29673)(3.47461,3.33478)(3.52983,3.37277)
+ (3.57974,3.41071)(3.62435,3.44861)(3.66367,3.48645)
+ (3.69771,3.52425)(3.72649,3.56199)(3.75,3.59969)(3.76826,3.63734)
+ (3.78129,3.67494)(3.78909,3.7125)(3.79167,3.75)(3.78904,3.78746)
+ (3.78121,3.82486)(3.76819,3.86222)(3.75,3.89953)(3.72664,3.9368)
+ (3.69812,3.97401)(3.66445,4.01118)(3.62564,4.0483)(3.58171,4.08537)
+ (3.53265,4.1224)(3.47849,4.15938)(3.41923,4.19631)
+%%
+\path(3.39296,3.37075)(3.4511,3.40176)(3.50433,3.43287)
+ (3.55261,3.46409)(3.59592,3.49541)(3.63424,3.52685)
+ (3.66754,3.55839)(3.69579,3.59005)(3.71897,3.62182)
+ (3.73705,3.65369)(3.75,3.68568)(3.7578,3.71779)(3.76042,3.75)
+ (3.75783,3.78233)(3.75,3.81477)(3.73691,3.84733)(3.71853,3.88)
+ (3.69483,3.91279)(3.66578,3.9457)(3.63135,3.97872)(3.59152,4.01186)
+ (3.54625,4.04512)(3.49552,4.0785)(3.43929,4.112)(3.37755,4.14562)
+%%
+\path(3.39286,3.44071)(3.44871,3.46535)(3.5,3.49019)
+ (3.54669,3.51523)(3.58871,3.54048)(3.62601,3.56593)
+ (3.65854,3.59158)(3.68622,3.61745)(3.70902,3.64352)
+ (3.72685,3.66981)(3.73967,3.69632)(3.74741,3.72305)(3.75,3.75)
+ (3.74738,3.77718)(3.7395,3.80458)(3.72627,3.83222)(3.70763,3.86009)
+ (3.68351,3.8882)(3.65385,3.91654)(3.61856,3.94513)(3.57759,3.97397)
+ (3.53084,4.00306)(3.47826,4.0324)(3.41976,4.062)(3.35526,4.09185)
+%%
+\path(3.41207,3.50691)(3.46585,3.5258)(3.51542,3.54493)
+ (3.56068,3.56429)(3.60155,3.58389)(3.63797,3.60374)
+ (3.66983,3.62385)(3.69705,3.6442)(3.71955,3.66482)(3.73723,3.6857)
+ (3.75,3.70686)(3.75776,3.72829)(3.76042,3.75)(3.75786,3.772)
+ (3.75,3.79429)(3.73672,3.81688)(3.71791,3.83978)(3.69345,3.86299)
+ (3.66325,3.88651)(3.62716,3.91036)(3.58508,3.93454)
+ (3.53687,3.95906)(3.48241,3.98392)(3.42157,4.00914)(3.3542,4.03471)
+%%
+\path(3.44909,3.56967)(3.50114,3.58335)(3.54927,3.59725)
+ (3.59338,3.61138)(3.63338,3.62575)(3.66914,3.64036)
+ (3.70058,3.65523)(3.72757,3.67034)(3.75,3.68572)(3.76775,3.70137)
+ (3.7807,3.71729)(3.78871,3.7335)(3.79167,3.75)(3.78942,3.7668)
+ (3.78182,3.7839)(3.76873,3.80132)(3.75,3.81907)(3.72546,3.83715)
+ (3.69495,3.85557)(3.6583,3.87434)(3.61533,3.89348)(3.56585,3.91299)
+ (3.50967,3.93289)(3.4466,3.95318)(3.37642,3.97388)
+%%
+\path(3.50255,3.62924)(3.55328,3.63818)(3.60037,3.64731)
+ (3.6437,3.65662)(3.68317,3.66613)(3.71864,3.67584)(3.75,3.68576)
+ (3.7771,3.69589)(3.79982,3.70624)(3.81799,3.71682)(3.83148,3.72763)
+ (3.84012,3.73869)(3.84375,3.75)(3.8422,3.76157)(3.83527,3.77341)
+ (3.8228,3.78553)(3.80457,3.79794)(3.78037,3.81064)(3.75,3.82366)
+ (3.71321,3.837)(3.66978,3.85067)(3.61944,3.8647)(3.56192,3.87908)
+ (3.49696,3.89383)(3.42425,3.90898)
+%%
+\path(3.57125,3.68585)(3.62111,3.6905)(3.66761,3.69525)
+ (3.71062,3.70012)(3.75,3.70511)(3.78562,3.71023)(3.81734,3.71548)
+ (3.84501,3.72086)(3.86847,3.72638)(3.88754,3.73205)
+ (3.90206,3.73787)(3.91183,3.74385)(3.91667,3.75)(3.91636,3.75632)
+ (3.91068,3.76281)(3.89941,3.7695)(3.8823,3.77637)(3.85908,3.78346)
+ (3.82949,3.79075)(3.79324,3.79827)(3.75,3.80602)(3.69946,3.81401)
+ (3.64125,3.82226)(3.57502,3.83078)(3.50036,3.83958)
+%%
+\path(3.65406,3.73974)(3.70358,3.74046)(3.75,3.74121)
+ (3.79318,3.74198)(3.833,3.74276)(3.86929,3.74358)(3.90191,3.74441)
+ (3.93068,3.74527)(3.95544,3.74616)(3.976,3.74708)(3.99216,3.74802)
+ (4.0037,3.74899)(4.01042,3.75)(4.01206,3.75104)(4.00837,3.75211)
+ (3.99908,3.75322)(3.9839,3.75437)(3.96252,3.75556)(3.9346,3.75679)
+ (3.89979,3.75807)(3.8577,3.75939)(3.80792,3.76076)(3.75,3.76219)
+ (3.68346,3.76367)(3.60778,3.76522)
+%%
+\path(3.75,3.79107)(3.79972,3.78823)(3.84661,3.7853)
+ (3.89054,3.78228)(3.93135,3.77916)(3.9689,3.77593)(4.00301,3.7726)
+ (4.03353,3.76915)(4.06025,3.76559)(4.08298,3.7619)(4.10151,3.75807)
+ (4.1156,3.75411)(4.125,3.75)(4.12945,3.74573)(4.12867,3.7413)
+ (4.12234,3.7367)(4.11013,3.73191)(4.09167,3.72692)(4.06658,3.72172)
+ (4.03443,3.71631)(3.99475,3.71065)(3.94705,3.70474)
+ (3.89077,3.69857)(3.8253,3.6921)(3.75,3.68532)
+%%
+\path(3.75,2.95191)(3.68279,2.9999)(3.62348,3.04636)
+ (3.57169,3.09136)(3.52707,3.13497)(3.4893,3.17726)(3.45806,3.21828)
+ (3.43308,3.25809)(3.41407,3.29673)(3.40078,3.33428)
+ (3.39296,3.37075)(3.39039,3.40622)(3.39286,3.44071)
+ (3.40015,3.47426)(3.41207,3.50691)(3.42844,3.5387)(3.44909,3.56967)
+ (3.47384,3.59984)(3.50255,3.62924)(3.53507,3.6579)(3.57125,3.68585)
+ (3.61095,3.71312)(3.65406,3.73974)(3.70045,3.76571)(3.75,3.79107)
+%%
+\path(3.87769,3.10015)(3.81014,3.13738)(3.75,3.17364)
+ (3.69699,3.20897)(3.65084,3.24339)(3.61129,3.27696)
+ (3.57809,3.30969)(3.55101,3.34161)(3.52983,3.37277)
+ (3.51434,3.40318)(3.50433,3.43287)(3.49961,3.46187)(3.5,3.49019)
+ (3.50533,3.51787)(3.51542,3.54493)(3.53012,3.57138)
+ (3.54927,3.59725)(3.57273,3.62255)(3.60037,3.64731)
+ (3.63203,3.67153)(3.66761,3.69525)(3.70697,3.71847)(3.75,3.74121)
+ (3.79658,3.76348)(3.84661,3.7853)
+%%
+\path(3.97698,3.24175)(3.91004,3.26948)(3.85004,3.29665)
+ (3.79676,3.32326)(3.75,3.34934)(3.70956,3.3749)(3.67526,3.39995)
+ (3.64691,3.42452)(3.62435,3.44861)(3.60741,3.47223)
+ (3.59592,3.49541)(3.58974,3.51816)(3.58871,3.54048)
+ (3.59269,3.56239)(3.60155,3.58389)(3.61516,3.60501)
+ (3.63338,3.62575)(3.65609,3.64612)(3.68317,3.66613)
+ (3.71451,3.68579)(3.75,3.70511)(3.78953,3.7241)(3.833,3.74276)
+ (3.8803,3.76111)(3.93135,3.77916)
+%%
+\path(4.04971,3.37715)(3.98409,3.39652)(3.92492,3.4156)
+ (3.87206,3.43439)(3.82538,3.45289)(3.78474,3.47113)(3.75,3.4891)
+ (3.72103,3.5068)(3.69771,3.52425)(3.67992,3.54144)(3.66754,3.55839)
+ (3.66045,3.57511)(3.65854,3.59158)(3.6617,3.60783)(3.66983,3.62385)
+ (3.68282,3.63964)(3.70058,3.65523)(3.723,3.6706)(3.75,3.68576)
+ (3.78148,3.70072)(3.81734,3.71548)(3.85752,3.73004)
+ (3.90191,3.74441)(3.95043,3.7586)(4.00301,3.7726)
+%%
+\path(4.09761,3.50676)(4.03372,3.51878)(3.97585,3.53068)
+ (3.9239,3.54247)(3.87779,3.55414)(3.83742,3.56569)(3.80273,3.57714)
+ (3.77361,3.58847)(3.75,3.59969)(3.73181,3.61081)(3.71897,3.62182)
+ (3.7114,3.63272)(3.70902,3.64352)(3.71176,3.65422)(3.71955,3.66482)
+ (3.73232,3.67532)(3.75,3.68572)(3.77252,3.69603)(3.79982,3.70624)
+ (3.83182,3.71636)(3.86847,3.72638)(3.90969,3.73632)
+ (3.95544,3.74616)(4.00565,3.75592)(4.06025,3.76559)
+%%
+\path(4.12223,3.63093)(4.06031,3.63652)(4.00399,3.64209)
+ (3.95323,3.64764)(3.90797,3.65315)(3.86819,3.65864)(3.83384,3.6641)
+ (3.80489,3.66953)(3.78129,3.67494)(3.76301,3.68033)(3.75,3.68568)
+ (3.74223,3.69101)(3.73967,3.69632)(3.74227,3.7016)(3.75,3.70686)
+ (3.76282,3.71209)(3.7807,3.71729)(3.8036,3.72248)(3.83148,3.72763)
+ (3.86431,3.73277)(3.90206,3.73787)(3.94468,3.74296)
+ (3.99216,3.74802)(4.04444,3.75306)(4.10151,3.75807)
+%%
+\path(4.125,3.75)(4.0651,3.75)(4.01042,3.75)(3.96094,3.75)
+ (3.91667,3.75)(3.8776,3.75)(3.84375,3.75)(3.8151,3.75)
+ (3.79167,3.75)(3.77344,3.75)(3.76042,3.75)(3.7526,3.75)(3.75,3.75)
+ (3.7526,3.75)(3.76042,3.75)(3.77344,3.75)(3.79167,3.75)
+ (3.8151,3.75)(3.84375,3.75)(3.8776,3.75)(3.91667,3.75)
+ (3.96094,3.75)(4.01042,3.75)(4.0651,3.75)(4.125,3.75)
+%%
+\path(4.10725,3.86428)(4.04926,3.85943)(3.99613,3.85457)
+ (3.94789,3.84967)(3.90456,3.84476)(3.8662,3.83982)(3.83283,3.83486)
+ (3.80449,3.82987)(3.78121,3.82486)(3.76304,3.81983)(3.75,3.81477)
+ (3.74214,3.80969)(3.7395,3.80458)(3.7421,3.79945)(3.75,3.79429)
+ (3.76323,3.78911)(3.78182,3.7839)(3.80582,3.77867)(3.83527,3.77341)
+ (3.87021,3.76812)(3.91068,3.76281)(3.95672,3.75748)
+ (4.00837,3.75211)(4.06567,3.74672)(4.12867,3.7413)
+%%
+\path(4.07018,3.97405)(4.01387,3.96504)(3.96208,3.95594)
+ (3.91488,3.94676)(3.87233,3.93749)(3.8345,3.92814)(3.80146,3.91869)
+ (3.77327,3.90916)(3.75,3.89953)(3.73173,3.88982)(3.71853,3.88)
+ (3.71047,3.87009)(3.70763,3.86009)(3.71008,3.84998)
+ (3.71791,3.83978)(3.73119,3.82947)(3.75,3.81907)(3.77443,3.80855)
+ (3.80457,3.79794)(3.84049,3.78721)(3.8823,3.77637)(3.93007,3.76543)
+ (3.9839,3.75437)(4.04389,3.7432)(4.11013,3.73191)
+%%
+\path(4.01493,4.07958)(3.95994,4.06701)(3.90916,4.05428)
+ (3.86269,4.04136)(3.82061,4.02827)(3.78301,4.01499)(3.75,4.00153)
+ (3.72167,3.98787)(3.69812,3.97401)(3.67945,3.95996)(3.66578,3.9457)
+ (3.6572,3.93123)(3.65385,3.91654)(3.65582,3.90164)(3.66325,3.88651)
+ (3.67625,3.87116)(3.69495,3.85557)(3.71949,3.83974)(3.75,3.82366)
+ (3.78662,3.80733)(3.82949,3.79075)(3.87877,3.77391)(3.9346,3.75679)
+ (3.99715,3.7394)(4.06658,3.72172)
+%%
+\path(3.94252,4.1811)(3.8884,4.16554)(3.8382,4.1497)
+ (3.79203,4.13357)(3.75,4.11715)(3.71222,4.10042)(3.67882,4.08337)
+ (3.64992,4.066)(3.62564,4.0483)(3.60613,4.03026)(3.59152,4.01186)
+ (3.58195,3.9931)(3.57759,3.97397)(3.57857,3.95446)(3.58508,3.93454)
+ (3.59727,3.91422)(3.61533,3.89348)(3.63943,3.8723)(3.66978,3.85067)
+ (3.70656,3.82859)(3.75,3.80602)(3.8003,3.78296)(3.8577,3.75939)
+ (3.92244,3.73529)(3.99475,3.71065)
+%%
+\path(3.85391,4.27884)(3.80014,4.26079)(3.75,4.24234)
+ (3.70361,4.22348)(3.6611,4.20419)(3.62261,4.18445)(3.58827,4.16425)
+ (3.55823,4.14357)(3.53265,4.1224)(3.51169,4.10072)(3.49552,4.0785)
+ (3.48431,4.05574)(3.47826,4.0324)(3.47756,4.00847)(3.48241,3.98392)
+ (3.49304,3.95874)(3.50967,3.93289)(3.53255,3.90634)
+ (3.56192,3.87908)(3.59806,3.85106)(3.64125,3.82226)
+ (3.69179,3.79265)(3.75,3.76219)(3.81621,3.73084)(3.89077,3.69857)
+%%
+\path(3.75,4.373)(3.69598,4.35293)(3.64529,4.33232)
+ (3.59808,4.31117)(3.55447,4.28944)(3.51462,4.26712)
+ (3.47868,4.24417)(3.44683,4.22058)(3.41923,4.19631)
+ (3.39607,4.17133)(3.37755,4.14562)(3.36387,4.11914)
+ (3.35526,4.09185)(3.35196,4.06372)(3.3542,4.03471)(3.36226,4.00478)
+ (3.37642,3.97388)(3.39698,3.94196)(3.42425,3.90898)
+ (3.45859,3.87487)(3.50036,3.83958)(3.54995,3.80305)
+ (3.60778,3.76522)(3.6743,3.726)(3.75,3.68532)
+%%
+\path(3.75,3.75)(3,3.75)
+%%
+\path(3.08562,3.76557)(3.11416,3.76557)
+\path(3.05708,3.76038)(3.11416,3.76038)
+\path(3.02854,3.75519)(3.11416,3.75519)
+\path(3,3.75)(3.11416,3.75)
+\path(3.02854,3.74481)(3.11416,3.74481)
+\path(3.05708,3.73962)(3.11416,3.73962)
+\path(3.08562,3.73443)(3.11416,3.73443)
+\path(3.11416,3.75)(3.11416,3.77076)(3,3.75)(3.11416,3.72924)(3.11416,3.75)
+%%
+\path(3.75,3.75)(3.75,3.29644)
+%%
+\path(3.73443,3.33925)(3.73443,3.35352)
+\path(3.73962,3.32498)(3.73962,3.35352)
+\path(3.74481,3.31071)(3.74481,3.35352)
+\path(3.75,3.29644)(3.75,3.35352)
+\path(3.75519,3.31071)(3.75519,3.35352)
+\path(3.76038,3.32498)(3.76038,3.35352)
+\path(3.76557,3.33925)(3.76557,3.35352)
+\path(3.75,3.35352)(3.72924,3.35352)(3.75,3.29644)(3.77076,3.35352)(3.75,3.35352)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(4.875,2.625)
+ (4.875,4.875)(2.625,4.875)(2.625,2.625)(4.875,2.625)
+%%
+\allinethickness{0.4pt}%
+\color{rgb_000000}%
+\path(3.17823,0.61398)
+ (3.2696,0.641697)(3.35808,0.672175)(3.44338,0.705355)
+ (3.52526,0.741164)(3.60346,0.779511)(3.67777,0.820294)
+ (3.748,0.863394)(3.81395,0.908683)(3.87549,0.956019)
+ (3.93248,1.00525)(3.98483,1.05622)(4.03246,1.10877)
+ (4.07534,1.16272)(4.11344,1.2179)(4.14676,1.27413)(4.17536,1.33125)
+ (4.19927,1.38908)(4.21858,1.44744)(4.23339,1.50617)
+ (4.24381,1.56512)(4.24998,1.62413)(4.25204,1.68304)
+ (4.25015,1.74173)(4.24449,1.80006)
+%%
+\path(3.20899,0.72735)(3.28831,0.749673)(3.36501,0.774599)
+ (3.43887,0.802101)(3.50964,0.832134)(3.57711,0.86464)
+ (3.64108,0.899549)(3.70136,0.936774)(3.75778,0.976219)
+ (3.8102,1.01777)(3.85849,1.06132)(3.90256,1.10672)(3.94232,1.15384)
+ (3.97773,1.20253)(4.00875,1.25265)(4.03538,1.30404)
+ (4.05764,1.35653)(4.07557,1.40997)(4.08922,1.46419)
+ (4.09868,1.51905)(4.10405,1.57438)(4.10544,1.63004)
+ (4.10297,1.68587)(4.0968,1.74173)(4.08706,1.79749)
+%%
+\path(3.25032,0.823133)(3.31889,0.840786)(3.38504,0.860893)
+ (3.44855,0.883449)(3.50922,0.908436)(3.56683,0.935822)
+ (3.62121,0.965564)(3.67218,0.997604)(3.7196,1.03187)
+ (3.76331,1.06829)(3.8032,1.10676)(3.83917,1.14717)(3.87115,1.18943)
+ (3.89907,1.23339)(3.92291,1.27893)(3.94265,1.32592)
+ (3.95829,1.37421)(3.96988,1.42366)(3.97745,1.47411)
+ (3.98107,1.52542)(3.98083,1.57745)(3.97684,1.63004)(3.9692,1.68304)
+ (3.95805,1.73632)(3.94353,1.78975)
+%%
+\path(3.30152,0.904095)(3.36048,0.917621)(3.41712,0.933458)
+ (3.47125,0.951621)(3.52267,0.972112)(3.5712,0.994925)
+ (3.61667,1.02004)(3.65892,1.04742)(3.6978,1.07702)(3.73319,1.10879)
+ (3.76496,1.14265)(3.79303,1.17853)(3.81732,1.21634)
+ (3.83777,1.25597)(3.85434,1.29732)(3.86702,1.34026)
+ (3.87582,1.38467)(3.88074,1.43043)(3.88184,1.47739)
+ (3.87918,1.52542)(3.87283,1.57438)(3.8629,1.62413)(3.84948,1.67451)
+ (3.83271,1.72541)(3.81271,1.77667)
+%%
+\path(3.36219,0.972363)(3.41251,0.982168)(3.46056,0.994146)
+ (3.50614,1.00833)(3.54909,1.02474)(3.58923,1.04339)(3.6264,1.06427)
+ (3.66046,1.08739)(3.69125,1.1127)(3.71867,1.14019)(3.74261,1.16981)
+ (3.76296,1.20149)(3.77966,1.23517)(3.79266,1.27077)(3.8019,1.3082)
+ (3.80739,1.34736)(3.80911,1.38814)(3.80708,1.43043)
+ (3.80136,1.47411)(3.79199,1.51905)(3.77905,1.56512)
+ (3.76263,1.61219)(3.74284,1.66012)(3.71979,1.70877)(3.69363,1.75801)
+%%
+\path(3.43214,1.02959)(3.4747,1.03597)(3.51496,1.04439)
+ (3.55275,1.0549)(3.58792,1.06753)(3.6203,1.08231)(3.64973,1.09927)
+ (3.67607,1.1184)(3.6992,1.13971)(3.71899,1.16319)(3.73534,1.18881)
+ (3.74816,1.21653)(3.75738,1.24631)(3.76294,1.27809)(3.7648,1.3118)
+ (3.76296,1.34736)(3.7574,1.38467)(3.74815,1.42366)(3.73525,1.46419)
+ (3.71875,1.50617)(3.69874,1.54948)(3.67529,1.59398)
+ (3.64852,1.63955)(3.61855,1.68606)(3.58552,1.73338)
+%%
+\path(3.51138,1.07706)(3.54694,1.08023)(3.58016,1.0853)
+ (3.61086,1.09235)(3.63888,1.10142)(3.66407,1.11255)
+ (3.68628,1.12577)(3.70537,1.14113)(3.72121,1.15862)
+ (3.73369,1.17827)(3.74271,1.20006)(3.74817,1.22398)(3.75,1.25)
+ (3.74815,1.27809)(3.74259,1.3082)(3.73328,1.34026)(3.72024,1.37421)
+ (3.70349,1.40997)(3.68306,1.44744)(3.65901,1.48653)
+ (3.63142,1.52713)(3.60039,1.56912)(3.56602,1.61239)
+ (3.52843,1.65681)(3.48778,1.70226)
+%%
+\path(3.60007,1.11578)(3.62936,1.11587)(3.65621,1.11774)
+ (3.68045,1.12147)(3.70192,1.1271)(3.72047,1.13471)(3.73595,1.14434)
+ (3.74823,1.15603)(3.75716,1.16982)(3.76264,1.18573)
+ (3.76456,1.20378)(3.76283,1.22398)(3.75738,1.24631)
+ (3.74815,1.27077)(3.73509,1.29732)(3.7182,1.32592)(3.69748,1.35653)
+ (3.67293,1.38908)(3.6446,1.42349)(3.61256,1.4597)(3.57688,1.49759)
+ (3.53766,1.53708)(3.49501,1.57805)(3.44908,1.62039)(3.40001,1.66397)
+%%
+\path(3.69855,1.14651)(3.72225,1.14361)(3.74337,1.14236)
+ (3.76176,1.14283)(3.77726,1.14511)(3.78969,1.14925)
+ (3.79892,1.15533)(3.8048,1.16341)(3.80719,1.17352)(3.80598,1.18573)
+ (3.80105,1.20006)(3.7923,1.21653)(3.77966,1.23517)(3.76307,1.25597)
+ (3.74248,1.27893)(3.71787,1.30404)(3.68923,1.33125)
+ (3.65659,1.36053)(3.61998,1.39183)(3.57947,1.42509)
+ (3.53514,1.46021)(3.48708,1.49713)(3.43543,1.53574)
+ (3.38033,1.57593)(3.32194,1.6176)
+%%
+\path(3.80729,1.16986)(3.82604,1.16398)(3.84208,1.15962)
+ (3.85522,1.15685)(3.86529,1.15577)(3.87214,1.15645)(3.8756,1.15897)
+ (3.87551,1.16341)(3.87174,1.16982)(3.86415,1.17827)
+ (3.85261,1.18881)(3.83704,1.20149)(3.81732,1.21634)(3.7934,1.23339)
+ (3.76522,1.25265)(3.73275,1.27413)(3.69598,1.29782)
+ (3.65492,1.32371)(3.60961,1.35175)(3.56011,1.3819)(3.50651,1.41411)
+ (3.4489,1.44831)(3.38744,1.48442)(3.32226,1.52235)(3.25354,1.56199)
+%%
+\path(3.92693,1.18624)(3.94139,1.17736)(3.95296,1.16985)
+ (3.96145,1.1638)(3.96668,1.1593)(3.96848,1.15645)(3.96666,1.15533)
+ (3.96105,1.15603)(3.95151,1.15862)(3.93788,1.16319)
+ (3.92002,1.16981)(3.89781,1.17853)(3.87115,1.18943)
+ (3.83994,1.20253)(3.80413,1.2179)(3.76366,1.23554)(3.71851,1.25549)
+ (3.66869,1.27773)(3.61423,1.30227)(3.55518,1.32909)
+ (3.49162,1.35815)(3.42367,1.38939)(3.35146,1.42277)
+ (3.27515,1.45821)(3.19494,1.49562)
+%%
+\path(4.05827,1.19595)(4.06911,1.18399)(4.07686,1.17324)
+ (4.08133,1.1638)(4.08232,1.15577)(4.07962,1.14925)(4.07305,1.14434)
+ (4.06242,1.14113)(4.04754,1.13971)(4.02825,1.14019)
+ (4.00437,1.14265)(3.97577,1.14717)(3.94232,1.15384)(3.9039,1.16272)
+ (3.86043,1.17387)(3.81183,1.18736)(3.75806,1.20321)
+ (3.69912,1.22147)(3.63501,1.24216)(3.56578,1.26527)(3.4915,1.29081)
+ (3.41229,1.31874)(3.32827,1.34904)(3.23963,1.38165)(3.14657,1.4165)
+%%
+\path(4.20232,1.19917)(4.21023,1.18399)(4.21485,1.16985)
+ (4.21597,1.15685)(4.21335,1.14511)(4.20679,1.13471)
+ (4.19606,1.12577)(4.18094,1.1184)(4.16122,1.1127)(4.1367,1.10879)
+ (4.10719,1.10676)(4.07249,1.10672)(4.03246,1.10877)(3.98694,1.113)
+ (3.93582,1.11951)(3.87898,1.12838)(3.81635,1.13966)(3.7479,1.15344)
+ (3.67361,1.16975)(3.59351,1.18864)(3.50765,1.21013)
+ (3.41613,1.23423)(3.31908,1.26093)(3.21668,1.2902)(3.10914,1.32202)
+%%
+\path(3.17823,0.61398)(3.19224,0.673067)(3.20899,0.72735)
+ (3.22838,0.77725)(3.25032,0.823133)(3.27472,0.865321)
+ (3.30152,0.904095)(3.33069,0.939703)(3.36219,0.972363)
+ (3.39601,1.00227)(3.43214,1.02959)(3.47059,1.05448)
+ (3.51138,1.07706)(3.55453,1.09746)(3.60007,1.11578)(3.64806,1.1321)
+ (3.69855,1.14651)(3.7516,1.15908)(3.80729,1.16986)(3.8657,1.1789)
+ (3.92693,1.18624)(3.99108,1.19191)(4.05827,1.19595)
+ (4.12864,1.19837)(4.20232,1.19917)
+%%
+\path(3.35808,0.672175)(3.35983,0.72558)(3.36501,0.774599)
+ (3.37347,0.819598)(3.38504,0.860893)(3.39963,0.898765)
+ (3.41712,0.933458)(3.43745,0.965188)(3.46056,0.994146)
+ (3.4864,1.0205)(3.51496,1.04439)(3.54621,1.06595)(3.58016,1.0853)
+ (3.61682,1.10254)(3.65621,1.11774)(3.69838,1.13099)
+ (3.74337,1.14236)(3.79125,1.15188)(3.84208,1.15962)(3.89595,1.1656)
+ (3.95296,1.16985)(4.01323,1.17239)(4.07686,1.17324)
+ (4.14402,1.17239)(4.21485,1.16985)
+%%
+\path(3.52526,0.741164)(3.51545,0.788632)(3.50964,0.832134)
+ (3.50762,0.871978)(3.50922,0.908436)(3.51427,0.941744)
+ (3.52267,0.972112)(3.5343,0.999723)(3.54909,1.02474)
+ (3.56698,1.0473)(3.58792,1.06753)(3.61189,1.08554)(3.63888,1.10142)
+ (3.66888,1.11525)(3.70192,1.1271)(3.73803,1.13704)(3.77726,1.14511)
+ (3.81965,1.15134)(3.86529,1.15577)(3.91427,1.15842)(3.96668,1.1593)
+ (4.02266,1.15842)(4.08232,1.15577)(4.14583,1.15134)(4.21335,1.14511)
+%%
+\path(3.67777,0.820294)(3.65721,0.861701)(3.64108,0.899549)
+ (3.62915,0.934095)(3.62121,0.965564)(3.6171,0.994154)
+ (3.61667,1.02004)(3.6198,1.04337)(3.6264,1.06427)(3.6364,1.08287)
+ (3.64973,1.09927)(3.66636,1.11354)(3.68628,1.12577)
+ (3.70947,1.13602)(3.73595,1.14434)(3.76576,1.15076)
+ (3.79892,1.15533)(3.83551,1.15806)(3.8756,1.15897)(3.91928,1.15806)
+ (3.96666,1.15533)(4.01786,1.15076)(4.07305,1.14434)
+ (4.13239,1.13602)(4.19606,1.12577)
+%%
+\path(3.81395,0.908683)(3.7835,0.944037)(3.75778,0.976219)
+ (3.73655,1.00544)(3.7196,1.03187)(3.70673,1.05569)(3.6978,1.07702)
+ (3.69268,1.09599)(3.69125,1.1127)(3.69345,1.12725)(3.6992,1.13971)
+ (3.70846,1.15015)(3.72121,1.15862)(3.73744,1.16517)
+ (3.75716,1.16982)(3.7804,1.1726)(3.80719,1.17352)(3.83761,1.1726)
+ (3.87174,1.16982)(3.90966,1.16517)(3.95151,1.15862)
+ (3.99741,1.15015)(4.04754,1.13971)(4.10207,1.12725)(4.16122,1.1127)
+%%
+\path(3.93248,1.00525)(3.89302,1.03469)(3.85849,1.06132)
+ (3.82862,1.08529)(3.8032,1.10676)(3.78203,1.12584)(3.76496,1.14265)
+ (3.75186,1.15728)(3.74261,1.16981)(3.73712,1.1803)(3.73534,1.18881)
+ (3.73721,1.19538)(3.74271,1.20006)(3.75182,1.20285)
+ (3.76456,1.20378)(3.78095,1.20285)(3.80105,1.20006)
+ (3.82491,1.19538)(3.85261,1.18881)(3.88428,1.1803)(3.92002,1.16981)
+ (3.95999,1.15728)(4.00437,1.14265)(4.05336,1.12584)(4.10719,1.10676)
+%%
+\path(4.03246,1.10877)(3.9849,1.13255)(3.94232,1.15384)
+ (3.90448,1.17276)(3.87115,1.18943)(3.84215,1.20393)
+ (3.81732,1.21634)(3.79653,1.22673)(3.77966,1.23517)
+ (3.76664,1.24168)(3.75738,1.24631)(3.75184,1.24908)(3.75,1.25)
+ (3.75184,1.24908)(3.75738,1.24631)(3.76664,1.24168)
+ (3.77966,1.23517)(3.79653,1.22673)(3.81732,1.21634)
+ (3.84215,1.20393)(3.87115,1.18943)(3.90448,1.17276)
+ (3.94232,1.15384)(3.9849,1.13255)(4.03246,1.10877)
+%%
+\path(4.11344,1.2179)(4.05862,1.23638)(4.00875,1.25265)
+ (3.96358,1.26681)(3.92291,1.27893)(3.88655,1.28908)
+ (3.85434,1.29732)(3.82617,1.30368)(3.8019,1.3082)(3.78147,1.3109)
+ (3.7648,1.3118)(3.75185,1.3109)(3.74259,1.3082)(3.737,1.30368)
+ (3.73509,1.29732)(3.73691,1.28908)(3.74248,1.27893)
+ (3.75189,1.26681)(3.76522,1.25265)(3.78259,1.23638)(3.80413,1.2179)
+ (3.83001,1.1971)(3.86043,1.17387)(3.89561,1.14806)(3.93582,1.11951)
+%%
+\path(4.17536,1.33125)(4.1141,1.34487)(4.05764,1.35653)
+ (4.00578,1.36629)(3.95829,1.37421)(3.91502,1.38033)
+ (3.87582,1.38467)(3.84055,1.38727)(3.80911,1.38814)
+ (3.78141,1.38727)(3.7574,1.38467)(3.73702,1.38033)(3.72024,1.37421)
+ (3.70706,1.36629)(3.69748,1.35653)(3.69152,1.34487)
+ (3.68923,1.33125)(3.69069,1.3156)(3.69598,1.29782)(3.70521,1.27783)
+ (3.71851,1.25549)(3.73607,1.23067)(3.75806,1.20321)
+ (3.78473,1.17295)(3.81635,1.13966)
+%%
+\path(4.21858,1.44744)(4.1516,1.45669)(4.08922,1.46419)
+ (4.03123,1.46999)(3.97745,1.47411)(3.9277,1.47657)(3.88184,1.47739)
+ (3.83976,1.47657)(3.80136,1.47411)(3.76654,1.46999)
+ (3.73525,1.46419)(3.70743,1.45669)(3.68306,1.44744)
+ (3.66212,1.43639)(3.6446,1.42349)(3.63055,1.40867)(3.61998,1.39183)
+ (3.61298,1.3729)(3.60961,1.35175)(3.60998,1.32826)(3.61423,1.30227)
+ (3.62251,1.27364)(3.63501,1.24216)(3.65195,1.20761)(3.67361,1.16975)
+%%
+\path(4.24381,1.56512)(4.17177,1.57053)(4.10405,1.57438)
+ (4.04046,1.57668)(3.98083,1.57745)(3.925,1.57668)(3.87283,1.57438)
+ (3.82422,1.57053)(3.77905,1.56512)(3.73724,1.55811)
+ (3.69874,1.54948)(3.66348,1.53917)(3.63142,1.52713)
+ (3.60256,1.51329)(3.57688,1.49759)(3.5544,1.47993)(3.53514,1.46021)
+ (3.51915,1.43832)(3.50651,1.41411)(3.49729,1.38745)
+ (3.49162,1.35815)(3.48963,1.32601)(3.4915,1.29081)(3.49742,1.25228)(3.50765,1.21013)
+%%
+\path(4.25204,1.68304)(4.1755,1.68516)(4.10297,1.68587)
+ (4.03426,1.68516)(3.9692,1.68304)(3.90765,1.6795)(3.84948,1.67451)
+ (3.79458,1.66806)(3.74284,1.66012)(3.69417,1.65063)
+ (3.64852,1.63955)(3.60582,1.62683)(3.56602,1.61239)
+ (3.52909,1.59616)(3.49501,1.57805)(3.46379,1.55795)
+ (3.43543,1.53574)(3.40997,1.51128)(3.38744,1.48442)
+ (3.36791,1.45499)(3.35146,1.42277)(3.3382,1.38755)(3.32827,1.34904)
+ (3.32183,1.30695)(3.31908,1.26093)
+%%
+\path(4.24449,1.80006)(4.16396,1.79942)(4.08706,1.79749)
+ (4.01364,1.79428)(3.94353,1.78975)(3.87659,1.78389)
+ (3.81271,1.77667)(3.75175,1.76806)(3.69363,1.75801)
+ (3.63824,1.74647)(3.58552,1.73338)(3.53538,1.71867)
+ (3.48778,1.70226)(3.44267,1.68406)(3.40001,1.66397)
+ (3.35977,1.64186)(3.32194,1.6176)(3.28653,1.59104)(3.25354,1.56199)
+ (3.22299,1.53026)(3.19494,1.49562)(3.16944,1.4578)(3.14657,1.4165)
+ (3.12642,1.37138)(3.10914,1.32202)
+%%
+\path(3.75,1.25)(3.27753,1.48623)
+%%
+\path(3.34504,1.46989)(3.36522,1.4598)
+\path(3.32254,1.47533)(3.3629,1.45515)
+\path(3.30004,1.48078)(3.36058,1.45051)
+\path(3.27753,1.48623)(3.35825,1.44587)
+\path(3.29539,1.4715)(3.35593,1.44123)
+\path(3.31325,1.45677)(3.35361,1.43659)
+\path(3.33111,1.44204)(3.35129,1.43195)
+\path(3.35825,1.44587)(3.36754,1.46444)(3.27753,1.48623)
+ (3.34897,1.42731)(3.35825,1.44587)
+%%
+\path(3.75,1.25)(3.14565,0.947826)
+%%
+\path(3.19923,0.99202)(3.21941,1.00211)
+\path(3.18137,0.977289)(3.22173,0.997469)
+\path(3.16351,0.962557)(3.22405,0.992827)
+\path(3.14565,0.947826)(3.22637,0.988186)
+\path(3.16815,0.953275)(3.22869,0.983545)
+\path(3.19065,0.958724)(3.23101,0.978904)
+\path(3.21315,0.964173)(3.23333,0.974263)
+\path(3.22637,0.988186)(3.21709,1.00675)(3.14565,0.947826)
+ (3.23565,0.969622)(3.22637,0.988186)
+%%
+\allinethickness{1pt}%
+\color{rgb_980000}%
+\path(4.875,0.125)
+ (4.875,2.375)(2.625,2.375)(2.625,0.125)(4.875,0.125)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/layout.xp b/graphics/epix/doc/layout.xp
new file mode 100644
index 0000000000..cd3e201011
--- /dev/null
+++ b/graphics/epix/doc/layout.xp
@@ -0,0 +1,36 @@
+/* -*-ePiX-*- */
+/* layout.xp -- June 27, 2007 */
+#include "epix.h"
+using namespace ePiX;
+
+const double a(sqrt(3));
+P f(double u, double v)
+{
+ return P((u-v)*(u+v), 2*u*v, u); //u*(u-a*v)*(u+a*v));
+}
+
+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");
+ 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);
+ inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j));
+ }
+
+ end();
+}
+
diff --git a/graphics/epix/doc/manual.pdf b/graphics/epix/doc/manual.pdf
new file mode 100644
index 0000000000..bd8fc76619
--- /dev/null
+++ b/graphics/epix/doc/manual.pdf
Binary files differ
diff --git a/graphics/epix/doc/manual.tex b/graphics/epix/doc/manual.tex
new file mode 100644
index 0000000000..71aa59aa97
--- /dev/null
+++ b/graphics/epix/doc/manual.tex
@@ -0,0 +1,5030 @@
+%% Version 1.2.0
+\documentclass[12pt]{book}
+\usepackage{amsmath,latexsym,epic,eepic,pstricks,xcolor,comment}
+\usepackage[dvips,hyperref]{hyperref}
+
+\usepackage{makeidx}
+\makeindex
+
+\renewcommand{\thefigure}{\arabic{chapter}.\arabic{figure}}
+
+\newcommand{\code}[1]{\texttt{#1}}
+\newcommand{\filename}[1]{\texttt{#1}}
+\newcommand{\Key}[1]{\texttt{#1}}
+\newcommand{\URL}[1]{\texttt{#1}}
+
+%% \setlength{\topmargin}{0.5in}
+\newcommand{\ePiX}{\code{ePiX}}
+\newcommand{\ext}{\code{ePiX\_ext}}
+\newcommand{\epix}{\code{epix}}
+\newcommand{\eepic}{\code{eepic}}
+\newcommand{\C}{\code{C}}
+\newcommand{\CXX}{\code{C++}}
+\newcommand{\pyepix}{\code{Pyepix}}
+
+\DeclareMathOperator{\clip}{clip}
+
+\newcommand{\Header}[1]{\smallskip\noindent\texttt{#1}%
+ \index{Header file!{#1}@\texttt{#1}}\quad}
+
+%% Substitution commands easily removable by sed for texinfo:
+%% Remove recalcitrant chunks,
+\newcommand{\texicomment}{}
+\newcommand{\texicommentend}{}
+
+%% mark simple math,
+\newcommand{\teximath}[1]{$#1$}
+%% make function index entries,
+\newcommand{\findex}[1]{}
+
+%% top-level division (first argument for texinfo node name)
+\newcommand{\texinfochapter}[2]{\chapter{#2}}
+\newcommand{\texinfoappendix}[2]{\chapter{#2}}
+
+%%\renewcommand{\subsection*}[1]{\subsection{#1}}
+
+\title{ \ePiX\ Tutorial and \\ Reference Manual}
+\author{Andrew D. Hwang \\
+ Department\ of Math and CS \\
+ College of the Holy Cross}
+\date{Version 1.2, September, 2007}
+
+\begin{document}
+
+\maketitle
+
+\tableofcontents
+
+\texinfochapter{1}{Introduction}
+
+\ePiX, a collection of batch utilities, creates mathematically
+accurate figures, plots, and animations containing \LaTeX\ typography.
+The input syntax is easy to learn, and the user interface resembles
+that of \LaTeX\ itself: You prepare a scene description in a text
+editor, then ``compile'' the input file into a picture. \LaTeX- and
+web-compatible output types include a \LaTeX\ picture-like environment
+written with \code{PSTricks}, \code{tikz}, or \code{eepic} macros;
+vector images (\code{eps}, \code{ps}, and~\code{pdf}); and bitmapped
+images and movies (\code{png}, \code{mng}, and~\code{gif}).
+
+\ePiX's strengths include:
+
+\begin{itemize}
+\item Quality of output: \ePiX\ creates 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.
+
+\item Ease of use: Figure objects and their attributes are specified
+ by simple, descriptive commands.
+
+\item Flexibility: Objects are described by 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 command-line switches or minor
+ changes to the input file.
+
+\item Power and extendibility: \ePiX\ inherits the power of \CXX\ 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 a
+ figure with a command line option or by using a Makefile.
+
+\item 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.
+
+\item License: \ePiX\ is \emph{free software}.\index{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.
+
+\end{itemize}
+
+
+\ePiX\ facilitates logical, as opposed to visual, structuring of
+mathematical figures, analogous to the relationship between \LaTeX\
+and a word processor. A few stylistic defaults streamline the creation
+of simple figures, but there are few internal restrictions on the
+contents or appearance of a figure; aesthetic and practical decisions
+are left to you.
+
+If you are a:
+
+\begin{itemize}
+
+\item Potential user, you may wish to skip immediately to ``Software
+ Dependencies'' before investing additional time.
+
+\item New user, proceed from here until you have enough understanding
+ to run the software, then experiment with the samples files while
+ reading Chapter~\ref{chapter:started}, or return to the manual as
+ needed.
+
+\item More advanced user, browse at will, probably starting with
+ Chapter~\ref{chapter:ref-man}.
+
+\end{itemize}
+
+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 \CXX\
+syntax, is introduced as needed.
+
+
+\section{Changes in Version~1.2}
+
+\ePiX~1.2.x has been written almost entirely from scratch. The
+conceptual model is unchanged, but there are a few changes of
+syntax. If you're new to~\ePiX, please skip straight to
+Section~\ref{section:software_deps}.
+
+
+\subsection{Syntax Changes}
+
+Except as noted below, \ePiX~1.0 files will compile under
+Version~1.2. Generally, 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).
+
+\begin{itemize}
+
+\item (Mandatory) The global variable \verb+tix+ in a \filename{flix}
+ file must be manipulated through the function \verb+tix()+.
+
+\item (Mandatory) The command \code{use\_pstricks()} is obsolete.
+ PSTricks output is obtained systematically as an output format.
+
+\item (Mandatory) Deprecated ``aliases'' no longer exist:
+ \code{triple} (for the \code{P} class), \code{D}~(for \code{Deriv}),
+ and \code{I}~(for \code{Integral}). Lowercase trig function names
+ conflicted with the standard namespace and have been removed.
+
+\item (Mandatory) Geometric object commands (\code{circle},
+ \code{plane}, \code{segment}, and~\code{sphere}), which formerly
+ created class objects, now perform drawing just as \code{ellipse},
+ \code{line}, \code{rect}, etc., do. The classes are available with
+ capitalized names (\code{Circle}, etc.).
+
+\item (Mandatory) Camera orientation is controlled with functions
+ named \code{tilt}, \code{pan}, and~\code{roll}; each rotates
+ the camera about an axis through the viewpoint, not through the
+ target.
+
+\item (Recommended) The global size variables \verb+x_min+,
+ \verb+x_max+, \verb+y_min+, \verb+y_max+, \verb+x_size+, and
+ \verb+y_size+ should be replaced by the function calls
+ \verb+xmin()+, etc. (No underscores.)
+
+\item (Suggested) The camera may be accessed through the function
+ \code{cam()}.
+
+\item (Suggested) The size and bounding box are given in one command,
+ such as \code{picture(P(-1,0), P(1,1), "4x3in")}. The old syntax
+ will be retained indefinitely.
+
+\end{itemize}
+
+
+\subsection{New Features}
+
+\begin{itemize}
+
+\item Output is cleanly separated from the internal representation.
+ Figures may be written with a choice of macros---\code{PSTricks},
+ \code{tikz}, and \code{eepic} at present---and new output types
+ are easily coded so long as the format supports arbitrary line
+ segments, color, and the ability to place a \LaTeX\ box at a
+ specified location.
+
+\item Colors are a manipulable data type, available in RGB, CMY, CMYK,
+ and Gray models. \filename{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. Filters performing CMYK separation are provided.
+
+\item Color filling is controlled with declarations, similarly to line
+ colors in \ePiX~1.0. Arrows and markers of type spot, dot, ddot,
+ and~circ are now colored like other markers. Parametric surfaces
+ may be color-shaded.
+
+ If a figure contains many shaded elements, a color-capable output
+ format (e.g.\ \code{PSTricks}~or \code{tikz}) should be used for
+ efficiency. Filled regions are implemented as fine hatching in
+ \filename{eepic}.
+
+\item An \code{axis} class provides coordinate axes with labels in a
+ variety of styles: decimals or scientific notation of specified
+ precision, fractions, trig fractions, logarithmic labels in
+ arbitrary (integer) base, and user-supplied styles.
+
+\item \ePiX~1.2.x performs page layout. Sub-figures may be manipulated
+ flexibly. The sample files give several applications.
+
+\item 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.
+
+\end{itemize}
+
+
+\section{Software Dependencies}
+\label{section:software_deps}
+
+\index{Installation|(}
+\index{Mac OS X}
+
+If you run GNU/Linux, a BSD, or Solaris, you probably have (and can
+surely install) all the external software needed to use \ePiX. On
+Mac~OS~X, you will need the Apple developer tools and an X~server
+(XCode and XDarwin on the Tiger disks), and the free~\code{fink}
+package manager to build a GNU 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 a
+\LaTeX\ picture; \code{dvi}; PostScript, \code{pdf}~or \code{eps}; and
+if desired, to a bitmapped image or movie. Four shell
+scripts---\epix, \code{laps}, \code{elaps}, and~\code{flix}---automate
+the various file format conversions.
+
+\ePiX\ consists of a \CXX\ library, header, and shell scripts, and
+requires GNU \code{bash} and a compiler \emph{for normal use}. For
+complete functionality, you need \code{g++} (Version~3.2 or later),
+\code{bash}, a text editor (\ePiX\ works particularly well with
+\code{emacs}), a \LaTeX\ distribution, \code{Ghostscript}, \code{gv}
+(or your favorite PS/PDF previewer), and \code{ImageMagick}. GNU
+\code{grep} and \code{sed} are good to have. You may need additional
+``developer packages'' (\code{binutils}, \code{make}) in order to
+build \ePiX. The more up to date your software is, the better your
+experience is likely to be, but bleeding edge versions are not
+necessary, or even always desirable.
+
+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 GNU environment.
+
+Jay Belanger's \code{emacs} mode allows you to write, compile, and
+view \ePiX\ figures without leaving \code{emacs}. If you use another
+editor, you'll want to create template source files so you don't have
+to type boilerplate code each time you write a new figure.
+\index{Emacs@\code{emacs}}
+
+
+\subsection{Setting up an Environment Under Windows}
+
+\index{Windows operating system|(}
+\begin{comment}
+Version~1.0.4 of \ePiX\ has been implemented in Python~2.2 by Andrew
+Sterian, making \ePiX\ available on any platform that supports Python,
+and without requiring a \CXX~compiler or~\code{bash}. Python is a
+GPL-ed scripting language, and is available with a Windows installer
+and detailed instructions. The easiest alternative for Windows users
+is probably to install Python~2.2 or later (if necessary) and
+\code{Pyepix}. The \code{pyepix} project home page is:
+\URL{claymore.engineer.gvsu.edu/~steriana/Python/index.html}
+\end{comment}
+
+Cygwin can be used to run \ePiX\ under Windows. Download
+\filename{setup.exe} from \URL{www.cygwin.com}, then install the
+packages you need. The following are recommended, and sufficient for
+the actions described in this manual.
+\begin{verbatim}
+(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
+\end{verbatim}
+\index{Windows operating system|)}
+
+
+\section{Installation}
+
+\ePiX\ is distributed over the World-Wide Web as source code. Packages
+may be found at \URL{mathcs.holycross.edu/\~{}ahwang/epix/ePiX.html}
+The latest stable release is also on the CTAN mirrors, in the
+\code{graphics} directory. (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:
+\begin{verbatim}
+ tar -zxvf epix-x.y.z.tar.gz
+ tar -jxvf epix-x.y.z.tar.bz2
+\end{verbatim}
+(\code{x.y.z}~is the version number) or, if your \code{tar}
+doesn't do decompression,
+\begin{verbatim}
+ gunzip -c epix-x.y.z.tar.gz | tar -xvf -
+ bzcat epix-x.y.z.tar.bz2 | tar -xvf -
+\end{verbatim}
+\code{cd} to the source directory, \filename{epix-x.y.z}. The
+\filename{INSTALL} file contains detailed installation instructions.
+If you're impatient, the short of it is \code{./configure [--options];
+ make; make install}. Run \code{./configure --help} for a list of
+options.
+
+By default, \ePiX\ installs in subdirectories of
+\filename{/usr/local}; if you want to install elsewhere, supply
+\code{./configure} with the appropriate \code{--prefix}. You may also
+want to consult \filename{POST-INSTALL} for information on setting
+your \code{PATH} variable so your shell can find \ePiX. The manual
+and sample files are in \filename{/usr/local/share/doc/epix}.
+\index{Installation|)}
+
+
+\subsection{Development}
+
+There are two mailing lists, one for user questions, one for
+development discussion. Please visit
+\URL{savannah.nongnu.org/mail/?group=epix} to subscribe.
+
+
+\texinfochapter{2}{Getting Started}
+\label{chapter:started}
+
+This chapter describes the basics of creating figures in \ePiX\ for
+readers familiar with \LaTeX\ but completely new to~\CXX. No detailed
+knowledge of~\CXX\ is needed to use \ePiX, only a bit of grammar that
+is easily absorbed by example.
+
+Section~\ref{section:running} describes the commands (shell scripts)
+comprising \ePiX, and explains how to set up a graphical environment
+using standard *nix programs. Section~\ref{section:overview} briefly
+describes figure creation. Section~\ref{section:tutorial} presents a
+few files side-by-side with their output, and should be read at a
+computer so you can run the exercises.
+
+
+\section{Running \ePiX}
+\label{section:running}
+
+An ``input file'' is a human-written figure specification containing
+\ePiX\ commands. An ``output file'' is machine-created, and is
+included directly into a \LaTeX\ document with the appropriate
+packages.
+
+Conversion (``compiling'' a figure) is accomplished with four shell
+scripts, \code{laps}, \code{epix}, \code{elaps}, and \code{flix}.
+Each script has a preferred extension for its input files, and is
+invoked with a command of the form
+\begin{verbatim}
+ <script> [options] <input file(s)>
+\end{verbatim}
+Often, no options are necessary. \code{<script> --help}
+describes \code{<script>}'s options.
+\texicomment
+Figure~\ref{fig:programs} (page~\pageref{fig:programs}) diagrams the
+shell scripts and the file types they process.
+\texicommentend
+
+By default, output file names are constructed by replacing the input
+extension with the (preferred) output extension. For brevity,
+extensions may be omitted. If the script has doubts about your intent,
+it proceeds with default behavior and prints a warning message.
+
+The author is a great fan of \Key{TAB} completion, under which a
+shell, based on what has been typed so far, automatically fills in a
+command when the \Key{TAB} key is pressed. \ePiX\ comes with code
+snippets that complete intelligently when the first part of a command
+is one of the shell scripts. For example, if command completion is
+active, typing \code{epix} \Key{TAB} prints only names of \code{epix}
+input files. To use this feature, you must install Ian MacDonald's
+\code{bash completion} package. The \filename{INSTALL} and
+\filename{POST\_INSTALL} files contain details.
+
+
+\subsubsection*{\code{laps}}
+
+\code{laps} performs \LaTeX\ to PostScript/PDF conversion, and is
+independent of the rest of \ePiX. By default, \code{laps} invokes
+\LaTeX~and \code{dvips}. The option \code{--pdf} creates a PDF~file by
+post-processing the PostScript with~\code{ps2pdf}. Other \TeX-family
+processors (\code{pslatex}, \code{pdftex}, etc.) may be used instead
+of~\LaTeX\ by invoking \code{laps} with an appropriate option.
+
+
+\subsubsection*{\code{epix}}
+
+\code{epix} compiles an input file into a \LaTeX\ picture. The input
+file should have extension \filename{xp} (for eXtended Picture). Jay
+Belanger's \code{emacs} mode is Highly Recommended; the installation
+procedure can be found in the \filename{POST\_INSTALL} file. When this
+mode is active, \code{emacs} automatically inserts a preamble template
+when a new \filename{xp} file is created. In addition, you can peruse
+\ePiX's info file, or format, compile, and preview files, all from
+within \code{emacs}.
+\index{Emacs@\code{emacs}}
+
+Output files from the script \code{epix} have extension
+\filename{eepic}, after Conrad Kwok's enhancements to the \LaTeX\
+picture environment. In Version~1.2, however, an output file need not
+contain \code{eepic} macros at all.
+
+An output file is \code{input} directly into a \LaTeX\ document whose
+preamble contains appropriate \code{usepackage} lines.
+\texicomment
+\begin{center}
+ \begin{tabular}{cc}
+ Format & Required Package(s) \\
+ \hline
+ \code{eepic} & \code{epic,eepic,xcolor} \\
+ \code{pst} & \code{pstricks} \\
+ \code{tikz} & \code{tikz}
+ \end{tabular}
+\end{center}
+\texicommentend
+Rotated text requires the \code{rotating} package.
+
+
+\subsubsection*{\code{elaps}}
+
+\code{elaps} creates stand-alone vector images (\filename{eps}~or
+\filename{pdf}) from \code{epix} input files or \filename{eepic}
+figures, even those not produced with \code{epix}. \code{elaps}
+automatically loads the \LaTeX\ packages needed for features described
+in this manual. Additional \LaTeX\ packages and \code{dvips} options
+may be specified on the command line.
+
+
+\subsubsection*{\code{flix}}
+
+\code{flix} creates bitmapped images and movies,
+Section~\ref{section:animation}. Input files should have extension
+\filename{flx}, and must contain a valid \code{epix} header as well as
+additional code. Jay Belanger's \code{emacs} mode facilitates creation
+of \code{flix} files.
+
+
+\section{The Drawing Model}
+\label{section:overview}
+
+To draw a figure manually, you select a sheet of paper of appropriate
+size and add paths, markers, and labels. These scene elements have
+attributes (line color, line width, fill color, font size, etc.)
+affecting their appearance.
+
+\index{canvas}
+\ePiX's drawing model behaves similarly. A \code{picture} command
+sets the \emph{canvas} (or logical drawing area, a Cartesian
+rectangle) and the true size of the final figure. A \code{begin}
+command initializes the ``virtual paper'' for drawing. Subsequent
+\emph{drawing commands} add objects to the scene: lines, curves,
+function plots, labels, and the like. The printed appearance of scene
+elements is determined by the current ``attribute state'' and
+controlled by \emph{style declaration} which remain in effect until
+superseded. Finally, an \code{end} command closes the figure and
+prints it to the output file.
+
+In this manual, command descriptions follow a few
+conventions. Optional arguments are enclosed in square brackets. A
+\code{len} argument is either a number (representing a length in
+\code{pt}) or a double-quoted string containing a number and a
+two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or
+\code{"6cm"}. A \code{color} argument is a named primary
+(\code{Red()}, \code{Cyan()}, \code{White()}, etc.), or a \code{Color}
+specified by densities (\code{RGB(r,g,b)}, \code{CMY(c,m,y)}, etc.)
+
+\begin{itemize}
+
+\item Fill color: \code{fill(color)}, \code{nofill()}.
+
+\item Line color and width: \code{plain([color])},
+ \code{bold([color])}.
+
+\item Text size: \code{font\_size([size])}, returns to
+ \code{normalsize} if no argument is given.
+
+\end{itemize}
+
+\noindent A complete list of style commands is found in
+Section~\ref{section:quickref}, starting on
+page~\pageref{section:quickref}.
+
+To handle three-dimensional scenes, a \code{camera} performs point
+projection from a selected spatial location to the canvas. As a user,
+you'll need to control relatively few of the \code{camera}'s
+parameters. Keep in mind, however, that elements are added to a scene
+in the same order their commands appear in the output file, and that
+later elements generally cover earlier ones. Some three-dimensional
+scenes require manual ordering of the input file; such ordering is
+dependent on the \code{camera}'s location.
+
+By default, \ePiX\ draws thin, solid, black lines, performs no filling
+of regions, prints text in a 12~pt Roman font, and looks down the
+\teximath{z}~axis from a large distance, giving orthogonal projection
+on the \teximath{(x,y)}~plane. When the \code{camera} is moved, the
+\teximath{z}~axis points vertically up on the page.
+
+
+\section{Tutorial}
+\label{section: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 \code{C}/\CXX, should be mostly
+self-explanatory. One-line comments begin with the
+string~``\verb+//+''.
+
+
+%%\index{Emacs@\code{emacs}}
+\index{Graphical interface}
+To use the sample files interactively, you'll need working software:
+\filename{bash}, \filename{emacs}, \ePiX, \filename{g++},
+\filename{gv}, and a running X~server. To complete your ``GUI'',
+start~\filename{gv} and select ``Watch file'' from the ``State''
+menu. The loaded file will update automatically when it changes.
+
+Create a ``scratch'' directory, \code{cd} into it, and run the command
+\begin{verbatim}
+ tar -zxf /usr/local/share/doc/epix/sample_src.tar.gz
+\end{verbatim}
+(Change the path 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 \filename{README} file serves
+as a table of contents.
+
+Open a sample file in \filename{emacs}, compile it from the drop-down
+menu (or with the keyboard command), then open the \filename{EPS} file
+in~\filename{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.
+
+
+\subsubsection*{Basic Drawing}
+
+The first sample, \filename{hello.xp}, contains code needed to specify
+the figure's size, followed by the classic greeting. The \code{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.
+\begin{verbatim}
+/* -*-ePiX-*- */
+#include "epix.h" // These lines are analogous
+using namespace ePiX; // to a usepackage command.
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "2 x 1in"); // corners, true size
+
+ begin(); // ---- Figure body starts here ----
+
+ border(Black(), "1pt"); // color, line width
+
+ font_size("Huge"); // May be any font size, e.g. "scriptsize"
+ label(P(0,0), "Hello, world!");
+
+ end(); // ---- End figure; write output file ----
+}
+\end{verbatim}
+
+\begin{center}
+ \input{hello.eepic}
+\end{center}
+
+\begin{itemize}
+
+\item Change the color and width of the
+ border. (\code{RGB(r,g,b);} creates an RGB color, CMY colors are
+ analogous. Named primaries are available. The densities should be
+ between \teximath{0}~and \teximath{1} for ``expected'' behavior.)
+
+\item Add \code{backing(Cyan());} after the \code{border} command.
+
+\item Put the command \code{crop\_ellipse();} before the \code{border}
+ command. Permute the \code{crop\_ellipse} command with the
+ \code{border} and \code{backing} lines, and note how the attribute
+ (\code{crop}) affects objects (\code{border}, \code{backing}).
+
+\end{itemize}
+
+
+\subsubsection*{Geometric Objects}
+
+Our next file uses simple objects to draw a 2-D house-and-sun scene.
+
+\begin{verbatim}
+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)); // the door
+ nofill();
+
+ bold(); // draw thicker lines
+ 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();
+}
+\end{verbatim}
+
+\begin{center}
+ \input{objects.eepic}
+\end{center}
+
+\begin{itemize}
+
+\item Add declarations such as \code{bold(RGB(1,0.9,0.5))} or
+ \code{fill(Yellow())} to color the scene. (Color and filling are
+ orthogonal attributes.)
+\end{itemize}
+
+\noindent The sample file \filename{house.flx} uses loops to draw
+gradient fills of the lawn, sky, and sun, and animates a sunset.
+
+
+\subsubsection*{Function Plotting}
+
+Plotted functions must be defined in the ``preamble'', before
+\code{main}. ``High-level'' elements---coordinate axes and grids, axis
+labels, and graphs---are drawn with mnemonically-named commands.
+\begin{verbatim}
+// 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), "5 x 1in"); // [-2,2] x [-1,1]
+
+ begin();
+ revolutions(); // set angle units, [0,1] = one turn
+
+ h_axis(16); // axes w/default endpts
+ v_axis(4);
+ h_axis_labels(4, P(0,-4), b); // shift down 4pt, align below
+
+ plain(Red());
+ plot(f, xmin(), xmax(), 120); // use 120 intervals
+
+ end();
+}
+\end{verbatim}
+
+\begin{center}
+ \input{plotting.eepic}
+\end{center}
+
+\begin{itemize}
+
+\item Define and plot some different functions; adjust the bounding
+ box as necessary. (Use repeated multiplication for polynomials.
+ The \code{polarplot} command graphs \teximath{r=f(\theta)}.)
+
+\item Change the arguments to \code{h\_axis\_labels}. The first
+ specifies the number of intervals to label; the second gives the
+ label offset in~\code{pt}. The last puts each label below~(\code{b})
+ its Cartesian location.
+
+\end{itemize}
+
+
+\subsubsection*{Multivariable Plotting}
+
+Functions of two or three variables are defined just like functions of
+one variable, but for plotting the return type must be a
+point~(\code{P}), not a real number~(\code{double}). The \code{domain}
+class specifies the set of inputs to plot.
+
+\begin{verbatim}
+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), "2 x 1in");
+ begin();
+ pst_format(); // use PSTricks macros for output
+
+ // 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));
+
+ plain(Blue(1.2)); // line color and width
+ fill(Yellow()); // shading color
+ surface(f, R);
+
+ end();
+}
+\end{verbatim}
+
+\begin{center}
+ \input{plotting2.eepic}
+\end{center}
+
+
+\subsubsection*{Loops and Control Structures}
+\label{taylor_poly}
+
+A function can be defined by an arbitrary algorithm, and a
+\code{domain} may be used to plot a family of functions for several
+values of one variable.
+
+\begin{footnotesize}
+\begin{verbatim}
+P sin_n(double x, double n) // Taylor polynomial of sin x
+{
+ const int N((int) floor(n)); // convert n to an index bound
+ 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); // return (x, y)
+}
+
+int main()
+{
+ picture(P(0, -1), P(6*M_PI, 1), "5 x 1in");
+
+ begin();
+
+ set_crop();
+ bold(Green());
+ plot(Sin, 0, xmax(), 120);
+
+ domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40));
+ for (int i=3; 0 <= i; --i) // print in descending degree
+ {
+ bold(RGB(0.25*i, 0, 1-0.25*i)); // degree-dependent color
+ plot(sin_n, R.slice2(5*i+1)); // plot for n = 5i+1
+ }
+ end();
+}
+\end{verbatim}
+\end{footnotesize}
+
+\begin{center}
+ \input{plotting3.eepic}
+\end{center}
+
+
+\subsubsection*{Page Layout}
+
+Page layout can be composed from sub-pages with \code{screen} objects.
+In the loop body below, objects are added to the ``active''
+\code{screen}, then \code{inset} into the ``canvas'', the screen
+representing the entire figure.
+
+\begin{verbatim}
+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"); // overall size
+
+ 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();
+}
+\end{verbatim}
+
+\begin{center}
+ \input{layout.eepic}
+\end{center}
+
+
+\section{\CXX\ Basics}
+
+\index{Cplusplus@\CXX|(}
+An \ePiX\ source file is a \CXX~program. If you've successfully
+modified and compiled the sample files, you know enough~\CXX\ to use
+\ePiX. In the author's experience, \code{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 \emph{The \code{C} Programming Language},
+second edition~\cite{KnR}.
+
+
+\subsection{File Format}
+
+\index{Emacs@\code{emacs}}
+Jay Belanger's \code{emacs} mode for \code{ePiX} inserts a file
+template when an empty buffer is opened with the extension~\code{xp}.
+This section explains the purposes served by the template. A few
+additional remarks may help you avoid basic syntax pitfalls.
+
+A \CXX\ file consists of ``statements'', analogous to ordinary
+sentences. Common types include \emph{declarations} (which
+``register'' a function, variable, or type name with the compiler),
+\emph{definitions} (which assign meaning to declared names), and
+\emph{function calls} (which cause a named function to execute). Most
+statements in an \ePiX\ input file are function calls (``commands'').
+Plain declarations are relatively rare in user files, since a
+definition serves to declare any new names that it contains.
+
+Every statement ends with a semicolon, and conventionally a file
+contains at most one statement per line. The compiler ignores
+nearly all whitespace (spaces, tabs, and newlines), which should be
+used freely 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
+\findex{include}
+\begin{verbatim}
+#include "epix.h" // N.B. pre-processor directive, no semicolon
+using namespace ePiX;
+\end{verbatim}
+The first line is analogous to a \LaTeX\ \code{usepackage} command: It
+loads the contents of the ``header'' file \filename{epix.h}, importing
+the names of commands provided by~\ePiX. To avoid name conflicts,
+\ePiX's commands are enclosed in a ``namespace''. For example, the
+\code{label} command is actually known to the compiler as
+\code{ePiX::label}. The second line above tells the compiler to apply
+the prefix tacitly.
+
+
+\subsection{Variables and Functions}
+%% \index{Variable}\index{Variable!names}
+%% \index{Function}\index{Function!names}
+
+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 \code{double} (double-precision
+floating point number), \code{P}, and \code{int}. The name of a
+variable may consist (only) of letters (including the underscore
+character) and digits, and must begin with a letter:
+\begin{verbatim}
+my_var, var2, MY_var, aLongVariableName; // valid
+my-var, 2var, \v@riable, $x, ${MY_VARIABLE}; // not valid
+\end{verbatim}
+Variable names are case-sensitive, and numerous (non-universal)
+conventions govern the significance of capitalization. Generally, make
+names descriptive but not unwieldy, and avoid language keywords (such
+as \code{const}, \code{true}, \code{double}, \code{class}, or
+\code{public}) and names that begin with an underscore.
+
+A function accepts ``arguments'' and ``returns a value''. To define a
+function in~\CXX, 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. The code block
+\begin{verbatim}
+double f(double x)
+{
+ return sqrt(1-x*x);
+}
+\end{verbatim}
+specifies the \code{double}-valued function~\teximath{f} of one \code{double}
+variable defined by the formula \teximath{f(x)=\sqrt{1-x^2}}.
+
+
+\subsection{Comments}
+
+\CXX\ has two types of comments. \code{C}-style comments, which may
+span several lines, are delimited by the strings \code{/*}~and
+\code{*/}. One-line comments, analogous to the \LaTeX~\code{\%}, are
+begun with \code{//}. A one-line comment may appear within a multi-line
+comment, but a \code{C}-style comment may not; the compiler will
+mistake the first~\code{*/} it encounters as the end of the current
+multi-line comment.
+
+
+\subsection{Program Execution}
+
+All the ``action'' in a \CXX\ program occurs inside the special
+function~\code{main}. Running a compiled \CXX~program is viewed by the
+operating system as calling the program's \code{main} function. The
+return value (an \code{int}) is the program's exit status. The
+contents of the output file start with \code{begin()} and terminate
+with \code{end()}. Intervening statements constitute the \emph{body}
+of the file.
+
+In \CXX, a function may not be defined inside another function. Thus,
+variables may be defined inside \code{main}, but functions cannot be.
+
+
+\subsection{Strings and Raw Output}
+
+In \CXX, a \code{string} is a sequence of characters. Most
+\code{string}s in \ePiX\ input files are \emph{literals},
+double-quoted \code{string}s whose value is read from the input. In a
+string literal, backslash is an escape character; a single backslash
+is produced by a double backslash in the input file. Certain letters
+have special meanings when backslash-escaped, including ``\verb+\n+''
+(newline) and ``\verb+\t+'' (\Key{TAB}). Unlike~\LaTeX, \CXX~does not
+require a space to separate an escape sequence from following text;
+the string ``\verb+\\textwidth+'' literally represents a \LaTeX\
+command, while ``\verb+\textwidth+'' is read ``\code{TABextwidth}'' by
+the compiler.
+
+Though not commonly needed, raw text can be printed to the output
+file. The functions \code{write}, \code{pre\_write}, and
+\code{post\_write} accept \code{string} arguments. \code{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. As an
+application, a complete \LaTeX\ \code{figure} environment (with
+caption and label) can be produced by an \ePiX\ file,
+Figure~\ref{fig:captioned}.
+
+\index{pre\_write}
+\index{post\_write}
+\index{write}
+\findex{pre\_write}
+\findex{post\_write}
+\findex{write}
+\begin{figure}
+\begin{footnotesize}
+\begin{verbatim}
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "10cm x 3in);
+ begin();
+ pre_write("\\begin{figure}[hbt]"); // comes before the picture
+
+ post_write("\\caption{A \\LaTeX\\ figure.}"); // and after
+ post_write("\\end{figure}");
+
+ < ... other ePiX commands ... >
+ write("%% A comment near the end, but inside the picture.");
+ end();
+} // End of main()
+\end{verbatim}
+\end{footnotesize}
+\caption{Generating a self-contained figure in \ePiX.}
+\label{fig:captioned}
+\end{figure}
+
+
+\subsection{Conditionals and Loops}
+
+An algorithm's behavior usually depends on internal state. A
+\emph{conditional statement} causes blocks of code to be executed
+according to criteria. A \emph{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.
+
+\texicomment
+Figure~\ref{fig:gcd} illustrates conditionals and loops with
+Euclid's algorithm for the greatest common divisor. Three pieces of
+notation require explanation: \code{j\%i} means~``\teximath{j\pmod i}'',
+\code{||} is logical~``or'', and \code{==} is ``test for equality''.
+(A single~``\code{=}'' is the assignment operator.)
+
+\index{Function!Euclidean algorithm}
+\begin{figure}[hbt]
+\begin{footnotesize}
+\begin{verbatim}
+int gcd (int i, int j)
+{
+ int temp(i); // initialization syntax
+ if (i==0 || j==0)
+ return i+j; // define gcd(k,0) = k
+
+ else {
+ if (j < i) // swap them
+ {
+ temp = j;
+ j = i;
+ i = temp;
+ }
+ // the work is done here...
+ while (0 != (temp = j%i)) // assign temp, test for zero
+ {
+ j = i;
+ i = temp;
+ }
+ return i;
+ }
+}
+\end{verbatim}
+\end{footnotesize}
+\caption{Euclid's division algorithm in~\CXX.}
+\label{fig:gcd}
+\end{figure}
+\texicommentend
+
+%% \noindent For details on conditionals, or for more advanced techniques
+%% of \CXX\ programming, please consult a textbook or online tutorial.
+\index{Cplusplus@\CXX|)}
+
+%% Force previous two figures onto the same page
+%%\clearpage
+
+\section{Animation}
+\label{section:animation}
+
+\index{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~\code{flix} automates the process of
+compiling a suitable input file into a collection of \filename{png}s
+and assembling these frames into a \filename{mng}~or \filename{gif}
+animation. ImageMagick is the image-handling engine.
+
+A \code{flix} file is an \code{epix} file with two restrictions:
+\begin{itemize}
+ \item The \code{double} variable \code{tix()} is used as
+ ``clock''.
+
+ \item \code{main} accepts two command line arguments and sets
+ \code{tix()} accordingly.
+\end{itemize}
+\index{Emacs@\code{emacs}}
+Jay Belanger's \code{emacs} mode recognizes the file
+extension~\filename{.flx} and inserts template code if an empty buffer
+is opened. Creation of \code{flix} files is as easy as creation of
+\code{epix} files. The \filename{samples} directory contains a
+handful of \code{flix} files that may be consulted for ideas.
+
+By default, \code{flix} creates movies with 24~frames, in which
+\code{tix()} runs from~0 to~1, and animates at
+\teximath{0.08}~sec/frame. These and other parameters can be changed
+with command-line options.
+
+A ``typical'' \code{.flx} file may take 30~seconds to a few minutes to
+compile, depending on the number of frames and the complexity of each
+frame. To facilitate debugging, \code{elaps} can be run on a
+\code{flix} file. \code{elaps} runs in a fraction of the time, and if
+\code{elaps} can't produce a viewable image, \code{flix} will surely
+fail. While running, \code{flix} prints a progress bar counting the
+number of \filename{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 \code{convert} utility assembles the movie.
+\index{Animation|)}
+
+
+\section{Layout Tricks}
+\label{section:layout}
+\index{Layout}
+
+\subsection{Stereograms}
+\index{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.
+
+\subsubsection*{Crossed-Eyes Stereograms}
+
+The sample files \filename{lorenz.xp}~and \filename{twisted\_cubic.xp}
+use page layout to draw crossed-eyes stereograms. For each frame,
+create and activate a \code{screen}, set the camera, and call the
+scene function. The frames are 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.
+
+\subsubsection*{Bi-Color Stereograms}
+
+The sample files \filename{cube.flx}~and \filename{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.
+
+\subsubsection*{Stereographic Movies}
+
+Either form of stereogram can be animated in a \code{.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
+\code{flix}, debug the scene with \code{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.
+
+
+\subsection{Inset Images}
+
+\ePiX\ can place external images into a figure, similarly to
+Rolf Niepraschk's \code{overpic} package. You provide the Cartesian
+center point, the file name, and optionally the true height and/or
+width of the image:
+\findex{label}
+\begin{verbatim}
+ label(P(a,b), "\\includegraphics[width=w,height=h]{file}");
+\end{verbatim}
+This effect requires the \filename{graphicx} package. When compiling a
+stand-alone graphic containing an external image, you must specify the
+\filename{graphicx} package on the command line: \code{elaps -p
+graphicx <file>}
+
+\texicomment
+\begin{figure}[hbt]
+ \begin{center}
+ \input{ePiX.eepic}
+ \end{center}
+ \caption{Visual guide to \ePiX's shell scripts}
+ \label{fig:programs}
+\end{figure}
+\texicommentend
+
+
+\texinfochapter{3}{Reference Manual}
+\label{chapter:ref-man}
+
+This chapter details \ePiX's capabilities, discussing attributes and
+data types, and listing available commands in the form
+\begin{verbatim}
+ label(P posn, [P offset], string text, [align]);
+ circle(P ctr, double rad=1, normal=P(0,0,1));
+\end{verbatim}
+As in Chapter~\ref{chapter:started}, function arguments are given by
+type (\code{P}, \code{double}, \code{string}, etc.)\ and name, or by
+name alone if the type is clear. Optional arguments are enclosed in
+square brackets. A few argument types, such as \code{[align]} above,
+admit only a small number of values; these cases are explained when
+the corresponding command is first introduced.
+
+A name followed by an equals sign and a value indicates a default
+argument; if omitted in an input file, the compiler substitutes the
+default value. Only trailing arguments may be specified this way. For
+example, if the \code{rad} argument of the \code{circle} command is
+omitted, the \code{normal} argument \emph{must} be omitted as well.
+
+In an input file, only an argument's value is given, not the type:
+\begin{verbatim}
+ label(P(0,0), P(0,-4), "Hello world", b);
+ circle(P(0,-0.25), sqrt(2)); // use default normal
+\end{verbatim}
+
+Generally, \code{len} signifies either a number (representing a length
+in \code{pt}) or a double-quoted string containing a number and a
+two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or
+\code{"6cm"}. \code{color} represents a \code{Color} object
+constructed from a named primary (\code{Blue()}, \code{Magenta(0.7)},
+etc.), a color specification (\code{RGB(r,g,b)}, \code{CMY(c,m,y)},
+etc.), or an operator applied to an existing \code{Color}.
+
+
+\section{File Structure}
+
+An \ePiX\ input file constitutes a short \CXX\ program. When this
+program is compiled and run by one of the shell scripts, it creates a
+figure file suitable for inclusion in \LaTeX.
+
+\index{Preamble}
+Like a \LaTeX\ document, an \ePiX\ file contains a \emph{preamble},
+which sets up a drawing environment, and a \emph{body}, which contains
+actual figure-generating commands. The minimal file has the form
+\findex{picture}
+\findex{begin}
+\findex{end}
+\begin{verbatim}
+#include "epix.h" // N.B. no semicolon
+using namespace ePiX;
+
+int main() {
+ picture(P(a1,b1), P(a2,b2), "n1 [unit1] x n2 unit2");
+ begin(); // end of preamble, start of body
+ end(); // end of body
+}
+\end{verbatim}
+\ePiX\ commands are of four general types: drawing, attribute setting,
+definitions (of data and functions), and operations on existing
+objects. Except as noted below, drawing and attribute commands must
+appear in the body, between \code{begin()}~and \code{end()}. Function
+definitions must come in the preamble, before \code{main()}. Data
+definitions may appear in the preamble or body.
+
+
+\subsubsection*{Output Format}
+\index{Output format}
+
+The \code{end()} command writes the output file to \code{stdout},
+using \code{eepic} macros by default. The shell scripts redirect
+\code{stdout} to an appropriate disk file.
+
+The attribute-setting command \code{pst\_format()} causes the output
+file to be written using \code{PSTricks} macros when \code{end} is
+called. Similarly, \code{tikz\_format()} causes the file to be written
+using \code{tikz} macros, and \code{eepic\_format()} causes the file
+to be written using \code{eepic} macros. These commands may appear
+anywhere in the figure body. There is no reason for a file to contain
+more than one such command.
+
+The output format may be selected on the command line, overriding any
+explicit request in the input file. Supplying \code{epix},
+\code{elaps}, or \code{flix} with one of the options \code{--pst},
+\code{--tikz}, or \code{--eepic} is tantamount to issuing a
+\code{pst\_format()} (etc.)\ command just before the end of the
+file. These options are listed in decreasing precedence. If more than
+one is given, the ``strongest'' applies, regardless of the command
+line order.
+
+A figure may be written directly to a specified disk file, in a format
+unaffected by the command line flags above. The command
+\begin{verbatim}
+ print_eepic("file.tex");
+\end{verbatim}
+writes the figure to the named file using \code{eepic}
+macros. Analogous commands exist for the formats \code{pst}~and
+\code{tikz}. These commands perform an immediate action. Consequently,
+the command's location in the input file is significant, and multiple
+commands may appear in a single file, so long as distinct file name
+arguments are provided. Applications include writing the same figure
+in multiple formats, or creating successive ``snapshots'' of a lengthy
+computation.
+
+
+\section{Picture Size and Aspect Ratio}
+
+\index{Picture!size}
+\index{Picture!offset}
+The \code{picture} command specifies a figure's logical and true
+sizes. In the ``minimal file'' snippet above, the \emph{canvas} is the
+Cartesian rectangle \teximath{[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.
+
+The true (printed) width and height are read from \code{picture}'s
+third argument, a ``size \code{string}'' such as \verb+"4cm x 1in"+,
+containing a number and optional \LaTeX\ length unit, an~\code{x},
+another number, and a mandatory length unit. Spaces may be used for
+legibility. The mandatory length unit becomes the \LaTeX\
+\code{unitlength}. The argument \verb+"4cm x 1in"+ creates a picture
+4~cm wide and 1~in high, but internally converts 4~cm to inches.
+Recognized length units are \code{pt} (points, the default), \code{cm}
+(centimeters), \code{in} (inches), \code{mm} (millimeters), \code{pc}
+(picas), and \code{bp} (big points).
+(\code{1in = 2.54cm = 72bp = 72.27pt}, \code{1pc = 12pt}.)
+
+The logical and true sizes may be defined separately with the commands
+\findex{bounding\_box}
+\findex{picture}
+\findex{unitlength}
+\begin{verbatim}
+ bounding_box(P(a1,b1), P(a2,b2));
+ picture(n1, n2);
+ unitlength(len); // len a length string, not a double
+\end{verbatim}
+One way or another, the logical and true dimensions \emph{must} have
+positive values when the \code{begin()} command is issued.
+
+\LaTeX\ treats the contents of a picture environment as a single box,
+aligned by default on its lower left corner. An \code{offset} command
+accepts two \code{double} arguments or a size \code{string} and shifts
+the page location accordingly. The command
+\code{offset("0.25 x -0.5cm")} shifts the picture right
+\teximath{0.25}~cm and down \teximath{0.5}~cm. If the
+\code{unitlength} is 1~cm, the command \code{offset(0.25, -0.5)} has
+the same effect.
+
+A non-zero \code{offset} causes a picture's contents to appear in a
+location where \LaTeX\ does not expect them. This can be useful in a
+\LaTeX\ document, but should be avoided when compiling a stand-alone
+image, since \code{dvips} may crop according to rules of its own.
+
+
+\index{Picture!aspect ratio}
+\index{Picture!bounding box}
+The canvas's corners are \code{(xmin(),ymin())} and
+\code{(xmax(),ymax())}, while its width and height are
+\code{xsize()}~and \code{ysize()}. The canvas is a virtual, advisory
+data structure; its dimensions are not directly related to the
+figure's printed size, and picture elements may lie outside the
+canvas. Affine scaling maps the canvas to the page when the output
+file is written.
+\begin{center}
+\input{scaling.eepic}
+\end{center}
+\label{page:scaling}
+The figure's aspect ratio is controlled by sizing the canvas. The
+aspect ratio is ``true'' if the canvas and page rectangles are
+geometrically similar, e.g., if both boxes are 1.5~times as wide as
+they are tall.
+
+
+\section{Color}
+\label{section:color}
+
+\index{Color|(}
+\ePiX\ provides a \code{Color} data type. Four models are implemented:
+\code{RGB}, \code{CMY}, \code{CMYK}, and \code{Gray}. A \code{Color}
+holds primary color ``channels'', each carrying an intensity between
+0~(no color) and~1 (full saturation). ``No color'' means black in
+\code{RGB} and \code{Gray}, white in \code{CMY(K)}. \code{RGB},
+\code{CMY}, and~\code{CMYK} colors are written to the output file as
+commands in the corresponding model. \code{Gray} shades are written
+in~\code{RGB}.
+
+Operations on red-green-blue colors are described below. Functionally,
+colors are converted to~\code{RGB}, operated upon, then converted back
+to the original model. Conversions are as described in Uwe Kern's
+\filename{xcolor} manual~\cite{xcolor}.
+
+
+\subsection{Constructors}
+
+Each color model has a ``constructor'' creating a color of specified
+densities. The \code{RGB}~and \code{CMY} models have named ``primary''
+constructors; the density argument is optional and defaults to~1.
+\findex{RGB}
+\findex{Red}
+\findex{Green}
+\findex{Blue}
+\findex{White}
+\findex{Black}
+\begin{verbatim}
+ // 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);
+\end{verbatim}
+\findex{CMY}
+\findex{Cyan}
+\findex{Magenta}
+\findex{Yellow}
+\findex{CMY\_White}
+\findex{CMY\_Black}
+\findex{CMYK}
+\findex{Gray}
+\begin{verbatim}
+ // 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)
+\end{verbatim}
+Each \code{CMY} constructor has a corresponding \code{CMYK} function,
+e.g.\ \code{CyanK()}~or \code{CMYK\_White()}.
+
+Though color densities lie between 0~and 1, \ePiX's primary color
+constructors take arguments mod~4, viewed as elements
+of~\teximath{[-2,2]}. Consider \code{Red(d)}, ``red with
+density~\teximath{d}''. For integer values of~\teximath{d}, the
+constructor has the following meanings: \code{Red(0)}~is black,
+\code{Red(1)}~is red, \code{Red(2)}=\code{Red(-2)}~is white, and
+\code{Red(-1)}~is anti-red, or cyan. For non-integer~\teximath{d}, the
+constructor interpolates between the bracketing integer values,
+Figure~\ref{fig:densities}. Other primary constructors work
+analogously.
+
+\begin{figure}[hbt]
+ \begin{center}
+ \input{color_density.eepic}
+ \end{center}
+ \caption{The red primary constructor.}
+\label{fig:densities}
+\end{figure}
+
+Let \teximath{\delta:[-2,2]\to[0,1]} be the piecewise-linear function
+that converts real numbers to primary color densities,
+\teximath{\clip:\mathbf{R}\to[0,1]} the clipping function. The
+non-primary constructor \code{RGB(r, g, b)} computes the density of
+the red channel as
+\teximath{\clip\bigl(\delta(r)+\delta(-g)+\delta(-b)\bigr)}; the green
+and blue channel densities are computed similarly. Every color can be
+created with arguments between 0~and 1, but the constructor accepts
+arbitrary real arguments and returns colors varying ``continuously and
+periodically''.
+
+\index{Color!transparency}
+Colors possess an ``alpha-channel'' for transparency. Except as
+supported by the output format, this feature is a stub.
+
+
+\subsection{Color Operations}
+
+Colors can be scaled, inverted, blended, superposed, and filtered. In
+the code below, \code{tint}~is a \code{Color}. The effect of each
+operation is described in the \code{rgb} model; the visual result is
+the same in all models.
+\findex{Color.invert}
+\findex{Color.blend}
+\findex{Color.superpose}
+\findex{Color.alpha}
+\findex{Color.filter}
+\begin{verbatim}
+ tint *= double c; // multiply channels by c, rebuild
+ 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.alpha(double d); // set alpha channel to clip(d)
+
+ tint.filter(col); // return min density in each channel
+\end{verbatim}
+Except for \code{filter}, these operators modify their object.
+\code{filter} simulates the effect of viewing \code{col}
+through a transparent sheet of \code{tint}, and returns a new
+\code{Color} object having the same model as \code{tint} without
+modifying \code{tint} itself.
+
+
+\section{Scene Attributes}
+
+Objects in a scene sit in 3-dimensional space. A \emph{camera}
+maps objects to the \emph{active screen}. The active \code{screen}
+may, in turn crop its contents. Each drawing command creates an
+object, ``photographs'' it, and adds the image to the active
+\code{screen}. This section describes the \code{Camera} and
+\code{screen} classes and a few associated concepts.
+
+
+\subsection{Angular Mode}
+\index{Angle units}
+
+By default, angles are measured in \code{radian}s. Two other angular
+modes are available: \code{degrees}~and \code{revolutions}. The
+angular mode is set with a named command, \code{radians()},
+\code{degrees()}, or \code{revolutions()}. The current angular mode
+affects all trigonometric functions and operations.
+
+
+\subsection{The Camera}
+\index{Camera|(emph}
+\index{Screen|(}
+
+Three-dimensional scenes are drawn on flat paper by applying a
+mathematical transformation. By default, \ePiX\ uses \emph{point
+projection}, the technique used by art students when they trace on a
+window with grease pencil, Figure~\ref{fig:camera}.
+
+\begin{figure}[hbt]
+ \begin{center}
+ \input{camera.eepic}
+ \end{center}
+ \vspace*{-0.25in}
+ \caption{Point projection.}
+ \label{fig:camera}
+\end{figure}
+
+\index{Camera!viewpoint}
+\index{Viewpoint}
+\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 \emph{body} (data
+that determines the position and orientation of the camera), a
+\emph{lens} (the actual mapping to the screen plane), and a
+\emph{filter} (a color through which the scene is viewed).
+
+
+\subsubsection*{Body}
+
+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 \emph{sea}, \emph{sky}, and~\emph{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 \emph{viewpoint}, the camera's
+spatial location. The \emph{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
+\emph{range}. The \emph{camera sphere} is centered at the viewpoint
+and passes through the target. The orientation, viewpoint, target,
+and range completely (and redundantly) determine the camera's
+geometric situation in the world.
+
+
+\subsubsection*{The Lens}
+\index{Camera!lens}
+
+A \emph{lens} maps the world to the screen. \ePiX\ comes with four
+lenses: \emph{shadow} (the default), \emph{orthogonal},
+\emph{fisheye}, and \emph{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 the camera sphere, then maps the
+sphere to the screen plane; the fisheye lens does orthogonal
+projection (so the entire image lies inside the disk centered at the
+target whose radius is the range) while the bubble lens does
+stereographic projection from the target's antipode.
+\index{Screen|)}
+
+
+\index{Camera!manipulation|(}
+An input file normally uses a single camera, so a global object named
+\code{camera} is defined automatically. At the start of a figure, the
+\code{camera} looks down on the \teximath{(x_1,x_2)}-plane from a
+distant point on the \teximath{x_3}-axis. The resulting view,
+essentially projection along the axis, is suitable for 2-dimensional
+figures.
+
+The \code{camera} is manipulated similarly to a real camera:
+\findex{Camera.at}
+\findex{Camera.look\_at}
+\findex{Camera.range}
+\findex{Camera.focus}
+\findex{Camera.tilt}
+\findex{Camera.pan}
+\findex{Camera.roll}
+\findex{Camera.clip\_range}
+\begin{verbatim}
+ 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
+\end{verbatim}
+Explicitly setting the viewpoint or target makes the sky vector
+parallel to the projection of the \teximath{x_3}~axis when possible;
+otherwise the \teximath{x_2}-axis is used. Setting the range or focus
+moves the \code{camera} parallel along the eye line. Each command
+re-sizes the image; note that increasing the focus \emph{enlarges} the
+image. The three rotation operations fix the viewpoint, but only roll
+fixes the target.
+
+
+\subsubsection*{Filtering and Color Separation}
+\index{Color!separation}
+\index{Camera!color separation}
+
+The \code{camera} has a \emph{filter} through which all scene
+\code{Color}s pass. For uniformity, the filter should only be set at
+the start of the file body, before any visible elements have been
+placed in the scene. The filter has two primary uses---model
+conversion and color separation---but can also be used for special
+effects.
+
+There is a \code{Neutral} color, for which filtering has no effect at
+all. The \code{camera}'s default filter is \code{Neutral}. In
+addition, each color model has a \emph{neutral} representative,
+\code{RGB\_Neutral}, etc. Passing \code{Color}s through a neutral
+filter preserves their appearance but converts them to the neutral
+\code{Color}'s model.
+
+Filtering can be used to ``split'' a \code{Color} into primary
+constituents. For \code{RGB} channels, the primaries themselves are
+suitable filters. For \code{CMYK} channels, there are special
+\emph{process} filters, named \verb+C_Process+, etc.
+\begin{verbatim}
+ camera.filter(CMY_Neutral()); // convert all colors to CMY
+ camera.filter(Gray_Neutral()); // black and white photography
+ camera.filter(Green()); // the green channel
+ camera.filter(M_Process()); // the magenta channel
+ camera.filter(Red(1.4)); // la vie en rose?
+\end{verbatim}
+\index{Camera!manipulation of|)}
+\index{Camera|)}
+
+
+\subsection{Clipping}
+
+\index{Clipping|(}
+
+Two operations handle elements lying far from the target.
+\emph{Cropping} culls elements based on their screen location, and is
+described later. \emph{Clipping} removes objects whose spatial
+location lies outside the ``clip region''.
+
+Initially, the clip region is a very large box centered at the
+origin. Commands are provided to resize this box, keeping the faces
+parallel to coordinate planes.
+\findex{clip\_box}
+\findex{clip\_to}
+\begin{verbatim}
+ 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)
+ clip_box(); // very large box
+\end{verbatim}
+Additional ``clippers'' may be added manually. Individual clipping
+planes are specified by a point and inward-pointing normal vector.
+Parallel planes cutting a ``slice'' or ``slab'' are described by a
+location, direction, and a distance. The location lies halfway between
+the clipping planes, and the planes' normals point toward the location.
+\findex{clip\_face}
+\findex{clip\_slice}
+\findex{clip\_restore}
+\begin{verbatim}
+ clip_face(P loc, P perp); // perp points inward
+ clip_slice(loc, perp); // very close parallel planes
+ clip_slice(loc, perp, dist); // planes separated by dist
+ clip_restore(); // remove manually-added clip planes
+\end{verbatim}
+Like \code{clip\_restore}, the \code{clip\_box} and \code{clip\_to}
+commands remove all user-specified half spaces.
+\index{Clipping|)}
+
+
+\subsection{Screens and Page Layout}
+\index{Screen|(}
+\index{Screen!active}
+\index{Layout}
+
+By default, drawing occurs in the Cartesian coordinate system of the
+\code{canvas}. However, insets and subfigures are most naturally
+composed in ``local'' coordinates, then placed into their final
+location as a unit, a process called \emph{layout}. \ePiX\ implements
+layout with the \code{screen} class.
+
+
+\subsubsection*{Screens}
+\index{Bounding box}
+
+A \code{screen} is a Cartesian plane containing a distinguished
+coordinate rectangle, its \emph{bounding box}. The \code{canvas} of a
+figure is a \code{screen}, as is the internal representation of the
+printed page. At any point of a file body, some \code{screen} is
+\emph{active}, or ``open for drawing''. A new \code{screen} is created
+from a pair of opposite corners, but is not used until explicitly
+activated.
+\findex{activate}
+\findex{deactivate}
+\begin{verbatim}
+ screen subfig(P(a1,b1), P(a2,b2)); // [a1, a2] x [b1, b2]
+ activate(subfig); // open subfig for drawing
+ // commands to draw in subfig
+ deactivate(subfig); // re-activate the previous screen
+\end{verbatim}
+
+The \code{canvas} is automatically drawn at the \code{end} of the
+input file. The contents of other \code{screen}s must be incorporated
+into the \code{canvas} explicitly with an \code{import}~or
+\code{inset} command. \code{import} affinely scales the bounding box
+of the ``child'' \code{screen} to the \code{canvas}. \code{inset}
+specifies corners in the ``parent'' where the child is
+placed.
+\findex{import}
+\findex{inset}
+\begin{verbatim}
+ 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
+\end{verbatim}
+
+
+\subsubsection*{Extracting}
+
+The portion of a \code{screen} enclosed by a specified rectangle can
+be \emph{extracted}. Each of the commands
+\findex{extract}
+\findex{canvas}
+\begin{verbatim}
+ subfig.extract(P sw, P ne);
+ canvas().extract(P sw, P ne);
+\end{verbatim}
+returns the \code{screen} having stated corners and containing part of
+\code{subfig} or the \code{canvas}, respectively. Elliptical and
+diamond-shaped portions of a \code{screen} may be extracted. The
+contents occupy the ellipse or diamond inscribed in the given
+rectangle.
+\findex{extract\_diamond}
+\findex{extract\_ellipse}
+\begin{verbatim}
+ subfig.extract_ellipse(sw, ne);
+ canvas().extract_diamond(sw, ne);
+\end{verbatim}
+The \code{screen} returned by \code{extract} (or its variants) may be
+used just like a manually-constructed \code{screen}, for example to
+construct a magnified inset.
+
+
+\subsubsection*{True-Size Drawing}
+\label{truesize}
+
+On occasion, it is necessary to draw at known page size, independently
+of the unit length. For 2-dimensional drawing in the
+\teximath{(x_1,x_2)}-plane with the \code{camera} in its default
+location, the coordinates (horizontal, vertical, or both) of a
+\code{screen} may be interpreted as true~pt offsets relative to a
+specified point rather than as Cartesian coordinates.
+\findex{inlay}
+\findex{inlay\_horizontal}
+\findex{inlay\_vertical}
+\begin{verbatim}
+ inlay(subfig, P loc);
+ inlay_horizontal(subfig, loc);
+ inlay_vertical(subfig, loc);
+\end{verbatim}
+Each command maps the origin of \code{subfig} to the specified
+location in the active \code{screen}. The first performs affine
+scaling so that one Cartesian unit in \code{subfig} maps to one
+true~pt on the page. The second and third commands perform this
+scaling only in the named direction.
+
+\findex{pt\_to\_screen}
+The \code{inlay} functions are suitable only for 2-dimensional
+effects. For 3-dimensional true-size drawing, the function
+\code{pt\_to\_screen} converts a true length of 1~pt into Cartesian
+coordinates in the active \code{screen}. For example, the command
+\code{line(P(0,0), P(pt\_to\_screen(12),0))} draws a line segment
+12~pt long with its left endpoint at the Cartesian origin. True size
+drawing is unusual in an input file, but has definite uses in library
+code; \ePiX's right angle marker is a typical application.
+
+Either type of true-size drawing works as described when drawing in
+the \code{canvas}, and \emph{only} when drawing in a \code{screen}
+imported to the \code{canvas} at ``true Cartesian'' size (one
+\code{screen} unit maps to one Cartesian unit in the \code{canvas}).
+In other situations, the true size coordinate(s) will be scaled by
+additional affine transformation(s).
+
+
+\subsubsection*{Cropping and Decorations}
+
+\index{Cropping}
+A \code{screen} has a \emph{crop mask}: rectangular (default),
+elliptical, or diamond-shaped. If cropping is switched on in the
+active \code{screen}, added elements are cropped to the crop mask.
+For example, cropping by the default crop mask in the \code{canvas}
+ensures the figure lies inside the printed region allocated by
+\LaTeX.
+
+The \code{crop} commands below affect the active \code{screen}
+only. Cropping is not a ``global'' attribute, but must be set or unset
+explicitly for each \code{screen}. By default, cropping is switched
+off.
+\findex{crop}
+\findex{crop\_ellipse}
+\findex{crop\_diamond}
+\findex{set\_crop}
+\begin{verbatim}
+ set_crop(); // activate cropping
+ set_crop(false); // deactivate cropping
+ crop_diamond(); // <>-shaped mask, set crop state
+ crop_ellipse(); // etc...
+ crop(); // crop active screen's contents
+\end{verbatim}
+Normally the crop mask is inscribed in the \code{screen}'s bounding
+box. The commands \code{crop\_diamond} and \code{crop\_ellipse} also
+accept a pair of \code{P}~arguments, which are treated as corners of
+the crop box.
+
+The active \code{screen} may be decorated with a \code{border}
+(outline of specified color and line width) and \code{backing} (solid
+fill color). The crop mask determines the shape of the \code{border}
+and \code{backing}.
+\findex{border}
+\findex{backing}
+\begin{verbatim}
+ border(color, len);
+ backing(color);
+\end{verbatim}
+Identically-named member functions can be applied to an arbitrary
+\code{screen} whether or not it is active:
+\begin{verbatim}
+ scr.crop_rectangle().backing(Blue(1.8));
+ canvas().crop();
+\end{verbatim}
+
+
+\subsubsection*{Affine Maps}
+\index{Affine map}
+
+A \emph{plane affine map} has the form \teximath{T(x) = Ax+b} for some
+invertible \teximath{2\times2} matrix~\teximath{A} and a constant
+vector~\teximath{b}. \ePiX's \code{affine} class allows affine maps to
+be built and applied to \code{screen}s' contents.
+
+An affine map is uniquely determined by the images of three
+non-collinear points. The constructor returns the affine map sending
+the points \teximath{(1,0)}, \teximath{(0,1)}, and~\teximath{(0,0)} to
+\code{pt1}, \code{pt2}, and~\code{pt0}, respectively.
+\findex{affine}
+\begin{verbatim}
+ affine af(P pt1, P pt2, P pt0=P(0,0));
+\end{verbatim}
+To emphasize, the arguments are locations, not displacements, and the
+image of the origin comes last. There is also a \code{void}
+constructor (taking no arguments) which returns the identity map.
+
+To facilitate construction of affine maps, an existing \code{affine}
+may be post-composed with a variety of ``elementary'' affine
+transformations. In the commands below, \code{th} is an angle (in
+current units), \code{sc} is a non-zero \code{double}, and \code{ctr}
+is a point fixed by the composing transformation. In each command,
+\code{ctr} defaults to \teximath{(0,0)}.
+\findex{shift}
+\findex{rotate}
+\findex{reflect}
+\findex{h\_scale}
+\findex{v\_scale}
+\findex{scale}
+\findex{h\_shear}
+\findex{v\_shear}
+\findex{postcomp}
+\begin{verbatim}
+ affine af; // the identity map
+ af.shift(P arg); // translate by arg
+ af.rotate(th, [ctr]); // counterclockwise rotation about ctr
+ af.reflect(th, [ctr]); // reflect across line through ctr
+
+ af.h_scale(sc, [ctr]); // horizontal scaling
+ af.v_scale(sc, [ctr]); // vertical scaling
+ af.scale(sc, [ctr]); // dilatation
+
+ af.h_shear(sc, [ctr]); // shear preserving horizontals
+ af.v_shear(sc, [ctr]); // shear preserving verticals
+
+ af.invert(); // the inverse
+ af.postcomp(affine f); // post-compose with f
+ af(f); // pre-compose, af not modified
+\end{verbatim}
+A non-invertible \code{affine} can be created \emph{only} by shearing
+or scaling with an extremely large or extremely small argument, or by
+supplying three collinear points to the constructor. Calling
+\code{invert} on a non-invertible map merely issues a warning and
+performs no action.
+
+An \code{affine} may be applied to a \code{screen}'s current contents.
+The \code{screen} class has eight member functions (\code{shift}
+through \code{shear}) with syntax identical to the affine map
+functions. In addition, an arbitrary \code{affine} may be applied to a
+\code{screen}:
+\findex{apply}
+\begin{verbatim}
+ scr.shift(arg); // shift scr's contents by arg; etc.
+ scr.apply(f); // apply f to scr's contents
+\end{verbatim}
+To apply a composition of several maps to a \code{screen}, it's best
+to build an \code{affine} map by composition, then \code{apply} the
+map. Composing \code{affine}s is cheap; \code{apply}ing an
+\code{affine} is costly in proportion to the number of elements in the
+\code{screen}.
+
+Applying an \code{affine} to a \code{screen} has no effect on the
+bounding box, \code{border}, or \code{backing}, and may move elements
+outside the bounding box even if cropping is active. To ensure a
+\code{screen}'s contents lie inside the bounding box, \code{crop} the
+\code{screen} \emph{after} \code{apply}ing the \code{affine}(s).
+
+The sample file \filename{inverse.xp} uses \code{affine} maps to
+depict branches of inverse functions in one variable,
+\filename{symmetry.xp} depicts the permutation group~\teximath{S_3}
+by its action on a regular hexagon.
+\index{Screen|)}
+
+
+\section{Drawing Attributes}
+
+\ePiX\ maintains drawing states for filled regions, paths, and text
+objects.
+
+
+\subsection{Filled Regions}
+
+\index{Filling}
+\index{Path|(}
+\index{Path!filled}
+Filling is either on or off. When filling is active, closed paths are
+filled with the current \emph{fill color}.
+\findex{fill}
+\findex{nofill}
+\begin{verbatim}
+ fill(); // turn filling on
+ fill(color); // turn filling on, specify color
+ nofill(); // turn filling off, same as fill(false);
+\end{verbatim}
+
+
+\subsection{Paths}
+
+Paths and borders of filled regions are drawn with two \emph{pen}s,
+each described by color and line width. The \emph{line pen} draws
+all path-like objects. The \emph{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.
+\findex{pen}
+\begin{verbatim}
+ pen(len); // set line pen width
+ pen(color); // set line color, keep width
+ pen(color, len); // set color and width
+\end{verbatim}
+As usual, \code{len} may be either a length string or a \code{double},
+interpreted as a width in~\code{pt}. There are \code{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:
+\findex{plain}
+\findex{bold}
+\findex{bbold}
+\begin{verbatim}
+ plain([color]); // 0.4pt
+ bold([color]); // 0.8pt
+ bbold([color]); // 1.6pt
+\end{verbatim}
+
+
+\subsubsection*{Path Style}
+
+\index{Path!style}
+By default, path-like objects are drawn with solid lines. Dashed,
+dotted, and free-form path style patterns are also available. (The
+\code{base} underlayer is always solid.) The page length of a pattern
+defaults to 12~pt, but can be set.
+\findex{line\_style}
+\findex{dash\_size}
+\begin{verbatim}
+ line_style(string);
+ dash_size(len=12);
+\end{verbatim}
+The path style is set with a WYSIWYG string of dashes, spaces, and
+periods, representing a pattern of dashes, gaps, and dots. In the
+sample styles below, the repeating units have the same page size,
+12~pt.
+\begin{center}
+ \input{pathstyle.eepic}
+\end{center}
+For brevity and uniformity, named commands are provided.
+\findex{solid}
+\findex{dashed}
+\findex{dotted}
+\begin{verbatim}
+ solid(); "-" dashed(); "- -" dotted(); " . "
+\end{verbatim}
+A sequence of \teximath{n}~dashes, spaces, and dots corresponds to a
+dash/dot pattern in an interval divided into \teximath{n}~subintervals
+of equal length. If the \teximath{i}th character is a dash or space,
+the \teximath{i}th~subinterval is drawn solid or empty,
+respectively. If the \teximath{i}th~character is a period, a dot is
+placed at the midpoint of the \teximath{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 \code{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 \code{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~\ref{section:extensions} for guidance.
+\index{Path|)}
+
+
+\subsection{Text Objects}
+
+\index{Labels|(emph}
+\index{Labels!alignment}
+
+Two types of textual element may appear in a file: \emph{labels} (text
+boxes) and \emph{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 \emph{alignment point} is attached to each
+label, and Cartesian coordinates position the alignment point.
+
+\subsubsection*{Labels}
+
+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:\input{basepoint.eepic}
+
+\index{Labels!alignment|(}
+The alignment point may be \emph{offset} manually by a specified
+number of \code{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.
+\findex{label}
+\begin{verbatim}
+ label(P posn, P offset, string msg, [align]);
+ label(posn, msg);
+\end{verbatim}
+The first two components of the \code{offset} argument are numbers
+of~\code{pt} to shift the alignment point right and up. The optional
+\code{align} argument may be one---or an appropriate pair---of
+\code{t}, \code{b}, \code{r}, or~\code{l} (top, bottom, right, left),
+or~\code{c} (center). These alignment options specify the position of
+the label \emph{relative to the Cartesian location}~\code{posn},
+namely they work \emph{opposite} to the way they work in \LaTeX.
+\begin{center}
+ \input{alignment_lr.eepic}\qquad
+ \input{alignment.eepic}
+\end{center}
+\index{Labels!alignment|)}
+
+The \code{msg} argument is usually a snippet of \LaTeX\ code enclosed
+in double quotes. \CXX~treats ``\verb+\+'' as an escape character, so
+a double backslash is needed in the source to get a single backslash
+in the output. For example,
+\begin{verbatim}
+ label(P(0,0), P(2,-1), "$\\rho = \\sin\\theta$", br);
+\end{verbatim}
+positions an alignment point \code{2pt}~right and \code{1pt}~below the
+(Cartesian) origin, and typesets the equation
+\teximath{\rho=\sin\theta} below and to the right.
+
+\index{Labels!rotated}
+\index{Angle units}
+Labels can be rotated; the (counterclockwise) angle is set in current
+angle units with the command \code{label\_angle(theta)}. For example,
+a rotation angle of~90 degrees prints labels along a vertical
+axis. Though label rotation has legitimate uses, it can make labels
+more difficult to read, defeating their purpose. Do not use rotated
+labels merely because they are available. As a practical matter, if an
+output file contains rotated labels, the enclosing document must use
+the \code{rotating} package. \code{elaps} automatically loads this
+package.
+
+\index{Affine map!action on labels}
+An \code{affine} behaves moderately intelligently when acting on a
+marker or label. The mapping is applied to the label's location, and
+the ``linear part'' is used to adjust the offset and label angle. No
+attempt is made to treat alignment. For best results, if a
+\code{screen} will have an \code{affine} applied to it, label
+positions should be fine-tuned only with offsets, not alignment
+arguments. In all situations, the font itself is unchanged; no
+attempt is made to print sheared, scaled, or reflected text. The
+sample file \filename{inverse.xp} illustrates the effect of affine
+maps on labels.
+
+
+\subsubsection*{Fonts and Type Size}
+
+\index{Fonts}
+\index{Labels!fonts in}
+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
+\findex{font\_size}
+\findex{font\_face}
+\begin{verbatim}
+font_size("Large");
+font_face("sc");
+\end{verbatim}
+The argument of \verb+font_size+ is a valid \LaTeX\ size. If no
+argument is given, \code{normalsize} is understood. \verb+font_face+
+accepts a two-letter string, appended to the string ``\code{text}'' to
+give a \LaTeX\ font declaration command (``\code{textsc}'' above).
+Finer-grained control is accomplished by placing \LaTeX\ commands
+into the label text.
+
+
+\subsubsection*{Label Attributes and Masked Labels}
+
+Each label command has a corresponding ``mask'' version
+(\code{masklabel}) that draws an opaque rectangle under the label
+text. The mask size exceeds the label's size by an amount of
+\emph{padding}, and the mask is itself surrounded by a rectangular
+\emph{border}, of specified color and width.
+\findex{label\_color}
+\findex{label\_mask}
+\findex{label\_pad}
+\findex{label\_border}
+\findex{no\_label\_border}
+\begin{verbatim}
+ label_color(color); // set label text color
+ label_mask(color=White()); // set mask color
+ label_pad(string len);
+
+ label_border(color, [len]); // set color (and line width)
+ label_border(len); // set line width only
+ no_label_border(); // turn off label borders
+\end{verbatim}
+
+
+\subsubsection*{Markers}
+
+\index{Marker types|(}
+\ePiX's marker types, listed in Table~\ref{table:marker}, are obtained
+with the command \verb+marker(P pt, <MARKER TYPE>);+ Several
+``dot-like'' marker types are available by name: \input{dots.eepic}
+\findex{spot}
+\findex{dot}
+\findex{ddot}
+\findex{box}
+\findex{bbox}
+\findex{ring}
+\findex{circ}
+\begin{verbatim}
+ spot(P pt); dot(P pt); ddot(P pt);
+ --- box(P pt); bbox(P pt);
+ ring(P pt); circ(P pt); ---
+\end{verbatim}
+A \code{circ} is filled with the current \code{mask\_color}, and a
+\code{ring} is ``hollow''. Each dot-like marker can also be called
+with label syntax, generating a labeled marker with one command.
+\begin{verbatim}
+ dot(P posn, offset=P(0,0), msg="", align=none); // etc.
+\end{verbatim}
+
+\findex{dot\_size}
+By default, \code{spot}~and \code{ring} are 4~pt in diameter;
+\code{dot}, \code{box}, and~\code{circ} are 3~pt in diameter;
+\code{ddot}~and \code{bbox} are 2~pt in diameter. At arbitrary
+diameter, a \code{spot} is \teximath{4/3}~the diameter of a~\code{dot}
+and a~\code{ddot} is \teximath{2/3}~the diameter. The command
+\code{dot\_size(diam=3)} sets the diameter of a \code{dot}, and hence
+the size of all dot-like markers.
+
+\begin{table}[tb]
+ \begin{center}
+ \input{marker.eepic}
+ \end{center}
+ \caption{\ePiX's \code{marker} types.}
+ \label{table:marker}
+\end{table}
+\index{Marker types|)}
+
+
+
+\subsubsection*{Reminders}
+
+When constructing and placing a label,
+\begin{itemize}
+\item Offsets are specified in \code{pt} (true length), not Cartesian
+ units: A label's location relative to its alignment point should not
+ depend on the logical or printed size of the figure.
+
+\item The label text is enclosed in double quotes (the single
+ character~\code{"}), and contains the \LaTeX\ code to generate the
+ label. Backslashes are doubled.
+ \index{Labels!backslash in}
+ \index{Labels!in double quotes}
+\end{itemize}
+\index{Labels|)}
+
+
+\subsection{Color Declarations}
+
+Old-style color declarations set the fill color, line color, and
+text color.
+\findex{rgb}
+\findex{cmyk}
+\begin{verbatim}
+ rgb(r, g, b); cmyk(c, m, y, k);
+ rgb(P); cmyk(P); // for function-controlled colors
+ red(d); // similarly for other primaries
+\end{verbatim}
+\index{Color|)}
+
+
+\section{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.
+
+
+\subsection{Geometric Data Structures}
+
+\index{Point|(}
+The simplest object in the world, and by far the most common named
+data structure, is~\code{P}, an ordered triple of real numbers
+(double-precision floats). The function~\code{P(x1,x2,x3)} creates the
+point~\teximath{(x_1,x_2,x_3)}. If only two arguments are provided,
+\teximath{x_3=0} by default. This convention allows \ePiX\ to treat
+2-~and 3-dimensional figures uniformly. The standard basis is
+available: \code{E\_1=P(1,0,0)}, etc.
+
+Depending on context, a \code{P} may represent either a
+\emph{location} (point) or a \emph{displacement} (vector). Almost all
+\ePiX\ functions treat a~\code{P} as a point. However, algebraic
+operators and commands that plot vector fields treat \code{P}
+arguments as displacements.
+
+Polar, cylindrical, and spherical coordinate \code{P}~constructors are
+sensitive to the current angular mode.
+\index{Angular mode}
+\findex{P}
+\findex{polar}
+\findex{cis}
+\findex{cyl}
+\findex{sph}
+\begin{verbatim}
+ 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))
+\end{verbatim}
+
+Algebraic operations---addition/subtraction, scalar multiplication;
+scalar, cross, and componentwise products; orthogonalization---can
+be performed on~\code{P}s. In compound expressions, the binary
+operators below should be enclosed in parentheses, and scalars must be
+collected at left, \code{P}s at right.
+\findex{P.x1}
+\findex{P.x2}
+\findex{P.x3}
+\findex{J}
+\begin{verbatim}
+ double u=pt.x1(); // first coordinate of pt, etc.
+ P(a,b,c)|P(x,y,z); // scalar 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)
+\end{verbatim}
+Explicitly, \code{p\%q}~is the unique vector \code{p+k*q}
+perpendicular to~\code{q}.
+
+\code{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 \code{P}~operators.
+\index{Point|)}
+
+
+\subsubsection*{Other Geometric Classes}
+
+In addition to~\code{P}, objects of type \code{Circle}, \code{Plane},
+\code{Segment}, and \code{Sphere} can be used for Euclidean geometry
+constructions. Simple affine operations are supplied for each type, as
+is a \code{draw()} function, which represents the object as a path in
+the screen.
+\findex{shift}
+\findex{move\_to}
+\findex{scale}
+\findex{draw}
+\begin{verbatim}
+ 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();
+\end{verbatim}
+A \code{Segment}'s ``center'' is its midpoint. A \code{Plane} has no
+center; \code{move\_to} translates the \code{Plane} to pass through
+\code{arg}, and \code{scale} has no effect.
+
+\index{Circle}
+A \code{Circle} data structure consists of a center, radius, and a
+perpendicular unit vector. Three constructors are provided:
+\findex{Circle}
+\begin{verbatim}
+ Circle(center=P(0,0,0), double rad=1, normal=E_3);
+ Circle(P center, P point);
+ Circle(P p1, P p2, P p3);
+\end{verbatim}
+The second constructor creates the \code{Circle} parallel to the
+\teximath{(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 \teximath{(x_1,x_2)}~plane.) The third returns the
+\code{Circle} passing through the given points; the points must not be
+collinear.
+
+The data defining a \code{Circle} are recovered with member functions
+named \code{center()}, \code{radius()}, and \code{perp()}.
+
+\index{Plane}
+\findex{Plane}
+A \code{Plane} is specified by a point and normal vector, or by three
+non-collinear points. The \code{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.
+
+\index{Segment}
+\findex{Segment}
+A \code{Segment} is constructed from its endpoints. The member
+function \code{midpoint()} returns the center.
+
+\index{Sphere}
+\findex{Sphere}
+A \code{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 \code{center()}~and \code{radius()} return the defining
+data. Capabilities specific to geography and spherical geometry are
+described below, pp.~\pageref{non-eucl}ff.
+
+The \code{draw()} function of a \code{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 \code{Sphere} and
+the center is not close to the \code{target}.
+
+
+\subsubsection*{Intersection}
+
+\index{Intersection}
+
+To facilitate geometric computation, \ePiX's \code{Circle},
+\code{Plane}, \code{Segment}, and \code{Sphere} classes can be
+intersected with the \code{*}~operator.
+\texicomment
+Table~\ref{table:intersect}
+lists the return types for each pair of arguments. Intersection is
+commutative, so only the top half of the table is shown. For purposes
+of intersection, a \code{Segment} is extended into a line.
+The sample file \filename{pascal.xp} gives typical applications of
+objects and intersection.
+\findex{intersection}
+\begin{table}[hbt]
+\begin{center}
+ \begin{tabular}{c|cccc}
+ \code{*} &
+ \code{Segment} & \code{Circle} & \code{Plane} & \code{Sphere} \\
+ \hline
+ \code{Segment} & \code{P} & \code{Segment} & \code{P} & \code{Segment} \\
+ \code{Circle} & & \code{Segment} & \code{Segment} & \code{Segment} \\
+ \code{Plane} & & & \code{Segment} & \code{Circle} \\
+ \code{Sphere} & & & & \code{Circle}
+ \end{tabular}
+ \caption{Object intersection types.}
+ \label{table:intersect}
+\end{center}
+\end{table}
+\texicommentend
+
+A \code{Circle} has a center, radius, and unit normal; a \code{Plane}
+has a distinguished point and unit normal; a \code{Segment} has two
+endpoints; a \code{Sphere} has a center and radius. An object is
+\emph{malformed} if these conditions are not met. The constructors
+return well-formed objects with two exceptions: \code{Circle} and
+\code{Plane} create malformed objects if called with three collinear
+points. The operator~\code{*} returns a malformed object if either
+argument is malformed, or if the operands are disjoint, tangent, or
+coincident. Malformedness is benign: Calling \code{draw()} on a
+malformed object does nothing.
+
+
+\subsubsection*{Orthonormal Frames}
+
+A \code{frame} comprises three mutually perpendicular unit
+vectors. The constructor takes three vectors. The \code{frame}'s third
+vector~\teximath{e_3} is positively proportional to~\code{v3}, the
+second vector~\teximath{e_2} is positively proportional to
+\code{v2\%v3}, and the first is the cross product,
+\teximath{e_1=e_2\times e_3}. Thus, a \code{frame} is right-handed,
+and does not depend on~\code{v1}.
+
+The elements of a \code{frame} are named \code{sea}, \code{sky}, and
+\code{eye}, just as for the \code{camera}. A \code{frame} can be
+rotated through an arbitrary angle about any of its elements.
+\findex{frame}
+\begin{verbatim}
+ frame(); // the standard basis {E_1, E_2, E_3}
+ frame fr(v1, v2, v3); // orthonormalize {v1, v2, v3}
+ fr.sea(); // the first element of fr, etc.
+ fr.rot1(theta); // rotate fr through theta about sea, etc.
+\end{verbatim}
+
+
+\subsection{Path-Like Elements}
+
+Basic path-like objects are drawn with named commands. Arguments of
+polygon commands are endpoints/vertices. Except for \code{line}~and
+\code{Line}, the following are subject to filling.
+\findex{line}
+\findex{Line}
+\findex{triangle}
+\findex{rect}
+\findex{quad}
+\findex{circle}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+The optional \code{line} argument is an expansion parameter:
+\code{line(p1,p2,t);} draws a segment centered at the midpoint of
+\code{p1}~and \code{p2}, with length scaled
+by~\teximath{2^{t/100}}. (Setting \teximath{t=100} doubles the length,
+while \teximath{t=-100} halves the length.) The arguments of
+\code{rect()} must lie in a plane parallel to a coordinate plane. The
+arguments to \code{circle} commands are the same as for \code{Circle}
+constructors.
+
+Quadratic and cubic splines are described by their control points. A
+list of~\code{P} is drawn as a ``natural'' spline (the \teximath{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.
+\findex{spline}
+\findex{arc}
+\findex{ellipse}
+\begin{verbatim}
+ 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]);
+\end{verbatim}
+\texicomment
+Mathematically, these commands draw parametric paths
+\begin{align*}
+ \text{Spline:}\quad&(1-t)^2 p_1 + 2(1-t)t p_2 + t^2 p_3,
+ && t\in[0,1] \\
+ \text{Spline:}\quad&(1-t)^3 p_1 + 3(1-t)^2t p_2 + 3(1-t)t^2 p_3 + t^3p_4,
+ && t\in[0,1] \\
+ \text{Arc:}\quad&\mathrm{ctr} + (\cos t)(\mathrm{rad},0,0)
+ + (\sin t)(0,\mathrm{rad},0),
+ && t\in[t_\mathrm{min}, t_\mathrm{max}] \\
+ \text{Ellipse:}\quad&\mathrm{ctr} + (\cos t)v_1 + (\sin t)v_2,
+ && t\in[t_\mathrm{min}, t_\mathrm{max}].
+\end{align*}
+\texicommentend
+If parameter bounds are omitted in an \code{ellipse} command, the
+entire ellipse is drawn. When the angular range subtends one or more
+full turns in an \code{arc}~or \code{ellipse} the curve is subject to
+filling.
+
+Commands for planar (half-)ellipses remain from \ePiX's early days:
+\findex{ellipse}
+\findex{ellipse\_left}
+\findex{ellipse\_right}
+\findex{ellipse\_top}
+\findex{ellipse\_bottom}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+If \code{radius} is \code{P(a,b)}, these commands draw all or half of
+the ellipse with given center in the \teximath{(x_1,x_2)} plane, axes
+parallel to the coordinate axes, and axis lengths \teximath{2a}~and
+\teximath{2b}.
+
+Two commands are available to mark off right angles or a subtended
+angle. Each accepts a spatial location and two non-zero directions,
+and draws a scene element in the plane spanned by the vectors.
+\findex{right\_angle}
+\findex{arc\_measure}
+\begin{verbatim}
+ right_angle(P loc, P v1, P v2, scale=8);
+ arc_measure(P loc, P v1, P v2, scale=8);
+ arc_measure(P loc, P v1, P v2, offset, text, align, scale=8);
+\end{verbatim}
+The \code{right\_angle} command does not check its arguments for
+perpendicularity. The \code{arc\_measure} commands mark the
+\emph{small} angle subtended by the directions; the label form places
+a label at the midpoint of the arc. The (optional) \code{scale}
+argument is the true size in~\code{pt} of the marker.
+
+
+\subsubsection*{Recursive Fractal Curves}
+
+\index{Path!fractal}
+Consider a path made up of equal-length segments that can point at any
+angle of the form~\teximath{2\pi k/n} radians, for \teximath{0\leq
+k<n}, like spokes on a wheel. A path is specified by a finite sequence
+of integers, taken modulo~\teximath{n}. For example, if
+\teximath{n=6}, then the sequence \teximath{0, 1, -1, 0} corresponds
+to the ASCII path \verb+_/\_+. \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,
+Figure~\ref{fig:fractal}. The seed above generates the standard
+von~Koch snowflake fractal. In code:
+\findex{fractal}
+\begin{verbatim}
+ const int seed[] = {6, 4, 0, 1, -1, 0};
+ fractal(P(a,b), P(c,d), depth, seed);
+\end{verbatim}
+The first entry of \code{seed[]} (here~6) is the number of
+``spokes''~\teximath{n}, the second~(4) is the number of terms in the
+seed, and the remaining entries are the seed proper. The final path
+joins \teximath{(a,b)}~to \teximath{(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.
+\begin{figure}[hbt]
+ \begin{center}
+ \input{koch.eepic}
+ \end{center}
+ \caption{Successive iterations of \{\code{4,8,0,1,0,3,3,0,1,0}\}}
+ \label{fig:fractal}
+\end{figure}
+
+
+\subsubsection*{Arrows}
+
+\index{Arrow}
+Line segments, splines, and arcs can be drawn with arrowheads at one
+end. In profile, an arrowhead's width is \code{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:
+\findex{arrow\_width}
+\findex{arrow\_ratio}
+\findex{arrow\_inset}
+\begin{verbatim}
+ arrow_width(w=3); // width in pt
+ arrow_ratio(r=5.5); // height-to-width
+ arrow_inset(c=0); // base indent as frac of ht
+\end{verbatim}
+\input{arrow.eepic} Inset\teximath{=0}\qquad
+\input{arrow25.eepic} Inset\teximath{=0.25}\qquad
+\input{arrow50.eepic} Inset\teximath{=0.5} \\
+The \code{inset} must be between \teximath{-1}~and \teximath{1}. Each
+\code{arrow} command accepts an optional \code{scale} argument, which
+scales the arrowhead.
+\findex{arrow}
+\begin{verbatim}
+ 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
+\end{verbatim}
+A few ``special-purpose'' commands are supplied:
+\findex{dart}
+\findex{aarrow}
+\findex{arc\_arrow}
+\begin{verbatim}
+ 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]);
+\end{verbatim}
+If an \code{arc\_arrow} is too short, nothing is drawn.
+
+
+\subsection{Coordinate Axes and Labels}
+
+\index{Labels!axis|(}
+\index{Axes!labeling}
+\index{Axes|(}
+\ePiX\ provides an \code{axis} class for coordinate axes. Labels are
+generated automatically in a variety of styles: decimal, scientific
+notation, fraction, and trigonometric fraction. Logarithmic axes and
+labels are available. Axis and labeling commands from Version~1.0 have
+been retained.
+
+
+\subsubsection*{The \code{axis} Class}
+
+An \code{axis} consists of a line segment divided into a specified
+number of equal-length subintervals by ``major'' (long) tick marks.
+Each subinterval may be divided further by ``minor'' (short) tick
+marks. Minor ticks may be equally-spaced (``Cartesian'') or
+logarithmically placed. Finally, a label is written at each major tick
+mark with specified offset and alignment. Labels are generated
+automatically from the endpoints, so the line should be parallel to a
+coordinate axis. Label attributes (masking, borders, font size and
+face, rotation angle) are determined by the current label style, not
+by the \code{axis}.
+
+The command
+\findex{axis}
+\begin{verbatim}
+ axis(P tail, P head, int n, P offset=P(0,0), [align = none]);
+\end{verbatim}
+creates an axis joining \code{tail} to \code{head}, divided into
+\code{n}~segments of equal length, with a major tick mark and label at
+each division point and endpoint. The \code{offset} and \code{align}
+arguments have the same meaning as for ordinary labels.
+
+The number and length of minor ticks, and the alignment of ticks, are
+controlled with member functions:
+\findex{axis.subdivide}
+\findex{axis.tick\_ratio}
+\findex{axis.align}
+\begin{verbatim}
+ axis Ax(P(a,c), P(b,c), n);
+ Ax.subdivide(n); // put n-1 minor ticks in each axis segment
+ Ax.tick_ratio(r); // minor length = r*major length
+ Ax.align(AL=c); // align all ticks; AL = t, b, l, r, or c
+\end{verbatim}
+By default, major ticks are \code{6pt}~long and twice the length of
+minor ticks. The global declaration \code{tick\_size(len)} sets the
+major length, subject to ``reasonable stylistic limits''. For visual
+consistency, tick lengths should not be changed casually.
+
+\index{Axes!labeling}
+Labels on an \code{axis} may be drawn in several styles, selected with
+member functions:
+\findex{axis.dec}
+\findex{axis.frac}
+\findex{axis.trig}
+\findex{axis.sci}
+\findex{axis.unmark}
+\findex{axis.precision}
+\findex{axis.align\_labels}
+\begin{verbatim}
+ Ax.dec(); // decimals (default)
+ Ax.frac(); // fractions, e.g. 0.5 -> \frac{1}{2}
+ Ax.trig(); // fractional multiples of \pi
+ Ax.sci(); // scientific notation, k\times base^N
+
+ Ax.unmark(double); // remove label at selected location
+ Ax.precision(p); // set number of digits for decimal labels
+ Ax.align_labels(AL); // re-align labels
+\end{verbatim}
+Arbitrary textual labels depending on one coordinate are obtained by
+writing a \code{string}-valued function of~\code{double} and
+``registering'' it:
+\findex{axis.label\_rep}
+\begin{verbatim}
+ // f represents x as a string in given precision and base
+ std::string f(double x, unsigned int prec, unsigned int base);
+ Ax.label_rep(f);
+\end{verbatim}
+For example, textual tags can be printed instead of numeric labels.
+
+By default, an \code{axis} is Cartesian. The member function
+\code{log(int b=10)} converts an \code{axis} to ``log mode'' with
+specified base; this affects both tick marks and labeling. If \code{b}
+is at least~3, minor tick marks appropriate for a logarithmic axis
+base~\code{b} are drawn. Second, labels are written in decimal or
+scientific notation appropriately for a logarithmic axis; that is,
+``\teximath{k\times b^N}'' (or its decimal value) is written at
+location \teximath{N+\log_b k}.
+
+Minor ticks of a log \code{axis} may be labeled individually; again,
+this is controlled with member functions:
+\findex{axis.tag}
+\findex{axis.tag235}
+\findex{axis.tags}
+\findex{axis.untag}
+\begin{verbatim}
+ Ax.tag(d); // labels at N+log_b(d)
+ Ax.tag235(); // tag 2, 3, and 5 if b=10
+ Ax.tags(); // tag 1, ..., b-1
+ Ax.untag(); // remove all tags, including 1
+ Ax.untag(double); // remove one tag, e.g. Ax.untag(9);
+\end{verbatim}
+
+For convenience, an \code{axis} object along an edge of the active
+\code{screen} can be created with a named command:
+\findex{top\_axis}
+\findex{bottom\_axis}
+\findex{left\_axis}
+\findex{right\_axis}
+\begin{verbatim}
+ top_axis(n, offset, align);
+ bottom_axis(n, offset, align);
+ left_axis(n, offset, align);
+ right_axis(n, offset, align);
+\end{verbatim}
+The ticks automatically point into the bounding box.
+
+The functions above create objects or set \code{axis} attributes, but
+write no output. Tick marks and labels can be printed separately, or
+at once:
+\findex{axis.draw}
+\findex{axis.draw\_ticks}
+\findex{axis.draw\_labels}
+\begin{verbatim}
+ Ax.draw(); // axis, tick marks, and labels
+ Ax.draw_ticks(); // axis and ticks only
+ Ax.draw_labels();
+\end{verbatim}
+
+
+\subsubsection*{Other Axis-Drawing Commands}
+
+\index{Axes!logarithmic}
+\ePiX\ formerly supplied commands for drawing simple axes and their
+labels. These commands have been kept for compatibility. Horizontal
+axes are generated with
+\findex{h\_axis}
+\findex{h\_log\_axis}
+\findex{v\_axis}
+\findex{v\_log\_axis}
+\begin{verbatim}
+ h_axis(p1, p2, n, align=c); // n subintervals (n+1 ticks)
+ h_log_axis(p1, p2, n, align=c, base=10);
+\end{verbatim}
+For vertical axes, use \code{v\_axis}. The style of tick mark is
+appropriate for an axis of the given type. Horizontal axis tick marks
+may be aligned \code{t}~(above the axis) or~\code{b}
+(below). Similarly, vertical axis ticks may be aligned \code{r}~or
+\code{l}.
+
+The endpoint arguments of a coordinate axis may be omitted, in which
+case they default to \teximath{p_1=(x_\mathrm{min},0)} and
+\teximath{p_2=(x_\mathrm{max},0)} for a horizontal axis, or to
+\teximath{p_1=(0,y_\mathrm{min})} and
+\teximath{p_2=(0,y_\mathrm{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
+\findex{h\_axis\_labels}
+\findex{h\_axis\_masklabels}
+\findex{h\_axis\_log\_labels}
+\findex{h\_axis\_log\_masklabels}
+\findex{v\_axis\_labels}
+\findex{v\_axis\_masklabels}
+\findex{v\_axis\_log\_labels}
+\findex{v\_axis\_log\_masklabels}
+\begin{verbatim}
+ 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, [n], offset, [align], base=10);
+ h_axis_log_masklabels(p1, p2, [n], offset, [align], base=10);
+\end{verbatim}
+Labels for a vertical axis are generated with \code{v\_axis\_labels},
+etc. The labels are automatically generated to match their horizontal
+location. The first puts \teximath{(n+1)}~evenly-spaced labels on the segment
+joining \code{p1}~and \code{p2}. As with ordinary labels, the
+\code{offset} is in~\code{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 \code{axis\_[mask]labels} command, with the same defaults. The
+\code{offset} and number of labels must always be specified.
+
+
+\subsubsection*{Broken Axes}
+\index{Axes!broken}
+
+Broken axes are best drawn using page layout, especially if axis
+labels are to be drawn. To accomplish the task, create a screen for
+each piece of axis, using appropriate Cartesian coordinates for the
+corners, then \code{inset} the screens so the axis pieces are nearly
+end to end. A zig-zag glyph signifies the break:
+\findex{axis\_break}
+\begin{verbatim}
+ axis_break(P, P, scale=12);
+\end{verbatim}
+The \code{P} arguments are the screen coordinates of the ends to be
+joined; the optional third argument is the true height and width
+in~\code{pt} of the glyph. The sample file \filename{coord\_tricks.xp}
+uses layout and axis breaks.
+
+
+\subsubsection*{Coordinate Grids}
+
+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.
+\findex{grid}
+\findex{polar\_grid}
+\begin{verbatim}
+ grid(n1, n2); // fills the bounding box
+ grid(p1, p2, n1, n2); // fills the box with corners p1, p2
+ polar_grid(r, n1, n2);
+\end{verbatim}
+
+Log and semi-log grids are drawn with analogous syntax:
+\findex{log\_grid}
+\findex{log1\_grid}
+\findex{log2\_grid}
+\begin{verbatim}
+ 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
+\end{verbatim}
+The~\teximath{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.
+
+\index{Graph paper}
+Graph paper may be created by superimposing grids:
+\texicomment
+\begin{center}
+ \begin{minipage}[b]{2.5in}
+ \begin{footnotesize}
+\texicommentend
+\findex{pen}
+\findex{grid}
+\begin{verbatim}
+ pen(0.25);
+ grid(10*xsize(), 10*ysize());
+ pen(0.5);
+ grid(2*xsize(), 2*ysize());
+ pen(1);
+ grid(xsize(), ysize());
+\end{verbatim}
+\texicomment
+ \end{footnotesize}
+ \end{minipage}
+ \qquad
+ \input{graphpaper.eepic}
+\end{center}
+\index{Axes|)}
+\texicommentend
+
+\subsection{The Path Class}
+
+\index{Path!class}
+A \code{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 \code{P}-valued
+function~\code{f} of one variable.
+\findex{path}
+\begin{verbatim}
+ 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]);
+\end{verbatim}
+
+The member function \code{pt()} accepts a~\code{P} or three (or two)
+doubles and appends the specified point to a \code{path}. This
+snippet creates a regular \teximath{n}-gon:
+\begin{verbatim}
+ path ngon; // declare new path
+ for (int i=0; i<=n; ++i)
+ ngon.pt(cis(i*full_turn()/n)); // works in all angle modes
+\end{verbatim}
+Compound paths may be built by concatenation. If \code{path1}~and
+\code{path2} share an endpoint, the commands
+\begin{verbatim}
+ path1 += path2;
+ path1 -= path2;
+\end{verbatim}
+replace \code{path1} with the result of traversing \code{path1}
+``forward'', then following \code{path2} in the forward or reverse
+direction (respectively). For expected results, the first
+(or last) point on~\code{path2} should be the last point
+of~\code{path1}. The notation suggests 1-dimensional homology
+chains. The sample file \filename{contour.xp} illustrates path
+creation and manipulation.
+
+A \code{path} is a data structure, and must be drawn explicitly to
+create visible output. By default a \code{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
+\teximath{n}-gon snippet above,
+\findex{path.close}
+\findex{path.fill}
+\findex{path.draw}
+\begin{verbatim}
+ ngon.close(); // mark path as closed
+ ngon.fill(); // draw filled region if filling is active
+ ngon.draw(); // print to the screen
+\end{verbatim}
+\code{path::close()} adds a closing edge if necessary. Once a
+\code{path} is closed, no more points can be added. A closed path
+clips and crops differently than an open \code{path} with the same
+data. \code{path::fill()} has no effect on an unclosed \code{path}.
+
+
+\subsection{Function Plotting}
+
+\index{Plotting|(}
+The noun ``map'' refers to a \CXX\ function that accepts one or
+more \code{double} arguments and returns a \code{double}~or
+a~\code{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 \code{double}-valued maps are
+graphed and \code{P}-valued maps are drawn parametrically. Either sort
+of depiction is called a ``plot''. \ePiX\ plots are either ``wire
+mesh'', produced by a \code{plot} command, or ``shaded'', produced by
+a \code{surface} command.
+
+
+\subsubsection*{Basic Plotting}
+
+For the moment, ``function'' means ``function of one variable''
+(precisely, a \code{double}-valued function of a \code{double}
+variable). A function graph depends on the domain and the number of
+points to use. Each of the commands
+\findex{plot}
+\findex{polarplot}
+\findex{shadeplot}
+\begin{verbatim}
+ plot(f, t_min, t_max, n);
+ polarplot(f, t_min, t_max, n);
+ shadeplot(f, t_min, t_max, n);
+\end{verbatim}
+graphs the function~\code{f} on the interval \code{[t\_min, t\_max]}
+by dividing the interval into \code{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
+\code{shadeplot}, the region between their graphs is shaded.
+
+
+\subsubsection*{Domains and Wiremesh Plots}
+
+\index{Domain|(}
+An \ePiX\ \code{domain} is a coordinate box of dimension one, two, or
+three, specified by a pair of opposite corners and two \emph{meshes}
+(``coarse'' and ``fine'', respectively) which specify the amount of
+data to be plotted. Plotting is explained in detail below.
+\findex{domain}
+\begin{verbatim}
+ // [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)]);
+\end{verbatim}
+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 \teximath{m_i}~should be a (usually small) integer multiple
+of~\teximath{n_i} for each~\teximath{i}.
+
+A \code{domain} may be \emph{resized} in any coordinate for which the
+thickness is positive, and can be \emph{sliced} by setting one
+variable to a constant. The result of slicing is a \code{domain} whose
+dimension is one smaller than the original. Finally,
+``\code{slices}'' operators return the list of \code{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.
+\findex{domain.resize}
+\findex{domain.slice}
+\findex{domain.slices}
+\begin{verbatim}
+ R2.resize2(a,b); // [a1,b1] x [a,b]
+ R2.slice1(t); // set x1 = t
+ R3.slices3([n]); // (n+1) domains with x3 = const
+\end{verbatim}
+\begin{center}
+ \input{slices.eepic}
+\end{center}
+\smallskip
+When possible, resizing preserves grid square sizes. Generally,
+though, integer truncation occurs: If \code{R=domain(P(0,0), P(1,1),
+mesh(10,6))}, then \code{R.resize1(0,0.25)} is the rectangle
+\teximath{[0,0.25]\times[0,1]} subdivided into \teximath{2\times6}
+subrectangles, since \teximath{10\div4=2} in integer arithmetic. For
+expected behavior, choose mesh sizes to avoid integer truncation.
+
+
+The arguments of a \code{plot} command are a map, followed by either a
+domain or its logical equivalent.
+\findex{plot}
+\begin{verbatim}
+ 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
+\end{verbatim}
+By (compiler-enforced) convention, \code{plot} commands involving a
+\code{P}-valued map accept a \code{domain} argument, as in the second
+and third commands above. To plot a \code{double}-valued function, by
+contrast, supply the logical equivalent of a \code{domain}, usually
+the endpoints and the number of intervals, as in the first \code{plot}
+command above.
+
+Resizing and slicing allow a map~\code{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 \code{plot}
+command:
+\findex{plot}
+\begin{verbatim}
+ plot(F, R2.resize1(0,0.5));
+ plot(F, R2.slices1());
+\end{verbatim}
+
+
+\subsubsection*{Meshes and Plotting}
+
+The \code{P}~arguments of a \code{domain} are a pair of opposite
+corners. The first \code{mesh} argument, the \emph{coarse} mesh,
+specifies the number of subdivisions in each coordinate direction.
+The second \code{mesh}, the \emph{fine} mesh, determines the number of
+points used in each direction when plotting.
+
+\begin{comment}
+Suppose the \code{domain}~\code{R2} is, as above, the rectangle
+\teximath{[0,3]\times[-1,2]}. The argument \code{mesh(12,6)} divides the
+rectangle a \teximath{12\times6}~array of subrectangles known as the
+\emph{coarse mesh}. A \code{P}-valued map~\code{F} of two variables is
+plotted over the edges of the coarse mesh. Rather than drawing
+quadrilaterals, however, \ePiX\ draws the image curves at the
+resolution specified by the argument \code{mesh(60,60)}, the
+\emph{fine mesh}. In this example, the curves in each direction are
+drawn using 60~line segments.
+\end{comment}
+
+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~\ref{fig:plot} are drawn with a
+\teximath{6\times20} coarse mesh. In the first picture, the fine mesh
+is also \teximath{6\times20}, while in the second, the fine mesh is
+\teximath{12\times60}.
+
+\begin{figure}[hbt]
+ \begin{center}
+ \input{plot_a.eepic}\hspace*{0.5in}
+ \input{plot_b.eepic}
+ \caption{Coarse and fine meshes.}
+ \label{fig:plot}
+ \end{center}
+\end{figure}
+
+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 \emph{perpendicularly} to a coordinate direction,
+while the fine mesh's size determines the number of segments used
+\emph{along} that direction. For predictable results, the fine mesh
+should be a small multiple of the coarse mesh.
+
+Plotting works analogously for 3-dimensional \code{domain}s and maps
+depending on three variables: The ``one-dimensional skeleton'' of the
+\code{domain}'s image is drawn. A \code{P}-valued map of
+three variables can be plotted over a 1-~or 2-dimensional
+\code{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 \code{domain}.
+\index{Domain|)}
+
+
+\subsubsection*{Shaded Surfaces}
+
+\index{Plotting!surface|(}
+
+\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 \code{surface} command is identical to a \code{plot}
+command when only a single surface is drawn. For example,
+\findex{surface}
+\begin{verbatim}
+ surface(F, R, cull=0);
+\end{verbatim}
+plots the \code{P}-valued function~\code{F} over the domain~\code{R},
+the shaded equivalent of the corresponding \code{plot} command. The
+optional \code{cull} argument removes elements that point toward
+(\code{cull=-1}) or away from (\code{cull=1}) the camera. Naturally,
+orientation of mesh elements depends on the parametrization~\code{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 \code{cull} argument.
+\findex{surface\_rev}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+The first revolves the graph of~\teximath{f} about the
+\teximath{x}-axis, the second uses the parametric curve
+\teximath{t\mapsto\bigl(f(t),g(t)\bigr)} as profile. In each case, the
+parameter interval \verb+[t_min,t_max]+ is divided into \verb+n_lats+
+equal-length subintervals, \verb+n_longs+ copies of the profile curve
+are drawn, and the complete surface (one full turn) is drawn.
+
+The third form uses a \code{domain} to control the range of
+longitudes, and draws a surface of rotation in the Cartesian
+coordinate system defined by the orthonormal basis \code{coords}, by
+default the standard basis. The arguments \code{f}~and \code{g} define
+a parametric curve in the plane spanned by the first two elements
+of~\code{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 \emph{patch} is drawn, not the
+visible edge of the mathematical surface. See
+\filename{samples/artifacts.xp}.
+
+
+\subsubsection*{Multiple Domains and/or Maps}
+
+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 \code{domain}s. In the code snippets below, \code{F}~and
+\code{G} are \code{P}-valued functions of 3~variables, and~\code{R} is
+a 3-dimensional \code{domain}.
+
+To plot the images of several \code{domain}s under a \emph{single
+map}, assemble the \code{domain}s into a list if necessary, then issue
+a \code{surface} command:
+\findex{surface}
+\findex{domain\_list}
+\findex{domain\_list.add}
+\begin{verbatim}
+ 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
+\end{verbatim}
+For multiple maps, \ePiX\ provides the \code{scenery}
+class. Conceptually, \code{scenery} is an agglomeration of shaded
+surfaces, built one surface at a time from maps and 2-dimensional
+\code{domain}s. The \code{add} function accepts two arguments---a map,
+and either a \code{domain} or a list of \code{domain}s---and
+contributes its data to the \code{scenery} rather than plotting
+immediately. Completed \code{scenery} is drawn manually.
+\findex{scenery}
+\findex{scenery.add}
+\findex{scenery.draw}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+Complete examples are included in the \filename{samples} directory:
+\filename{spherical.xp}~and \filename{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 \filename{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
+\filename{hugelatex}; your mileage may vary.
+
+
+\subsubsection*{User-Specified Color Shading}
+
+\index{Color!surface plotting}
+By default, a \code{surface} or \code{scenery} is colored according to
+the current fill color. For finer control, each \code{surface},
+\code{surface\_rev}, and \code{scenery} command accepts an optional
+position-dependent \code{color} specification.
+\findex{surface}
+\findex{surface\_rev}
+\findex{scenery}
+\findex{scenery.add}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+The \code{color} argument is a \code{P}-valued function of two or
+three \code{double}s whose output is interpreted as a set of
+\code{RGB}~densities. If \code{color} takes two arguments, they are
+\code{domain} coordinates, and the surface is colored according to
+parameter values. If \code{color} takes three arguments, they are
+Cartesian coordinates, and the surface is colored according to spatial
+location. Please see the sample files
+\filename{surface\_shade.xp}~and \filename{S2\_harmonics.xp}.
+\index{Plotting!surface|)}
+
+
+\subsection{Calculus Plotting}
+\index{Plotting!calculus|(}
+
+\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, \code{f}~and \code{g} are \code{double}-valued
+functions of one variable.
+
+\subsubsection*{Utility Functions}
+
+\findex{sup}
+\findex{inf}
+\findex{newton}
+\begin{verbatim}
+ sup(f, a, b); // max/min of f on [a,b]
+ inf(f, a, b);
+ newton(f, g, x0); // find approximate crossing point
+\end{verbatim}
+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~\teximath{g} defaults to the zero function if
+omitted.
+
+\subsubsection*{Derivatives and Integrals}
+
+The classes \code{Deriv}~and \code{Integral} are used to calculate
+values of derivatives and integrals, and to plot these functions.
+\findex{Deriv}
+\findex{Deriv.eval}
+\findex{Deriv.left}
+\findex{Deriv.right}
+\findex{Integral}
+\findex{Integral.eval}
+\begin{verbatim}
+ 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
+\end{verbatim}
+The lower limit on an integral is~0 by default. \code{Deriv}s and
+\code{Integral}s can be used directly in a \code{plot} command:
+\findex{plot}
+\findex{riemann\_sum}
+\begin{verbatim}
+ 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);
+\end{verbatim}
+The second graphs the definite integral \teximath{x\mapsto\int_{x_0}^x
+f(t)\,dt} over~\teximath{[a,b]}. As above, \teximath{x_0}~defaults
+to~0. The third draws rectangles or trapezoids whose area approximates
+the definite integral of~\teximath{f} over~\teximath{[a,b]}. The
+\code{TYPE} may be \code{UPPER}, \code{LOWER}, \code{LEFT},
+\code{RIGHT}, \code{MIDPT}, or~\code{TRAP}.
+
+Tangent lines and envelopes (families of tangent lines) are drawn with
+\findex{tan\_line}
+\findex{envelope}
+\findex{tan\_field}
+\begin{verbatim}
+ 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
+\end{verbatim}
+The sample files \filename{conic.xp}~and \filename{lissajous.xp}
+illustrate these features.
+
+
+\subsubsection*{Systems of Differential Equations}
+
+Let \code{F}~be a \code{P}-valued function of two or three variables.
+\findex{ode\_plot}
+\findex{flow}
+\begin{verbatim}
+ ode_plot(F, p_0, t_min, t_max, n);
+ flow(F, p_0, t_max, n);
+\end{verbatim}
+The first plots the solution curve of the initial-value problem
+\teximath{\dot{x}=F(x)}, \teximath{x(0)=p_0}, over the specified time
+interval. If \teximath{t_\mathrm{min}} is omitted, its value is~0, so
+the curve starts at~\teximath{p_0}. With manual calculation to rotate
+a planar field a quarter turn, \code{ode\_plot} can be used to draw
+level curves (isobars) of a function of two variables; see the sample
+file \filename{dipole.xp}. The \code{flow} function returns the
+result of starting at~\teximath{p_0} and flowing by~\teximath{F} for
+time~\teximath{t_\mathrm{max}}, using Euler's method with~\teximath{n}
+time steps. 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~\code{R} in three styles:
+\findex{vector\_field}
+\findex{dart\_field}
+\findex{slope\_field}
+\begin{verbatim}
+ vector_field(F, R, [scale]); // true length
+ dart_field (F, R, [scale]); // const length
+ slope_field (F, R, [scale]); // const length
+\end{verbatim}
+The field is sampled at the grid points of the coarse mesh. If the
+domain is 2-dimensional, the plot is a planar slice of the field, even
+if the field depends on three variables. If the domain is
+3-dimensional, the field is drawn in successive slices
+\teximath{x_3=\mathrm{const}}, starting at the height of the first
+corner of~\code{R} and ending at the height of the second corner.
+
+The optional final argument, which defaults to~\teximath{1}, scales the
+arrowheads in a vector field, and scales the (constant) length of
+field elements for slope and dart fields. The sample files
+\filename{layout2.xp}, \filename{lorenz.xp}, \filename{slopefield.xp},
+and \filename{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.
+\index{Plotting|)}
+
+
+\subsection{Non-Euclidean Geometry}
+\label{non-eucl}
+
+\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.
+\findex{hyperbolic\_line}
+\findex{disk\_line}
+\begin{verbatim}
+ hyperbolic_line(p, q);
+ disk_line(p, q);
+\end{verbatim}
+For compatibility with 2-dimensional hyperbolic space, the half-space
+model is the set \teximath{\{(x_1,x_2,x_3)\mid x_2>0\}}.
+
+\index{Plotting!spherical|(}
+A \code{frame} determines geographical coordinates on a \code{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
+\code{Sphere}, a \code{frame}, the numerical latitude, and a range of
+longitudes. A longitude line is described similarly.
+\findex{latitude}
+\findex{longitude}
+\findex{back\_latitude}
+\findex{back\_longitude}
+\begin{verbatim}
+ latitude(lat, long_min, long_max, Sphere S, frame coords);
+ longitude(lngtd, lat_min, lat_max, Sphere S, frame coords);
+\end{verbatim}
+By default, \code{coords} is the standard \code{frame} and \code{S} is
+the unit sphere. These commands draw only the portion of the curve
+that is visible from the current viewpoint. The function
+\code{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:
+\findex{front\_arc}
+\findex{front\_arc2}
+\findex{front\_line}
+\findex{back\_arc}
+\findex{back\_arc2}
+\findex{back\_line}
+\begin{verbatim}
+ 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
+\end{verbatim}
+Triangles and regular (Platonic) polyhedra are provided. The sample
+file \filename{sample/polyhedra.xp} illustrates usage.
+\findex{front\_triangle}
+\findex{front\_tetra}
+\findex{front\_cube}
+\findex{front\_octa}
+\findex{front\_dodeca}
+\findex{front\_icosa}
+\findex{back\_triangle}
+\findex{back\_tetra}
+\findex{back\_cube}
+\findex{back\_octa}
+\findex{back\_dodeca}
+\findex{back\_icosa}
+\begin{verbatim}
+ 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
+\end{verbatim}
+Each function has a \code{back} version, which draws the hidden
+portion. The tetrahedron, cube, and octahedron are (up to scale)
+inscribed in the cube of side length~\teximath{2} centered at the origin whose
+sides are parallel to~\code{frame}. The point \teximath{(1,1,1)} is a vertex of
+the tetrahedron.
+
+Up to scale, the icosahedron's vertices lie on the golden rectangle
+with vertices \teximath{(\pm\gamma,0,\pm1)} and its images under cyclic
+permutation of coordinates. The dodecahedron is dual to the
+icosahedron.
+
+\subsubsection*{Spherical Plotting}
+
+Parametrized paths on a \code{Sphere~S} (by default the unit sphere)
+can be specified either by radial projection of a \code{P}-valued
+curve, or by stereographic projection of a plane curve given as a pair
+of \code{double}-valued functions:
+\findex{frontplot\_R}
+\findex{frontplot\_N}
+\findex{frontplot\_S}
+\findex{backplot\_R}
+\findex{backplot\_N}
+\findex{backplot\_S}
+\begin{verbatim}
+ 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
+\end{verbatim}
+Attempts to perform radial projection on a path through the origin
+will generate division-by-zero errors. Stereographic projection maps
+the equatorial plane \teximath{\{x_3=0\}} to the unit sphere by
+projection from the corresponding pole: \teximath{N=(0,0,1)},
+\teximath{S=(0,0,-1)}.
+
+Each spherical plot command has a \code{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.
+
+
+\subsection{Data Plotting}
+\index{Plotting!data|(}
+\index{Data plotting|(}
+
+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~\code{\%}
+is a comment.
+
+\ePiX\ provides two \code{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 \code{P}-valued
+function~\code{F}, and plot the resulting points:
+\findex{plot}
+\begin{verbatim}
+ plot("filename", STYLE, [i_1], [i_2], [i_3], [F]);
+ plot("filename", STYLE, F, [i_1], [i_2], [i_3]);
+\end{verbatim}
+The first argument is the name of the data file. The \code{STYLE} may
+be \code{PATH}, which joins the points in the order they appear, or
+any of the marker types in Table~\ref{table:marker}. The
+integers~\teximath{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''~\code{F} is omitted in
+the first command, it defaults to the Cartesian point constructor. The
+function~\code{F} is mandatory in the second form; useful choices
+include \code{log\_log}, \code{log\_lin}, and~\code{lin\_log}, which
+plot the corresponding coordinate logarithmically.
+
+
+\subsubsection*{Data Files}
+
+For more elaborate analysis, the \code{data\_file} class presents an
+interface to a file as an ordered list of columns. There are two
+general ways to create a \code{data\_file}: read in an external file,
+or generate data (up to three columns) using specified
+\code{double}-valued functions. In the constructors below, each
+function~\code{fi} is a \code{double}-valued function of one variable.
+\findex{data\_file}
+\findex{data\_file.read}
+\begin{verbatim}
+ 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
+\end{verbatim}
+
+Columns of a \code{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~\code{f} is a \code{double}-valued
+function of one variable and~\code{F} is a \code{P}-valued function of
+two or three variables, whose components are written back to the
+selected columns.
+\findex{data\_file.transform}
+\begin{verbatim}
+ DF.transform(f, i); // apply f to selected column(s)
+ DF.transform(F, i=1, j=2);
+ DF.transform(F, i, j, k);
+\end{verbatim}
+Basic statistical operations on columns are provided.
+\findex{data\_file.dot}
+\findex{data\_file.avg}
+\findex{data\_file.var}
+\findex{data\_file.covar}
+\findex{data\_file.regression}
+\begin{verbatim}
+ 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
+\end{verbatim}
+A \code{data\_file} is scatter plotted using syntax as described above.
+% The output is cropped automatically to the bounding box.
+\findex{data\_file.plot}
+\begin{verbatim}
+ DF.plot(STYLE, [i1], [i2], [i3], [F]);
+ DF.plot(STYLE, F, [i1], [i2], [i3]);
+\end{verbatim}
+Histograms and bar charts are described below.
+
+A \code{data\_file} can be written to a disk file as raw data, or in
+specified format. Below, \code{fmt} denotes a \code{string}-valued
+formatting function of two variables and \filename{myfile} is the
+name of the disk file to be written.
+\findex{data\_file.precision}
+\findex{data\_file.write}
+\begin{verbatim}
+ 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
+\end{verbatim}
+A column can be extracted as a \code{C++}~\code{vector} for use by
+another function.
+\findex{data\_file.column}
+\begin{verbatim}
+ DF.column(i); // i-th column
+ DF.column(f, i); // i-th column, transformed by f
+\end{verbatim}
+
+
+\subsubsection*{Data Containers}
+
+\ePiX\ provides a \code{data\_mask} class for culling data from a file
+according to the values in a specified column, and a \code{data\_bins}
+class for sorting data by value.
+
+A \code{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
+\code{double}-valued function of \code{double}, by default the
+identity, \teximath{f(x)=x}.
+\findex{data\_mask}
+\begin{verbatim}
+ data_mask dm("[a, b]", [f]);
+ data_mask dm(a, b, [f]);
+\end{verbatim}
+A \code{data\_mask} ``passes'' inputs~\teximath{x} if~\teximath{f(x)}
+lies in the interval. The member function \code{reverse()} inverts
+this logical test.
+
+The \code{data\_file} class has \code{prune} functions to cull
+rows for which a specified column's entry satisfies a
+\code{data\_mask}'s criterion.
+\findex{data\_mask.prune}
+\begin{verbatim}
+ 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]
+\end{verbatim}
+
+A \code{data\_bins} object models an interval divided at specified
+locations into ``bins'', not necessarily of equal length. Numerical
+data is read in and the number of points in each bin counted. The
+lifetime of a \code{data\_bins} object has two stages. First, ``cuts''
+(endpoints of subintervals) are added. Then, once data is read, the
+cuts are ``locked'' and cannot subsequently be changed.
+\findex{data\_bins}
+\findex{data\_bins.cut}
+\findex{data\_bins.read}
+\begin{verbatim}
+ // [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
+\end{verbatim}
+
+\index{Histograms}
+\index{Bar Charts}
+A \code{data\_bins} object can be plotted as a histogram (rectangles'
+\emph{area} is proportional to the bin population), bar chart
+(rectangles' \emph{height} is proportional to the bin population), or
+spline interpolation of a bar chart.
+\findex{data\_bins.histogram}
+\findex{data\_bins.bar\_chart}
+\findex{data\_bins.plot}
+\begin{verbatim}
+ db.histogram(c=1); // c = vertical scale factor
+ db.bar_chart(c=1);
+ db.plot(c=1);
+\end{verbatim}
+By default (\code{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 in the
+bin; thus, the total area over an interval~\teximath{[a,b]} does not
+depend on how~\teximath{[a,b]} has been subdivided. The sample files
+\filename{dataplot.xp}~and \filename{histogram.xp} illustrate use.
+
+Statistical convention dictates cuts be chosen distinctly from data
+values; that is, values should all fall strictly within a bin, not at
+a boundary point. With large, unknown data sets, this convention may
+be difficult to uphold. \ePiX\ attempts to handle anomalous data
+intelligently, by keeping counts of values ``out-of-range'' or
+``on-cut''.
+
+In detail, if \teximath{x<a} or \teximath{x>b} is a data value, it is
+counted as out-of-range and does not contribute to the histogram
+population. If \teximath{x=a} or \teximath{x=b}, the value counts as
+both out-of-range and on-cut but is added to the population of the
+lowest or highest bin, respectively. Any other cut appearing as a data
+input is flagged as on-cut, and increments the population of each
+adjacent bin by one-half. When a histogram or bar chart is written,
+\ePiX\ prints a warning message summarizing the number of anomalous
+data seen.
+
+
+\subsubsection*{Error Bars}
+\index{Error bars}
+
+Simple horizontal and vertical error bars are provided. The final
+(optional) argument is the true height or width (respectively) in pt.
+\findex{h\_error\_bar}
+\findex{v\_error\_bar}
+\begin{verbatim}
+ h_error_bar(P location, double error, <mark type>, ht=6);
+ v_error_bar(P location, double error, <mark type>, wd=6);
+\end{verbatim}
+
+To create more complex elements, such as asymmetric bars, whisker
+plots, labeled error bars, and the like, write a custom function using
+true-size drawing, see page~\pageref{truesize}. For example, a
+fillable, labeled, asymmetric, vertical rectangular error bar can be
+implemented (entirely in \ePiX) like this:
+\begin{verbatim}
+ void error_bar(P loc, double lo, double hi, P offset,
+ std::string text, align, double wd=6)
+ {
+ const double width(pt_to_screen(0.5*wd)); // converts to 3pt
+ rect(loc - P(width, lo), loc + P(width, hi));
+ line(loc - P(width, 0), loc + P(width, 0));
+ label(loc + P(width, 0), offset, text, align);
+ }
+\end{verbatim}
+For stylistic uniformity, functions such as this should be put into a
+library and used systematically. Section~\ref{section:extensions}
+outlines the process of writing, compiling, and using a custom
+library.
+\index{Plotting!data|)}
+\index{Data plotting|)}
+
+
+\subsection{Legends}
+\index{Legends}
+
+A \code{legend} systematically labels different parts of a plot by
+associating visual ``keys'' with explanatory text. This tends to be
+most useful for plots containing several distinct but conceptually
+related graphs requiring contrast.
+
+Visually, a \code{legend} is represented as an aligned list of rows,
+each containing a box (the key), a gap (the label skip), and some
+text. These rows are printed in a (usually large) masked label. By
+default, keys are \code{12pt}~squares bordered in black, the label
+skip is~\code{6pt}, the background is white, and the border is plain
+black. These attributes are controlled (simultaneously for all items)
+with member functions. Parameters of type \code{double} represent
+lengths in~\code{pt}.
+\findex{legend}
+\findex{legend.backing}
+\findex{legend.border}
+\findex{legend.item\_border}
+\findex{legend.label\_skip}
+\findex{legend.key\_size}
+\begin{verbatim}
+ legend L;
+ L.backing(color); // set background
+ L.border(color, [double]); // set border color [and width]
+ L.border(double); // border width
+
+ L.item_border(color, [double]);
+ L.item_border(double); // same, for item borders
+
+ L.label_skip(double);
+ L.key_size(double);
+\end{verbatim}
+
+
+\subsubsection*{Legend Keys}
+
+There are three types of legend key, representing filled regions,
+paths, and markers. Fill and path keys get their visual attributes
+from the current drawing state. A mark key must be told the marker
+type. Each is created by specifying the item text.
+\findex{legend.fill\_item}
+\findex{legend.path\_item}
+\findex{legend.mark\_item}
+\begin{verbatim}
+ L.fill_item(text);
+ L.path_item(text);
+ L.mark_item(<mark type>, text);
+\end{verbatim}
+Keys in the printed legend appear in the same order they are created
+in the input file.
+
+
+\subsubsection*{Creating a Legend}
+
+Normally, a \code{legend} is defined near the start of a file, and an
+item is added at the point in the file where the corresponding object
+or plot is drawn, so that the item receives the correct attributes. A
+\code{legend} is placed into the figure with the \code{draw}
+function. The arguments have the same meaning as for ordinary
+\code{label}s.
+\findex{legend.draw}
+\begin{verbatim}
+ L.draw(P location, P offset, align);
+\end{verbatim}
+All three arguments are mandatory. ``Global'' \code{legend} settings
+(border, backing, etc.) may be changed anywhere between the
+\code{legend}'s creation and \code{draw} function. The sample file
+\filename{legend.xp} revisits the example on
+page~\pageref{taylor_poly}, including a trig-labeled axis and a
+legend. The file \filename{shadeplot.xp} contains filled keys, and
+\filename{dataplot.xp} contains a \code{legend} with items of mixed
+type.
+
+
+\section{More About \CXX}
+\index{Cplusplus@\CXX|(emph}
+
+A textbook or similarly detailed reference is essential for serious
+study of~\code{C} or~\CXX. \emph{The \code{C} Programming Language},
+second edition, by Kernighan~and Ritchie~\cite{KnR}, is an excellent,
+manageable resource for the basics of procedural
+programming. \emph{C++ Primer Plus}, by Stephen Prata~\cite{Prata},
+clearly lays out the extensive details of~\CXX. Marshall Cline's
+\emph{\CXX\ FAQ Lite}~\cite{Cline} engagingly discusses common points
+of confusion and furnishes tips on good design and programming.
+
+\CXX\ 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 \CXX~program that writes a
+\LaTeX\ picture as output. \ePiX\ may be viewed as an extension
+to~\CXX; in the same way that \LaTeX\ furnishes a high-level interface
+to~\TeX, \ePiX\ provides a high-level bridge between the computational
+power of~\CXX\ and the \LaTeX\ \code{picture} environment.
+
+\index{Function}
+\index{Conditional statement}
+Like all high-level programming languages, \CXX\ 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.
+
+\subsection{Names and Types}
+
+\index{Variable!names|(}
+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.
+\index{Variable!names|)}
+
+\index{Variable!type of}
+Every variable in \CXX\ has a ``type'',
+such as integer (\code{int}), double-precision floating point
+(\code{double}), or Boolean (\code{bool}, true~or false). \ePiX\
+provides additional types, the most common of which is~\code{P}, for
+point. The construct \code{P(x,y,z)} creates~\teximath{(x,y,z)}, while
+\code{P(x,y)} gives~\teximath{(x,y,0)}, which is effectively the
+pair~\teximath{(x,y)}. A variable is defined by giving its type, its
+name, and an initializing expression.
+
+\index{Variable!pointer}
+\index{Pointer}
+In~\code{C} and~\CXX, a \emph{pointer} variable holds the memory
+address of another variable. Pointers are useful for manipulating
+(possibly large) data structures through ``handles'' of fixed small
+size. \CXX\ also provides \emph{references}, which bind an additional
+name to an existing object and allow the object to be manipulated
+through this alias. The statements
+\begin{verbatim}
+ double x=1; // ordinary variable definition
+ double& rx=x; // bind a reference, signified by &
+\end{verbatim}
+define a variable~\code{x} having the value~1, and bind a reference
+variable~\code{rx} to it. As long as~\code{rx} exists, it refers
+to~\code{x}. If the value of~\code{x} changes, the value of~\code{rx}
+does as well. Conversely, the value of~\code{x} can be altered by
+assigning to~\code{rx}. However,~\code{rx} is the size of a pointer,
+regardless of the size of~\code{x}, so~\code{rx} can be passed
+efficiently in a function call.
+\texicomment
+Some applications are discussed on page~\pageref{references}.
+\texicommentend
+
+
+\subsection{Functions}
+
+\index{Function|(}
+In a programming language, the term ``function'' refers to a block of
+code that is executable by name. A \CXX\ 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:
+\begin{verbatim}
+ int factorial(unsigned int n)
+ {
+ if (n == 0) return 1;
+ else return n*factorial(n-1);
+ }
+\end{verbatim}
+
+\index{Function!returning \code{void}}
+The special type~\code{void} represents a ``null type''. A function
+that performs an action but does not return a value has return type
+\code{void}. A function that takes no arguments may be viewed as
+taking a single \code{void} argument.
+
+Every \CXX\ program has a special function~\code{main()}, which is
+called by the operating system when the program is run. The arguments
+of~\code{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 \code{main()} or in a
+separately-compiled file.
+
+Functions in~\CXX\ 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 \filename{functions.cc}
+contains simple functions defined by algorithms, and
+\filename{functions.h} illustrates the use of \CXX\ templates. Other
+source files, such as \filename{plots.cc}, may be consulted for
+Simpson's rule, Euler's method, and the like.
+
+
+\subsection{Mathematical Functions}
+
+\index{Function!mathematical|(}
+\CXX~knows several familiar mathematical functions by name:
+\begin{verbatim}
+ sqrt exp log log10 ceil floor fabs
+\end{verbatim}
+(\code{fabs} is the absolute value for a floating-point argument.)
+\ePiX\ provides trig and inverse trig functions sensitive to angular
+mode:
+\index{Angular mode}
+\findex{Cos}
+\findex{Sin}
+\findex{Tan}
+\findex{Sec}
+\findex{Csc}
+\findex{Cot}
+\findex{Acos}
+\findex{Asin}
+\findex{Atan}
+\begin{verbatim}
+ Cos Sin Tan
+ Sec Csc Cot
+ Acos Asin Atan
+\end{verbatim}
+The inverse functions are principle branches.
+
+The function \code{pow(x,y)} returns~\teximath{x^y} when
+\teximath{x>0}, and \code{atan2(y,x)} (N.B. argument order) returns
+\teximath{\mathrm{Arg}(x+iy)\in(-\pi,\pi]}, the principle branch of
+arg. \CXX~knows many constants to 20~decimal places, such as
+\code{M\_PI}, \code{M\_PI\_2}, and \code{M\_E} for~\teximath{\pi},
+\teximath{\pi/2}, and~\teximath{e} respectively. \ePiX\ defines a few
+additional functions:
+\findex{sgn}
+\findex{zero}
+\findex{sinx}
+\findex{cb}
+\begin{verbatim}
+ sgn zero sinx cb
+\end{verbatim}
+\texicomment
+\begin{center}
+ \input{sgn.eepic}\qquad
+ \input{sinx.eepic}\qquad
+ \input{cb.eepic}
+\end{center}
+\medskip
+\texicommentend
+\code{sgn} is the signum function; \code{zero} is the constant
+function; \code{sinx} is the function \teximath{x\mapsto \sin(x)/x}
+with the discontinuity removed; \code{cb} (for ``Charlie Brown'') is
+the period-2 extension of the absolute value function
+on~\teximath{[-1,1]}.
+
+The GNU \CXX\ library defines other functions, including inverse
+hyperbolic functions (\code{acosh}, etc.), \code{log}~and \code{exp}
+with base~2, 10, or arbitrary~\teximath{b} (\code{log2}, etc.), the
+error and gamma functions (\code{erf}~and \code{tgamma} [sic],
+respectively), and Bessel functions of first and second kind:
+\code{j0}, \code{j1}, \code{y0}, etc. Use, e.g., \code{jn(5,~)} to get
+higher indices. The GNU \C~library reference manual~\cite{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:
+\begin{verbatim}
+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); }
+\end{verbatim}
+\index{Function!mathematical|)}
+
+
+\subsection{Basics of Classes}
+
+\index{Classes|(}
+Unlike~\code{C}, \CXX\ supports ``object-oriented programming''. In a
+nutshell, a \emph{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
+\emph{interface} (the set of meaningful operations) from its
+\emph{implementation} (the data structures and algorithms that realize
+the interface).
+
+\index{Function!class member}
+A class implementation consists of \emph{members} (named data
+elements) and \emph{member functions} (functions that belong to the
+class and have free access to members). \CXX\ 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:
+\begin{verbatim}
+ Circle C1(P(1,0), 1.5); // circle of given center and radius
+ C1.draw(); // member function Circle::draw();
+\end{verbatim}
+Naturally, this call draws the circle~\code{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. For more details, please
+consult a book, such as Prata~\cite{Prata} or Stroustrup~\cite{S}, or
+Cline's on-line FAQ~\cite{Cline}.
+\index{Classes|)}
+
+
+\subsection{References and Function Arguments}
+
+\index{Function!call syntax}
+\index{Variable!reference}
+\label{references}
+\code{C}~and \CXX\ 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 an object from being altered
+unexpectedly by a function call in a different part of the program.
+Calling by value helps localize the logic of a program, and
+circumvents easy-to-write but extremely hard-to-find bugs.
+
+In \CXX, a function may accept reference arguments. Passing an object
+by reference grants the calling function access to the object itself,
+not to a copy. There are two common applications: The object is a
+large data structure for which copying is ``expensive'', or the
+function \emph{needs} to modify its arguments (e.g., a function
+\code{swap(x,y)} that exchanges the values of \code{x}~and
+\code{y}).
+
+For the first situation, \CXX\ provides the \code{const} keyword,
+which ensures the function does not modify its arguments, but accepts
+a reference merely for efficiency. Any attempt to modify a
+\code{const} argument will be caught by the compiler. Most \ePiX\
+commands accept \code{const} reference arguments.
+
+The ability to pass function arguments by reference is sometimes
+touted as a feature in \CXX\ texts. However, the technique 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.
+
+A function declaration must indicate that its arguments are
+references. The declarations below have the indicated idiomatic
+meanings.
+\begin{verbatim}
+ 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
+\end{verbatim}
+Unlike pointer arguments, reference arguments impose no syntactic
+burden on the user. If~\code{A} is a~\code{matrix}, then
+\code{transpose(A);} and \code{trace(A);} will compile. You need not
+declare explicit reference variables and pass those to the function.
+
+
+\subsection{Overloading}
+
+\index{Function!overloaded}
+\CXX\ provides ``overloading'': Multiple functions can be given the
+same name, so long as the number and/or type of their arguments
+differ. (It is \emph{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.
+\index{Function|)}
+
+
+\subsection{Scope}
+
+\index{Variable!local}
+A \CXX\ 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
+which variable names may be re-used without ambiguity. Function
+bodies are code blocks, as are the alternatives associated to control
+statements. A variable defined between curly braces is said to be
+\emph{local} to the scope in which it is defined; its value cannot
+be used out of scope. Variables should be declared in the smallest
+scope possible.
+
+The compiler is not picky about spaces, tabs, and newlines, so an
+input file should be formatted to make local scopes visually
+apparent. \code{emacs} automatically indents code to reflect scope,
+though the default behavior does not please all users. As with
+variable naming, clarity and consistency are paramount.
+
+
+\subsection{Headers and Pre-Processing}
+
+A \CXX\ 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~\CXX\ than in~\code{C}; the
+language itself supports safer and more featureful alternatives to
+macros, such as \code{const} variables and inline functions. File
+inclusion and conditional compilation are the chief uses of the
+pre-processor. Lines of the form
+\begin{verbatim}
+ #include <iostream>
+ #include "epix.h"
+\end{verbatim}
+cause the contents of a \emph{header file} to be read into the source
+file. A header file contains variable and function
+\emph{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.
+
+\index{Input file!conditional compilation}
+Conditional compilation is similar to conditional \LaTeX\ code. For
+example, a file might produce either color or monochrome output as
+follows:
+\begin{verbatim}
+#ifdef COLOR
+ ... // code for generating color figure
+#endif /* COLOR */
+#ifndef COLOR
+ ... // monochrome code
+#endif /* undef COLOR */
+\end{verbatim}
+The ``compiler symbol'' \code{COLOR} is an ordinary \CXX\ name. To
+control compilation, either put a \code{\#define COLOR} line in the
+file, or (better) supply the flag on the command line: \\
+\verb+ epix -DCOLOR <file.xp>+ \\
+Every \code{\#ifdef} must have a matching \code{\#endif}. Commenting
+the \code{\#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.
+
+
+\subsection{Comparison with \LaTeX\ Syntax}
+
+As a programming language, \CXX\ 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 \CXX\
+include:
+
+\begin{enumerate}
+\item Every \CXX\ 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~\code{\#}, do not end with a semicolon.
+
+\item Backslash is an escape character in \CXX:
+ \index{Labels}
+\begin{verbatim}
+ // 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
+\end{verbatim}
+
+\item Variable and function names may contain letters (including
+ underscore) and digits \emph{only}, are case sensitive, and must
+ begin with a letter.
+
+\item Variables in \CXX\ must have a declared \emph{type}, such as
+ \code{int} (integer) or \code{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 \code{main}. Local variables should be defined in
+ the smallest possible scope. Unlike~\C, \CXX\ allows variables to be
+ defined where they first appear.
+
+\item \CXX~requires explicit use of~\code{*} to denote multiplication;
+ juxtaposition is not enough. \CXX~does not support the use of
+ \verb+^+ for exponentiation, e.g., \verb+t^2+ is invalid. Instead,
+ use \code{t*t}~or \code{pow(t,2)}.
+
+\item \CXX\ has single- and multi-line comments. Everything between a
+ double slash and the next newline is ignored, while the strings
+ \verb+/*+~and \verb+*/+ delimit multi-line comments. A single-line
+ comment may appear within a multi-line comment, but the compiler
+ does not nest multi-line comments.
+ \index{Input file!comment in}
+
+\end{enumerate}
+
+Between them, \C~and \CXX~have about 100~reserved keywords which
+cannot be used as function or variable names.
+\index{Cplusplus@\CXX|)}
+
+
+\section{Attribute Quick Reference}
+\label{section:quickref}
+
+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 \code{len} argument is a double-quoted string containing a number
+and a two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or
+\code{"6cm"}. A \code{color} argument is a named primary
+(\code{Red()}, \code{Cyan()}, \code{White()}, etc.), a \code{Color}
+specified by densities (\code{RGB(...)}, \code{CMYK(...)}, etc.), or a
+\code{Color} object. Using \code{Neutral()} as a \code{Color} argument
+generally turns off the corresponding attribute.
+
+\begin{itemize}
+
+\item Angular mode: \code{radians()}, \code{degrees()}, or
+ \code{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., \code{Cos}, \code{Tan}.
+
+\item Fill style: \code{fill(color)}, \code{fill(bool)},
+ \code{nofill()}.
+
+\item Path style:
+
+ \begin{itemize}
+
+ \item Width: \code{plain()}, \code{bold()}, \code{bbold()},
+ \code{pen(len)}.
+
+ \item Line style: \code{line\_style(string)}. The argument is a
+ WYSIWYG sequence of dashes, spaces, and periods.
+ \code{dash\_size(double)} and \code{dot\_sep(double)} set the
+ (approximate) length in~\code{pt} of the pattern. The commands
+ \code{solid()}, \code{dashed()}, \code{dotted()} define
+ ``standard'' defaults for brevity.
+
+ \item Path color:
+ Paths can be drawn using \emph{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.
+
+ \code{pen(color,[len])}, \code{base(color,[len])}
+
+ Standard widths: \code{plain(color)}, \code{bold(color)},
+ \code{bbold(color)}
+
+ \end{itemize}
+
+\item Text attributes:
+
+ \begin{itemize}
+
+ \item Color: \code{label\_color(color)}
+
+ \item Mask: \code{label\_mask(color)}, \code{label\_pad(len)}
+
+ \item Border: \code{label\_border(color, [len])},
+ \code{label\_border(len)}. The command \code{no\_label\_border()}
+ turns off label borders.
+
+ \item Font size: \code{font\_size(LaTeX size)}, no argument means
+ \code{normalsize}.
+
+ \item Font face: \code{font\_face(LaTeX font)}, two-letter font
+ selection string, default is \code{rm}.
+
+ \item Rotation: \code{label\_angle(double)}
+
+ \end{itemize}
+
+\end{itemize}
+
+Do not confuse \code{Color} constructors with the similarly-named
+(deprecated) lowercase attribute-setting commands, \code{rgb(r,g,b)},
+\code{cmyk(c,m,y,k)}, \code{red(d)}, etc. These commands affect text,
+paths, and filled regions. For example, the single command
+\code{red()} has the same effect as the three commands
+\code{pen(Red())}, \code{fill(Red())}, and \code{label\_color(Red())}.
+
+
+\texinfochapter{4}{Advanced Topics}
+\label{chapter:adv}
+
+This chapter covers \emph{ad hoc} tricks and open-ended techniques
+that require relatively more programming sophistication. You will
+almost surely need an external \CXX\ reference if you do not speak the
+language.
+
+
+\section{Hidden Object Removal}
+\label{section:hidden}
+
+\index{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 \code{surface.*}.
+
+\index{Camera}
+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 \CXX\ 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
+\filename{saddle.xp} illustrates possible techniques.
+
+Shaded surfaces can be decorated with a bit of hackery. For example,
+the \code{facet::draw} function in \filename{facet.cc} can be
+modified easily to draw line elements, tangents, or normal vectors
+along with the facet itself. The sample file
+\filename{decorate.xp} contains a couple of ideas. (The
+decorations are activated by compiler flags; please consult the file
+itself for information on compiling.)
+\index{Hidden object removal|)}
+
+
+\section{Extensions}
+\label{section: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~\CXX\ to separately compiled libraries that add
+substantial new features. The structure of the source code is
+outlined in Section~\ref{section:programmers}.
+
+
+\subsection{Header Files}
+
+A \CXX~header file conventionally has suffix~\filename{.h}, as in
+\filename{myheader.h}. To use this custom header, put a line
+\code{\#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
+\begin{verbatim}
+ 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 }
+\end{verbatim}
+The keyword \code{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 \emph{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:
+\begin{verbatim}
+ Bold();
+ draw_square(cube(1.25));
+\end{verbatim}
+
+
+\subsection{Compiling}
+
+The next few sections outline the creation of a ``static library'' on
+GNU/Linux, and explain how to incorporate custom features at runtime.
+The extensively-commented sample files \filename{std\_F.cc}~and
+\filename{std\_F.h} illustrate the techniques described below, and may
+be used for guidance and experimentation.
+
+A small library is usually written as a \emph{header} file, which
+contains class and function declarations (also called ``prototypes''),
+and a \emph{source} file, which contains the actual
+code. Conventionally (under *nix), these files have extension
+\filename{.h}~and \filename{.cc} respectively. Header and source files
+may ``include'' other header files, to incorporate additional
+functionality.
+\begin{verbatim}
+/* 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 */
+\end{verbatim}
+This file exhibits two ``safety features''. The three \code{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.
+\begin{verbatim}
+/* 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
+\end{verbatim}
+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.
+\begin{verbatim}
+% g++ -c my_code.cc
+% ar -ru libcustom.a my_code.o
+% ranlib libcustom.a
+\end{verbatim}
+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~\filename{.a}. Once these
+steps are successfully completed, put the library \filename{libcustom.a}
+and header file \filename{my\_code.h} in your project directory. You're
+ready to use the code in an \ePiX\ figure.
+
+
+\subsection{Runtime Linking}
+
+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
+\begin{verbatim}
+ -I<include> -L<libdir> -l<lib>
+\end{verbatim}
+For example, to link \filename{figure.xp} against
+\filename{mylibs/libcustom.a}, run the command
+\begin{verbatim}
+ epix -Lmylibs -lcustom figure
+\end{verbatim}
+The options \code{-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
+\filename{\$HOME/.epixrc}, with syntax as above. A line in the config
+file that contains a pound sign~(\code{\#}) is a comment, no matter
+where in the line the~\code{\#} 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.
+
+
+\subsection{Using Multiple Versions}
+
+The script \filename{epix}~links by default against the \code{C}~math
+library \code{libm.a}~and the \ePiX\ library \code{libepix.a}. The
+command option \code{--no-defaults} clears the header and include
+paths and removes \code{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~1.0.0, build the package according to
+its \filename{INSTALL} instructions, but \emph{do not use the makefile
+ to install}. Instead, manually install the header and library only,
+using their version number:
+\begin{verbatim}
+# install -m 644 epix.h /usr/local/include/epix-1.0.h
+# install -m 644 libepix.a /usr/local/lib/libepix-1.0.a
+\end{verbatim}
+A non-system directory may be used instead of \filename{/usr/local}.
+To use the old version, a source file must \code{include} the
+appropriate header file (which is identified by its version number).
+To compile, issue a command such as
+\begin{verbatim}
+epix --no-defaults -I/usr/local -L/usr/local -lepix-1.0 file.xp
+\end{verbatim}
+
+
+\section{Programmer's Guide}
+\label{section:programmers}
+
+This section briefly surveys \ePiX's implementation, and is intended
+for (potential) programmers. The source code 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. For example, the
+user-visible classes defined in \filename{Color.h}, \filename{path.h},
+and~\filename{screen.h} contain only a pointer to the implementation
+class, and style data is hidden behind global commands.
+
+Functionally, the code consists of the user interface; implementation
+class\-es comprising drawing attributes, spatial objects, screens and
+representations of their elements, and output; and miscellaneous
+utility functions. The headers in each group, and their contents, are
+described in Section~\ref{section:interface}.
+
+The user interface headers are assembled into a single file,
+\filename{epix.h}, and installed in \filename{/usr/local/include} by
+default. In normal use, the shell scripts read only the user interface
+header. The individual headers, including the components of
+\filename{epix.h}, are installed in
+\filename{/usr/local/include/epix}. These are provided for authors of
+external libraries, who may need access to implementation details.
+
+
+\subsection{External Packages}
+
+\ePiX\ harnesses the computational power of~\CXX\ to the typographical
+capabilities of \LaTeX. Consequently, \ePiX\ should be viewed in part
+as a framework for expressing numerical data visually.
+
+In the course of your work, you may develop specialized code filling a
+gap in \ePiX's functionality. If your code seems likely to be of
+interest to other users, please consider bundling it as an external
+package and notifying the \ePiX\ community so your work can be linked
+from the project pages and distributed to interested users.
+
+There are no formal requirements for external packages, but in the
+interest of uniformity contributed code should follow the GNU Coding
+Standards~\cite{GNUCoding}. At a minimum, an external package should
+build with the standard \code{./configure; make; make install}
+commands, and the \code{configure} script should accept an option
+\code{--with-epix} for the user to specify a non-default \ePiX\
+install directory.
+
+If an external package builds a static library, it should provide a
+single header containing all the package's entry points, and enclose
+its interface in a namespace. Entry points should not collide with
+\ePiX\ functions. Naming the package ``\filename{epix-<...>}'' is a
+good idea, but not essential. For example, a package providing textual
+nodes and diagram layout might be named \filename{epix-nodes}. Input
+files would use the package with the lines
+\begin{verbatim}
+ #include "epix-nodes.h"
+ using namespace ePiX-nodes;
+\end{verbatim}
+and be compiled with
+\begin{verbatim}
+ epix -lepix-nodes <file>
+\end{verbatim}
+
+The user and internal interfaces of \ePiX-1.2 are not likely to
+change. Still, it's prudent to rely only on the user interface in
+contributed code whenever possible. Doing so also simplifies your work
+as an author; your library can simply \code{include} the user header
+file, and deal only with high-level objects and drawing attributes.
+
+
+\subsection{User Interface}
+\label{section:interface}
+
+These files (in order) comprise the global header \filename{epix.h}.
+
+\Header{enums.h} Marker, alignment, Riemann integral, and vector field
+types.
+
+\Header{length.h} Physical lengths, conceptually a number and
+two-letter \LaTeX\ length unit.
+
+\Header{interval.h} Closed, open, and half-open interval ranges for
+data culling.
+
+\Header{triples.h} The \code{P} class.
+
+\Header{functions.h} Angle-sensitive trig functions, miscellaneous
+utility functions, the \code{Deriv}~and \code{Integral} classes.
+
+\Header{pairs.h} Screen locations and displacements, with complex
+arithmetic operations.
+
+\Header{Color.h} The Color class interface, named
+primaries and constructors.
+
+\Header{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.
+
+\Header{frame.h} Orthonormal bases.
+
+\Header{domain.h} Coordinate boxes for function plotting.
+
+\Header{camera.h} The camera.
+
+\Header{screen.h} The screen class.
+
+\Header{picture.h} Dimension-setting, offset, layout, decoration,
+verbatim text, and output format commands.
+
+\Header{markers.h} Point markers, axis labels, and coordinate axes.
+
+\Header{axis.h} Coordinate axes and labels in various styles.
+
+\Header{legend.h} Plot legends.
+
+\Header{path.h} The path class.
+
+\Header{curves.h} Polygons, arrows, ellipses, arcs, splines,
+coordinate grids, and recursive fractal curves.
+
+\Header{circle.h} The \code{Circle} shape object class.
+
+\Header{plane.h} The \code{Plane} shape object class.
+
+\Header{segment.h} The \code{Segment} shape object class.
+
+\Header{sphere.h} The \code{Sphere} shape object class.
+
+\Header{intersections.h} Shape object intersection operators.
+
+\Header{plots.h} Plotting commands.
+
+\Header{surface.h} Shaded surface plots.
+
+\Header{data\_mask.h} Helper class for data pruning.
+
+\Header{data\_file.h} Class for storing and representing data.
+
+\Header{data\_bins.h} Class for sorting and counting data.
+
+\Header{geometry.h} Latitudes and longitudes; spherical plotting,
+arcs, polygons, and polyhedra; hyperbolic arcs.
+
+
+\subsection{Implementation Classes}
+
+\Header{Color\_Base.h} The Color implementation interface.
+
+\Header{Color\_CMY.h} The CMY color model.
+
+\Header{Color\_CMYK.h} The CMYK color model.
+
+\Header{Color\_Gray.h} The Gray color model.
+
+\Header{Color\_Neutral.h} Each color class has a ``Neutral'' member
+that converts colors to that model by filtering. This file defines the
+unique ``model-less'' Neutral color for which filtering performs no
+action.
+
+\Header{Color\_RGB.h} The RGB color model.
+
+\Header{Color\_Sep.h} Classes for CMYK separation.
+
+\Header{active\_screen.h} Simple manipulator for the active screen.
+
+\Header{picture\_data.h} Picture implementation: two \code{screen}s
+(representing the \code{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 \code{picture}
+environment in the output file. For simplicity, the \code{screen}s and
+dimensions are public; encapsulation from the user results from
+``hiding'' this header.
+
+
+\subsubsection*{Style Attributes}
+
+Declaration-style attributes are maintained with functions returning
+static references: \code{the\_angle\_style()},
+\code{the\_arrowhead\_style()}, \code{the\_label\_style()},
+\code{the\_mark\_size()}, \code{the\_paint\_style()}, and
+\code{the\_path\_style()}. Each function is declared in the
+analogously-named header.
+
+\Header{angle\_units.h} Angular modes: \code{radians},
+\code{revolutions}, and \code{degrees}.
+
+\Header{arrow\_style.h} Arrow head style data: width, ratio, and
+inset.
+
+\Header{label\_style.h} Text object style: Label and mask colors,
+padding, border color and width, alignment, font size, font face, and
+angle.
+
+\Header{marker\_style.h} Dot and tick sizes.
+
+\Header{paint\_style.h} Line and base pens, fill color.
+
+\Header{path\_style.h} Solid, dashed, dotted lines.
+
+\Header{pen\_data.h} The pen class.
+
+
+\subsubsection*{Objects}
+
+\Header{arrow\_data.h} Arrow representation.
+
+\Header{facet.h} Shaded surface elements.
+
+\Header{label\_data.h} Text (label and marker) objects.
+
+\Header{legend\_item.h} Items for \code{legend}s.
+
+\Header{path\_data.h} Path implementation.
+
+\Header{spline.h} The natural spline class.
+
+\Header{spline\_data.h} Templates for quadratic and cubic splines.
+
+
+\subsubsection*{Screen Representation}
+
+Elements in a \code{screen} are represented polymorphically as
+``\code{tile}s'', of which there are six types: \code{glyph} (textual
+elements), \code{pen\_arrow} (arrows), \code{pen\_fill} (filled
+regions), \code{pen\_line} (path-like elements), \code{verbatim}
+(raw text), and \code{legend\_tile} (legends).
+
+Border and background shape are dictated by the \code{screen\_mask}
+class. The cropping algorithm assumes the contour of a screen mask is
+convex.
+
+\Header{affine.h} Affine maps.
+
+\Header{cropping.h} Screen mask cropping.
+
+\Header{glyph.h} Markers and labels.
+
+\Header{legend\_tile.h} Screen representation of a \code{legend}.
+
+\Header{mask\_diamond.h} Screen diamond mask.
+
+\Header{mask\_ellipse.h} Screen elliptical mask.
+
+\Header{mask\_rectangle.h} Screen rectangular mask.
+
+\Header{pen\_arrow.h} Arrows.
+
+\Header{pen\_fill.h} Filled regions.
+
+\Header{pen\_line.h} Paths.
+
+\Header{screen\_data.h} Screen implementation class.
+
+\Header{screen\_mask.h} Screen mask interface.
+
+\Header{tile.h} Screen element interface.
+
+\Header{verbatim.h} Text in output stream.
+
+
+\subsubsection*{Output}
+
+Output is divided into a couple of high-level operations and several
+``atomic'' low-level operations. To create a new output
+format, one need only implement the \code{format} interface for the
+desired file type. Paths and filled regions may be implemented however
+the output type dictates.
+
+\Header{eepic.h} eepic macros.
+
+\Header{fmt\_template.h} ``skeleton'' header for new output formats.
+
+\Header{format.h} The output interface.
+
+\Header{pst.h} PSTricks macros.
+
+\Header{tikz.h} tikz macros.
+
+
+\subsubsection*{Utilities}
+
+\Header{Color\_Utils.h} Functions for setting color channel densities.
+
+\Header{clipping.h} The clip box.
+
+\Header{constants.h} Global constants: Line widths; dot, tick, and
+dash sizes; arrowhead parameters; miscellaneous numerical constants
+and internal parameters.
+
+\Header{crop\_algorithms.h} Path and loop clipping templates.
+
+\Header{deriv.h} Finite difference template.
+
+\Header{edge\_data.h} Path element representation template.
+
+\Header{errors.h} Warning and error messages.
+
+\Header{frac.h} Rational numbers and operators.
+
+\Header{halfspace.h} Halfspace cutting.
+
+\Header{hatching.h} Filling regions in eepic.
+
+\Header{lens.h} Camera lenses.
+
+\Header{map.h} Wrappers for templated plotting.
+
+\Header{plot\_algorithms.h} Plotting templates.
+
+\Header{screen\_crop.h} Crop paths and loops.
+
+\Header{utils.h} Truncation, date and time, line breaking.
+
+
+\appendix
+\texinfoappendix{A}{Software Freedom}
+\index{Free software|(}
+
+Academics in general, and mathematicians in particular, depend on free
+exchange of information. We prove theorems or establish experimental
+results, write up formal accounts, place preprints on public file
+servers, and submit papers to peer-reviewed journals. If accepted, the
+results---data, techniques, methods of reasoning, citations, and
+conclusions---are published in print and become part of the public
+record, governed by copyright law. Libraries purchase journal
+subscriptions, but researchers and scholars may use ideas from the
+literature merely by giving appropriate citations in their own
+work. ``Theft'' arises from false claims of authorship.
+
+Carried over to software, the academic process would guarantee rights
+similar to those provided by the GNU General Public License (GPL):
+
+\begin{itemize}
+
+\item (GPL~0) To run a program for any purpose.
+
+\item (GPL~1) To study how the program works, and adapt it to your
+ needs.
+
+\item (GPL~2) To redistribute copies of the program.
+
+\item (GPL~3) To improve the program, and release improvements to the
+ public, so that the whole community benefits.
+
+\end{itemize}
+
+In reality, attitudes toward software differ markedly. Most academics
+work on a proprietary platform, use proprietary software for research
+and teaching, and share information with colleagues and students in
+proprietary, even obfuscated, data formats. Contrary to the academic
+ethic, proprietary software licenses restrict access to information:
+preventing users from learning how a program works internally
+(``reverse engineering''), limiting the number of users who may run a
+piece of software, and forbidding users from running (or sometimes
+even installing) a purchased copy on multiple machines.
+
+Restrictions on use aside, if one cannot examine a program's source
+code, one cannot fully trust the output, any more than one can trust
+(for purposes of scientific publication) results of a commercial
+testing lab.
+
+\texicomment
+\noindent$\phantom{.}$\hfil\vbox{\hrule width 4in}\hfil
+\texicommentend
+
+Consider a hypothetical future world in which scholarly results are
+disseminated like software. Instead of subscriptions, journals
+sell licenses granting readership to a specified number of
+individuals. Photocopying an article for a class or research seminar
+constitutes ``piracy'', though if the institution has purchased a
+sufficiently large site license the teacher or speaker may bring the
+physical volume to class and project the pages onto a screen.
+
+Of course, reading an article is scarcely enlightening. Mathematics
+papers contain only the statements of theorems. Merely opening the
+journal binds the reader to a lengthy legal agreement, stating that
+theorems be used only for specific purposes and threatening serious
+legal consequences for attempting to discover the author's proofs.
+
+The actions of a single student, employee, or faculty member can
+expose an institution to a costly ``journal audit'' from the
+Mathematical Society of America (MSA), with the institution
+responsible for legal costs if the audit reveals license violations
+anywhere in the organization.
+
+Mathematicians who long for the Old Days when papers contained
+proofs and were shared freely are dismissed as idealistic cranks
+or labeled anti-business communists. Common knowledge asserts the
+obvious superiority of proprietary journals, and the necessity of
+licenses for keeping mathematicians gainfully employed.
+
+\texicomment
+\noindent$\phantom{.}$\hfil\vbox{\hrule width 4in}\hfil
+\texicommentend
+
+Back in our world, some vendors have attempted to placate opponents of
+closed source with ``shared source'' licenses, under which one may
+sign a non-disclosure agreement and subsequently examine source
+code. In the future world analogy, a shared source agreement would
+allow journal licensees to sign an NDA, then see the proofs of
+theorems. Readers could thereby correct errors in proofs (benefitting
+the publisher by improving the reliability of the journal), but would
+be legally forbidden from using the ideas elsewhere (denying benefit
+to other mathematicians).
+
+Legally and conceptually codifying software as a commodity ignores a
+fundamental reality: Like an idea or recipe, software can be copied
+without loss of the original. The perception of ``theft'' by copying
+arises from an artificial belief that software has an owner who must
+be monetarily compensated each time a person acquires a copy. The
+nature of software does not enforce the ``sale'' model in the way
+services and physical commodities do. It therefore seems
+philosophically inappropriate to treat software as a commodity, and
+perilous to conform the legal system to the enforcement of such a
+model.
+
+At its best, software enhances our productivity and
+creativity. Sharing software, like sharing ideas, benefits a larger
+number of people without detriment to existing users. I hope 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
+\URL{www.fsf.org}, to learn more about free software and how
+you can contribute to its development and adoption.
+\index{Free software|)}
+
+\texinfoappendix{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:
+
+\paragraph{Infrastructure} Donald Knuth, Conrad Kwok, Leslie Lamport,
+Tim Morgan, Piet van~Oostrum, Sunil Podar, Richard Stallman, Till
+Tantau, Herbert Voss, Timothy van~Zandt
+
+\paragraph{Enhancements} Jay Belanger, Robin Blume-Kohout, Julian
+Gilbey, Marcus Hanwell, Yvon Henel, Svend Daug{\aa}rd Pedersen, Andrew
+Sterian
+
+\paragraph{Porting and packaging} Julian Gilbey (Debian); Tsuguru Kato
+(FreeBSD); Markus Dittrich, Danny van Dyk, Christian Faulhammer,
+Olivier Fisette, Chris Gianelloni, Michael Hanselmann, Marcus Hanwell,
+David Holm, Peter Johanson, Patrick Kursawe, Tobias Scherbaum, Markus
+Ullmann (Gentoo); Guido Gonzato (RPM); Rene Rebe (T2)
+
+\paragraph{Debugging, 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
+
+\texicomment
+\begin{thebibliography}{9}
+%
+\bibitem{Cline} Marshall Cline, \emph{\CXX\ FAQ Lite}, \\
+ \URL{http://www.parashift.com/c++-faq-lite/}
+%
+\bibitem{xcolor} Uwe Kern, \emph{Extending \LaTeX's color facilities:
+ the \code{xcolor} package}, white paper, Jan.~21, 2007
+%
+\bibitem{KnR} Brian Kernighan and Dennis Ritchie, \emph{The \code{C}
+ Programming Language}, Second Ed., Prentice-Hall Software Series,
+ 1988
+%
+\bibitem{GNUC} Sandra Loosemore, Richard M. Stallman, et.\ al.,
+ \emph{The GNU \code{C}~Library Reference Manual}, GNU Press,
+ 2004
+%
+\bibitem{Prata} Stephen Prata, \emph{\CXX\ Primer Plus}, Sams, 2002
+%
+\bibitem{R} Keith Reckdahl, \emph{Using Imported Graphics in
+ \LaTeX2e}, Version~2.0, white paper, Dec.~15, 1997
+%
+\bibitem{GNUCoding} Richard M. Stallman, et.\ al., \emph{The GNU
+ Coding Standards}, \\
+ \URL{http://www.gnu.org/prep/standards/}
+%
+\bibitem{S} Bjarne Stroustrup, \emph{The \CXX\ Programming Language},
+ Special Ed., Addison-Wesley, 1997
+%
+\bibitem{Z} Timothy van~Zandt, \emph{PSTricks: PostScript Macros for
+ Generic \TeX}, Version~0.93a, white paper, Mar.~12, 1993
+%
+\end{thebibliography}
+
+\clearpage
+
+\printindex
+
+\end{document}
+
+\texicommentend
diff --git a/graphics/epix/doc/marker.eepic b/graphics/epix/doc/marker.eepic
new file mode 100644
index 0000000000..5ee5923a3b
--- /dev/null
+++ b/graphics/epix/doc/marker.eepic
@@ -0,0 +1,39 @@
+%% Generated from marker.xp on Tue Jan 4 15:32:18 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [0,5] x [0,1]
+%% Actual size: 3.75in x 1in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{0.25in}
+\begin{picture}(15,4)(-0,-0)
+%% ---
+\put(0.664176,3.77861){{\tt{CIRC}}}
+\whiten\put(0,4){\makebox(0,0)[c]{{\circle{0.166044}}}}
+\put(4.41418,3.77861){{\tt{SPOT}}}
+\put(3.75,4){\makebox(0,0)[c]{{\circle*{0.249066}}}}
+\put(8.16418,3.77861){{\tt{RING}}}
+\put(7.5,4){\makebox(0,0)[c]{{\circle{0.249066}}}}
+\put(11.9142,3.77861){{\tt{DOT}}}
+\put(11.25,4){\makebox(0,0)[c]{{\circle*{0.166044}}}}
+\put(15.6642,3.77861){{\tt{DDOT}}}
+\put(15,4){\makebox(0,0)[c]{{\circle*{0.110696}}}}
+\put(0.664176,1.77861){{\tt{PLUS}}}
+\put(0,2){\makebox(0,0)[c]{+}}
+\put(4.41418,1.77861){{\tt{OPLUS}}}
+\put(3.75,2){\makebox(0,0)[c]{$\oplus$}}
+\put(8.16418,1.77861){{\tt{TIMES}}}
+\put(7.5,2){\makebox(0,0)[c]{$\times$}}
+\put(11.9142,1.77861){{\tt{OTIMES}}}
+\put(11.25,2){\makebox(0,0)[c]{$\otimes$}}
+\put(0.664176,-0.221392){{\tt{DIAMOND}}}
+\put(0,0){\makebox(0,0)[c]{$\diamond$}}
+\put(4.41418,-0.221392){{\tt{UP}}}
+\put(3.75,0){\makebox(0,0)[c]{$\bigtriangleup$}}
+\put(8.16418,-0.221392){{\tt{DOWN}}}
+\put(7.5,0){\makebox(0,0)[c]{$\bigtriangledown$}}
+\put(11.9142,-0.221392){{\tt{BOX}}}
+\put(11.25,0){\makebox(0,0)[c]{\rule{3pt}{3pt}}}
+\put(15.6642,-0.221392){{\tt{BBOX}}}
+\put(15,0){\makebox(0,0)[c]{\rule{2pt}{2pt}}}
+\end{picture}
diff --git a/graphics/epix/doc/marker.xp b/graphics/epix/doc/marker.xp
new file mode 100644
index 0000000000..f1569c1476
--- /dev/null
+++ b/graphics/epix/doc/marker.xp
@@ -0,0 +1,68 @@
+/* -*-ePiX-*- */
+/* marker.c -- types of marker */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ unitlength("0.25in");
+ picture(P(15,4));
+ bounding_box(P(0,0), P(5,1));
+ // offset(P(-1,0));
+
+ begin();
+
+ double x1 = x_min;
+ double x2 = x_min + x_size/4;
+ double x3 = x_min + 2*x_size/4;
+ double x4 = x_min + 3*x_size/4;
+ double x5 = x_max;
+
+ double y1 = y_min;
+ double y2 = y_min + y_size/2;
+ double y3 = y_max;
+
+ label(P(x1,y3), P(12,-4), "{\\tt{CIRC}}");
+ circ(P(x1,y3));
+
+ label(P(x2,y3), P(12,-4), "{\\tt{SPOT}}");
+ spot(P(x2,y3));
+
+ label(P(x3,y3), P(12,-4), "{\\tt{RING}}");
+ ring(P(x3,y3));
+
+ label(P(x4,y3), P(12,-4), "{\\tt{DOT}}");
+ dot(P(x4,y3));
+
+ label(P(x5,y3), P(12,-4), "{\\tt{DDOT}}");
+ ddot(P(x5,y3));
+
+ label(P(x1,y2), P(12,-4), "{\\tt{PLUS}}");
+ marker(P(x1,y2), PLUS);
+
+ label(P(x2,y2), P(12,-4), "{\\tt{OPLUS}}");
+ marker(P(x2,y2), OPLUS);
+
+ label(P(x3,y2), P(12,-4), "{\\tt{TIMES}}");
+ marker(P(x3,y2), TIMES);
+
+ label(P(x4,y2), P(12,-4), "{\\tt{OTIMES}}");
+ marker(P(x4,y2), OTIMES);
+
+ label(P(x1,y1), P(12,-4), "{\\tt{DIAMOND}}");
+ marker(P(x1,y1), DIAMOND);
+
+ label(P(x2,y1), P(12,-4), "{\\tt{UP}}");
+ marker(P(x2,y1),UP);
+
+ label(P(x3,y1), P(12,-4), "{\\tt{DOWN}}");
+ marker(P(x3,y1), DOWN);
+
+ label(P(x4,y1), P(12,-4), "{\\tt{BOX}}");
+ marker(P(x4,y1), BOX);
+
+ label(P(x5,y1), P(12,-4), "{\\tt{BBOX}}");
+ marker(P(x5,y1), BBOX);
+
+ end();
+}
diff --git a/graphics/epix/doc/my_code.cc b/graphics/epix/doc/my_code.cc
new file mode 100644
index 0000000000..b7365fa63c
--- /dev/null
+++ b/graphics/epix/doc/my_code.cc
@@ -0,0 +1,15 @@
+/* my_code.cc */
+#include "my_code.h"
+using namespace ePiX;
+
+namespace Mine {
+ double lorentz_norm(P arg)
+ {
+ double x=arg.x1(), y=arg.x2(), z=arg.x3(); // extract coords
+ return -x*x + y*y + z*z;
+ }
+ bool spacelike(P arg)
+ {
+ return (lorentz_norm(arg) > 0);
+ }
+} // end of namespace
diff --git a/graphics/epix/doc/my_code.h b/graphics/epix/doc/my_code.h
new file mode 100644
index 0000000000..229e80dbf4
--- /dev/null
+++ b/graphics/epix/doc/my_code.h
@@ -0,0 +1,10 @@
+/* my_code.h */
+#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(P);
+ bool spacelike(P);
+} // end of namespace
diff --git a/graphics/epix/doc/objects.eepic b/graphics/epix/doc/objects.eepic
new file mode 100644
index 0000000000..9b17600895
--- /dev/null
+++ b/graphics/epix/doc/objects.eepic
@@ -0,0 +1,412 @@
+%% Generated from objects.xp on Thu Jun 28 14:55:45 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [0,5] x [0,2]
+%% Actual size: 3.75 x 1.5in
+%% Figure offset: left by 0in, down by 0in
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\xdefinecolor{rgb_e5e5e5}{rgb}{0.898039,0.898039,0.898039}
+\xdefinecolor{rgb_ffffff}{rgb}{1,1,1}
+\setlength{\unitlength}{1in}
+\begin{picture}(3.75,1.5)(-0,-0)
+\path(0.675,0.75)(2.325,0.75)(1.5,1.125)(0.675,0.75)
+%%
+\path(3.1875,1.125)(3.18724,1.13481)(3.18647,1.1446)
+ (3.18519,1.15433)(3.1834,1.16398)(3.18111,1.17353)(3.17832,1.18294)
+ (3.17505,1.19219)(3.17129,1.20126)(3.16706,1.21012)
+ (3.16238,1.21875)(3.15725,1.22712)(3.15169,1.23521)(3.14571,1.243)
+ (3.13934,1.25046)(3.13258,1.25758)(3.12546,1.26434)(3.118,1.27071)
+ (3.11021,1.27669)(3.10212,1.28225)(3.09375,1.28738)
+ (3.08512,1.29206)(3.07626,1.29629)(3.06719,1.30005)
+ (3.05794,1.30332)(3.04853,1.30611)(3.03898,1.3084)(3.02933,1.31019)
+ (3.0196,1.31147)(3.00981,1.31224)(3,1.3125)(2.99019,1.31224)
+ (2.9804,1.31147)(2.97067,1.31019)(2.96102,1.3084)(2.95147,1.30611)
+ (2.94206,1.30332)(2.93281,1.30005)(2.92374,1.29629)
+ (2.91488,1.29206)(2.90625,1.28738)(2.89788,1.28225)
+ (2.88979,1.27669)(2.882,1.27071)(2.87454,1.26434)(2.86742,1.25758)
+ (2.86066,1.25046)(2.85429,1.243)(2.84831,1.23521)(2.84275,1.22712)
+ (2.83762,1.21875)(2.83294,1.21012)(2.82871,1.20126)
+ (2.82495,1.19219)(2.82168,1.18294)(2.81889,1.17353)(2.8166,1.16398)
+ (2.81481,1.15433)(2.81353,1.1446)(2.81276,1.13481)(2.8125,1.125)
+ (2.81276,1.11519)(2.81353,1.1054)(2.81481,1.09567)(2.8166,1.08602)
+ (2.81889,1.07647)(2.82168,1.06706)(2.82495,1.05781)
+ (2.82871,1.04874)(2.83294,1.03988)(2.83762,1.03125)
+ (2.84275,1.02288)(2.84831,1.01479)(2.85429,1.007)(2.86066,0.999538)
+ (2.86742,0.992417)(2.87454,0.98566)(2.882,0.979285)
+ (2.88979,0.973309)(2.89788,0.967749)(2.90625,0.96262)
+ (2.91488,0.957936)(2.92374,0.95371)(2.93281,0.949954)
+ (2.94206,0.946677)(2.95147,0.943889)(2.96102,0.941597)
+ (2.97067,0.939808)(2.9804,0.938527)(2.99019,0.937757)(3,0.9375)
+ (3.00981,0.937757)(3.0196,0.938527)(3.02933,0.939808)
+ (3.03898,0.941597)(3.04853,0.943889)(3.05794,0.946677)
+ (3.06719,0.949954)(3.07626,0.95371)(3.08512,0.957936)
+ (3.09375,0.96262)(3.10212,0.967749)(3.11021,0.973309)
+ (3.118,0.979285)(3.12546,0.98566)(3.13258,0.992417)
+ (3.13934,0.999538)(3.14571,1.007)(3.15169,1.01479)(3.15725,1.02288)
+ (3.16238,1.03125)(3.16706,1.03988)(3.17129,1.04874)
+ (3.17505,1.05781)(3.17832,1.06706)(3.18111,1.07647)(3.1834,1.08602)
+ (3.18519,1.09567)(3.18647,1.1054)(3.18724,1.11519)(3.1875,1.125)
+%%
+\path(0.75,0)(2.25,0)(2.25,0.75)(0.75,0.75)(0.75,0)
+%%
+\color{rgb_e5e5e5}%
+\path(2.025,0.00550459)(1.725,0.00550459)
+\path(2.025,0.0110092)(1.725,0.0110092)
+\path(2.025,0.0165138)(1.725,0.0165138)
+\path(2.025,0.0220183)(1.725,0.0220183)
+\path(2.025,0.0275229)(1.725,0.0275229)
+\path(2.025,0.0330275)(1.725,0.0330275)
+\path(2.025,0.0385321)(1.725,0.0385321)
+\path(2.025,0.0440367)(1.725,0.0440367)
+\path(2.025,0.0495413)(1.725,0.0495413)
+\path(2.025,0.0550459)(1.725,0.0550459)
+\path(2.025,0.0605505)(1.725,0.0605505)
+\path(2.025,0.066055)(1.725,0.066055)
+\path(2.025,0.0715596)(1.725,0.0715596)
+\path(2.025,0.0770642)(1.725,0.0770642)
+\path(2.025,0.0825688)(1.725,0.0825688)
+\path(2.025,0.0880734)(1.725,0.0880734)
+\path(2.025,0.093578)(1.725,0.093578)
+\path(2.025,0.0990826)(1.725,0.0990826)
+\path(2.025,0.104587)(1.725,0.104587)
+\path(2.025,0.110092)(1.725,0.110092)
+\path(2.025,0.115596)(1.725,0.115596)
+\path(2.025,0.121101)(1.725,0.121101)
+\path(2.025,0.126606)(1.725,0.126606)
+\path(2.025,0.13211)(1.725,0.13211)
+\path(2.025,0.137615)(1.725,0.137615)
+\path(2.025,0.143119)(1.725,0.143119)
+\path(2.025,0.148624)(1.725,0.148624)
+\path(2.025,0.154128)(1.725,0.154128)
+\path(2.025,0.159633)(1.725,0.159633)
+\path(2.025,0.165138)(1.725,0.165138)
+\path(2.025,0.170642)(1.725,0.170642)
+\path(2.025,0.176147)(1.725,0.176147)
+\path(2.025,0.181651)(1.725,0.181651)
+\path(2.025,0.187156)(1.725,0.187156)
+\path(2.025,0.192661)(1.725,0.192661)
+\path(2.025,0.198165)(1.725,0.198165)
+\path(2.025,0.20367)(1.725,0.20367)
+\path(2.025,0.209174)(1.725,0.209174)
+\path(2.025,0.214679)(1.725,0.214679)
+\path(2.025,0.220183)(1.725,0.220183)
+\path(2.025,0.225688)(1.725,0.225688)
+\path(2.025,0.231193)(1.725,0.231193)
+\path(2.025,0.236697)(1.725,0.236697)
+\path(2.025,0.242202)(1.725,0.242202)
+\path(2.025,0.247706)(1.725,0.247706)
+\path(2.025,0.253211)(1.725,0.253211)
+\path(2.025,0.258716)(1.725,0.258716)
+\path(2.025,0.26422)(1.725,0.26422)
+\path(2.025,0.269725)(1.725,0.269725)
+\path(2.025,0.275229)(1.725,0.275229)
+\path(2.025,0.280734)(1.725,0.280734)
+\path(2.025,0.286239)(1.725,0.286239)
+\path(2.025,0.291743)(1.725,0.291743)
+\path(2.025,0.297248)(1.725,0.297248)
+\path(2.025,0.302752)(1.725,0.302752)
+\path(2.025,0.308257)(1.725,0.308257)
+\path(2.025,0.313761)(1.725,0.313761)
+\path(2.025,0.319266)(1.725,0.319266)
+\path(2.025,0.324771)(1.725,0.324771)
+\path(2.025,0.330275)(1.725,0.330275)
+\path(2.025,0.33578)(1.725,0.33578)
+\path(2.025,0.341284)(1.725,0.341284)
+\path(2.025,0.346789)(1.725,0.346789)
+\path(2.025,0.352294)(1.725,0.352294)
+\path(2.025,0.357798)(1.725,0.357798)
+\path(2.025,0.363303)(1.725,0.363303)
+\path(2.025,0.368807)(1.725,0.368807)
+\path(2.025,0.374312)(1.725,0.374312)
+\path(2.025,0.379817)(1.725,0.379817)
+\path(2.025,0.385321)(1.725,0.385321)
+\path(2.025,0.390826)(1.725,0.390826)
+\path(2.025,0.39633)(1.725,0.39633)
+\path(2.025,0.401835)(1.725,0.401835)
+\path(2.025,0.407339)(1.725,0.407339)
+\path(2.025,0.412844)(1.725,0.412844)
+\path(2.025,0.418349)(1.725,0.418349)
+\path(2.025,0.423853)(1.725,0.423853)
+\path(2.025,0.429358)(1.725,0.429358)
+\path(2.025,0.434862)(1.725,0.434862)
+\path(2.025,0.440367)(1.725,0.440367)
+\path(2.025,0.445872)(1.725,0.445872)
+\path(2.025,0.451376)(1.725,0.451376)
+\path(2.025,0.456881)(1.725,0.456881)
+\path(2.025,0.462385)(1.725,0.462385)
+\path(2.025,0.46789)(1.725,0.46789)
+\path(2.025,0.473394)(1.725,0.473394)
+\path(2.025,0.478899)(1.725,0.478899)
+\path(2.025,0.484404)(1.725,0.484404)
+\path(2.025,0.489908)(1.725,0.489908)
+\path(2.025,0.495413)(1.725,0.495413)
+\path(2.025,0.500917)(1.725,0.500917)
+\path(2.025,0.506422)(1.725,0.506422)
+\path(2.025,0.511927)(1.725,0.511927)
+\path(2.025,0.517431)(1.725,0.517431)
+\path(2.025,0.522936)(1.725,0.522936)
+\path(2.025,0.52844)(1.725,0.52844)
+\path(2.025,0.533945)(1.725,0.533945)
+\path(2.025,0.53945)(1.725,0.53945)
+\path(2.025,0.544954)(1.725,0.544954)
+\path(2.025,0.550459)(1.725,0.550459)
+\path(2.025,0.555963)(1.725,0.555963)
+\path(2.025,0.561468)(1.725,0.561468)
+\path(2.025,0.566972)(1.725,0.566972)
+\path(2.025,0.572477)(1.725,0.572477)
+\path(2.025,0.577982)(1.725,0.577982)
+\path(2.025,0.583486)(1.725,0.583486)
+\path(2.025,0.588991)(1.725,0.588991)
+\path(2.025,0.594495)(1.725,0.594495)
+\path(2.01955,0.6)(2.01955,0)
+\path(2.01409,0.6)(2.01409,0)
+\path(2.00864,0.6)(2.00864,0)
+\path(2.00318,0.6)(2.00318,0)
+\path(1.99773,0.6)(1.99773,0)
+\path(1.99227,0.6)(1.99227,0)
+\path(1.98682,0.6)(1.98682,0)
+\path(1.98136,0.6)(1.98136,0)
+\path(1.97591,0.6)(1.97591,0)
+\path(1.97045,0.6)(1.97045,0)
+\path(1.965,0.6)(1.965,0)
+\path(1.95955,0.6)(1.95955,0)
+\path(1.95409,0.6)(1.95409,0)
+\path(1.94864,0.6)(1.94864,0)
+\path(1.94318,0.6)(1.94318,0)
+\path(1.93773,0.6)(1.93773,0)
+\path(1.93227,0.6)(1.93227,0)
+\path(1.92682,0.6)(1.92682,0)
+\path(1.92136,0.6)(1.92136,0)
+\path(1.91591,0.6)(1.91591,0)
+\path(1.91045,0.6)(1.91045,0)
+\path(1.905,0.6)(1.905,0)
+\path(1.89955,0.6)(1.89955,0)
+\path(1.89409,0.6)(1.89409,0)
+\path(1.88864,0.6)(1.88864,0)
+\path(1.88318,0.6)(1.88318,0)
+\path(1.87773,0.6)(1.87773,0)
+\path(1.87227,0.6)(1.87227,0)
+\path(1.86682,0.6)(1.86682,0)
+\path(1.86136,0.6)(1.86136,0)
+\path(1.85591,0.6)(1.85591,0)
+\path(1.85045,0.6)(1.85045,0)
+\path(1.845,0.6)(1.845,0)
+\path(1.83955,0.6)(1.83955,0)
+\path(1.83409,0.6)(1.83409,0)
+\path(1.82864,0.6)(1.82864,0)
+\path(1.82318,0.6)(1.82318,0)
+\path(1.81773,0.6)(1.81773,0)
+\path(1.81227,0.6)(1.81227,0)
+\path(1.80682,0.6)(1.80682,0)
+\path(1.80136,0.6)(1.80136,0)
+\path(1.79591,0.6)(1.79591,0)
+\path(1.79045,0.6)(1.79045,0)
+\path(1.785,0.6)(1.785,0)
+\path(1.77955,0.6)(1.77955,0)
+\path(1.77409,0.6)(1.77409,0)
+\path(1.76864,0.6)(1.76864,0)
+\path(1.76318,0.6)(1.76318,0)
+\path(1.75773,0.6)(1.75773,0)
+\path(1.75227,0.6)(1.75227,0)
+\path(1.74682,0.6)(1.74682,0)
+\path(1.74136,0.6)(1.74136,0)
+\path(1.73591,0.6)(1.73591,0)
+\path(1.73045,0.6)(1.73045,0)
+\color{rgb_000000}%
+\path(1.725,0)(2.025,0)(2.025,0.6)(1.725,0.6)(1.725,0)
+%%
+\color{rgb_ffffff}%
+\path(1.4941,0.45)(1.5,0.434819)
+\path(1.48819,0.45)(1.5,0.419637)
+\path(1.48229,0.45)(1.5,0.404456)
+\path(1.47639,0.45)(1.5,0.389275)
+\path(1.47049,0.45)(1.5,0.374093)
+\path(1.46458,0.45)(1.5,0.358912)
+\path(1.45868,0.45)(1.5,0.343731)
+\path(1.45278,0.45)(1.5,0.32855)
+\path(1.44688,0.45)(1.5,0.313368)
+\path(1.44097,0.45)(1.5,0.298187)
+\path(1.43507,0.45)(1.5,0.283006)
+\path(1.42917,0.45)(1.5,0.267824)
+\path(1.42327,0.45)(1.5,0.252643)
+\path(1.41736,0.45)(1.5,0.237462)
+\path(1.41146,0.45)(1.5,0.22228)
+\path(1.40556,0.45)(1.5,0.207099)
+\path(1.39966,0.45)(1.5,0.191918)
+\path(1.39375,0.45)(1.5,0.176737)
+\path(1.38785,0.45)(1.5,0.161555)
+\path(1.38195,0.45)(1.49859,0.15)
+\path(1.37605,0.45)(1.49269,0.15)
+\path(1.37014,0.45)(1.48679,0.15)
+\path(1.36424,0.45)(1.48088,0.15)
+\path(1.35834,0.45)(1.47498,0.15)
+\path(1.35244,0.45)(1.46908,0.15)
+\path(1.34653,0.45)(1.46318,0.15)
+\path(1.34063,0.45)(1.45727,0.15)
+\path(1.33473,0.45)(1.45137,0.15)
+\path(1.32883,0.45)(1.44547,0.15)
+\path(1.32292,0.45)(1.43957,0.15)
+\path(1.31702,0.45)(1.43366,0.15)
+\path(1.31112,0.45)(1.42776,0.15)
+\path(1.30522,0.45)(1.42186,0.15)
+\path(1.29931,0.45)(1.41596,0.15)
+\path(1.29341,0.45)(1.41005,0.15)
+\path(1.28751,0.45)(1.40415,0.15)
+\path(1.28161,0.45)(1.39825,0.15)
+\path(1.2757,0.45)(1.39235,0.15)
+\path(1.2698,0.45)(1.38644,0.15)
+\path(1.2639,0.45)(1.38054,0.15)
+\path(1.258,0.45)(1.37464,0.15)
+\path(1.25209,0.45)(1.36874,0.15)
+\path(1.24619,0.45)(1.36283,0.15)
+\path(1.24029,0.45)(1.35693,0.15)
+\path(1.23439,0.45)(1.35103,0.15)
+\path(1.22848,0.45)(1.34513,0.15)
+\path(1.22258,0.45)(1.33922,0.15)
+\path(1.21668,0.45)(1.33332,0.15)
+\path(1.21078,0.45)(1.32742,0.15)
+\path(1.20487,0.45)(1.32152,0.15)
+\path(1.19897,0.45)(1.31561,0.15)
+\path(1.19307,0.45)(1.30971,0.15)
+\path(1.18717,0.45)(1.30381,0.15)
+\path(1.18126,0.45)(1.29791,0.15)
+\path(1.17536,0.45)(1.292,0.15)
+\path(1.16946,0.45)(1.2861,0.15)
+\path(1.16356,0.45)(1.2802,0.15)
+\path(1.15765,0.45)(1.2743,0.15)
+\path(1.15175,0.45)(1.26839,0.15)
+\path(1.14585,0.45)(1.26249,0.15)
+\path(1.13995,0.45)(1.25659,0.15)
+\path(1.13404,0.45)(1.25069,0.15)
+\path(1.12814,0.45)(1.24478,0.15)
+\path(1.12224,0.45)(1.23888,0.15)
+\path(1.11634,0.45)(1.23298,0.15)
+\path(1.11043,0.45)(1.22708,0.15)
+\path(1.10453,0.45)(1.22117,0.15)
+\path(1.09863,0.45)(1.21527,0.15)
+\path(1.09273,0.45)(1.20937,0.15)
+\path(1.08682,0.45)(1.20347,0.15)
+\path(1.08092,0.45)(1.19756,0.15)
+\path(1.07502,0.45)(1.19166,0.15)
+\path(1.06912,0.45)(1.18576,0.15)
+\path(1.06321,0.45)(1.17986,0.15)
+\path(1.05731,0.45)(1.17395,0.15)
+\path(1.05141,0.45)(1.16805,0.15)
+\path(1.05,0.438445)(1.16215,0.15)
+\path(1.05,0.423263)(1.15625,0.15)
+\path(1.05,0.408082)(1.15034,0.15)
+\path(1.05,0.392901)(1.14444,0.15)
+\path(1.05,0.37772)(1.13854,0.15)
+\path(1.05,0.362538)(1.13264,0.15)
+\path(1.05,0.347357)(1.12673,0.15)
+\path(1.05,0.332176)(1.12083,0.15)
+\path(1.05,0.316994)(1.11493,0.15)
+\path(1.05,0.301813)(1.10903,0.15)
+\path(1.05,0.286632)(1.10312,0.15)
+\path(1.05,0.27145)(1.09722,0.15)
+\path(1.05,0.256269)(1.09132,0.15)
+\path(1.05,0.241088)(1.08542,0.15)
+\path(1.05,0.225907)(1.07951,0.15)
+\path(1.05,0.210725)(1.07361,0.15)
+\path(1.05,0.195544)(1.06771,0.15)
+\path(1.05,0.180363)(1.06181,0.15)
+\path(1.05,0.165181)(1.0559,0.15)
+\path(1.05,0.444063)(1.06527,0.45)
+\path(1.05,0.438126)(1.08054,0.45)
+\path(1.05,0.432189)(1.09581,0.45)
+\path(1.05,0.426252)(1.11108,0.45)
+\path(1.05,0.420315)(1.12635,0.45)
+\path(1.05,0.414378)(1.14162,0.45)
+\path(1.05,0.408441)(1.15689,0.45)
+\path(1.05,0.402504)(1.17216,0.45)
+\path(1.05,0.396567)(1.18743,0.45)
+\path(1.05,0.39063)(1.2027,0.45)
+\path(1.05,0.384693)(1.21797,0.45)
+\path(1.05,0.378756)(1.23324,0.45)
+\path(1.05,0.372819)(1.24851,0.45)
+\path(1.05,0.366882)(1.26378,0.45)
+\path(1.05,0.360945)(1.27905,0.45)
+\path(1.05,0.355008)(1.29432,0.45)
+\path(1.05,0.349071)(1.30959,0.45)
+\path(1.05,0.343134)(1.32486,0.45)
+\path(1.05,0.337197)(1.34013,0.45)
+\path(1.05,0.33126)(1.3554,0.45)
+\path(1.05,0.325323)(1.37067,0.45)
+\path(1.05,0.319386)(1.38594,0.45)
+\path(1.05,0.313449)(1.40121,0.45)
+\path(1.05,0.307512)(1.41648,0.45)
+\path(1.05,0.301575)(1.43175,0.45)
+\path(1.05,0.295638)(1.44702,0.45)
+\path(1.05,0.289701)(1.46229,0.45)
+\path(1.05,0.283764)(1.47756,0.45)
+\path(1.05,0.277827)(1.49283,0.45)
+\path(1.05,0.27189)(1.5,0.44685)
+\path(1.05,0.265953)(1.5,0.440913)
+\path(1.05,0.260016)(1.5,0.434976)
+\path(1.05,0.254079)(1.5,0.429039)
+\path(1.05,0.248142)(1.5,0.423102)
+\path(1.05,0.242205)(1.5,0.417165)
+\path(1.05,0.236268)(1.5,0.411228)
+\path(1.05,0.230331)(1.5,0.405291)
+\path(1.05,0.224394)(1.5,0.399354)
+\path(1.05,0.218457)(1.5,0.393417)
+\path(1.05,0.21252)(1.5,0.38748)
+\path(1.05,0.206583)(1.5,0.381543)
+\path(1.05,0.200646)(1.5,0.375606)
+\path(1.05,0.194709)(1.5,0.369669)
+\path(1.05,0.188772)(1.5,0.363732)
+\path(1.05,0.182835)(1.5,0.357795)
+\path(1.05,0.176898)(1.5,0.351858)
+\path(1.05,0.170961)(1.5,0.345921)
+\path(1.05,0.165024)(1.5,0.339984)
+\path(1.05,0.159087)(1.5,0.334047)
+\path(1.05,0.15315)(1.5,0.32811)
+\path(1.05717,0.15)(1.5,0.322173)
+\path(1.07244,0.15)(1.5,0.316236)
+\path(1.08771,0.15)(1.5,0.310299)
+\path(1.10298,0.15)(1.5,0.304362)
+\path(1.11825,0.15)(1.5,0.298425)
+\path(1.13352,0.15)(1.5,0.292488)
+\path(1.14879,0.15)(1.5,0.286551)
+\path(1.16406,0.15)(1.5,0.280614)
+\path(1.17933,0.15)(1.5,0.274677)
+\path(1.1946,0.15)(1.5,0.26874)
+\path(1.20987,0.15)(1.5,0.262803)
+\path(1.22514,0.15)(1.5,0.256866)
+\path(1.24041,0.15)(1.5,0.250929)
+\path(1.25568,0.15)(1.5,0.244992)
+\path(1.27095,0.15)(1.5,0.239055)
+\path(1.28622,0.15)(1.5,0.233118)
+\path(1.30149,0.15)(1.5,0.227181)
+\path(1.31676,0.15)(1.5,0.221244)
+\path(1.33203,0.15)(1.5,0.215307)
+\path(1.3473,0.15)(1.5,0.20937)
+\path(1.36257,0.15)(1.5,0.203433)
+\path(1.37784,0.15)(1.5,0.197496)
+\path(1.39311,0.15)(1.5,0.191559)
+\path(1.40838,0.15)(1.5,0.185622)
+\path(1.42365,0.15)(1.5,0.179685)
+\path(1.43892,0.15)(1.5,0.173748)
+\path(1.45419,0.15)(1.5,0.167811)
+\path(1.46946,0.15)(1.5,0.161874)
+\path(1.48473,0.15)(1.5,0.155937)
+\color{rgb_000000}%
+\path(1.05,0.15)(1.5,0.15)(1.5,0.45)(1.05,0.45)(1.05,0.15)
+%%
+\allinethickness{0.8pt}%
+\path(1.05,0.15)(1.05,0.45)
+%%
+\path(1.275,0.15)(1.275,0.45)
+%%
+\path(1.5,0.15)(1.5,0.45)
+%%
+\path(1.05,0.15)(1.5,0.15)
+%%
+\path(1.05,0.3)(1.5,0.3)
+%%
+\path(1.05,0.45)(1.5,0.45)
+%%
+\path(0,0)(3.75,0)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/objects.xp b/graphics/epix/doc/objects.xp
new file mode 100644
index 0000000000..d0828f0b94
--- /dev/null
+++ b/graphics/epix/doc/objects.xp
@@ -0,0 +1,33 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(0,0), P(5,2), "3.75 x 1.5in");
+
+ begin();
+
+ // roof
+ triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices
+
+ // sun
+ circle(P(4,1.5), 0.25); // center and radius
+
+ // house
+ rect(P(1,0), P(3,1)); // opposite corners
+ // grid(P(1,0), P(3,1), 1, 10); // corners, numbers of subdivisions
+
+ // door
+ fill(Black(0.1));
+ rect(P(2.3,0), P(2.7,0.8)); // corners
+
+ fill(White());
+ // window
+ rect(P(1.4,0.2), P(2, 0.6));
+ bold();
+ grid(P(1.4,0.2), P(2, 0.6), 2, 2);
+
+ line(P(xmin(),0), P(xmax(),0));
+ end();
+}
diff --git a/graphics/epix/doc/pathstyle.eepic b/graphics/epix/doc/pathstyle.eepic
new file mode 100644
index 0000000000..531523bf45
--- /dev/null
+++ b/graphics/epix/doc/pathstyle.eepic
@@ -0,0 +1,225 @@
+%% Generated from pathstyle.xp on Tue Jul 17 15:01:22 EDT 2007 by
+%% ePiX-1.1.8
+%%
+%% Cartesian bounding box: [0,4] x [0,4]
+%% Actual size: 4 x 1in
+%% Figure offset: left by 0in, down by 0in
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\setlength{\unitlength}{1in}
+\begin{picture}(4,1)(-0,-0)
+\path(0,1)(0.0394737,1)
+\path(0.118421,1)(0.157895,1)
+\path(0.157895,1)(0.197368,1)
+\path(0.276316,1)(0.315789,1)
+\path(0.315789,1)(0.355263,1)
+\path(0.434211,1)(0.473684,1)
+\path(0.473684,1)(0.513158,1)
+\path(0.592105,1)(0.631579,1)
+\path(0.631579,1)(0.671053,1)
+\path(0.75,1)(0.789474,1)
+\path(0.789474,1)(0.828947,1)
+\path(0.907895,1)(0.947368,1)
+\path(0.947368,1)(0.986842,1)
+\path(1.06579,1)(1.10526,1)
+\path(1.10526,1)(1.14474,1)
+\path(1.22368,1)(1.26316,1)
+\path(1.26316,1)(1.30263,1)
+\path(1.38158,1)(1.42105,1)
+\path(1.42105,1)(1.46053,1)
+\path(1.53947,1)(1.57895,1)
+\path(1.57895,1)(1.61842,1)
+\path(1.69737,1)(1.73684,1)
+\path(1.73684,1)(1.77632,1)
+\path(1.85526,1)(1.89474,1)
+\path(1.89474,1)(1.93421,1)
+\path(2.01316,1)(2.05263,1)
+\path(2.05263,1)(2.09211,1)
+\path(2.17105,1)(2.21053,1)
+\path(2.21053,1)(2.25,1)
+\path(2.32895,1)(2.36842,1)
+\path(2.36842,1)(2.40789,1)
+\path(2.48684,1)(2.52632,1)
+\path(2.52632,1)(2.56579,1)
+\path(2.64474,1)(2.68421,1)
+\path(2.68421,1)(2.72368,1)
+\path(2.80263,1)(2.84211,1)
+\path(2.84211,1)(2.88158,1)
+\path(2.96053,1)(3,1)
+\put(3.05535,1){\makebox(0,0)[l]{\code{line\_style("-\ \ -")}}}
+\path(0,0.75)(0.0263158,0.75)
+\path(0.131579,0.75)(0.157895,0.75)
+\path(0.157895,0.75)(0.184211,0.75)
+\path(0.289474,0.75)(0.315789,0.75)
+\path(0.315789,0.75)(0.342105,0.75)
+\path(0.447368,0.75)(0.473684,0.75)
+\path(0.473684,0.75)(0.5,0.75)
+\path(0.605263,0.75)(0.631579,0.75)
+\path(0.631579,0.75)(0.657895,0.75)
+\path(0.763158,0.75)(0.789474,0.75)
+\path(0.789474,0.75)(0.815789,0.75)
+\path(0.921053,0.75)(0.947368,0.75)
+\path(0.947368,0.75)(0.973684,0.75)
+\path(1.07895,0.75)(1.10526,0.75)
+\path(1.10526,0.75)(1.13158,0.75)
+\path(1.23684,0.75)(1.26316,0.75)
+\path(1.26316,0.75)(1.28947,0.75)
+\path(1.39474,0.75)(1.42105,0.75)
+\path(1.42105,0.75)(1.44737,0.75)
+\path(1.55263,0.75)(1.57895,0.75)
+\path(1.57895,0.75)(1.60526,0.75)
+\path(1.71053,0.75)(1.73684,0.75)
+\path(1.73684,0.75)(1.76316,0.75)
+\path(1.86842,0.75)(1.89474,0.75)
+\path(1.89474,0.75)(1.92105,0.75)
+\path(2.02632,0.75)(2.05263,0.75)
+\path(2.05263,0.75)(2.07895,0.75)
+\path(2.18421,0.75)(2.21053,0.75)
+\path(2.21053,0.75)(2.23684,0.75)
+\path(2.34211,0.75)(2.36842,0.75)
+\path(2.36842,0.75)(2.39474,0.75)
+\path(2.5,0.75)(2.52632,0.75)
+\path(2.52632,0.75)(2.55263,0.75)
+\path(2.65789,0.75)(2.68421,0.75)
+\path(2.68421,0.75)(2.71053,0.75)
+\path(2.81579,0.75)(2.84211,0.75)
+\path(2.84211,0.75)(2.86842,0.75)
+\path(2.97368,0.75)(3,0.75)
+\put(3.05535,0.75){\makebox(0,0)[l]{\code{line\_style("-\ \ \ \ -")}}}
+\put(0.0789474,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(0.236842,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(0.394737,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(0.552632,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(0.710526,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(0.868421,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.02632,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.18421,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.34211,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.5,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.65789,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.81579,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(1.97368,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.13158,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.28947,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.44737,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.60526,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.76316,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(2.92105,0.5){\makebox(0,0){\circle{0.0055348}}}
+\put(3.05535,0.5){\makebox(0,0)[l]{\code{line\_style(" .\ ")}}}
+\path(0,0.25)(0.0315789,0.25)
+\put(0.0789474,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.126316,0.25)(0.157895,0.25)
+\path(0.157895,0.25)(0.189474,0.25)
+\put(0.236842,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.284211,0.25)(0.315789,0.25)
+\path(0.315789,0.25)(0.347368,0.25)
+\put(0.394737,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.442105,0.25)(0.473684,0.25)
+\path(0.473684,0.25)(0.505263,0.25)
+\put(0.552632,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.6,0.25)(0.631579,0.25)
+\path(0.631579,0.25)(0.663158,0.25)
+\put(0.710526,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.757895,0.25)(0.789474,0.25)
+\path(0.789474,0.25)(0.821053,0.25)
+\put(0.868421,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(0.915789,0.25)(0.947368,0.25)
+\path(0.947368,0.25)(0.978947,0.25)
+\put(1.02632,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.07368,0.25)(1.10526,0.25)
+\path(1.10526,0.25)(1.13684,0.25)
+\put(1.18421,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.23158,0.25)(1.26316,0.25)
+\path(1.26316,0.25)(1.29474,0.25)
+\put(1.34211,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.38947,0.25)(1.42105,0.25)
+\path(1.42105,0.25)(1.45263,0.25)
+\put(1.5,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.54737,0.25)(1.57895,0.25)
+\path(1.57895,0.25)(1.61053,0.25)
+\put(1.65789,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.70526,0.25)(1.73684,0.25)
+\path(1.73684,0.25)(1.76842,0.25)
+\put(1.81579,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(1.86316,0.25)(1.89474,0.25)
+\path(1.89474,0.25)(1.92632,0.25)
+\put(1.97368,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.02105,0.25)(2.05263,0.25)
+\path(2.05263,0.25)(2.08421,0.25)
+\put(2.13158,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.17895,0.25)(2.21053,0.25)
+\path(2.21053,0.25)(2.24211,0.25)
+\put(2.28947,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.33684,0.25)(2.36842,0.25)
+\path(2.36842,0.25)(2.4,0.25)
+\put(2.44737,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.49474,0.25)(2.52632,0.25)
+\path(2.52632,0.25)(2.55789,0.25)
+\put(2.60526,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.65263,0.25)(2.68421,0.25)
+\path(2.68421,0.25)(2.71579,0.25)
+\put(2.76316,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.81053,0.25)(2.84211,0.25)
+\path(2.84211,0.25)(2.87368,0.25)
+\put(2.92105,0.25){\makebox(0,0){\circle{0.0055348}}}
+\path(2.96842,0.25)(3,0.25)
+\put(3.05535,0.25){\makebox(0,0)[l]{\code{line\_style("-\ .\ -")}}}
+\put(0.0157895,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.0631579,0)(0.0947368,0)
+\put(0.142105,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.173684,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.221053,0)(0.252632,0)
+\put(0.3,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.331579,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.378947,0)(0.410526,0)
+\put(0.457895,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.489474,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.536842,0)(0.568421,0)
+\put(0.615789,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.647368,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.694737,0)(0.726316,0)
+\put(0.773684,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.805263,0){\makebox(0,0){\circle{0.0055348}}}
+\path(0.852632,0)(0.884211,0)
+\put(0.931579,0){\makebox(0,0){\circle{0.0055348}}}
+\put(0.963158,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.01053,0)(1.04211,0)
+\put(1.08947,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.12105,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.16842,0)(1.2,0)
+\put(1.24737,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.27895,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.32632,0)(1.35789,0)
+\put(1.40526,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.43684,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.48421,0)(1.51579,0)
+\put(1.56316,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.59474,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.64211,0)(1.67368,0)
+\put(1.72105,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.75263,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.8,0)(1.83158,0)
+\put(1.87895,0){\makebox(0,0){\circle{0.0055348}}}
+\put(1.91053,0){\makebox(0,0){\circle{0.0055348}}}
+\path(1.95789,0)(1.98947,0)
+\put(2.03684,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.06842,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.11579,0)(2.14737,0)
+\put(2.19474,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.22632,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.27368,0)(2.30526,0)
+\put(2.35263,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.38421,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.43158,0)(2.46316,0)
+\put(2.51053,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.54211,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.58947,0)(2.62105,0)
+\put(2.66842,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.7,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.74737,0)(2.77895,0)
+\put(2.82632,0){\makebox(0,0){\circle{0.0055348}}}
+\put(2.85789,0){\makebox(0,0){\circle{0.0055348}}}
+\path(2.90526,0)(2.93684,0)
+\put(2.98421,0){\makebox(0,0){\circle{0.0055348}}}
+\put(3.05535,0){\makebox(0,0)[l]{\code{line\_style(".\ - .")}}}
+\end{picture}
diff --git a/graphics/epix/doc/pathstyle.xp b/graphics/epix/doc/pathstyle.xp
new file mode 100644
index 0000000000..47fe65e5e1
--- /dev/null
+++ b/graphics/epix/doc/pathstyle.xp
@@ -0,0 +1,24 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+void dash_sample(double ht, std::string pattern)
+{
+ line_style(pattern);
+ line(P(0,ht), P(3,ht));
+ label(P(3, ht), P(4,0), "\\code{line\\_style(\""+pattern+"\")}", r);
+}
+
+int main() {
+ picture(P(0,0), P(4,4), "4x1in");
+
+ begin();
+
+ dash_sample(4, "-\\ \\ -");
+ dash_sample(3, "-\\ \\ \\ \\ -");
+ dash_sample(2, " .\\ ");
+ dash_sample(1, "-\\ .\\ -");
+ dash_sample(0, ".\\ - .");
+
+ end();
+}
diff --git a/graphics/epix/doc/plot_a.eepic b/graphics/epix/doc/plot_a.eepic
new file mode 100644
index 0000000000..bf0e6e787a
--- /dev/null
+++ b/graphics/epix/doc/plot_a.eepic
@@ -0,0 +1,95 @@
+%% Generated from plot_a.xp on Tue Jul 3 00:20:34 EDT 2007 by
+%% ePiX-1.0.25
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 1.5in x 1.5in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(1.5,1.5)(-0,-0)
+%% ---
+\path(0.75,0.75)(0.709403,0.666178)(0.666551,0.577699)(0.62125,0.484165)
+ (0.573284,0.385128)(0.522412,0.280089)(0.46836,0.168485)
+\path(0.75,0.75)(0.749023,0.665974)(0.74798,0.585752)(0.746855,0.509046)
+ (0.745629,0.435587)(0.744277,0.365124)(0.742767,0.297412)
+\path(0.75,0.75)(0.788831,0.67297)(0.830368,0.605884)(0.875481,0.548895)
+ (0.925286,0.502471)(0.981254,0.467495)(1.04539,0.445422)
+\path(0.75,0.75)(0.824541,0.685618)(0.903621,0.632501)(0.988754,0.590989)
+ (1.08184,0.561798)(1.18533,0.546138)(1.30251,0.545884)
+\path(0.75,0.75)(0.852385,0.702504)(0.959101,0.662234)(1.07131,0.62933)
+ (1.19037,0.604066)(1.31791,0.586882)(1.45594,0.578419)
+\path(0.75,0.75)(0.869635,0.722554)(0.991406,0.694618)(1.11537,0.666178)
+ (1.24159,0.637221)(1.37013,0.607733)(1.50104,0.577699)
+\path(0.75,0.75)(0.874862,0.74491)(0.998815,0.731016)(1.12092,0.708519)
+ (1.24029,0.677746)(1.35609,0.639142)(1.46759,0.593248)
+\path(0.75,0.75)(0.867939,0.768582)(0.982511,0.77261)(1.09249,0.76265)
+ (1.19682,0.739556)(1.29466,0.704421)(1.38541,0.658506)
+\path(0.75,0.75)(0.849863,0.792084)(0.945428,0.818543)(1.03584,0.830052)
+ (1.12046,0.827563)(1.1988,0.812243)(1.27061,0.785404)
+\path(0.75,0.75)(0.822527,0.813279)(0.891435,0.864939)(0.956495,0.905455)
+ (1.01755,0.935412)(1.07452,0.955475)(1.12739,0.966366)
+\path(0.75,0.75)(0.788515,0.829523)(0.825104,0.905071)(0.859908,0.976933)
+ (0.893055,1.04537)(0.924661,1.11063)(0.954829,1.17292)
+\path(0.75,0.75)(0.750924,0.838139)(0.751807,0.93073)(0.752656,1.02814)
+ (0.753481,1.13079)(0.754288,1.23912)(0.755083,1.35363)
+\path(0.75,0.75)(0.713174,0.837085)(0.677771,0.934566)(0.643292,1.043)
+ (0.609295,1.16316)(0.575368,1.29605)(0.541119,1.44293)
+\path(0.75,0.75)(0.678756,0.825621)(0.609753,0.912727)(0.542063,1.01182)
+ (0.47484,1.12367)(0.40728,1.24929)(0.33859,1.39004)
+\path(0.75,0.75)(0.650938,0.804706)(0.554306,0.866713)(0.459296,0.936218)
+ (0.365158,1.01352)(0.27118,1.09902)(0.176669,1.19323)
+\path(0.75,0.75)(0.632446,0.776969)(0.516918,0.803473)(0.403366,0.829523)
+ (0.291738,0.855133)(0.181986,0.880311)(0.0740632,0.905071)
+\path(0.75,0.75)(0.625191,0.746217)(0.501394,0.73363)(0.379543,0.712441)
+ (0.260522,0.68298)(0.145146,0.645689)(0.0341447,0.601107)
+\path(0.75,0.75)(0.630074,0.71664)(0.509637,0.668642)(0.390202,0.606516)
+ (0.273258,0.531127)(0.160206,0.443655)(0.0523099,0.345536)
+\path(0.75,0.75)(0.646869,0.69196)(0.541651,0.618018)(0.435639,0.528643)
+ (0.330189,0.424716)(0.22666,0.307508)(0.126363,0.178624)
+\path(0.75,0.75)(0.674167,0.674761)(0.59542,0.587383)(0.514234,0.48787)
+ (0.431158,0.376427)(0.346809,0.253475)(0.261856,0.119648)
+\path(0.75,0.75)(0.709403,0.666178)(0.666551,0.577699)(0.62125,0.484165)
+ (0.573284,0.385128)(0.522412,0.280089)(0.46836,0.168485)
+\path(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)
+\path(0.709403,0.666178)(0.749023,0.665974)(0.788831,0.67297)
+ (0.824541,0.685618)(0.852385,0.702504)(0.869635,0.722554)
+ (0.874862,0.74491)(0.867939,0.768582)(0.849863,0.792084)
+ (0.822527,0.813279)(0.788515,0.829523)(0.750924,0.838139)
+ (0.713174,0.837085)(0.678756,0.825621)(0.650938,0.804706)
+ (0.632446,0.776969)(0.625191,0.746217)(0.630074,0.71664)
+ (0.646869,0.69196)(0.674167,0.674761)(0.709403,0.666178)
+\path(0.666551,0.577699)(0.74798,0.585752)(0.830368,0.605884)
+ (0.903621,0.632501)(0.959101,0.662234)(0.991406,0.694618)
+ (0.998815,0.731016)(0.982511,0.77261)(0.945428,0.818543)
+ (0.891435,0.864939)(0.825104,0.905071)(0.751807,0.93073)
+ (0.677771,0.934566)(0.609753,0.912727)(0.554306,0.866713)
+ (0.516918,0.803473)(0.501394,0.73363)(0.509637,0.668642)
+ (0.541651,0.618018)(0.59542,0.587383)(0.666551,0.577699)
+\path(0.62125,0.484165)(0.746855,0.509046)(0.875481,0.548895)
+ (0.988754,0.590989)(1.07131,0.62933)(1.11537,0.666178)(1.12092,0.708519)
+ (1.09249,0.76265)(1.03584,0.830052)(0.956495,0.905455)(0.859908,0.976933)
+ (0.752656,1.02814)(0.643292,1.043)(0.542063,1.01182)(0.459296,0.936218)
+ (0.403366,0.829523)(0.379543,0.712441)(0.390202,0.606516)
+ (0.435639,0.528643)(0.514234,0.48787)(0.62125,0.484165)
+\path(0.573284,0.385128)(0.745629,0.435587)(0.925286,0.502471)
+ (1.08184,0.561798)(1.19037,0.604066)(1.24159,0.637221)(1.24029,0.677746)
+ (1.19682,0.739556)(1.12046,0.827563)(1.01755,0.935412)(0.893055,1.04537)
+ (0.753481,1.13079)(0.609295,1.16316)(0.47484,1.12367)(0.365158,1.01352)
+ (0.291738,0.855133)(0.260522,0.68298)(0.273258,0.531127)
+ (0.330189,0.424716)(0.431158,0.376427)(0.573284,0.385128)
+\path(0.522412,0.280089)(0.744277,0.365124)(0.981254,0.467495)
+ (1.18533,0.546138)(1.31791,0.586882)(1.37013,0.607733)(1.35609,0.639142)
+ (1.29466,0.704421)(1.1988,0.812243)(1.07452,0.955475)(0.924661,1.11063)
+ (0.754288,1.23912)(0.575368,1.29605)(0.40728,1.24929)(0.27118,1.09902)
+ (0.181986,0.880311)(0.145146,0.645689)(0.160206,0.443655)
+ (0.22666,0.307508)(0.346809,0.253475)(0.522412,0.280089)
+\path(0.46836,0.168485)(0.742767,0.297412)(1.04539,0.445422)
+ (1.30251,0.545884)(1.45594,0.578419)(1.50104,0.577699)(1.46759,0.593248)
+ (1.38541,0.658506)(1.27061,0.785404)(1.12739,0.966366)(0.954829,1.17292)
+ (0.755083,1.35363)(0.541119,1.44293)(0.33859,1.39004)(0.176669,1.19323)
+ (0.0740632,0.905071)(0.0341447,0.601107)(0.0523099,0.345536)
+ (0.126363,0.178624)(0.261856,0.119648)(0.46836,0.168485)
+\end{picture}
diff --git a/graphics/epix/doc/plot_a.xp b/graphics/epix/doc/plot_a.xp
new file mode 100644
index 0000000000..4304d501d3
--- /dev/null
+++ b/graphics/epix/doc/plot_a.xp
@@ -0,0 +1,27 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+P f(double u, double v)
+{
+ double x=u*Cos(v), y=u*Sin(v);
+ // return P(x, y, 0.25*x*(x*x-3*y*y));
+ return P(x, y, x*y);
+}
+
+domain R(P(0,0), P(1,1), mesh(6, 20), mesh(6, 20));
+
+int main()
+{
+ bounding_box(P(-1,-1),P(1,1));
+ unitlength("1in");
+ picture(1.5,1.5);
+
+ begin();
+ revolutions();
+
+ camera.at(P(3, 1, 3));
+
+ plot(f, R);
+
+ end();
+}
diff --git a/graphics/epix/doc/plot_b.eepic b/graphics/epix/doc/plot_b.eepic
new file mode 100644
index 0000000000..cf847bd346
--- /dev/null
+++ b/graphics/epix/doc/plot_b.eepic
@@ -0,0 +1,225 @@
+%% Generated from plot_b.xp on Tue Jul 3 00:20:46 EDT 2007 by
+%% ePiX-1.0.25
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 1.5in x 1.5in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(1.5,1.5)(-0,-0)
+%% ---
+\path(0.75,0.75)(0.729972,0.708648)(0.709403,0.666178)(0.688271,0.622545)
+ (0.666551,0.577699)(0.64422,0.531591)(0.62125,0.484165)
+ (0.597615,0.435364)(0.573284,0.385128)(0.548228,0.333393)
+ (0.522412,0.280089)(0.495802,0.225146)(0.46836,0.168485)
+\path(0.75,0.75)(0.749519,0.707493)(0.749023,0.665974)(0.74851,0.625406)
+ (0.74798,0.585752)(0.747429,0.546976)(0.746855,0.509046)
+ (0.746256,0.471927)(0.745629,0.435587)(0.744971,0.399997)
+ (0.744277,0.365124)(0.743544,0.330939)(0.742767,0.297412)
+\path(0.75,0.75)(0.769125,0.71024)(0.788831,0.67297)(0.809212,0.638181)
+ (0.830368,0.605884)(0.852415,0.576107)(0.875481,0.548895)
+ (0.899715,0.524319)(0.925286,0.502471)(0.952389,0.483477)
+ (0.981254,0.467495)(1.01215,0.454726)(1.04539,0.445422)
+\path(0.75,0.75)(0.786786,0.716409)(0.824541,0.685618)(0.863426,0.657638)
+ (0.903621,0.632501)(0.945323,0.610259)(0.988754,0.590989)
+ (1.03416,0.574791)(1.08184,0.561798)(1.1321,0.552178)(1.18533,0.546138)
+ (1.24196,0.543935)(1.30251,0.545884)
+\path(0.75,0.75)(0.800717,0.725352)(0.852385,0.702504)(0.905133,0.68146)
+ (0.959101,0.662234)(1.01444,0.644848)(1.07131,0.62933)(1.12989,0.615719)
+ (1.19037,0.604066)(1.25297,0.594429)(1.31791,0.586882)(1.38547,0.581511)
+ (1.45594,0.578419)
+\path(0.75,0.75)(0.809554,0.736337)(0.869635,0.722554)(0.93025,0.708648)
+ (0.991406,0.694618)(1.05311,0.680462)(1.11537,0.666178)(1.1782,0.651765)
+ (1.24159,0.637221)(1.30556,0.622545)(1.37013,0.607733)(1.43528,0.592786)
+ (1.50104,0.577699)
+\path(0.75,0.75)(0.812485,0.748563)(0.874862,0.74491)(0.937011,0.739054)
+ (0.998815,0.731016)(1.06016,0.720825)(1.12092,0.708519)(1.181,0.694142)
+ (1.24029,0.677746)(1.29868,0.659392)(1.35609,0.639142)(1.41242,0.617069)
+ (1.46759,0.593248)
+\path(0.75,0.75)(0.809307,0.761132)(0.867939,0.768582)(0.925727,0.772387)
+ (0.982511,0.77261)(1.03814,0.769331)(1.09249,0.76265)(1.14541,0.752681)
+ (1.19682,0.739556)(1.24659,0.723418)(1.29466,0.704421)(1.34095,0.682727)
+ (1.38541,0.658506)
+\path(0.75,0.75)(0.800408,0.773024)(0.849863,0.792084)(0.89824,0.807232)
+ (0.945428,0.818543)(0.991325,0.826113)(1.03584,0.830052)
+ (1.07891,0.830488)(1.12046,0.827563)(1.16044,0.821428)(1.1988,0.812243)
+ (1.23553,0.800178)(1.27061,0.785404)
+\path(0.75,0.75)(0.786698,0.783117)(0.822527,0.813279)(0.857449,0.840534)
+ (0.891435,0.864939)(0.924458,0.886556)(0.956495,0.905455)
+ (0.987531,0.921714)(1.01755,0.935412)(1.04655,0.946636)(1.07452,0.955475)
+ (1.10147,0.962021)(1.12739,0.966366)
+\path(0.75,0.75)(0.769508,0.790278)(0.788515,0.829523)(0.807041,0.867775)
+ (0.825104,0.905071)(0.842721,0.941445)(0.859908,0.976933)
+ (0.876682,1.01156)(0.893055,1.04537)(0.909044,1.07838)(0.924661,1.11063)
+ (0.939918,1.14213)(0.954829,1.17292)
+\path(0.75,0.75)(0.750468,0.793535)(0.750924,0.838139)(0.75137,0.883856)
+ (0.751807,0.93073)(0.752235,0.978809)(0.752656,1.02814)(0.753071,1.07878)
+ (0.753481,1.13079)(0.753886,1.18421)(0.754288,1.23912)(0.754687,1.29556)
+ (0.755083,1.35363)
+\path(0.75,0.75)(0.731375,0.79227)(0.713174,0.837085)(0.695327,0.884497)
+ (0.677771,0.934566)(0.660445,0.98737)(0.643292,1.043)(0.62626,1.10155)
+ (0.609295,1.16316)(0.592347,1.22794)(0.575368,1.29605)(0.558309,1.36765)
+ (0.541119,1.44293)
+\path(0.75,0.75)(0.714035,0.786396)(0.678756,0.825621)(0.644034,0.867713)
+ (0.609753,0.912727)(0.575798,0.960735)(0.542063,1.01182)
+ (0.508444,1.06609)(0.47484,1.12367)(0.441152,1.18468)(0.40728,1.24929)
+ (0.373126,1.31768)(0.33859,1.39004)
+\path(0.75,0.75)(0.700112,0.776448)(0.650938,0.804706)(0.60237,0.834787)
+ (0.554306,0.866713)(0.506646,0.900512)(0.459296,0.936218)
+ (0.412163,0.973871)(0.365158,1.01352)(0.318192,1.05521)(0.27118,1.09902)
+ (0.224034,1.145)(0.176669,1.19323)
+\path(0.75,0.75)(0.690966,0.763543)(0.632446,0.776969)(0.574432,0.790278)
+ (0.516918,0.803473)(0.459898,0.816554)(0.403366,0.829523)
+ (0.347314,0.842382)(0.291738,0.855133)(0.23663,0.867775)
+ (0.181986,0.880311)(0.127799,0.892743)(0.0740632,0.905071)
+\path(0.75,0.75)(0.687529,0.749216)(0.625191,0.746217)(0.563106,0.741014)
+ (0.501394,0.73363)(0.440168,0.724093)(0.379543,0.712441)
+ (0.319626,0.69872)(0.260522,0.68298)(0.202331,0.665282)
+ (0.145146,0.645689)(0.089057,0.624272)(0.0341447,0.601107)
+\path(0.75,0.75)(0.690195,0.735167)(0.630074,0.71664)(0.569825,0.694447)
+ (0.509637,0.668642)(0.4497,0.639299)(0.390202,0.606516)
+ (0.331328,0.570413)(0.273258,0.531127)(0.216163,0.488817)
+ (0.160206,0.443655)(0.105542,0.395829)(0.0523099,0.345536)
+\path(0.75,0.75)(0.698772,0.72298)(0.646869,0.69196)(0.594442,0.656957)
+ (0.541651,0.618018)(0.488661,0.575214)(0.435639,0.528643)
+ (0.382758,0.478428)(0.330189,0.424716)(0.2781,0.367679)(0.22666,0.307508)
+ (0.176029,0.244413)(0.126363,0.178624)
+\path(0.75,0.75)(0.712474,0.713891)(0.674167,0.674761)(0.63513,0.632594)
+ (0.59542,0.587383)(0.555099,0.539136)(0.514234,0.48787)
+ (0.472895,0.433619)(0.431158,0.376427)(0.389102,0.316355)
+ (0.346809,0.253475)(0.304364,0.187873)(0.261856,0.119648)
+\path(0.75,0.75)(0.729972,0.708648)(0.709403,0.666178)(0.688271,0.622545)
+ (0.666551,0.577699)(0.64422,0.531591)(0.62125,0.484165)
+ (0.597615,0.435364)(0.573284,0.385128)(0.548228,0.333393)
+ (0.522412,0.280089)(0.495802,0.225146)(0.46836,0.168485)
+\path(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)
+ (0.75,0.75)
+\path(0.75,0.75)
+\path(0.709403,0.666178)(0.722321,0.665223)(0.73558,0.665171)
+ (0.749023,0.665974)(0.762487,0.667581)(0.77581,0.669932)
+ (0.788831,0.67297)(0.801393,0.676634)(0.813343,0.680868)
+ (0.824541,0.685618)(0.834856,0.690836)(0.844172,0.696477)
+ (0.852385,0.702504)(0.859411,0.708879)(0.865178,0.715573)
+ (0.869635,0.722554)(0.872745,0.729792)(0.874488,0.737256)
+ (0.874862,0.74491)(0.873876,0.752715)(0.871555,0.760624)
+ (0.867939,0.768582)(0.863075,0.776527)(0.857026,0.784387)
+ (0.849863,0.792084)(0.841664,0.799529)(0.83252,0.806627)
+ (0.822527,0.813279)(0.811787,0.819381)(0.800411,0.82483)
+ (0.788515,0.829523)(0.776218,0.833364)(0.763645,0.836262)
+ (0.750924,0.838139)(0.738185,0.838931)(0.725558,0.83859)
+ (0.713174,0.837085)(0.701162,0.83441)(0.689648,0.830577)
+ (0.678756,0.825621)(0.668601,0.819601)(0.659294,0.812596)
+ (0.650938,0.804706)(0.643624,0.796048)(0.637436,0.786754)
+ (0.632446,0.776969)(0.628712,0.766846)(0.626283,0.756542)
+ (0.625191,0.746217)(0.625457,0.736026)(0.627088,0.72612)
+ (0.630074,0.71664)(0.634394,0.707713)(0.64001,0.699454)(0.646869,0.69196)
+ (0.654905,0.685309)(0.664036,0.679562)(0.674167,0.674761)
+ (0.685188,0.670929)(0.696978,0.668072)(0.709403,0.666178)
+\path(0.709403,0.666178)
+\path(0.666551,0.577699)(0.692974,0.578664)(0.720234,0.581422)
+ (0.74798,0.585752)(0.775839,0.591423)(0.80343,0.598206)
+ (0.830368,0.605884)(0.856279,0.614263)(0.880806,0.623178)
+ (0.903621,0.632501)(0.924433,0.642145)(0.942994,0.65206)
+ (0.959101,0.662234)(0.972601,0.672687)(0.98339,0.683461)
+ (0.991406,0.694618)(0.996632,0.706222)(0.999085,0.718337)
+ (0.998815,0.731016)(0.995896,0.74429)(0.990424,0.758164)
+ (0.982511,0.77261)(0.972282,0.787565)(0.959873,0.802924)
+ (0.945428,0.818543)(0.929098,0.834239)(0.911044,0.849789)
+ (0.891435,0.864939)(0.870449,0.879406)(0.848272,0.892888)
+ (0.825104,0.905071)(0.801155,0.915638)(0.776645,0.924286)
+ (0.751807,0.93073)(0.726882,0.934719)(0.702119,0.936048)
+ (0.677771,0.934566)(0.654093,0.930185)(0.631338,0.922887)
+ (0.609753,0.912727)(0.589573,0.899834)(0.571022,0.884408)
+ (0.554306,0.866713)(0.539611,0.847073)(0.527101,0.825857)
+ (0.516918,0.803473)(0.509181,0.780348)(0.503983,0.756921)
+ (0.501394,0.73363)(0.501461,0.710895)(0.504209,0.689112)
+ (0.509637,0.668642)(0.517723,0.649801)(0.528419,0.632855)
+ (0.541651,0.618018)(0.557321,0.605441)(0.575297,0.595218)
+ (0.59542,0.587383)(0.617495,0.581912)(0.641293,0.578726)
+ (0.666551,0.577699)
+\path(0.666551,0.577699)
+\path(0.62125,0.484165)(0.661714,0.489898)(0.703779,0.498369)
+ (0.746855,0.509046)(0.790294,0.521379)(0.833406,0.534828)
+ (0.875481,0.548895)(0.915825,0.563151)(0.953779,0.577259)
+ (0.988754,0.590989)(1.02025,0.604228)(1.04786,0.616974)(1.07131,0.62933)
+ (1.09041,0.641478)(1.10509,0.653667)(1.11537,0.666178)(1.12133,0.679307)
+ (1.12312,0.693337)(1.12092,0.708519)(1.11493,0.725052)(1.10538,0.743075)
+ (1.09249,0.76265)(1.07646,0.783756)(1.05751,0.806289)(1.03584,0.830052)
+ (1.01166,0.854761)(0.985141,0.880045)(0.956495,0.905455)
+ (0.925925,0.930468)(0.893649,0.954502)(0.859908,0.976933)
+ (0.824965,0.997111)(0.789108,1.01439)(0.752656,1.02814)(0.715955,1.0378)
+ (0.679371,1.04288)(0.643292,1.043)(0.608116,1.0379)(0.574243,1.02749)
+ (0.542063,1.01182)(0.511952,0.991116)(0.484258,0.965743)
+ (0.459296,0.936218)(0.437343,0.903175)(0.418635,0.867345)
+ (0.403366,0.829523)(0.391688,0.790542)(0.383719,0.751241)
+ (0.379543,0.712441)(0.379214,0.674923)(0.382764,0.639401)
+ (0.390202,0.606516)(0.401519,0.576814)(0.416683,0.550743)
+ (0.435639,0.528643)(0.458304,0.510741)(0.484558,0.497152)
+ (0.514234,0.48787)(0.547111,0.48278)(0.582903,0.481654)(0.62125,0.484165)
+\path(0.62125,0.484165)
+\path(0.573284,0.385128)(0.628255,0.398429)(0.685992,0.415579)
+ (0.745629,0.435587)(0.806153,0.457413)(0.866435,0.480025)
+ (0.925286,0.502471)(0.981521,0.523945)(1.03403,0.543843)
+ (1.08184,0.561798)(1.12417,0.577699)(1.16045,0.591675)(1.19037,0.604066)
+ (1.21379,0.615372)(1.23079,0.626204)(1.24159,0.637221)(1.24651,0.649085)
+ (1.24594,0.662413)(1.24029,0.677746)(1.22996,0.695523)(1.21536,0.716063)
+ (1.19682,0.739556)(1.17465,0.766054)(1.14912,0.795468)(1.12046,0.827563)
+ (1.08886,0.861958)(1.0545,0.89813)(1.01755,0.935412)(0.978193,0.973008)
+ (0.936617,1.01)(0.893055,1.04537)(0.847784,1.07804)(0.80113,1.10688)
+ (0.753481,1.13079)(0.705284,1.14872)(0.65704,1.15976)(0.609295,1.16316)
+ (0.562623,1.15839)(0.517613,1.14522)(0.47484,1.12367)(0.434852,1.09408)
+ (0.398146,1.05707)(0.365158,1.01352)(0.336248,0.964504)
+ (0.311704,0.911264)(0.291738,0.855133)(0.276497,0.797481)
+ (0.266074,0.739664)(0.260522,0.68298)(0.259863,0.628631)
+ (0.264107,0.577699)(0.273258,0.531127)(0.287318,0.489709)
+ (0.306294,0.454081)(0.330189,0.424716)(0.358995,0.401924)
+ (0.392679,0.38584)(0.431158,0.376427)(0.474277,0.373467)
+ (0.521781,0.37656)(0.573284,0.385128)
+\path(0.573284,0.385128)
+\path(0.522412,0.280089)(0.592255,0.303678)(0.666599,0.332557)
+ (0.744277,0.365124)(0.823805,0.399632)(0.903434,0.434308)
+ (0.981254,0.467495)(1.05533,0.497794)(1.12387,0.524191)(1.18533,0.546138)
+ (1.23857,0.563575)(1.28285,0.576899)(1.31791,0.586882)(1.34384,0.594557)
+ (1.36104,0.601102)(1.37013,0.607733)(1.37182,0.615613)(1.3669,0.625786)
+ (1.35609,0.639142)(1.34008,0.656388)(1.31944,0.67804)(1.29466,0.704421)
+ (1.26612,0.735658)(1.2341,0.771686)(1.1988,0.812243)(1.16038,0.856871)
+ (1.11892,0.904905)(1.07452,0.955475)(1.02726,1.0075)(0.977251,1.05971)
+ (0.924661,1.11063)(0.86973,1.15865)(0.812793,1.20206)(0.754288,1.23912)
+ (0.694765,1.26811)(0.634877,1.28752)(0.575368,1.29605)(0.517045,1.29277)
+ (0.460742,1.27718)(0.40728,1.24929)(0.35743,1.20959)(0.311875,1.15903)
+ (0.27118,1.09902)(0.235783,1.03125)(0.205991,0.95767)(0.181986,0.880311)
+ (0.163849,0.801232)(0.151584,0.722411)(0.145146,0.645689)
+ (0.144472,0.572724)(0.149503,0.504968)(0.160206,0.443655)
+ (0.17659,0.389804)(0.198709,0.344221)(0.22666,0.307508)
+ (0.260573,0.280059)(0.300586,0.26206)(0.346809,0.253475)
+ (0.39928,0.254024)(0.457909,0.263169)(0.522412,0.280089)
+\path(0.522412,0.280089)
+\path(0.46836,0.168485)(0.553304,0.204953)(0.645257,0.248719)
+ (0.742767,0.297412)(0.843765,0.348317)(0.945636,0.398569)
+ (1.04539,0.445422)(1.13995,0.486548)(1.22644,0.5203)(1.30251,0.545884)
+ (1.36653,0.563399)(1.41769,0.573743)(1.45594,0.578419)(1.48186,0.579303)
+ (1.49647,0.578408)(1.50104,0.577699)(1.49691,0.578964)(1.48538,0.583732)
+ (1.46759,0.593248)(1.44451,0.60847)(1.41692,0.63008)(1.38541,0.658506)
+ (1.35037,0.693935)(1.31206,0.736325)(1.27061,0.785404)(1.22604,0.840659)
+ (1.17832,0.901326)(1.12739,0.966366)(1.07317,1.03445)(1.01563,1.10395)
+ (0.954829,1.17292)(0.890909,1.23916)(0.824171,1.30025)(0.755083,1.35363)
+ (0.684297,1.39674)(0.612645,1.42719)(0.541119,1.44293)(0.470828,1.44243)
+ (0.402935,1.42483)(0.33859,1.39004)(0.278856,1.33875)(0.224644,1.27245)
+ (0.176669,1.19323)(0.135426,1.10367)(0.101196,1.00663)
+ (0.0740632,0.905071)(0.053964,0.801877)(0.0407306,0.699748)
+ (0.0341447,0.601107)(0.0339864,0.508057)(0.0400764,0.422378)
+ (0.0523099,0.345536)(0.0706802,0.278715)(0.0952918,0.222844)
+ (0.126363,0.178624)(0.164213,0.146543)(0.209236,0.126873)
+ (0.261856,0.119648)(0.322456,0.124628)(0.391288,0.141232)
+ (0.46836,0.168485)
+\path(0.46836,0.168485)
+\end{picture}
diff --git a/graphics/epix/doc/plot_b.xp b/graphics/epix/doc/plot_b.xp
new file mode 100644
index 0000000000..f7560071e9
--- /dev/null
+++ b/graphics/epix/doc/plot_b.xp
@@ -0,0 +1,27 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+P f(double u, double v)
+{
+ double x=u*Cos(v), y=u*Sin(v);
+ // return P(x, y, 0.25*x*(x*x-3*y*y));
+ return P(x, y, x*y);
+}
+
+domain R(P(0,0), P(1,1), mesh(6, 20), mesh(12,60));
+
+int main()
+{
+ bounding_box(P(-1,-1),P(1,1));
+ unitlength("1in");
+ picture(1.5,1.5);
+
+ begin();
+ revolutions();
+
+ camera.at(P(3, 1, 3));
+
+ plot(f, R);
+
+ end();
+}
diff --git a/graphics/epix/doc/plotting.eepic b/graphics/epix/doc/plotting.eepic
new file mode 100644
index 0000000000..ca0911610b
--- /dev/null
+++ b/graphics/epix/doc/plotting.eepic
@@ -0,0 +1,82 @@
+%% Generated from plotting.xp on Thu Jun 28 15:36:18 EDT 2007 by
+%% ePiX-1.1.6
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 5 x 1in
+%% Figure offset: left by 0in, down by 0in
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}
+\xdefinecolor{rgb_ff0000}{rgb}{1,0,0}
+\setlength{\unitlength}{1in}
+\begin{picture}(5,1)(-0,-0)
+\path(0,0.5)(5,0.5)
+%%
+\put(0,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(0.3125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(0.625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(0.9375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(1.25,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(1.5625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(1.875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(2.1875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(2.5,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(2.8125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(3.125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(3.4375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(3.75,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(4.0625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(4.375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(4.6875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\put(5,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}}
+\path(2.5,0)(2.5,1)
+%%
+\put(2.5,0){\makebox(0,0){$\rule{4pt}{0.5pt}$}}
+\put(2.5,0.25){\makebox(0,0){$\rule{4pt}{0.5pt}$}}
+\put(2.5,0.5){\makebox(0,0){$\rule{4pt}{0.5pt}$}}
+\put(2.5,0.75){\makebox(0,0){$\rule{4pt}{0.5pt}$}}
+\put(2.5,1){\makebox(0,0){$\rule{4pt}{0.5pt}$}}
+\put(0,0.444652){\makebox(0,0)[t]{$-2$}}
+\put(1.25,0.444652){\makebox(0,0)[t]{$-1$}}
+\put(2.5,0.444652){\makebox(0,0)[t]{$\phantom{-}0$}}
+\put(3.75,0.444652){\makebox(0,0)[t]{$\phantom{-}1$}}
+\put(5,0.444652){\makebox(0,0)[t]{$\phantom{-}2$}}
+\color{rgb_ff0000}%
+\path(0,0.5)(0.0416667,0.527125)
+ (0.0833333,0.559633)(0.125,0.601537)(0.166667,0.654364)
+ (0.208333,0.716506)(0.25,0.783173)(0.291667,0.846957)
+ (0.333333,0.898935)(0.375,0.930119)(0.416667,0.933013)
+ (0.458333,0.902995)(0.5,0.839302)(0.541667,0.745419)
+ (0.583333,0.628809)(0.625,0.5)(0.666667,0.371191)
+ (0.708333,0.254581)(0.75,0.160698)(0.791667,0.0970055)
+ (0.833333,0.0669873)(0.875,0.0698806)(0.916667,0.101065)
+ (0.958333,0.153043)(1,0.216827)(1.04167,0.283494)(1.08333,0.345636)
+ (1.125,0.398463)(1.16667,0.440367)(1.20833,0.472875)(1.25,0.5)
+ (1.29167,0.527125)(1.33333,0.559633)(1.375,0.601537)
+ (1.41667,0.654364)(1.45833,0.716506)(1.5,0.783173)
+ (1.54167,0.846957)(1.58333,0.898935)(1.625,0.930119)
+ (1.66667,0.933013)(1.70833,0.902995)(1.75,0.839302)
+ (1.79167,0.745419)(1.83333,0.628809)(1.875,0.5)(1.91667,0.371191)
+ (1.95833,0.254581)(2,0.160698)(2.04167,0.0970055)
+ (2.08333,0.0669873)(2.125,0.0698806)(2.16667,0.101065)
+ (2.20833,0.153043)(2.25,0.216827)(2.29167,0.283494)
+ (2.33333,0.345636)(2.375,0.398463)(2.41667,0.440367)
+ (2.45833,0.472875)(2.5,0.5)(2.54167,0.527125)(2.58333,0.559633)
+ (2.625,0.601537)(2.66667,0.654364)(2.70833,0.716506)(2.75,0.783173)
+ (2.79167,0.846957)(2.83333,0.898935)(2.875,0.930119)
+ (2.91667,0.933013)(2.95833,0.902995)(3,0.839302)(3.04167,0.745419)
+ (3.08333,0.628809)(3.125,0.5)(3.16667,0.371191)(3.20833,0.254581)
+ (3.25,0.160698)(3.29167,0.0970055)(3.33333,0.0669873)
+ (3.375,0.0698806)(3.41667,0.101065)(3.45833,0.153043)(3.5,0.216827)
+ (3.54167,0.283494)(3.58333,0.345636)(3.625,0.398463)
+ (3.66667,0.440367)(3.70833,0.472875)(3.75,0.5)(3.79167,0.527125)
+ (3.83333,0.559633)(3.875,0.601537)(3.91667,0.654364)
+ (3.95833,0.716506)(4,0.783173)(4.04167,0.846957)(4.08333,0.898935)
+ (4.125,0.930119)(4.16667,0.933013)(4.20833,0.902995)(4.25,0.839302)
+ (4.29167,0.745419)(4.33333,0.628809)(4.375,0.5)(4.41667,0.371191)
+ (4.45833,0.254581)(4.5,0.160698)(4.54167,0.0970055)
+ (4.58333,0.0669873)(4.625,0.0698806)(4.66667,0.101065)
+ (4.70833,0.153043)(4.75,0.216827)(4.79167,0.283494)
+ (4.83333,0.345636)(4.875,0.398463)(4.91667,0.440367)
+ (4.95833,0.472875)(5,0.5)
+%%
+\end{picture}
diff --git a/graphics/epix/doc/plotting.xp b/graphics/epix/doc/plotting.xp
new file mode 100644
index 0000000000..ad310f7b02
--- /dev/null
+++ b/graphics/epix/doc/plotting.xp
@@ -0,0 +1,26 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double x)
+{
+ return 0.75*Sin(x) - 0.25*Sin(2*x);
+}
+
+int main()
+{
+ picture(P(-2,-1),P(2,1), "5x1in");
+
+ 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();
+}
diff --git a/graphics/epix/doc/plotting2.eepic b/graphics/epix/doc/plotting2.eepic
new file mode 100644
index 0000000000..5f56a743ec
--- /dev/null
+++ b/graphics/epix/doc/plotting2.eepic
@@ -0,0 +1,1766 @@
+%% Generated from plotting2.xp on Tue Sep 25 00:02:47 EDT 2007 by
+%% ePiX-1.2.0
+%%
+%% Cartesian bounding box: [-1,1] x [-1,1]
+%% Actual size: 2 x 1in
+%% Figure offset: left by 0in, down by 0in
+%%
+%% usepackages pstricks
+%%
+\newcmykcolor{cmy_0000ff}{0 0 1 0}%
+\newcmykcolor{cmy_0101ff}{0 0 0.996078 0.00392157}%
+\newcmykcolor{cmy_0202ff}{0 0 0.992157 0.00784314}%
+\newcmykcolor{cmy_0303ff}{0 0 0.988235 0.0117647}%
+\newcmykcolor{cmy_0505ff}{0 0 0.980392 0.0196078}%
+\newcmykcolor{cmy_0606ff}{0 0 0.976471 0.0235294}%
+\newcmykcolor{cmy_0808ff}{0 0 0.968627 0.0313725}%
+\newcmykcolor{cmy_0909ff}{0 0 0.964706 0.0352941}%
+\newcmykcolor{cmy_0a0aff}{0 0 0.960784 0.0392157}%
+\newcmykcolor{cmy_0b0bff}{0 0 0.956863 0.0431373}%
+\newcmykcolor{cmy_0c0cff}{0 0 0.952941 0.0470588}%
+\newcmykcolor{cmy_0d0dff}{0 0 0.94902 0.0509804}%
+\newcmykcolor{cmy_0e0eff}{0 0 0.945098 0.054902}%
+\newcmykcolor{cmy_0f0fff}{0 0 0.941176 0.0588235}%
+\newcmykcolor{cmy_1111ff}{0 0 0.933333 0.0666667}%
+\newcmykcolor{cmy_1313ff}{0 0 0.92549 0.0745098}%
+\newcmykcolor{cmy_1515ff}{0 0 0.917647 0.0823529}%
+\newcmykcolor{cmy_1616ff}{0 0 0.913725 0.0862745}%
+\newcmykcolor{cmy_1818ff}{0 0 0.905882 0.0941176}%
+\newcmykcolor{cmy_1919ff}{0 0 0.901961 0.0980392}%
+\newcmykcolor{cmy_1b1bff}{0 0 0.894118 0.105882}%
+\newcmykcolor{cmy_1c1cff}{0 0 0.890196 0.109804}%
+\newcmykcolor{cmy_2020ff}{0 0 0.87451 0.12549}%
+\newcmykcolor{cmy_2323ff}{0 0 0.862745 0.137255}%
+\newcmykcolor{cmy_2525ff}{0 0 0.854902 0.145098}%
+\newcmykcolor{cmy_2626ff}{0 0 0.85098 0.14902}%
+\newcmykcolor{cmy_2828ff}{0 0 0.843137 0.156863}%
+\newcmykcolor{cmy_2929ff}{0 0 0.839216 0.160784}%
+\newcmykcolor{cmy_2a2aff}{0 0 0.835294 0.164706}%
+\newcmykcolor{cmy_2d2dff}{0 0 0.823529 0.176471}%
+\newcmykcolor{cmy_3030ff}{0 0 0.811765 0.188235}%
+\newcmykcolor{cmy_3131ff}{0 0 0.807843 0.192157}%
+\newcmykcolor{cmy_3232ff}{0 0 0.803922 0.196078}%
+\newcmykcolor{cmy_3434ff}{0 0 0.796078 0.203922}%
+\newcmykcolor{cmy_3535ff}{0 0 0.792157 0.207843}%
+\newcmykcolor{cmy_3636ff}{0 0 0.788235 0.211765}%
+\newcmykcolor{cmy_3737ff}{0 0 0.784314 0.215686}%
+\newcmykcolor{cmy_3838ff}{0 0 0.780392 0.219608}%
+\newcmykcolor{cmy_3939ff}{0 0 0.776471 0.223529}%
+\newcmykcolor{cmy_3a3aff}{0 0 0.772549 0.227451}%
+\newcmykcolor{cmy_3b3bff}{0 0 0.768627 0.231373}%
+\newcmykcolor{cmy_3c3cff}{0 0 0.764706 0.235294}%
+\newcmykcolor{cmy_3d3dff}{0 0 0.760784 0.239216}%
+\newcmykcolor{cmy_3e3eff}{0 0 0.756863 0.243137}%
+\newcmykcolor{cmy_3f3fff}{0 0 0.752941 0.247059}%
+\newcmykcolor{cmy_4141ff}{0 0 0.745098 0.254902}%
+\newcmykcolor{cmy_4343ff}{0 0 0.737255 0.262745}%
+\newcmykcolor{cmy_4545ff}{0 0 0.729412 0.270588}%
+\newcmykcolor{cmy_4848ff}{0 0 0.717647 0.282353}%
+\newcmykcolor{cmy_4949ff}{0 0 0.713725 0.286275}%
+\newcmykcolor{cmy_4a4aff}{0 0 0.709804 0.290196}%
+\newcmykcolor{cmy_4b4bff}{0 0 0.705882 0.294118}%
+\newcmykcolor{cmy_4c4cff}{0 0 0.701961 0.298039}%
+\newcmykcolor{cmy_4d4dff}{0 0 0.698039 0.301961}%
+\newcmykcolor{cmy_4e4eff}{0 0 0.694118 0.305882}%
+\newcmykcolor{cmy_4f4fff}{0 0 0.690196 0.309804}%
+\newcmykcolor{cmy_5050ff}{0 0 0.686275 0.313725}%
+\newcmykcolor{cmy_5151ff}{0 0 0.682353 0.317647}%
+\newcmykcolor{cmy_5252ff}{0 0 0.678431 0.321569}%
+\newcmykcolor{cmy_5353ff}{0 0 0.67451 0.32549}%
+\newcmykcolor{cmy_5454ff}{0 0 0.670588 0.329412}%
+\newcmykcolor{cmy_5555ff}{0 0 0.666667 0.333333}%
+\newcmykcolor{cmy_5656ff}{0 0 0.662745 0.337255}%
+\newcmykcolor{cmy_5757ff}{0 0 0.658824 0.341176}%
+\newcmykcolor{cmy_5858ff}{0 0 0.654902 0.345098}%
+\newcmykcolor{cmy_5959ff}{0 0 0.65098 0.34902}%
+\newcmykcolor{cmy_5a5aff}{0 0 0.647059 0.352941}%
+\newcmykcolor{cmy_5b5bff}{0 0 0.643137 0.356863}%
+\newcmykcolor{cmy_5c5cff}{0 0 0.639216 0.360784}%
+\newcmykcolor{cmy_5d5dff}{0 0 0.635294 0.364706}%
+\newcmykcolor{cmy_5e5eff}{0 0 0.631373 0.368627}%
+\newcmykcolor{cmy_5f5fff}{0 0 0.627451 0.372549}%
+\newcmykcolor{cmy_6060ff}{0 0 0.623529 0.376471}%
+\newcmykcolor{cmy_6161ff}{0 0 0.619608 0.380392}%
+\newcmykcolor{cmy_6262ff}{0 0 0.615686 0.384314}%
+\newcmykcolor{cmy_6363ff}{0 0 0.611765 0.388235}%
+\newcmykcolor{cmy_6464ff}{0 0 0.607843 0.392157}%
+\newcmykcolor{cmy_6565ff}{0 0 0.603922 0.396078}%
+\newcmykcolor{cmy_6666ff}{0 0 0.6 0.4}%
+\newcmykcolor{cmy_6767ff}{0 0 0.596078 0.403922}%
+\newcmykcolor{cmy_6868ff}{0 0 0.592157 0.407843}%
+\newcmykcolor{cmy_6969ff}{0 0 0.588235 0.411765}%
+\newcmykcolor{cmy_6a6aff}{0 0 0.584314 0.415686}%
+\newcmykcolor{cmy_6b6bff}{0 0 0.580392 0.419608}%
+\newcmykcolor{cmy_6c6cff}{0 0 0.576471 0.423529}%
+\newcmykcolor{cmy_6d6dff}{0 0 0.572549 0.427451}%
+\newcmykcolor{cmy_6e6eff}{0 0 0.568627 0.431373}%
+\newcmykcolor{cmy_6f6fff}{0 0 0.564706 0.435294}%
+\newcmykcolor{cmy_7070ff}{0 0 0.560784 0.439216}%
+\newcmykcolor{cmy_7171ff}{0 0 0.556863 0.443137}%
+\newcmykcolor{cmy_7272ff}{0 0 0.552941 0.447059}%
+\newcmykcolor{cmy_7373ff}{0 0 0.54902 0.45098}%
+\newcmykcolor{cmy_7474ff}{0 0 0.545098 0.454902}%
+\newcmykcolor{cmy_7575ff}{0 0 0.541176 0.458824}%
+\newcmykcolor{cmy_7676ff}{0 0 0.537255 0.462745}%
+\newcmykcolor{cmy_7777ff}{0 0 0.533333 0.466667}%
+\newcmykcolor{cmy_7878ff}{0 0 0.529412 0.470588}%
+\newcmykcolor{cmy_7979ff}{0 0 0.52549 0.47451}%
+\newcmykcolor{cmy_7a7aff}{0 0 0.521569 0.478431}%
+\newcmykcolor{cmy_7b7bff}{0 0 0.517647 0.482353}%
+\newcmykcolor{cmy_7c7cff}{0 0 0.513725 0.486275}%
+\newcmykcolor{cmy_7d7dff}{0 0 0.509804 0.490196}%
+\newcmykcolor{cmy_7e7eff}{0 0 0.505882 0.494118}%
+\newcmykcolor{cmy_7f7fff}{0 0 0.501961 0.498039}%
+\newrgbcolor{rgb_000000}{0 0 0}%
+\newrgbcolor{rgb_19197f}{0.0980392 0.0980392 0.498039}%
+\newrgbcolor{rgb_191980}{0.0980392 0.0980392 0.501961}%
+\newrgbcolor{rgb_191981}{0.0980392 0.0980392 0.505882}%
+\newrgbcolor{rgb_1a1a82}{0.101961 0.101961 0.509804}%
+\newrgbcolor{rgb_1a1a83}{0.101961 0.101961 0.513725}%
+\newrgbcolor{rgb_1a1a84}{0.101961 0.101961 0.517647}%
+\newrgbcolor{rgb_1a1a85}{0.101961 0.101961 0.521569}%
+\newrgbcolor{rgb_1a1a86}{0.101961 0.101961 0.52549}%
+\newrgbcolor{rgb_1b1b87}{0.105882 0.105882 0.529412}%
+\newrgbcolor{rgb_1b1b88}{0.105882 0.105882 0.533333}%
+\newrgbcolor{rgb_1b1b89}{0.105882 0.105882 0.537255}%
+\newrgbcolor{rgb_1b1b8a}{0.105882 0.105882 0.541176}%
+\newrgbcolor{rgb_1b1b8b}{0.105882 0.105882 0.545098}%
+\newrgbcolor{rgb_1c1c8c}{0.109804 0.109804 0.54902}%
+\newrgbcolor{rgb_1c1c8d}{0.109804 0.109804 0.552941}%
+\newrgbcolor{rgb_1c1c8e}{0.109804 0.109804 0.556863}%
+\newrgbcolor{rgb_1c1c8f}{0.109804 0.109804 0.560784}%
+\newrgbcolor{rgb_1c1c90}{0.109804 0.109804 0.564706}%
+\newrgbcolor{rgb_1d1d91}{0.113725 0.113725 0.568627}%
+\newrgbcolor{rgb_1d1d92}{0.113725 0.113725 0.572549}%
+\newrgbcolor{rgb_1d1d93}{0.113725 0.113725 0.576471}%
+\newrgbcolor{rgb_1d1d94}{0.113725 0.113725 0.580392}%
+\newrgbcolor{rgb_1d1d95}{0.113725 0.113725 0.584314}%
+\newrgbcolor{rgb_1e1e96}{0.117647 0.117647 0.588235}%
+\newrgbcolor{rgb_1e1e97}{0.117647 0.117647 0.592157}%
+\newrgbcolor{rgb_1e1e98}{0.117647 0.117647 0.596078}%
+\newrgbcolor{rgb_1e1e99}{0.117647 0.117647 0.6}%
+\newrgbcolor{rgb_1e1e9a}{0.117647 0.117647 0.603922}%
+\newrgbcolor{rgb_1f1f9b}{0.121569 0.121569 0.607843}%
+\newrgbcolor{rgb_1f1f9c}{0.121569 0.121569 0.611765}%
+\newrgbcolor{rgb_1f1f9d}{0.121569 0.121569 0.615686}%
+\newrgbcolor{rgb_1f1f9e}{0.121569 0.121569 0.619608}%
+\newrgbcolor{rgb_1f1f9f}{0.121569 0.121569 0.623529}%
+\newrgbcolor{rgb_2020a0}{0.12549 0.12549 0.627451}%
+\newrgbcolor{rgb_2020a1}{0.12549 0.12549 0.631373}%
+\newrgbcolor{rgb_2020a2}{0.12549 0.12549 0.635294}%
+\newrgbcolor{rgb_2020a3}{0.12549 0.12549 0.639216}%
+\newrgbcolor{rgb_2020a4}{0.12549 0.12549 0.643137}%
+\newrgbcolor{rgb_2121a5}{0.129412 0.129412 0.647059}%
+\newrgbcolor{rgb_2121a6}{0.129412 0.129412 0.65098}%
+\newrgbcolor{rgb_2121a7}{0.129412 0.129412 0.654902}%
+\newrgbcolor{rgb_2121a8}{0.129412 0.129412 0.658824}%
+\newrgbcolor{rgb_2121a9}{0.129412 0.129412 0.662745}%
+\newrgbcolor{rgb_2222aa}{0.133333 0.133333 0.666667}%
+\newrgbcolor{rgb_2222ab}{0.133333 0.133333 0.670588}%
+\newrgbcolor{rgb_2222ac}{0.133333 0.133333 0.67451}%
+\newrgbcolor{rgb_2222ad}{0.133333 0.133333 0.678431}%
+\newrgbcolor{rgb_2222ae}{0.133333 0.133333 0.682353}%
+\newrgbcolor{rgb_2323af}{0.137255 0.137255 0.686275}%
+\newrgbcolor{rgb_2323b0}{0.137255 0.137255 0.690196}%
+\newrgbcolor{rgb_2323b1}{0.137255 0.137255 0.694118}%
+\newrgbcolor{rgb_2323b2}{0.137255 0.137255 0.698039}%
+\newrgbcolor{rgb_2323b3}{0.137255 0.137255 0.701961}%
+\newrgbcolor{rgb_2424b4}{0.141176 0.141176 0.705882}%
+\newrgbcolor{rgb_2424b5}{0.141176 0.141176 0.709804}%
+\newrgbcolor{rgb_2424b6}{0.141176 0.141176 0.713725}%
+\newrgbcolor{rgb_2525b9}{0.145098 0.145098 0.72549}%
+\newrgbcolor{rgb_2525bb}{0.145098 0.145098 0.733333}%
+\newrgbcolor{rgb_2525bd}{0.145098 0.145098 0.741176}%
+\newrgbcolor{rgb_2626bf}{0.14902 0.14902 0.74902}%
+\newrgbcolor{rgb_2626c0}{0.14902 0.14902 0.752941}%
+\newrgbcolor{rgb_2626c1}{0.14902 0.14902 0.756863}%
+\newrgbcolor{rgb_2626c2}{0.14902 0.14902 0.760784}%
+\newrgbcolor{rgb_2727c3}{0.152941 0.152941 0.764706}%
+\newrgbcolor{rgb_2727c4}{0.152941 0.152941 0.768627}%
+\newrgbcolor{rgb_2727c5}{0.152941 0.152941 0.772549}%
+\newrgbcolor{rgb_2727c6}{0.152941 0.152941 0.776471}%
+\newrgbcolor{rgb_2727c7}{0.152941 0.152941 0.780392}%
+\newrgbcolor{rgb_2828c8}{0.156863 0.156863 0.784314}%
+\newrgbcolor{rgb_2828c9}{0.156863 0.156863 0.788235}%
+\newrgbcolor{rgb_2828ca}{0.156863 0.156863 0.792157}%
+\newrgbcolor{rgb_2828cc}{0.156863 0.156863 0.8}%
+\newrgbcolor{rgb_2929cd}{0.160784 0.160784 0.803922}%
+\newrgbcolor{rgb_2929ce}{0.160784 0.160784 0.807843}%
+\newrgbcolor{rgb_2929d1}{0.160784 0.160784 0.819608}%
+\newrgbcolor{rgb_2a2ad4}{0.164706 0.164706 0.831373}%
+\newrgbcolor{rgb_2a2ad5}{0.164706 0.164706 0.835294}%
+\newrgbcolor{rgb_2a2ad6}{0.164706 0.164706 0.839216}%
+\newrgbcolor{rgb_2b2bd8}{0.168627 0.168627 0.847059}%
+\newrgbcolor{rgb_2b2bd9}{0.168627 0.168627 0.85098}%
+\newrgbcolor{rgb_2b2bdb}{0.168627 0.168627 0.858824}%
+\newrgbcolor{rgb_2c2cde}{0.172549 0.172549 0.870588}%
+\newrgbcolor{rgb_2d2de2}{0.176471 0.176471 0.886275}%
+\newrgbcolor{rgb_2d2de3}{0.176471 0.176471 0.890196}%
+\newrgbcolor{rgb_2d2de5}{0.176471 0.176471 0.898039}%
+\newrgbcolor{rgb_2e2ee6}{0.180392 0.180392 0.901961}%
+\newrgbcolor{rgb_2e2ee8}{0.180392 0.180392 0.909804}%
+\newrgbcolor{rgb_2e2ee9}{0.180392 0.180392 0.913725}%
+\newrgbcolor{rgb_2f2feb}{0.184314 0.184314 0.921569}%
+\newrgbcolor{rgb_2f2fed}{0.184314 0.184314 0.929412}%
+\newrgbcolor{rgb_2f2fef}{0.184314 0.184314 0.937255}%
+\newrgbcolor{rgb_3030f0}{0.188235 0.188235 0.941176}%
+\newrgbcolor{rgb_3030f1}{0.188235 0.188235 0.945098}%
+\newrgbcolor{rgb_3030f2}{0.188235 0.188235 0.94902}%
+\newrgbcolor{rgb_3030f3}{0.188235 0.188235 0.952941}%
+\newrgbcolor{rgb_3030f4}{0.188235 0.188235 0.956863}%
+\newrgbcolor{rgb_3131f5}{0.192157 0.192157 0.960784}%
+\newrgbcolor{rgb_3131f6}{0.192157 0.192157 0.964706}%
+\newrgbcolor{rgb_3131f8}{0.192157 0.192157 0.972549}%
+\newrgbcolor{rgb_3131f9}{0.192157 0.192157 0.976471}%
+\newrgbcolor{rgb_3232fb}{0.196078 0.196078 0.984314}%
+\newrgbcolor{rgb_3232fc}{0.196078 0.196078 0.988235}%
+\newrgbcolor{rgb_3232fd}{0.196078 0.196078 0.992157}%
+\newrgbcolor{rgb_3232fe}{0.196078 0.196078 0.996078}%
+\psset{unit=1in,linewidth=0.4pt}%
+\begin{pspicture}(2,1)(0,0)%
+\psline(1,0.5)(0.460099,0.0671161)
+\psset{fillcolor=rgb_000000}%
+\pspolygon[fillstyle=solid](0.513324,0.109791)(0.500341,0.125984)
+ (0.460099,0.0671161)(0.526308,0.093598)(0.513324,0.109791)
+\psline(1,0.5)(2.30211,0.383998)
+\pspolygon[fillstyle=solid](2.19255,0.39376)(2.1907,0.373086)
+ (2.30211,0.383998)(2.19439,0.414433)(2.19255,0.39376)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1.21563,0.452275)(1.23301,0.375451)
+ (1.17732,0.388446)(1.12142,0.416397)(1.11204,0.483169)
+ (1.164,0.462409)(1.21563,0.452275)
+\psset{fillcolor=cmy_5858ff}%
+\psset{linecolor=rgb_2121a6}%
+\pspolygon[fillstyle=solid](1.31978,0.464555)(1.34701,0.395075)
+ (1.28931,0.377672)(1.23301,0.375451)(1.21563,0.452275)
+ (1.26742,0.453019)(1.31978,0.464555)
+\psset{fillcolor=cmy_6969ff}%
+\psset{linecolor=rgb_1d1d95}%
+\pspolygon[fillstyle=solid](1.11204,0.483169)(1.12142,0.416397)
+ (1.0645,0.458716)(1.0058,0.514406)(1.0053,0.553791)
+ (1.05928,0.513957)(1.11204,0.483169)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1.42762,0.517893)(1.46924,0.473639)
+ (1.40679,0.427311)(1.34701,0.395075)(1.31978,0.464555)
+ (1.3731,0.486452)(1.42762,0.517893)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](1.0053,0.553791)(1.0058,0.514406)
+ (0.944617,0.581935)(0.880444,0.659087)(0.892338,0.65446)
+ (0.949725,0.601259)(1.0053,0.553791)
+\psset{fillcolor=cmy_6565ff}%
+\psset{linecolor=rgb_1e1e99}%
+\pspolygon[fillstyle=solid](1.19425,0.509734)(1.21563,0.452275)
+ (1.164,0.462409)(1.11204,0.483169)(1.10071,0.531856)
+ (1.14768,0.517332)(1.19425,0.509734)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](1.28699,0.515829)(1.31978,0.464555)
+ (1.26742,0.453019)(1.21563,0.452275)(1.19425,0.509734)
+ (1.24062,0.509263)(1.28699,0.515829)
+\psset{fillcolor=cmy_6f6fff}%
+\psset{linecolor=rgb_1c1c8f}%
+\pspolygon[fillstyle=solid](1.10071,0.531856)(1.11204,0.483169)
+ (1.05928,0.513957)(1.0053,0.553791)(1.00473,0.579391)
+ (1.05312,0.552809)(1.10071,0.531856)
+\psset{fillcolor=cmy_6666ff}%
+\psset{linecolor=rgb_1e1e98}%
+\pspolygon[fillstyle=solid](1.38015,0.548201)(1.42762,0.517893)
+ (1.3731,0.486452)(1.31978,0.464555)(1.28699,0.515829)
+ (1.33349,0.529041)(1.38015,0.548201)
+\psset{fillcolor=cmy_6c6cff}%
+\psset{linecolor=rgb_1d1d92}%
+\pspolygon[fillstyle=solid](1.54036,0.603855)(1.60334,0.602838)
+ (1.53472,0.5328)(1.46924,0.473639)(1.42762,0.517893)
+ (1.48342,0.557617)(1.54036,0.603855)
+\psset{fillcolor=cmy_7979ff}%
+\psset{linecolor=rgb_1a1a85}%
+\pspolygon[fillstyle=solid](1.00473,0.579391)(1.0053,0.553791)
+ (0.949725,0.601259)(0.892338,0.65446)(0.905094,0.644715)
+ (0.955399,0.610498)(1.00473,0.579391)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.892338,0.65446)(0.880444,0.659087)
+ (0.812994,0.742797)(0.742326,0.82905)(0.772133,0.767878)
+ (0.833083,0.710977)(0.892338,0.65446)
+\psset{fillcolor=cmy_7070ff}%
+\psset{linecolor=rgb_1c1c8e}%
+\pspolygon[fillstyle=solid](1.1691,0.547312)(1.19425,0.509734)
+ (1.14768,0.517332)(1.10071,0.531856)(1.08754,0.562251)
+ (1.12854,0.552782)(1.1691,0.547312)
+\psset{fillcolor=cmy_7777ff}%
+\psset{linecolor=rgb_1b1b87}%
+\pspolygon[fillstyle=solid](1.08754,0.562251)(1.10071,0.531856)
+ (1.05312,0.552809)(1.00473,0.579391)(1.00408,0.591586)
+ (1.04606,0.57537)(1.08754,0.562251)
+\psset{fillcolor=cmy_6d6dff}%
+\psset{linecolor=rgb_1d1d91}%
+\pspolygon[fillstyle=solid](1.24902,0.548712)(1.28699,0.515829)
+ (1.24062,0.509263)(1.19425,0.509734)(1.1691,0.547312)
+ (1.20925,0.545979)(1.24902,0.548712)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.905094,0.644715)(0.892338,0.65446)
+ (0.833083,0.710977)(0.772133,0.767878)(0.801956,0.715411)
+ (0.853879,0.680337)(0.905094,0.644715)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](1.47358,0.599945)(1.54036,0.603855)
+ (1.48342,0.557617)(1.42762,0.517893)(1.38015,0.548201)
+ (1.42692,0.572286)(1.47358,0.599945)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](1.00408,0.591586)(1.00473,0.579391)
+ (0.955399,0.610498)(0.905094,0.644715)(0.918709,0.630156)
+ (0.961612,0.610155)(1.00408,0.591586)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](1.32731,0.565028)(1.38015,0.548201)
+ (1.33349,0.529041)(1.28699,0.515829)(1.24902,0.548712)
+ (1.2884,0.555226)(1.32731,0.565028)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](0.772133,0.767878)(0.742326,0.82905)
+ (0.668933,0.912872)(0.593817,0.988506)(0.647182,0.869075)
+ (0.709925,0.821791)(0.772133,0.767878)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.918709,0.630156)(0.905094,0.644715)
+ (0.853879,0.680337)(0.801956,0.715411)(0.832163,0.670073)
+ (0.875495,0.650521)(0.918709,0.630156)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](1.14055,0.565734)(1.1691,0.547312)
+ (1.12854,0.552782)(1.08754,0.562251)(1.07271,0.575185)
+ (1.10684,0.569509)(1.14055,0.565734)
+\psset{fillcolor=cmy_7979ff}%
+\psset{linecolor=rgb_1a1a85}%
+\pspolygon[fillstyle=solid](1.65578,0.705915)(1.74819,0.763081)
+ (1.67477,0.680906)(1.60334,0.602838)(1.54036,0.603855)
+ (1.59806,0.654266)(1.65578,0.705915)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](1.07271,0.575185)(1.08754,0.562251)
+ (1.04606,0.57537)(1.00408,0.591586)(1.00338,0.591308)
+ (1.0382,0.582558)(1.07271,0.575185)
+\psset{fillcolor=cmy_7575ff}%
+\psset{linecolor=rgb_1b1b89}%
+\pspolygon[fillstyle=solid](0.801956,0.715411)(0.772133,0.767878)
+ (0.709925,0.821791)(0.647182,0.869075)(0.697531,0.775355)
+ (0.749674,0.74781)(0.801956,0.715411)
+\psset{fillcolor=cmy_7a7aff}%
+\psset{linecolor=rgb_1a1a84}%
+\pspolygon[fillstyle=solid](1.2064,0.564093)(1.24902,0.548712)
+ (1.20925,0.545979)(1.1691,0.547312)(1.14055,0.565734)
+ (1.17375,0.563943)(1.2064,0.564093)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](1.40315,0.59151)(1.47358,0.599945)
+ (1.42692,0.572286)(1.38015,0.548201)(1.32731,0.565028)
+ (1.36563,0.577419)(1.40315,0.59151)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.00338,0.591308)(1.00408,0.591586)
+ (0.961612,0.610155)(0.918709,0.630156)(0.933183,0.611153)
+ (0.968339,0.601011)(1.00338,0.591308)
+\psset{fillcolor=cmy_6c6cff}%
+\psset{linecolor=rgb_1d1d92}%
+\pspolygon[fillstyle=solid](0.189032,0.289372)(0.105002,0.195832)
+ (0.106173,0.133184)(0.107102,0.0871823)(0.187635,0.204779)
+ (0.187646,0.241139)(0.189032,0.289372)
+\psset{fillcolor=cmy_7c7cff}%
+\psset{linecolor=rgb_1a1a82}%
+\pspolygon[fillstyle=solid](1.26963,0.569425)(1.32731,0.565028)
+ (1.2884,0.555226)(1.24902,0.548712)(1.2064,0.564093)
+ (1.23839,0.566016)(1.26963,0.569425)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](0.832163,0.670073)(0.801956,0.715411)
+ (0.749674,0.74781)(0.697531,0.775355)(0.746272,0.701846)
+ (0.788976,0.687585)(0.832163,0.670073)
+\psset{fillcolor=cmy_7c7cff}%
+\psset{linecolor=rgb_1a1a82}%
+\pspolygon[fillstyle=solid](1.56495,0.658972)(1.65578,0.705915)
+ (1.59806,0.654266)(1.54036,0.603855)(1.47358,0.599945)
+ (1.51977,0.629498)(1.56495,0.658972)
+\psset{fillcolor=cmy_4949ff}%
+\psset{linecolor=rgb_2424b5}%
+\pspolygon[fillstyle=solid](0.19769,0.416171)(0.10474,0.365653)
+ (0.104222,0.273918)(0.105002,0.195832)(0.189032,0.289372)
+ (0.192187,0.348273)(0.19769,0.416171)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](0.933183,0.611153)(0.918709,0.630156)
+ (0.875495,0.650521)(0.832163,0.670073)(0.863092,0.630402)
+ (0.898045,0.621157)(0.933183,0.611153)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](0.647182,0.869075)(0.593817,0.988506)
+ (0.518501,1.04983)(0.444947,1.09101)(0.524261,0.929508)
+ (0.584894,0.90608)(0.647182,0.869075)
+\psset{fillcolor=cmy_5353ff}%
+\psset{linecolor=rgb_2222ab}%
+\pspolygon[fillstyle=solid](0.697531,0.775355)(0.647182,0.869075)
+ (0.584894,0.90608)(0.524261,0.929508)(0.596275,0.807827)
+ (0.646156,0.795963)(0.697531,0.775355)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.187635,0.204779)(0.107102,0.0871823)
+ (0.107428,0.0586308)(0.107074,0.0480454)(0.191172,0.170524)
+ (0.188802,0.181093)(0.187635,0.204779)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](1.32922,0.579024)(1.40315,0.59151)
+ (1.36563,0.577419)(1.32731,0.565028)(1.26963,0.569425)
+ (1.29996,0.573925)(1.32922,0.579024)
+\psset{fillcolor=cmy_6c6cff}%
+\psset{linecolor=rgb_1d1d92}%
+\pspolygon[fillstyle=solid](0.863092,0.630402)(0.832163,0.670073)
+ (0.788976,0.687585)(0.746272,0.701846)(0.794552,0.644134)
+ (0.828519,0.638261)(0.863092,0.630402)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.109,0.566914)(1.14055,0.565734)
+ (1.10684,0.569509)(1.07271,0.575185)(1.05638,0.57247)
+ (1.08289,0.569392)(1.109,0.566914)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](1.05638,0.57247)(1.07271,0.575185)
+ (1.0382,0.582558)(1.00338,0.591308)(1.00261,0.579992)
+ (1.02959,0.576053)(1.05638,0.57247)
+\pspolygon[fillstyle=solid](1.47456,0.620443)(1.56495,0.658972)
+ (1.51977,0.629498)(1.47358,0.599945)(1.40315,0.59151)
+ (1.43958,0.606246)(1.47456,0.620443)
+\psset{fillcolor=cmy_5050ff}%
+\psset{linecolor=rgb_2222ae}%
+\pspolygon[fillstyle=solid](0.746272,0.701846)(0.697531,0.775355)
+ (0.646156,0.795963)(0.596275,0.807827)(0.663929,0.71633)
+ (0.704444,0.711739)(0.746272,0.701846)
+\psset{fillcolor=cmy_2323ff}%
+\psset{linecolor=rgb_2b2bdb}%
+\pspolygon[fillstyle=solid](0.218731,0.569601)(0.114562,0.578881)
+ (0.107723,0.468479)(0.10474,0.365653)(0.19769,0.416171)
+ (0.206264,0.490868)(0.218731,0.569601)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](1.00261,0.579992)(1.00338,0.591308)
+ (0.968339,0.601011)(0.933183,0.611153)(0.948523,0.588133)
+ (0.975553,0.584095)(1.00261,0.579992)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.1597,0.563866)(1.2064,0.564093)
+ (1.17375,0.563943)(1.14055,0.565734)(1.109,0.566914)
+ (1.13464,0.565078)(1.1597,0.563866)
+\psset{fillcolor=cmy_7474ff}%
+\psset{linecolor=rgb_1b1b8a}%
+\pspolygon[fillstyle=solid](0.948523,0.588133)(0.933183,0.611153)
+ (0.898045,0.621157)(0.863092,0.630402)(0.895059,0.594987)
+ (0.921647,0.591852)(0.948523,0.588133)
+\psset{fillcolor=cmy_2828ff}%
+\psset{linecolor=rgb_2a2ad6}%
+\pspolygon[fillstyle=solid](0.524261,0.929508)(0.444947,1.09101)
+ (0.375363,1.10732)(0.311925,1.09597)(0.413159,0.926478)
+ (0.466591,0.936797)(0.524261,0.929508)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.20765,0.562964)(1.26963,0.569425)
+ (1.23839,0.566016)(1.2064,0.564093)(1.1597,0.563866)
+ (1.18407,0.563204)(1.20765,0.562964)
+\psset{fillcolor=cmy_4f4fff}%
+\psset{linecolor=rgb_2323af}%
+\pspolygon[fillstyle=solid](0.794552,0.644134)(0.746272,0.701846)
+ (0.704444,0.711739)(0.663929,0.71633)(0.729448,0.647866)
+ (0.761441,0.647482)(0.794552,0.644134)
+\psset{fillcolor=cmy_2828ff}%
+\psset{linecolor=rgb_2a2ad6}%
+\pspolygon[fillstyle=solid](0.596275,0.807827)(0.524261,0.929508)
+ (0.466591,0.936797)(0.413159,0.926478)(0.504048,0.800507)
+ (0.548656,0.809592)(0.596275,0.807827)
+\psset{fillcolor=cmy_2929ff}%
+\psset{linecolor=rgb_2a2ad5}%
+\pspolygon[fillstyle=solid](0.663929,0.71633)(0.596275,0.807827)
+ (0.548656,0.809592)(0.504048,0.800507)(0.58863,0.707203)
+ (0.625178,0.714938)(0.663929,0.71633)
+\psset{fillcolor=cmy_3f3fff}%
+\psset{linecolor=rgb_2626bf}%
+\pspolygon[fillstyle=solid](0.298804,0.454436)(0.19769,0.416171)
+ (0.192187,0.348273)(0.189032,0.289372)(0.285765,0.364096)
+ (0.29087,0.406486)(0.298804,0.454436)
+\psset{fillcolor=cmy_6666ff}%
+\psset{linecolor=rgb_1e1e98}%
+\pspolygon[fillstyle=solid](0.895059,0.594987)(0.863092,0.630402)
+ (0.828519,0.638261)(0.794552,0.644134)(0.84333,0.598464)
+ (0.868903,0.597273)(0.895059,0.594987)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.38364,0.588709)(1.47456,0.620443)
+ (1.43958,0.606246)(1.40315,0.59151)(1.32922,0.579024)
+ (1.35719,0.584157)(1.38364,0.588709)
+\psset{fillcolor=cmy_6464ff}%
+\psset{linecolor=rgb_1e1e9a}%
+\pspolygon[fillstyle=solid](0.285765,0.364096)(0.189032,0.289372)
+ (0.187646,0.241139)(0.187635,0.204779)(0.282956,0.300896)
+ (0.283191,0.328573)(0.285765,0.364096)
+\psset{fillcolor=cmy_0909ff}%
+\psset{linecolor=rgb_3131f5}%
+\pspolygon[fillstyle=solid](0.258703,0.72553)(0.145957,0.803098)
+ (0.126792,0.692284)(0.114562,0.578881)(0.218731,0.569601)
+ (0.235947,0.649066)(0.258703,0.72553)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](1.2519,0.563022)(1.32922,0.579024)
+ (1.29996,0.573925)(1.26963,0.569425)(1.20765,0.562964)
+ (1.2303,0.562975)(1.2519,0.563022)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.76674,0.798575)(1.89443,0.91833)
+ (1.82212,0.844276)(1.74819,0.763081)(1.65578,0.705915)
+ (1.71247,0.755316)(1.76674,0.798575)
+\psset{fillcolor=cmy_1b1bff}%
+\psset{linecolor=rgb_2d2de3}%
+\pspolygon[fillstyle=solid](0.324666,0.560164)(0.218731,0.569601)
+ (0.206264,0.490868)(0.19769,0.416171)(0.298804,0.454436)
+ (0.309934,0.506308)(0.324666,0.560164)
+\psset{fillcolor=cmy_2d2dff}%
+\psset{linecolor=rgb_2929d1}%
+\pspolygon[fillstyle=solid](0.729448,0.647866)(0.663929,0.71633)
+ (0.625178,0.714938)(0.58863,0.707203)(0.669881,0.638666)
+ (0.698841,0.644979)(0.729448,0.647866)
+\psset{fillcolor=cmy_0909ff}%
+\psset{linecolor=rgb_3131f5}%
+\pspolygon[fillstyle=solid](0.413159,0.926478)(0.311925,1.09597)
+ (0.256452,1.05661)(0.210141,0.991471)(0.323082,0.85378)
+ (0.36506,0.8984)(0.413159,0.926478)
+\psset{fillcolor=cmy_0a0aff}%
+\psset{linecolor=rgb_3030f4}%
+\pspolygon[fillstyle=solid](0.504048,0.800507)(0.413159,0.926478)
+ (0.36506,0.8984)(0.323082,0.85378)(0.426348,0.750295)
+ (0.463108,0.78052)(0.504048,0.800507)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.6493,0.708781)(1.76674,0.798575)
+ (1.71247,0.755316)(1.65578,0.705915)(1.56495,0.658972)
+ (1.60841,0.686169)(1.6493,0.708781)
+\psset{fillcolor=cmy_5050ff}%
+\psset{linecolor=rgb_2222ae}%
+\pspolygon[fillstyle=solid](0.84333,0.598464)(0.794552,0.644134)
+ (0.761441,0.647482)(0.729448,0.647866)(0.794573,0.596748)
+ (0.818499,0.598346)(0.84333,0.598464)
+\psset{fillcolor=cmy_0d0dff}%
+\psset{linecolor=rgb_3030f1}%
+\pspolygon[fillstyle=solid](0.58863,0.707203)(0.504048,0.800507)
+ (0.463108,0.78052)(0.426348,0.750295)(0.523665,0.673044)
+ (0.554683,0.693119)(0.58863,0.707203)
+\psset{fillcolor=cmy_0606ff}%
+\psset{linecolor=rgb_3131f8}%
+\pspolygon[fillstyle=solid](0.366464,0.664928)(0.258703,0.72553)
+ (0.235947,0.649066)(0.218731,0.569601)(0.324666,0.560164)
+ (0.343397,0.613816)(0.366464,0.664928)
+\psset{fillcolor=cmy_0000ff}%
+\psset{linecolor=rgb_3232fe}%
+\pspolygon[fillstyle=solid](0.323082,0.85378)(0.210141,0.991471)
+ (0.173421,0.904998)(0.145957,0.803098)(0.258703,0.72553)
+ (0.287629,0.795046)(0.323082,0.85378)
+\psset{fillcolor=cmy_7474ff}%
+\psset{linecolor=rgb_1b1b8a}%
+\pspolygon[fillstyle=solid](1.03875,0.556754)(1.05638,0.57247)
+ (1.02959,0.576053)(1.00261,0.579992)(1.00179,0.559495)
+ (1.02033,0.558175)(1.03875,0.556754)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](1.07488,0.553783)(1.109,0.566914)
+ (1.08289,0.569392)(1.05638,0.57247)(1.03875,0.556754)
+ (1.05696,0.555279)(1.07488,0.553783)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](1.00179,0.559495)(1.00261,0.579992)
+ (0.975553,0.584095)(0.948523,0.588133)(0.964748,0.561577)
+ (0.983236,0.560652)(1.00179,0.559495)
+\psset{fillcolor=cmy_0000ff}%
+\psset{linecolor=rgb_3232fe}%
+\pspolygon[fillstyle=solid](0.426348,0.750295)(0.323082,0.85378)
+ (0.287629,0.795046)(0.258703,0.72553)(0.366464,0.664928)
+ (0.394092,0.711151)(0.426348,0.750295)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](1.53831,0.642183)(1.6493,0.708781)
+ (1.60841,0.686169)(1.56495,0.658972)(1.47456,0.620443)
+ (1.50763,0.632843)(1.53831,0.642183)
+\psset{fillcolor=cmy_7777ff}%
+\psset{linecolor=rgb_1b1b87}%
+\pspolygon[fillstyle=solid](1.10948,0.550772)(1.1597,0.563866)
+ (1.13464,0.565078)(1.109,0.566914)(1.07488,0.553783)
+ (1.09241,0.552281)(1.10948,0.550772)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](0.964748,0.561577)(0.948523,0.588133)
+ (0.921647,0.591852)(0.895059,0.594987)(0.92836,0.562423)
+ (0.946423,0.562194)(0.964748,0.561577)
+\psset{fillcolor=cmy_1515ff}%
+\psset{linecolor=rgb_2e2ee9}%
+\pspolygon[fillstyle=solid](0.669881,0.638666)(0.58863,0.707203)
+ (0.554683,0.693119)(0.523665,0.673044)(0.617846,0.615994)
+ (0.642811,0.628942)(0.669881,0.638666)
+\psset{fillcolor=cmy_0101ff}%
+\psset{linecolor=rgb_3232fd}%
+\pspolygon[fillstyle=solid](0.523665,0.673044)(0.426348,0.750295)
+ (0.394092,0.711151)(0.366464,0.664928)(0.471308,0.617992)
+ (0.495823,0.647676)(0.523665,0.673044)
+\psset{fillcolor=cmy_3838ff}%
+\psset{linecolor=rgb_2727c6}%
+\pspolygon[fillstyle=solid](0.794573,0.596748)(0.729448,0.647866)
+ (0.698841,0.644979)(0.669881,0.638666)(0.750078,0.58872)
+ (0.771713,0.593556)(0.794573,0.596748)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](1.29137,0.562256)(1.38364,0.588709)
+ (1.35719,0.584157)(1.32922,0.579024)(1.2519,0.563022)
+ (1.27231,0.562867)(1.29137,0.562256)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.191172,0.170524)(0.107074,0.0480454)
+ (0.106268,0.0557124)(0.105573,0.08167)(0.20082,0.188793)
+ (0.195007,0.173177)(0.191172,0.170524)
+\psset{fillcolor=cmy_7979ff}%
+\psset{linecolor=rgb_1a1a85}%
+\pspolygon[fillstyle=solid](0.282956,0.300896)(0.187635,0.204779)
+ (0.188802,0.181093)(0.191172,0.170524)(0.28937,0.271374)
+ (0.284992,0.281718)(0.282956,0.300896)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](1.14185,0.547647)(1.20765,0.562964)
+ (1.18407,0.563204)(1.1597,0.563866)(1.10948,0.550772)
+ (1.12599,0.549239)(1.14185,0.547647)
+\psset{fillcolor=cmy_0505ff}%
+\psset{linecolor=rgb_3131f9}%
+\pspolygon[fillstyle=solid](0.471308,0.617992)(0.366464,0.664928)
+ (0.343397,0.613816)(0.324666,0.560164)(0.432412,0.550565)
+ (0.450178,0.585184)(0.471308,0.617992)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](0.92836,0.562423)(0.895059,0.594987)
+ (0.868903,0.597273)(0.84333,0.598464)(0.893412,0.561425)
+ (0.910657,0.56219)(0.92836,0.562423)
+\psset{fillcolor=cmy_1616ff}%
+\psset{linecolor=rgb_2e2ee8}%
+\pspolygon[fillstyle=solid](0.432412,0.550565)(0.324666,0.560164)
+ (0.309934,0.506308)(0.298804,0.454436)(0.406584,0.481275)
+ (0.417922,0.515489)(0.432412,0.550565)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](1.43089,0.593568)(1.53831,0.642183)
+ (1.50763,0.632843)(1.47456,0.620443)(1.38364,0.588709)
+ (1.40831,0.592049)(1.43089,0.593568)
+\psset{fillcolor=cmy_0909ff}%
+\psset{linecolor=rgb_3131f5}%
+\pspolygon[fillstyle=solid](0.617846,0.615994)(0.523665,0.673044)
+ (0.495823,0.647676)(0.471308,0.617992)(0.574906,0.58195)
+ (0.595165,0.600168)(0.617846,0.615994)
+\psset{fillcolor=cmy_3636ff}%
+\psset{linecolor=rgb_2828c8}%
+\pspolygon[fillstyle=solid](0.406584,0.481275)(0.298804,0.454436)
+ (0.29087,0.406486)(0.285765,0.364096)(0.392802,0.420142)
+ (0.398255,0.449137)(0.406584,0.481275)
+\psset{fillcolor=cmy_2626ff}%
+\psset{linecolor=rgb_2b2bd8}%
+\pspolygon[fillstyle=solid](0.750078,0.58872)(0.669881,0.638666)
+ (0.642811,0.628942)(0.617846,0.615994)(0.711075,0.574268)
+ (0.729819,0.582261)(0.750078,0.58872)
+\psset{fillcolor=cmy_5555ff}%
+\psset{linecolor=rgb_2121a9}%
+\pspolygon[fillstyle=solid](0.893412,0.561425)(0.84333,0.598464)
+ (0.818499,0.598346)(0.794573,0.596748)(0.860696,0.558086)
+ (0.876726,0.560071)(0.893412,0.561425)
+\psset{fillcolor=cmy_7474ff}%
+\psset{linecolor=rgb_1b1b8a}%
+\pspolygon[fillstyle=solid](1.17127,0.54409)(1.2519,0.563022)
+ (1.2303,0.562975)(1.20765,0.562964)(1.14185,0.547647)
+ (1.15697,0.54595)(1.17127,0.54409)
+\psset{fillcolor=cmy_0b0bff}%
+\psset{linecolor=rgb_3030f3}%
+\pspolygon[fillstyle=solid](0.574906,0.58195)(0.471308,0.617992)
+ (0.450178,0.585184)(0.432412,0.550565)(0.542015,0.540801)
+ (0.557169,0.561937)(0.574906,0.58195)
+\psset{fillcolor=cmy_4848ff}%
+\psset{linecolor=rgb_2424b6}%
+\pspolygon[fillstyle=solid](0.860696,0.558086)(0.794573,0.596748)
+ (0.771713,0.593556)(0.750078,0.58872)(0.830997,0.552142)
+ (0.845422,0.555444)(0.860696,0.558086)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](0.392802,0.420142)(0.285765,0.364096)
+ (0.283191,0.328573)(0.282956,0.300896)(0.390156,0.374904)
+ (0.390121,0.395173)(0.392802,0.420142)
+\psset{fillcolor=cmy_7575ff}%
+\psset{linecolor=rgb_1b1b89}%
+\pspolygon[fillstyle=solid](1.32484,0.558669)(1.43089,0.593568)
+ (1.40831,0.592049)(1.38364,0.588709)(1.29137,0.562256)
+ (1.30893,0.560936)(1.32484,0.558669)
+\psset{fillcolor=cmy_1c1cff}%
+\psset{linecolor=rgb_2d2de2}%
+\pspolygon[fillstyle=solid](0.711075,0.574268)(0.617846,0.615994)
+ (0.595165,0.600168)(0.574906,0.58195)(0.678618,0.554358)
+ (0.693971,0.564896)(0.711075,0.574268)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](1.19703,0.539628)(1.29137,0.562256)
+ (1.27231,0.562867)(1.2519,0.563022)(1.17127,0.54409)
+ (1.18465,0.542005)(1.19703,0.539628)
+\psset{fillcolor=cmy_1818ff}%
+\psset{linecolor=rgb_2e2ee6}%
+\pspolygon[fillstyle=solid](0.542015,0.540801)(0.432412,0.550565)
+ (0.417922,0.515489)(0.406584,0.481275)(0.519554,0.497979)
+ (0.529474,0.519246)(0.542015,0.540801)
+\psset{fillcolor=cmy_3d3dff}%
+\psset{linecolor=rgb_2626c1}%
+\pspolygon[fillstyle=solid](0.830997,0.552142)(0.750078,0.58872)
+ (0.729819,0.582261)(0.711075,0.574268)(0.805053,0.543639)
+ (0.817512,0.548194)(0.830997,0.552142)
+\psset{fillcolor=cmy_6666ff}%
+\psset{linecolor=rgb_1e1e98}%
+\pspolygon[fillstyle=solid](1.01993,0.53134)(1.03875,0.556754)
+ (1.02033,0.558175)(1.00179,0.559495)(1.00092,0.532012)
+ (1.01046,0.531756)(1.01993,0.53134)
+\psset{fillcolor=cmy_6565ff}%
+\psset{linecolor=rgb_1e1e99}%
+\pspolygon[fillstyle=solid](1.00092,0.532012)(1.00179,0.559495)
+ (0.983236,0.560652)(0.964748,0.561577)(0.98189,0.532011)
+ (0.991382,0.5321)(1.00092,0.532012)
+\psset{fillcolor=cmy_6868ff}%
+\psset{linecolor=rgb_1e1e96}%
+\pspolygon[fillstyle=solid](1.03849,0.530055)(1.07488,0.553783)
+ (1.05696,0.555279)(1.03875,0.556754)(1.01993,0.53134)
+ (1.02929,0.53077)(1.03849,0.530055)
+\psset{fillcolor=cmy_1c1cff}%
+\psset{linecolor=rgb_2d2de2}%
+\pspolygon[fillstyle=solid](0.678618,0.554358)(0.574906,0.58195)
+ (0.557169,0.561937)(0.542015,0.540801)(0.653524,0.530867)
+ (0.66511,0.542917)(0.678618,0.554358)
+\psset{fillcolor=cmy_6262ff}%
+\psset{linecolor=rgb_1f1f9c}%
+\pspolygon[fillstyle=solid](0.98189,0.532011)(0.964748,0.561577)
+ (0.946423,0.562194)(0.92836,0.562423)(0.963262,0.531266)
+ (0.972499,0.531735)(0.98189,0.532011)
+\psset{fillcolor=cmy_6868ff}%
+\psset{linecolor=rgb_1e1e96}%
+\pspolygon[fillstyle=solid](1.05617,0.528201)(1.10948,0.550772)
+ (1.09241,0.552281)(1.07488,0.553783)(1.03849,0.530055)
+ (1.04746,0.529197)(1.05617,0.528201)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](0.963262,0.531266)(0.92836,0.562423)
+ (0.910657,0.56219)(0.893412,0.561425)(0.945465,0.52972)
+ (0.954234,0.530596)(0.963262,0.531266)
+\psset{fillcolor=cmy_3232ff}%
+\psset{linecolor=rgb_2828cc}%
+\pspolygon[fillstyle=solid](0.519554,0.497979)(0.406584,0.481275)
+ (0.398255,0.449137)(0.392802,0.420142)(0.507551,0.458909)
+ (0.512249,0.477666)(0.519554,0.497979)
+\psset{fillcolor=cmy_7575ff}%
+\psset{linecolor=rgb_1b1b89}%
+\pspolygon[fillstyle=solid](1.59029,0.647141)(1.71949,0.731475)
+ (1.68666,0.724552)(1.6493,0.708781)(1.53831,0.642183)
+ (1.56604,0.647284)(1.59029,0.647141)
+\psset{fillcolor=cmy_6868ff}%
+\psset{linecolor=rgb_1e1e96}%
+\pspolygon[fillstyle=solid](1.07258,0.525802)(1.14185,0.547647)
+ (1.12599,0.549239)(1.10948,0.550772)(1.05617,0.528201)
+ (1.06456,0.527069)(1.07258,0.525802)
+\psset{fillcolor=cmy_7070ff}%
+\psset{linecolor=rgb_1c1c8e}%
+\pspolygon[fillstyle=solid](1.46867,0.589042)(1.59029,0.647141)
+ (1.56604,0.647284)(1.53831,0.642183)(1.43089,0.593568)
+ (1.45111,0.592716)(1.46867,0.589042)
+\psset{fillcolor=cmy_3737ff}%
+\psset{linecolor=rgb_2727c7}%
+\pspolygon[fillstyle=solid](0.805053,0.543639)(0.711075,0.574268)
+ (0.693971,0.564896)(0.678618,0.554358)(0.783529,0.532958)
+ (0.793701,0.538535)(0.805053,0.543639)
+\psset{fillcolor=cmy_6c6cff}%
+\psset{linecolor=rgb_1d1d92}%
+\pspolygon[fillstyle=solid](1.21844,0.533751)(1.32484,0.558669)
+ (1.30893,0.560936)(1.29137,0.562256)(1.19703,0.539628)
+ (1.20832,0.536895)(1.21844,0.533751)
+\psset{fillcolor=cmy_5959ff}%
+\psset{linecolor=rgb_2121a5}%
+\pspolygon[fillstyle=solid](0.945465,0.52972)(0.893412,0.561425)
+ (0.876726,0.560071)(0.860696,0.558086)(0.928911,0.52734)
+ (0.937007,0.528634)(0.945465,0.52972)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](1.71949,0.731475)(1.86122,0.850819)
+ (1.81692,0.831665)(1.76674,0.798575)(1.6493,0.708781)
+ (1.68666,0.724552)(1.71949,0.731475)
+\psset{fillcolor=cmy_6868ff}%
+\psset{linecolor=rgb_1e1e96}%
+\pspolygon[fillstyle=solid](1.08732,0.52286)(1.17127,0.54409)
+ (1.15697,0.54595)(1.14185,0.547647)(1.07258,0.525802)
+ (1.08018,0.524399)(1.08732,0.52286)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](1.35106,0.550511)(1.46867,0.589042)
+ (1.45111,0.592716)(1.43089,0.593568)(1.32484,0.558669)
+ (1.33893,0.555247)(1.35106,0.550511)
+\psset{fillcolor=cmy_2525ff}%
+\psset{linecolor=rgb_2b2bd9}%
+\pspolygon[fillstyle=solid](0.653524,0.530867)(0.542015,0.540801)
+ (0.529474,0.519246)(0.519554,0.497979)(0.636366,0.506205)
+ (0.643926,0.518523)(0.653524,0.530867)
+\psset{fillcolor=cmy_5454ff}%
+\psset{linecolor=rgb_2222aa}%
+\pspolygon[fillstyle=solid](0.928911,0.52734)(0.860696,0.558086)
+ (0.845422,0.555444)(0.830997,0.552142)(0.913992,0.524138)
+ (0.921223,0.525839)(0.928911,0.52734)
+\psset{fillcolor=cmy_7373ff}%
+\psset{linecolor=rgb_1b1b8b}%
+\pspolygon[fillstyle=solid](0.390156,0.374904)(0.282956,0.300896)
+ (0.284992,0.281718)(0.28937,0.271374)(0.398466,0.350056)
+ (0.392913,0.35979)(0.390156,0.374904)
+\psset{fillcolor=cmy_3636ff}%
+\psset{linecolor=rgb_2828c8}%
+\pspolygon[fillstyle=solid](0.783529,0.532958)(0.678618,0.554358)
+ (0.66511,0.542917)(0.653524,0.530867)(0.76699,0.520758)
+ (0.774605,0.526998)(0.783529,0.532958)
+\psset{fillcolor=cmy_7979ff}%
+\psset{linecolor=rgb_1a1a85}%
+\pspolygon[fillstyle=solid](1.86122,0.850819)(2.0226,1.01759)
+ (1.96232,0.978383)(1.89443,0.91833)(1.76674,0.798575)
+ (1.81692,0.831665)(1.86122,0.850819)
+\psset{fillcolor=cmy_6666ff}%
+\psset{linecolor=rgb_1e1e98}%
+\pspolygon[fillstyle=solid](1.10005,0.519369)(1.19703,0.539628)
+ (1.18465,0.542005)(1.17127,0.54409)(1.08732,0.52286)
+ (1.09396,0.521183)(1.10005,0.519369)
+\psset{fillcolor=cmy_5050ff}%
+\psset{linecolor=rgb_2222ae}%
+\pspolygon[fillstyle=solid](0.913992,0.524138)(0.830997,0.552142)
+ (0.817512,0.548194)(0.805053,0.543639)(0.90107,0.520175)
+ (0.90726,0.522245)(0.913992,0.524138)
+\psset{fillcolor=cmy_5151ff}%
+\psset{linecolor=rgb_2222ad}%
+\pspolygon[fillstyle=solid](0.507551,0.458909)(0.392802,0.420142)
+ (0.390121,0.395173)(0.390156,0.374904)(0.50598,0.427985)
+ (0.505457,0.442216)(0.507551,0.458909)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.28937,0.271374)(0.191172,0.170524)
+ (0.195007,0.173177)(0.20082,0.188793)(0.306183,0.276904)
+ (0.296309,0.269877)(0.28937,0.271374)
+\psset{fillcolor=cmy_6363ff}%
+\psset{linecolor=rgb_1f1f9b}%
+\pspolygon[fillstyle=solid](1.23484,0.526055)(1.35106,0.550511)
+ (1.33893,0.555247)(1.32484,0.558669)(1.21844,0.533751)
+ (1.2273,0.530147)(1.23484,0.526055)
+\psset{fillcolor=cmy_3737ff}%
+\psset{linecolor=rgb_2727c7}%
+\pspolygon[fillstyle=solid](0.636366,0.506205)(0.519554,0.497979)
+ (0.512249,0.477666)(0.507551,0.458909)(0.62752,0.482848)
+ (0.630886,0.49422)(0.636366,0.506205)
+\psset{fillcolor=cmy_4d4dff}%
+\psset{linecolor=rgb_2323b1}%
+\pspolygon[fillstyle=solid](0.90107,0.520175)(0.805053,0.543639)
+ (0.793701,0.538535)(0.783529,0.532958)(0.890469,0.515566)
+ (0.895461,0.517942)(0.90107,0.520175)
+\psset{fillcolor=cmy_6363ff}%
+\psset{linecolor=rgb_1f1f9b}%
+\pspolygon[fillstyle=solid](1.11043,0.515333)(1.21844,0.533751)
+ (1.20832,0.536895)(1.19703,0.539628)(1.10005,0.519369)
+ (1.10555,0.517419)(1.11043,0.515333)
+\psset{fillcolor=cmy_3a3aff}%
+\psset{linecolor=rgb_2727c4}%
+\pspolygon[fillstyle=solid](0.76699,0.520758)(0.653524,0.530867)
+ (0.643926,0.518523)(0.636366,0.506205)(0.755889,0.507874)
+ (0.760736,0.514347)(0.76699,0.520758)
+\psset{fillcolor=cmy_3c3cff}%
+\psset{linecolor=rgb_2626c2}%
+\pspolygon[fillstyle=solid](1.6438,0.0321256)(1.71591,-0.120081)
+ (1.76775,-0.074723)(1.81976,-0.0100767)(1.73326,0.116772)
+ (1.68934,0.0674669)(1.6438,0.0321256)
+\psset{fillcolor=cmy_4b4bff}%
+\psset{linecolor=rgb_2323b3}%
+\pspolygon[fillstyle=solid](0.890469,0.515566)(0.783529,0.532958)
+ (0.774605,0.526998)(0.76699,0.520758)(0.882464,0.510471)
+ (0.886127,0.513068)(0.890469,0.515566)
+\psset{fillcolor=cmy_5858ff}%
+\psset{linecolor=rgb_2121a6}%
+\pspolygon[fillstyle=solid](1.36891,0.536746)(1.49483,0.572133)
+ (1.48332,0.582232)(1.46867,0.589042)(1.35106,0.550511)
+ (1.36109,0.544356)(1.36891,0.536746)
+\psset{fillcolor=cmy_5f5fff}%
+\psset{linecolor=rgb_1f1f9f}%
+\pspolygon[fillstyle=solid](1.1182,0.510778)(1.23484,0.526055)
+ (1.2273,0.530147)(1.21844,0.533751)(1.11043,0.515333)
+ (1.11466,0.513118)(1.1182,0.510778)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1.49483,0.572133)(1.62644,0.6285)
+ (1.61057,0.641013)(1.59029,0.647141)(1.46867,0.589042)
+ (1.48332,0.582232)(1.49483,0.572133)
+\psset{fillcolor=cmy_5858ff}%
+\psset{linecolor=rgb_2121a6}%
+\pspolygon[fillstyle=solid](1.24569,0.516371)(1.36891,0.536746)
+ (1.36109,0.544356)(1.35106,0.550511)(1.23484,0.526055)
+ (1.24099,0.52146)(1.24569,0.516371)
+\psset{fillcolor=cmy_5d5dff}%
+\psset{linecolor=rgb_2020a1}%
+\pspolygon[fillstyle=solid](1,0.5)(1.01993,0.53134)
+ (1.01046,0.531756)(1.00092,0.532012)(1,0.5)
+\pspolygon[fillstyle=solid](1,0.5)(1.00092,0.532012)
+ (0.991382,0.5321)(0.98189,0.532011)(1,0.5)
+\pspolygon[fillstyle=solid](1,0.5)(1.03849,0.530055)
+ (1.02929,0.53077)(1.01993,0.53134)(1,0.5)
+\pspolygon[fillstyle=solid](1,0.5)(0.98189,0.532011)
+ (0.972499,0.531735)(0.963262,0.531266)(1,0.5)
+\pspolygon[fillstyle=solid](1,0.5)(1.05617,0.528201)
+ (1.04746,0.529197)(1.03849,0.530055)(1,0.5)
+\psset{fillcolor=cmy_5c5cff}%
+\psset{linecolor=rgb_2020a2}%
+\pspolygon[fillstyle=solid](1,0.5)(0.963262,0.531266)
+ (0.954234,0.530596)(0.945465,0.52972)(1,0.5)
+\psset{fillcolor=cmy_4343ff}%
+\psset{linecolor=rgb_2525bb}%
+\pspolygon[fillstyle=solid](0.755889,0.507874)(0.636366,0.506205)
+ (0.630886,0.49422)(0.62752,0.482848)(0.750565,0.495176)
+ (0.752488,0.50145)(0.755889,0.507874)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1,0.5)(1.07258,0.525802)
+ (1.06456,0.527069)(1.05617,0.528201)(1,0.5)
+\psset{fillcolor=cmy_5c5cff}%
+\psset{linecolor=rgb_2020a2}%
+\pspolygon[fillstyle=solid](1,0.5)(0.945465,0.52972)
+ (0.937007,0.528634)(0.928911,0.52734)(1,0.5)
+\psset{fillcolor=cmy_4c4cff}%
+\psset{linecolor=rgb_2323b2}%
+\pspolygon[fillstyle=solid](0.882464,0.510471)(0.76699,0.520758)
+ (0.760736,0.514347)(0.755889,0.507874)(0.877275,0.505078)
+ (0.879506,0.507799)(0.882464,0.510471)
+\pspolygon[fillstyle=solid](0.62752,0.482848)(0.507551,0.458909)
+ (0.505457,0.442216)(0.50598,0.427985)(0.627253,0.462871)
+ (0.6263,0.472334)(0.62752,0.482848)
+\psset{fillcolor=cmy_5f5fff}%
+\psset{linecolor=rgb_1f1f9f}%
+\pspolygon[fillstyle=solid](1,0.5)(1.08732,0.52286)
+ (1.08018,0.524399)(1.07258,0.525802)(1,0.5)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](1,0.5)(0.928911,0.52734)
+ (0.921223,0.525839)(0.913992,0.524138)(1,0.5)
+\pspolygon[fillstyle=solid](1.12312,0.505768)(1.24569,0.516371)
+ (1.24099,0.52146)(1.23484,0.526055)(1.1182,0.510778)
+ (1.12103,0.508324)(1.12312,0.505768)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1.62644,0.6285)(1.76797,0.713246)
+ (1.74686,0.728005)(1.71949,0.731475)(1.59029,0.647141)
+ (1.61057,0.641013)(1.62644,0.6285)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](0.50598,0.427985)(0.390156,0.374904)
+ (0.392913,0.35979)(0.398466,0.350056)(0.515019,0.407859)
+ (0.509149,0.416487)(0.50598,0.427985)
+\psset{fillcolor=cmy_5959ff}%
+\psset{linecolor=rgb_2121a5}%
+\pspolygon[fillstyle=solid](1,0.5)(0.913992,0.524138)
+ (0.90726,0.522245)(0.90107,0.520175)(1,0.5)
+\psset{fillcolor=cmy_5f5fff}%
+\psset{linecolor=rgb_1f1f9f}%
+\pspolygon[fillstyle=solid](1,0.5)(1.10005,0.519369)
+ (1.09396,0.521183)(1.08732,0.52286)(1,0.5)
+\psset{fillcolor=cmy_5252ff}%
+\psset{linecolor=rgb_2222ac}%
+\pspolygon[fillstyle=solid](1.54709,0.00607935)(1.61087,-0.15044)
+ (1.66387,-0.145468)(1.71591,-0.120081)(1.6438,0.0321256)
+ (1.59652,0.0115261)(1.54709,0.00607935)
+\psset{fillcolor=cmy_5757ff}%
+\psset{linecolor=rgb_2121a7}%
+\pspolygon[fillstyle=solid](1,0.5)(0.90107,0.520175)
+ (0.895461,0.517942)(0.890469,0.515566)(1,0.5)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1,0.5)(1.11043,0.515333)
+ (1.10555,0.517419)(1.10005,0.519369)(1,0.5)
+\psset{fillcolor=cmy_5050ff}%
+\psset{linecolor=rgb_2222ae}%
+\pspolygon[fillstyle=solid](0.877275,0.505078)(0.755889,0.507874)
+ (0.752488,0.50145)(0.750565,0.495176)(0.875059,0.499586)
+ (0.875788,0.502332)(0.877275,0.505078)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](1,0.5)(0.890469,0.515566)
+ (0.886127,0.513068)(0.882464,0.510471)(1,0.5)
+\psset{fillcolor=cmy_5d5dff}%
+\psset{linecolor=rgb_2020a1}%
+\pspolygon[fillstyle=solid](1,0.5)(1.1182,0.510778)
+ (1.11466,0.513118)(1.11043,0.515333)(1,0.5)
+\psset{fillcolor=cmy_2626ff}%
+\psset{linecolor=rgb_2b2bd8}%
+\pspolygon[fillstyle=solid](1.73326,0.116772)(1.81976,-0.0100767)
+ (1.87193,0.0727816)(1.92376,0.172159)(1.81542,0.25192)
+ (1.77544,0.178833)(1.73326,0.116772)
+\psset{fillcolor=cmy_4b4bff}%
+\psset{linecolor=rgb_2323b3}%
+\pspolygon[fillstyle=solid](1.25055,0.504845)(1.37753,0.517385)
+ (1.37441,0.527719)(1.36891,0.536746)(1.24569,0.516371)
+ (1.24889,0.510816)(1.25055,0.504845)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](1,0.5)(0.882464,0.510471)
+ (0.879506,0.507799)(0.877275,0.505078)(1,0.5)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1,0.5)(1.12312,0.505768)
+ (1.12103,0.508324)(1.1182,0.510778)(1,0.5)
+\psset{fillcolor=cmy_5454ff}%
+\psset{linecolor=rgb_2222aa}%
+\pspolygon[fillstyle=solid](1.12505,0.500414)(1.25055,0.504845)
+ (1.24889,0.510816)(1.24569,0.516371)(1.12312,0.505768)
+ (1.12447,0.503125)(1.12505,0.500414)
+\psset{fillcolor=cmy_4f4fff}%
+\psset{linecolor=rgb_2323af}%
+\pspolygon[fillstyle=solid](0.750565,0.495176)(0.62752,0.482848)
+ (0.6263,0.472334)(0.627253,0.462871)(0.751245,0.483425)
+ (0.750144,0.489142)(0.750565,0.495176)
+\psset{fillcolor=cmy_4141ff}%
+\psset{linecolor=rgb_2525bd}%
+\pspolygon[fillstyle=solid](1.37753,0.517385)(1.50776,0.542368)
+ (1.50301,0.558773)(1.49483,0.572133)(1.36891,0.536746)
+ (1.37441,0.527719)(1.37753,0.517385)
+\psset{fillcolor=cmy_5757ff}%
+\psset{linecolor=rgb_2121a7}%
+\pspolygon[fillstyle=solid](1,0.5)(0.877275,0.505078)
+ (0.875788,0.502332)(0.875059,0.499586)(1,0.5)
+\psset{fillcolor=cmy_5858ff}%
+\psset{linecolor=rgb_2121a6}%
+\pspolygon[fillstyle=solid](1,0.5)(1.12505,0.500414)
+ (1.12447,0.503125)(1.12312,0.505768)(1,0.5)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.398466,0.350056)(0.28937,0.271374)
+ (0.296309,0.269877)(0.306183,0.276904)(0.418616,0.346439)
+ (0.406961,0.34569)(0.398466,0.350056)
+\psset{fillcolor=cmy_5454ff}%
+\psset{linecolor=rgb_2222aa}%
+\pspolygon[fillstyle=solid](0.875059,0.499586)(0.750565,0.495176)
+ (0.750144,0.489142)(0.751245,0.483425)(0.875906,0.494186)
+ (0.875097,0.496864)(0.875059,0.499586)
+\psset{fillcolor=cmy_5858ff}%
+\psset{linecolor=rgb_2121a6}%
+\pspolygon[fillstyle=solid](1,0.5)(0.875059,0.499586)
+ (0.875097,0.496864)(0.875906,0.494186)(1,0.5)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](1.76797,0.713246)(1.92548,0.836328)
+ (1.8979,0.852992)(1.86122,0.850819)(1.71949,0.731475)
+ (1.74686,0.728005)(1.76797,0.713246)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](1,0.5)(1.1239,0.494874)
+ (1.12486,0.497656)(1.12505,0.500414)(1,0.5)
+\psset{fillcolor=cmy_3b3bff}%
+\psset{linecolor=rgb_2727c3}%
+\pspolygon[fillstyle=solid](1.50776,0.542368)(1.64384,0.584677)
+ (1.63759,0.609591)(1.62644,0.6285)(1.49483,0.572133)
+ (1.50301,0.558773)(1.50776,0.542368)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](0.627253,0.462871)(0.50598,0.427985)
+ (0.509149,0.416487)(0.515019,0.407859)(0.635784,0.447596)
+ (0.630406,0.4546)(0.627253,0.462871)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](1,0.5)(0.875906,0.494186)
+ (0.877488,0.491574)(0.879836,0.489043)(1,0.5)
+\psset{fillcolor=cmy_4e4eff}%
+\psset{linecolor=rgb_2323b0}%
+\pspolygon[fillstyle=solid](1.1239,0.494874)(1.24918,0.491962)
+ (1.25065,0.498531)(1.25055,0.504845)(1.12505,0.500414)
+ (1.12486,0.497656)(1.1239,0.494874)
+\psset{fillcolor=cmy_5555ff}%
+\psset{linecolor=rgb_2121a9}%
+\pspolygon[fillstyle=solid](1,0.5)(1.11965,0.48934)
+ (1.12216,0.492093)(1.1239,0.494874)(1,0.5)
+\psset{fillcolor=cmy_5c5cff}%
+\psset{linecolor=rgb_2020a2}%
+\pspolygon[fillstyle=solid](1,0.5)(0.879836,0.489043)
+ (0.882942,0.486608)(0.886789,0.484281)(1,0.5)
+\psset{fillcolor=cmy_5555ff}%
+\psset{linecolor=rgb_2121a9}%
+\pspolygon[fillstyle=solid](1,0.5)(1.11239,0.484027)
+ (1.11639,0.486643)(1.11965,0.48934)(1,0.5)
+\psset{fillcolor=cmy_3e3eff}%
+\psset{linecolor=rgb_2626c0}%
+\pspolygon[fillstyle=solid](1.24918,0.491962)(1.37644,0.493576)
+ (1.37822,0.505923)(1.37753,0.517385)(1.25055,0.504845)
+ (1.25065,0.498531)(1.24918,0.491962)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1,0.5)(0.886789,0.484281)
+ (0.89136,0.482071)(0.896629,0.479987)(1,0.5)
+\psset{fillcolor=cmy_5959ff}%
+\psset{linecolor=rgb_2121a5}%
+\pspolygon[fillstyle=solid](0.875906,0.494186)(0.751245,0.483425)
+ (0.753877,0.478082)(0.758047,0.473156)(0.879836,0.489043)
+ (0.877488,0.491574)(0.875906,0.494186)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](1,0.5)(1.10226,0.479146)
+ (1.10767,0.48152)(1.11239,0.484027)(1,0.5)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](0.751245,0.483425)(0.627253,0.462871)
+ (0.630406,0.4546)(0.635784,0.447596)(0.758047,0.473156)
+ (0.753877,0.478082)(0.751245,0.483425)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1,0.5)(0.896629,0.479987)
+ (0.902567,0.478033)(0.909139,0.476214)(1,0.5)
+\psset{fillcolor=cmy_5757ff}%
+\psset{linecolor=rgb_2121a7}%
+\pspolygon[fillstyle=solid](1,0.5)(1.08949,0.474885)
+ (1.09619,0.476928)(1.10226,0.479146)(1,0.5)
+\psset{fillcolor=cmy_4a4aff}%
+\psset{linecolor=rgb_2424b4}%
+\pspolygon[fillstyle=solid](1.11965,0.48934)(1.24148,0.478487)
+ (1.24612,0.485243)(1.24918,0.491962)(1.1239,0.494874)
+ (1.12216,0.492093)(1.11965,0.48934)
+\psset{fillcolor=cmy_2a2aff}%
+\psset{linecolor=rgb_2a2ad4}%
+\pspolygon[fillstyle=solid](1.37644,0.493576)(1.50673,0.502132)
+ (1.50899,0.523306)(1.50776,0.542368)(1.37753,0.517385)
+ (1.37822,0.505923)(1.37644,0.493576)
+\psset{fillcolor=cmy_5959ff}%
+\psset{linecolor=rgb_2121a5}%
+\pspolygon[fillstyle=solid](1,0.5)(1.07439,0.47139)
+ (1.08221,0.473035)(1.08949,0.474885)(1,0.5)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](1,0.5)(0.909139,0.476214)
+ (0.916306,0.474532)(0.924023,0.47299)(1,0.5)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](0.20082,0.188793)(0.105573,0.08167)
+ (0.105946,0.125602)(0.108805,0.186635)(0.221782,0.25564)
+ (0.209394,0.216686)(0.20082,0.188793)
+\psset{fillcolor=cmy_3939ff}%
+\psset{linecolor=rgb_2727c5}%
+\pspolygon[fillstyle=solid](1.64384,0.584677)(1.78949,0.650223)
+ (1.78228,0.687084)(1.76797,0.713246)(1.62644,0.6285)
+ (1.63759,0.609591)(1.64384,0.584677)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](1,0.5)(1.05734,0.468753)
+ (1.06608,0.469961)(1.07439,0.47139)(1,0.5)
+\psset{fillcolor=cmy_5d5dff}%
+\psset{linecolor=rgb_2020a1}%
+\pspolygon[fillstyle=solid](1,0.5)(0.924023,0.47299)
+ (0.932243,0.471589)(0.940912,0.470334)(1,0.5)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1,0.5)(1.03876,0.46701)
+ (1.04821,0.467769)(1.05734,0.468753)(1,0.5)
+\psset{fillcolor=cmy_5c5cff}%
+\psset{linecolor=rgb_2020a2}%
+\pspolygon[fillstyle=solid](1,0.5)(0.940912,0.470334)
+ (0.949975,0.469227)(0.959372,0.468273)(1,0.5)
+\psset{fillcolor=cmy_6363ff}%
+\psset{linecolor=rgb_1f1f9b}%
+\pspolygon[fillstyle=solid](1.92548,0.836328)(2.1079,1.01222)
+ (2.07205,1.03012)(2.0226,1.01759)(1.86122,0.850819)
+ (1.8979,0.852992)(1.92548,0.836328)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1,0.5)(1.01915,0.466147)
+ (1.02906,0.466471)(1.03876,0.46701)(1,0.5)
+\psset{fillcolor=cmy_5e5eff}%
+\psset{linecolor=rgb_2020a0}%
+\pspolygon[fillstyle=solid](0.879836,0.489043)(0.758047,0.473156)
+ (0.763749,0.468665)(0.770971,0.464613)(0.886789,0.484281)
+ (0.882942,0.486608)(0.879836,0.489043)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1,0.5)(0.959372,0.468273)
+ (0.969041,0.467478)(0.978917,0.466848)(1,0.5)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](0.515019,0.407859)(0.398466,0.350056)
+ (0.406961,0.34569)(0.418616,0.346439)(0.535179,0.399064)
+ (0.523664,0.402099)(0.515019,0.407859)
+\psset{fillcolor=cmy_5b5bff}%
+\psset{linecolor=rgb_2020a3}%
+\pspolygon[fillstyle=solid](1,0.5)(0.999023,0.466116)
+ (1.00912,0.466032)(1.01915,0.466147)(1,0.5)
+\pspolygon[fillstyle=solid](1,0.5)(0.978917,0.466848)
+ (0.988933,0.466391)(0.999023,0.466116)(1,0.5)
+\psset{fillcolor=cmy_3535ff}%
+\psset{linecolor=rgb_2828c9}%
+\pspolygon[fillstyle=solid](1.24148,0.478487)(1.36555,0.467434)
+ (1.37221,0.480637)(1.37644,0.493576)(1.24918,0.491962)
+ (1.24612,0.485243)(1.24148,0.478487)
+\psset{fillcolor=cmy_4848ff}%
+\psset{linecolor=rgb_2424b6}%
+\pspolygon[fillstyle=solid](1.11239,0.484027)(1.22757,0.465351)
+ (1.23529,0.471816)(1.24148,0.478487)(1.11965,0.48934)
+ (1.11639,0.486643)(1.11239,0.484027)
+\psset{fillcolor=cmy_1b1bff}%
+\psset{linecolor=rgb_2d2de3}%
+\pspolygon[fillstyle=solid](1.50673,0.502132)(1.64155,0.520244)
+ (1.64513,0.55453)(1.64384,0.584677)(1.50776,0.542368)
+ (1.50899,0.523306)(1.50673,0.502132)
+\psset{fillcolor=cmy_2d2dff}%
+\psset{linecolor=rgb_2929d1}%
+\pspolygon[fillstyle=solid](1.56058,0.160334)(1.6438,0.0321256)
+ (1.68934,0.0674669)(1.73326,0.116772)(1.6364,0.222327)
+ (1.59977,0.186629)(1.56058,0.160334)
+\psset{fillcolor=cmy_6464ff}%
+\psset{linecolor=rgb_1e1e9a}%
+\pspolygon[fillstyle=solid](0.758047,0.473156)(0.635784,0.447596)
+ (0.64341,0.441874)(0.653304,0.437383)(0.770971,0.464613)
+ (0.763749,0.468665)(0.758047,0.473156)
+\psset{fillcolor=cmy_6f6fff}%
+\psset{linecolor=rgb_1c1c8f}%
+\pspolygon[fillstyle=solid](0.635784,0.447596)(0.515019,0.407859)
+ (0.523664,0.402099)(0.535179,0.399064)(0.653304,0.437383)
+ (0.64341,0.441874)(0.635784,0.447596)
+\psset{fillcolor=cmy_1b1bff}%
+\psset{linecolor=rgb_2d2de3}%
+\pspolygon[fillstyle=solid](1.36555,0.467434)(1.49191,0.456177)
+ (1.501,0.479507)(1.50673,0.502132)(1.37644,0.493576)
+ (1.37221,0.480637)(1.36555,0.467434)
+\psset{fillcolor=cmy_1919ff}%
+\psset{linecolor=rgb_2d2de5}%
+\pspolygon[fillstyle=solid](1.6364,0.222327)(1.73326,0.116772)
+ (1.77544,0.178833)(1.81542,0.25192)(1.7012,0.317458)
+ (1.67032,0.266403)(1.6364,0.222327)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](0.886789,0.484281)(0.770971,0.464613)
+ (0.779692,0.460981)(0.78988,0.457739)(0.896629,0.479987)
+ (0.89136,0.482071)(0.886789,0.484281)
+\psset{fillcolor=cmy_4949ff}%
+\psset{linecolor=rgb_2424b5}%
+\pspolygon[fillstyle=solid](1.10226,0.479146)(1.20772,0.4535)
+ (1.21837,0.45921)(1.22757,0.465351)(1.11239,0.484027)
+ (1.10767,0.48152)(1.10226,0.479146)
+\psset{fillcolor=cmy_1111ff}%
+\psset{linecolor=rgb_2f2fed}%
+\pspolygon[fillstyle=solid](1.81542,0.25192)(1.92376,0.172159)
+ (1.97421,0.285475)(2.02166,0.408983)(1.88544,0.421119)
+ (1.85244,0.33369)(1.81542,0.25192)
+\psset{fillcolor=cmy_3030ff}%
+\psset{linecolor=rgb_2929ce}%
+\pspolygon[fillstyle=solid](1.22757,0.465351)(1.34511,0.441628)
+ (1.3565,0.454315)(1.36555,0.467434)(1.24148,0.478487)
+ (1.23529,0.471816)(1.22757,0.465351)
+\psset{fillcolor=cmy_1313ff}%
+\psset{linecolor=rgb_2f2feb}%
+\pspolygon[fillstyle=solid](1.64155,0.520244)(1.78302,0.550882)
+ (1.78963,0.60413)(1.78949,0.650223)(1.64384,0.584677)
+ (1.64513,0.55453)(1.64155,0.520244)
+\psset{fillcolor=cmy_3939ff}%
+\psset{linecolor=rgb_2727c5}%
+\pspolygon[fillstyle=solid](1.78949,0.650223)(1.94995,0.746725)
+ (1.94296,0.80048)(1.92548,0.836328)(1.76797,0.713246)
+ (1.78228,0.687084)(1.78949,0.650223)
+\psset{fillcolor=cmy_0808ff}%
+\psset{linecolor=rgb_3131f6}%
+\pspolygon[fillstyle=solid](1.49191,0.456177)(1.62063,0.44471)
+ (1.63329,0.483148)(1.64155,0.520244)(1.50673,0.502132)
+ (1.501,0.479507)(1.49191,0.456177)
+\psset{fillcolor=cmy_4c4cff}%
+\psset{linecolor=rgb_2323b2}%
+\pspolygon[fillstyle=solid](1.08949,0.474885)(1.18236,0.443736)
+ (1.1957,0.448317)(1.20772,0.4535)(1.10226,0.479146)
+ (1.09619,0.476928)(1.08949,0.474885)
+\psset{fillcolor=cmy_6464ff}%
+\psset{linecolor=rgb_1e1e9a}%
+\pspolygon[fillstyle=solid](0.896629,0.479987)(0.78988,0.457739)
+ (0.801491,0.454842)(0.81447,0.452238)(0.909139,0.476214)
+ (0.902567,0.478033)(0.896629,0.479987)
+\psset{fillcolor=cmy_7c7cff}%
+\psset{linecolor=rgb_1a1a82}%
+\pspolygon[fillstyle=solid](0.306183,0.276904)(0.20082,0.188793)
+ (0.209394,0.216686)(0.221782,0.25564)(0.336923,0.313416)
+ (0.319506,0.291774)(0.306183,0.276904)
+\psset{fillcolor=cmy_1515ff}%
+\psset{linecolor=rgb_2e2ee9}%
+\pspolygon[fillstyle=solid](1.34511,0.441628)(1.46416,0.410519)
+ (1.47958,0.432922)(1.49191,0.456177)(1.36555,0.467434)
+ (1.3565,0.454315)(1.34511,0.441628)
+\psset{fillcolor=cmy_0808ff}%
+\psset{linecolor=rgb_3131f6}%
+\pspolygon[fillstyle=solid](1.7012,0.317458)(1.81542,0.25192)
+ (1.85244,0.33369)(1.88544,0.421119)(1.75179,0.433026)
+ (1.72856,0.373711)(1.7012,0.317458)
+\psset{fillcolor=cmy_5050ff}%
+\psset{linecolor=rgb_2222ae}%
+\pspolygon[fillstyle=solid](1.07439,0.47139)(1.15207,0.436591)
+ (1.16779,0.439816)(1.18236,0.443736)(1.08949,0.474885)
+ (1.08221,0.473035)(1.07439,0.47139)
+\psset{fillcolor=cmy_6b6bff}%
+\psset{linecolor=rgb_1d1d93}%
+\pspolygon[fillstyle=solid](0.770971,0.464613)(0.653304,0.437383)
+ (0.665477,0.434016)(0.679931,0.431611)(0.78988,0.457739)
+ (0.779692,0.460981)(0.770971,0.464613)
+\psset{fillcolor=cmy_3131ff}%
+\psset{linecolor=rgb_2929cd}%
+\pspolygon[fillstyle=solid](1.20772,0.4535)(1.31566,0.418861)
+ (1.33147,0.429708)(1.34511,0.441628)(1.22757,0.465351)
+ (1.21837,0.45921)(1.20772,0.4535)
+\psset{fillcolor=cmy_4545ff}%
+\psset{linecolor=rgb_2525b9}%
+\pspolygon[fillstyle=solid](1.4744,0.138283)(1.54709,0.00607935)
+ (1.59652,0.0115261)(1.6438,0.0321256)(1.56058,0.160334)
+ (1.51884,0.144112)(1.4744,0.138283)
+\psset{fillcolor=cmy_0101ff}%
+\psset{linecolor=rgb_3232fd}%
+\pspolygon[fillstyle=solid](1.62063,0.44471)(1.75179,0.433026)
+ (1.77018,0.49296)(1.78302,0.550882)(1.64155,0.520244)
+ (1.63329,0.483148)(1.62063,0.44471)
+\psset{fillcolor=cmy_6464ff}%
+\psset{linecolor=rgb_1e1e9a}%
+\pspolygon[fillstyle=solid](0.909139,0.476214)(0.81447,0.452238)
+ (0.828748,0.449869)(0.844242,0.44768)(0.924023,0.47299)
+ (0.916306,0.474532)(0.909139,0.476214)
+\psset{fillcolor=cmy_0505ff}%
+\psset{linecolor=rgb_3131f9}%
+\pspolygon[fillstyle=solid](1.46416,0.410519)(1.58342,0.369794)
+ (1.6039,0.406438)(1.62063,0.44471)(1.49191,0.456177)
+ (1.47958,0.432922)(1.46416,0.410519)
+\psset{fillcolor=cmy_0202ff}%
+\psset{linecolor=rgb_3232fc}%
+\pspolygon[fillstyle=solid](1.58342,0.369794)(1.7012,0.317458)
+ (1.72856,0.373711)(1.75179,0.433026)(1.62063,0.44471)
+ (1.6039,0.406438)(1.58342,0.369794)
+\psset{fillcolor=cmy_0e0eff}%
+\psset{linecolor=rgb_3030f0}%
+\pspolygon[fillstyle=solid](1.53245,0.306569)(1.6364,0.222327)
+ (1.67032,0.266403)(1.7012,0.317458)(1.58342,0.369794)
+ (1.55951,0.336116)(1.53245,0.306569)
+\psset{fillcolor=cmy_6969ff}%
+\psset{linecolor=rgb_1d1d95}%
+\pspolygon[fillstyle=solid](1.43923,0.040527)(1.49747,-0.0982892)
+ (1.55585,-0.134733)(1.61087,-0.15044)(1.54709,0.00607935)
+ (1.49491,0.0158499)(1.43923,0.040527)
+\psset{fillcolor=cmy_5555ff}%
+\psset{linecolor=rgb_2121a9}%
+\pspolygon[fillstyle=solid](1.05734,0.468753)(1.11756,0.432255)
+ (1.13529,0.434074)(1.15207,0.436591)(1.07439,0.47139)
+ (1.06608,0.469961)(1.05734,0.468753)
+\psset{fillcolor=cmy_6464ff}%
+\psset{linecolor=rgb_1e1e9a}%
+\pspolygon[fillstyle=solid](0.924023,0.47299)(0.844242,0.44768)
+ (0.860857,0.44562)(0.878483,0.443646)(0.940912,0.470334)
+ (0.932243,0.471589)(0.924023,0.47299)
+\psset{fillcolor=cmy_1818ff}%
+\psset{linecolor=rgb_2e2ee6}%
+\pspolygon[fillstyle=solid](1.31566,0.418861)(1.42461,0.371119)
+ (1.44579,0.3897)(1.46416,0.410519)(1.34511,0.441628)
+ (1.33147,0.429708)(1.31566,0.418861)
+\psset{fillcolor=cmy_5959ff}%
+\psset{linecolor=rgb_2121a5}%
+\pspolygon[fillstyle=solid](1.03876,0.46701)(1.07968,0.43057)
+ (1.09898,0.431103)(1.11756,0.432255)(1.05734,0.468753)
+ (1.04821,0.467769)(1.03876,0.46701)
+\psset{fillcolor=cmy_1111ff}%
+\psset{linecolor=rgb_2f2fed}%
+\pspolygon[fillstyle=solid](1.78302,0.550882)(1.93401,0.597589)
+ (1.94669,0.677812)(1.94995,0.746725)(1.78949,0.650223)
+ (1.78963,0.60413)(1.78302,0.550882)
+\psset{fillcolor=cmy_7777ff}%
+\psset{linecolor=rgb_1b1b87}%
+\pspolygon[fillstyle=solid](0.653304,0.437383)(0.535179,0.399064)
+ (0.549666,0.398476)(0.567233,0.399933)(0.679931,0.431611)
+ (0.665477,0.434016)(0.653304,0.437383)
+\psset{fillcolor=cmy_0101ff}%
+\psset{linecolor=rgb_3232fd}%
+\pspolygon[fillstyle=solid](1.75179,0.433026)(1.88544,0.421119)
+ (1.91311,0.510505)(1.93401,0.597589)(1.78302,0.550882)
+ (1.77018,0.49296)(1.75179,0.433026)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.418616,0.346439)(0.306183,0.276904)
+ (0.319506,0.291774)(0.336923,0.313416)(0.452538,0.361054)
+ (0.433703,0.351806)(0.418616,0.346439)
+\psset{fillcolor=cmy_3737ff}%
+\psset{linecolor=rgb_2727c7}%
+\pspolygon[fillstyle=solid](1.18236,0.443736)(1.27784,0.401367)
+ (1.29775,0.409345)(1.31566,0.418861)(1.20772,0.4535)
+ (1.1957,0.448317)(1.18236,0.443736)
+\psset{fillcolor=cmy_0c0cff}%
+\psset{linecolor=rgb_3030f2}%
+\pspolygon[fillstyle=solid](1.42461,0.371119)(1.53245,0.306569)
+ (1.55951,0.336116)(1.58342,0.369794)(1.46416,0.410519)
+ (1.44579,0.3897)(1.42461,0.371119)
+\psset{fillcolor=cmy_2020ff}%
+\psset{linecolor=rgb_2c2cde}%
+\pspolygon[fillstyle=solid](1.46963,0.263451)(1.56058,0.160334)
+ (1.59977,0.186629)(1.6364,0.222327)(1.53245,0.306569)
+ (1.50244,0.282108)(1.46963,0.263451)
+\psset{fillcolor=cmy_6363ff}%
+\psset{linecolor=rgb_1f1f9b}%
+\pspolygon[fillstyle=solid](0.940912,0.470334)(0.878483,0.443646)
+ (0.896998,0.44173)(0.916271,0.43986)(0.959372,0.468273)
+ (0.949975,0.469227)(0.940912,0.470334)
+\psset{fillcolor=cmy_5d5dff}%
+\psset{linecolor=rgb_2020a1}%
+\pspolygon[fillstyle=solid](1.01915,0.466147)(1.03945,0.431091)
+ (1.05979,0.43059)(1.07968,0.43057)(1.03876,0.46701)
+ (1.02906,0.466471)(1.01915,0.466147)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.535179,0.399064)(0.418616,0.346439)
+ (0.433703,0.351806)(0.452538,0.361054)(0.567233,0.399933)
+ (0.549666,0.398476)(0.535179,0.399064)
+\psset{fillcolor=cmy_3939ff}%
+\psset{linecolor=rgb_2727c5}%
+\pspolygon[fillstyle=solid](1.94995,0.746725)(2.13284,0.884999)
+ (2.12834,0.963057)(2.1079,1.01222)(1.92548,0.836328)
+ (1.94296,0.80048)(1.94995,0.746725)
+\psset{fillcolor=cmy_6262ff}%
+\psset{linecolor=rgb_1f1f9c}%
+\pspolygon[fillstyle=solid](0.959372,0.468273)(0.916271,0.43986)
+ (0.936157,0.438041)(0.956509,0.436296)(0.978917,0.466848)
+ (0.969041,0.467478)(0.959372,0.468273)
+\psset{fillcolor=cmy_5f5fff}%
+\psset{linecolor=rgb_1f1f9f}%
+\pspolygon[fillstyle=solid](0.999023,0.466116)(0.997986,0.433208)
+ (1.0188,0.431991)(1.03945,0.431091)(1.01915,0.466147)
+ (1.00912,0.466032)(0.999023,0.466116)
+\psset{fillcolor=cmy_6f6fff}%
+\psset{linecolor=rgb_1c1c8f}%
+\pspolygon[fillstyle=solid](0.78988,0.457739)(0.679931,0.431611)
+ (0.696648,0.429965)(0.71559,0.428845)(0.81447,0.452238)
+ (0.801491,0.454842)(0.78988,0.457739)
+\psset{fillcolor=cmy_6161ff}%
+\psset{linecolor=rgb_1f1f9d}%
+\pspolygon[fillstyle=solid](0.978917,0.466848)(0.956509,0.436296)
+ (0.977171,0.434667)(0.997986,0.433208)(0.999023,0.466116)
+ (0.988933,0.466391)(0.978917,0.466848)
+\psset{fillcolor=cmy_0303ff}%
+\psset{linecolor=rgb_3232fb}%
+\pspolygon[fillstyle=solid](1.88544,0.421119)(2.02166,0.408983)
+ (2.06392,0.537585)(2.09838,0.664828)(1.93401,0.597589)
+ (1.91311,0.510505)(1.88544,0.421119)
+\psset{fillcolor=cmy_4141ff}%
+\psset{linecolor=rgb_2525bd}%
+\pspolygon[fillstyle=solid](1.15207,0.436591)(1.23246,0.39052)
+ (1.25605,0.395068)(1.27784,0.401367)(1.18236,0.443736)
+ (1.16779,0.439816)(1.15207,0.436591)
+\psset{fillcolor=cmy_2323ff}%
+\psset{linecolor=rgb_2b2bdb}%
+\pspolygon[fillstyle=solid](1.27784,0.401367)(1.37438,0.342743)
+ (1.40077,0.355325)(1.42461,0.371119)(1.31566,0.418861)
+ (1.29775,0.409345)(1.27784,0.401367)
+\psset{fillcolor=cmy_1b1bff}%
+\psset{linecolor=rgb_2d2de3}%
+\pspolygon[fillstyle=solid](1.37438,0.342743)(1.46963,0.263451)
+ (1.50244,0.282108)(1.53245,0.306569)(1.42461,0.371119)
+ (1.40077,0.355325)(1.37438,0.342743)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](0.81447,0.452238)(0.71559,0.428845)
+ (0.736691,0.427999)(0.759855,0.427181)(0.844242,0.44768)
+ (0.828748,0.449869)(0.81447,0.452238)
+\psset{fillcolor=cmy_3939ff}%
+\psset{linecolor=rgb_2727c5}%
+\pspolygon[fillstyle=solid](1.39584,0.245193)(1.4744,0.138283)
+ (1.51884,0.144112)(1.56058,0.160334)(1.46963,0.263451)
+ (1.43409,0.251074)(1.39584,0.245193)
+\psset{fillcolor=cmy_0f0fff}%
+\psset{linecolor=rgb_2f2fef}%
+\pspolygon[fillstyle=solid](1.93401,0.597589)(2.09838,0.664828)
+ (2.12222,0.783232)(2.13284,0.884999)(1.94995,0.746725)
+ (1.94669,0.677812)(1.93401,0.597589)
+\psset{fillcolor=cmy_4e4eff}%
+\psset{linecolor=rgb_2323b0}%
+\pspolygon[fillstyle=solid](1.11756,0.432255)(1.18041,0.386614)
+ (1.20721,0.387725)(1.23246,0.39052)(1.15207,0.436591)
+ (1.13529,0.434074)(1.11756,0.432255)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](0.679931,0.431611)(0.567233,0.399933)
+ (0.587968,0.402922)(0.611934,0.40685)(0.71559,0.428845)
+ (0.696648,0.429965)(0.679931,0.431611)
+\psset{fillcolor=cmy_3434ff}%
+\psset{linecolor=rgb_2828ca}%
+\pspolygon[fillstyle=solid](1.23246,0.39052)(1.31435,0.328195)
+ (1.34554,0.333655)(1.37438,0.342743)(1.27784,0.401367)
+ (1.25605,0.395068)(1.23246,0.39052)
+\psset{fillcolor=cmy_3131ff}%
+\psset{linecolor=rgb_2929cd}%
+\pspolygon[fillstyle=solid](1.31435,0.328195)(1.39584,0.245193)
+ (1.43409,0.251074)(1.46963,0.263451)(1.37438,0.342743)
+ (1.34554,0.333655)(1.31435,0.328195)
+\psset{fillcolor=cmy_5a5aff}%
+\psset{linecolor=rgb_2020a4}%
+\pspolygon[fillstyle=solid](1.07968,0.43057)(1.1228,0.388846)
+ (1.15222,0.387052)(1.18041,0.386614)(1.11756,0.432255)
+ (1.09898,0.431103)(1.07968,0.43057)
+\psset{fillcolor=cmy_7272ff}%
+\psset{linecolor=rgb_1c1c8c}%
+\pspolygon[fillstyle=solid](0.844242,0.44768)(0.759855,0.427181)
+ (0.784951,0.42616)(0.811811,0.424741)(0.878483,0.443646)
+ (0.860857,0.44562)(0.844242,0.44768)
+\psset{fillcolor=cmy_6060ff}%
+\psset{linecolor=rgb_1f1f9e}%
+\pspolygon[fillstyle=solid](1.3764,0.157338)(1.43923,0.040527)
+ (1.49491,0.0158499)(1.54709,0.00607935)(1.4744,0.138283)
+ (1.42703,0.142821)(1.3764,0.157338)
+\psset{fillcolor=cmy_6363ff}%
+\psset{linecolor=rgb_1f1f9b}%
+\pspolygon[fillstyle=solid](1.03945,0.431091)(1.06103,0.395505)
+ (1.09234,0.391756)(1.1228,0.388846)(1.07968,0.43057)
+ (1.05979,0.43059)(1.03945,0.431091)
+\psset{fillcolor=cmy_7272ff}%
+\psset{linecolor=rgb_1c1c8c}%
+\pspolygon[fillstyle=solid](0.878483,0.443646)(0.811811,0.424741)
+ (0.840235,0.422779)(0.869988,0.42019)(0.916271,0.43986)
+ (0.896998,0.44173)(0.878483,0.443646)
+\psset{fillcolor=cmy_4a4aff}%
+\psset{linecolor=rgb_2424b4}%
+\pspolygon[fillstyle=solid](1.18041,0.386614)(1.24529,0.327916)
+ (1.2809,0.32634)(1.31435,0.328195)(1.23246,0.39052)
+ (1.20721,0.387725)(1.18041,0.386614)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.567233,0.399933)(0.452538,0.361054)
+ (0.47545,0.373217)(0.502743,0.387128)(0.611934,0.40685)
+ (0.587968,0.402922)(0.567233,0.399933)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](0.997986,0.433208)(0.996875,0.404353)
+ (1.02913,0.399802)(1.06103,0.395505)(1.03945,0.431091)
+ (1.0188,0.431991)(0.997986,0.433208)
+\psset{fillcolor=cmy_7171ff}%
+\psset{linecolor=rgb_1c1c8d}%
+\pspolygon[fillstyle=solid](0.916271,0.43986)(0.869988,0.42019)
+ (0.900811,0.41696)(0.932427,0.413148)(0.956509,0.436296)
+ (0.936157,0.438041)(0.916271,0.43986)
+\psset{fillcolor=cmy_6e6eff}%
+\psset{linecolor=rgb_1c1c90}%
+\pspolygon[fillstyle=solid](0.956509,0.436296)(0.932427,0.413148)
+ (0.964546,0.408882)(0.996875,0.404353)(0.997986,0.433208)
+ (0.977171,0.434667)(0.956509,0.436296)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.71559,0.428845)(0.611934,0.40685)
+ (0.639145,0.411067)(0.669551,0.414914)(0.759855,0.427181)
+ (0.736691,0.427999)(0.71559,0.428845)
+\psset{fillcolor=cmy_5656ff}%
+\psset{linecolor=rgb_2121a8}%
+\pspolygon[fillstyle=solid](1.31112,0.252497)(1.3764,0.157338)
+ (1.42703,0.142821)(1.4744,0.138283)(1.39584,0.245193)
+ (1.35487,0.24577)(1.31112,0.252497)
+\psset{fillcolor=cmy_4e4eff}%
+\psset{linecolor=rgb_2323b0}%
+\pspolygon[fillstyle=solid](1.24529,0.327916)(1.31112,0.252497)
+ (1.35487,0.24577)(1.39584,0.245193)(1.31435,0.328195)
+ (1.2809,0.32634)(1.24529,0.327916)
+\psset{fillcolor=cmy_5f5fff}%
+\psset{linecolor=rgb_1f1f9f}%
+\pspolygon[fillstyle=solid](1.1228,0.388846)(1.16806,0.339925)
+ (1.20762,0.332598)(1.24529,0.327916)(1.18041,0.386614)
+ (1.15222,0.387052)(1.1228,0.388846)
+\psset{fillcolor=cmy_7c7cff}%
+\psset{linecolor=rgb_1a1a82}%
+\pspolygon[fillstyle=solid](0.452538,0.361054)(0.336923,0.313416)
+ (0.359168,0.34034)(0.38701,0.370633)(0.502743,0.387128)
+ (0.47545,0.373217)(0.452538,0.361054)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.759855,0.427181)(0.669551,0.414914)
+ (0.703026,0.417762)(0.739356,0.419062)(0.811811,0.424741)
+ (0.784951,0.42616)(0.759855,0.427181)
+\psset{fillcolor=cmy_6e6eff}%
+\psset{linecolor=rgb_1c1c90}%
+\pspolygon[fillstyle=solid](1.06103,0.395505)(1.08409,0.360109)
+ (1.1268,0.349318)(1.16806,0.339925)(1.1228,0.388846)
+ (1.09234,0.391756)(1.06103,0.395505)
+\psset{fillcolor=cmy_7474ff}%
+\psset{linecolor=rgb_1b1b8a}%
+\pspolygon[fillstyle=solid](0.336923,0.313416)(0.221782,0.25564)
+ (0.239289,0.303779)(0.263419,0.358433)(0.38701,0.370633)
+ (0.359168,0.34034)(0.336923,0.313416)
+\psset{fillcolor=cmy_6767ff}%
+\psset{linecolor=rgb_1e1e97}%
+\pspolygon[fillstyle=solid](1.16806,0.339925)(1.21527,0.281861)
+ (1.26458,0.264805)(1.31112,0.252497)(1.24529,0.327916)
+ (1.20762,0.332598)(1.16806,0.339925)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.611934,0.40685)(0.502743,0.387128)
+ (0.53466,0.401467)(0.571331,0.414834)(0.669551,0.414914)
+ (0.639145,0.411067)(0.611934,0.40685)
+\psset{fillcolor=cmy_6d6dff}%
+\psset{linecolor=rgb_1d1d91}%
+\pspolygon[fillstyle=solid](0.221782,0.25564)(0.108805,0.186635)
+ (0.116083,0.263023)(0.130252,0.351753)(0.263419,0.358433)
+ (0.239289,0.303779)(0.221782,0.25564)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.811811,0.424741)(0.739356,0.419062)
+ (0.778241,0.418391)(0.819298,0.415485)(0.869988,0.42019)
+ (0.840235,0.422779)(0.811811,0.424741)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](0.996875,0.404353)(0.99567,0.382977)
+ (1.04025,0.371574)(1.08409,0.360109)(1.06103,0.395505)
+ (1.02913,0.399802)(0.996875,0.404353)
+\psset{fillcolor=cmy_7a7aff}%
+\psset{linecolor=rgb_1a1a84}%
+\pspolygon[fillstyle=solid](1.31393,0.130943)(1.36413,0.0350099)
+ (1.43413,-0.0414045)(1.49747,-0.0982892)(1.43923,0.040527)
+ (1.3792,0.0793428)(1.31393,0.130943)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.869988,0.42019)(0.819298,0.415485)
+ (0.862077,0.410271)(0.906078,0.402876)(0.932427,0.413148)
+ (0.900811,0.41696)(0.869988,0.42019)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](0.932427,0.413148)(0.906078,0.402876)
+ (0.950781,0.393616)(0.99567,0.382977)(0.996875,0.404353)
+ (0.964546,0.408882)(0.932427,0.413148)
+\psset{fillcolor=cmy_7070ff}%
+\psset{linecolor=rgb_1c1c8e}%
+\pspolygon[fillstyle=solid](1.21527,0.281861)(1.26407,0.212769)
+ (1.32218,0.181056)(1.3764,0.157338)(1.31112,0.252497)
+ (1.26458,0.264805)(1.21527,0.281861)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](1.26407,0.212769)(1.31393,0.130943)
+ (1.3792,0.0793428)(1.43923,0.040527)(1.3764,0.157338)
+ (1.32218,0.181056)(1.26407,0.212769)
+\psset{fillcolor=cmy_7777ff}%
+\psset{linecolor=rgb_1b1b87}%
+\pspolygon[fillstyle=solid](1.08409,0.360109)(1.10888,0.325677)
+ (1.1633,0.302583)(1.21527,0.281861)(1.16806,0.339925)
+ (1.1268,0.349318)(1.08409,0.360109)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.669551,0.414914)(0.571331,0.414834)
+ (0.612735,0.425841)(0.658661,0.43323)(0.739356,0.419062)
+ (0.703026,0.417762)(0.669551,0.414914)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](0.502743,0.387128)(0.38701,0.370633)
+ (0.42117,0.401992)(0.462221,0.431813)(0.571331,0.414834)
+ (0.53466,0.401467)(0.502743,0.387128)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.99567,0.382977)(0.994341,0.37309)
+ (1.05238,0.34969)(1.10888,0.325677)(1.08409,0.360109)
+ (1.04025,0.371574)(0.99567,0.382977)
+\psset{fillcolor=cmy_7d7dff}%
+\psset{linecolor=rgb_191981}%
+\pspolygon[fillstyle=solid](0.739356,0.419062)(0.658661,0.43323)
+ (0.708693,0.435991)(0.762219,0.433471)(0.819298,0.415485)
+ (0.778241,0.418391)(0.739356,0.419062)
+\pspolygon[fillstyle=solid](1.10888,0.325677)(1.13571,0.293061)
+ (1.20191,0.250812)(1.26407,0.212769)(1.21527,0.281861)
+ (1.1633,0.302583)(1.10888,0.325677)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](0.906078,0.402876)(0.87651,0.412187)
+ (0.935442,0.394373)(0.994341,0.37309)(0.99567,0.382977)
+ (0.950781,0.393616)(0.906078,0.402876)
+\psset{fillcolor=cmy_7e7eff}%
+\psset{linecolor=rgb_191980}%
+\pspolygon[fillstyle=solid](0.819298,0.415485)(0.762219,0.433471)
+ (0.818456,0.425453)(0.87651,0.412187)(0.906078,0.402876)
+ (0.862077,0.410271)(0.819298,0.415485)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](0.38701,0.370633)(0.263419,0.358433)
+ (0.295756,0.416063)(0.337777,0.472291)(0.462221,0.431813)
+ (0.42117,0.401992)(0.38701,0.370633)
+\psset{fillcolor=cmy_7272ff}%
+\psset{linecolor=rgb_1c1c8c}%
+\pspolygon[fillstyle=solid](0.571331,0.414834)(0.462221,0.431813)
+ (0.51047,0.457371)(0.565855,0.476055)(0.658661,0.43323)
+ (0.612735,0.425841)(0.571331,0.414834)
+\psset{fillcolor=cmy_7f7fff}%
+\psset{linecolor=rgb_19197f}%
+\pspolygon[fillstyle=solid](1.13571,0.293061)(1.16504,0.263219)
+ (1.2427,0.193231)(1.31393,0.130943)(1.26407,0.212769)
+ (1.20191,0.250812)(1.13571,0.293061)
+\pspolygon[fillstyle=solid](0.994341,0.37309)(0.99284,0.379708)
+ (1.0658,0.336973)(1.13571,0.293061)(1.10888,0.325677)
+ (1.05238,0.34969)(0.994341,0.37309)
+\pspolygon[fillstyle=solid](1.16504,0.263219)(1.19745,0.237271)
+ (1.28572,0.129037)(1.36413,0.0350099)(1.31393,0.130943)
+ (1.2427,0.193231)(1.16504,0.263219)
+\psset{fillcolor=cmy_7272ff}%
+\psset{linecolor=rgb_1c1c8c}%
+\pspolygon[fillstyle=solid](0.658661,0.43323)(0.565855,0.476055)
+ (0.62787,0.485674)(0.695551,0.484744)(0.762219,0.433471)
+ (0.708693,0.435991)(0.658661,0.43323)
+\psset{fillcolor=cmy_5d5dff}%
+\psset{linecolor=rgb_2020a1}%
+\pspolygon[fillstyle=solid](0.263419,0.358433)(0.130252,0.351753)
+ (0.154241,0.448121)(0.191195,0.545437)(0.337777,0.472291)
+ (0.295756,0.416063)(0.263419,0.358433)
+\psset{fillcolor=cmy_7b7bff}%
+\psset{linecolor=rgb_1a1a83}%
+\pspolygon[fillstyle=solid](0.87651,0.412187)(0.842212,0.450088)
+ (0.917852,0.418332)(0.99284,0.379708)(0.994341,0.37309)
+ (0.935442,0.394373)(0.87651,0.412187)
+\psset{fillcolor=cmy_7676ff}%
+\psset{linecolor=rgb_1b1b88}%
+\pspolygon[fillstyle=solid](0.762219,0.433471)(0.695551,0.484744)
+ (0.767541,0.472718)(0.842212,0.450088)(0.87651,0.412187)
+ (0.818456,0.425453)(0.762219,0.433471)
+\psset{fillcolor=cmy_6262ff}%
+\psset{linecolor=rgb_1f1f9c}%
+\pspolygon[fillstyle=solid](0.462221,0.431813)(0.337777,0.472291)
+ (0.390602,0.522128)(0.454699,0.560441)(0.565855,0.476055)
+ (0.51047,0.457371)(0.462221,0.431813)
+\psset{fillcolor=cmy_7c7cff}%
+\psset{linecolor=rgb_1a1a82}%
+\pspolygon[fillstyle=solid](0.99284,0.379708)(0.991097,0.4096)
+ (1.08095,0.336955)(1.16504,0.263219)(1.13571,0.293061)
+ (1.0658,0.336973)(0.99284,0.379708)
+\psset{fillcolor=cmy_6262ff}%
+\psset{linecolor=rgb_1f1f9c}%
+\pspolygon[fillstyle=solid](0.565855,0.476055)(0.454699,0.560441)
+ (0.52964,0.582636)(0.613978,0.585437)(0.695551,0.484744)
+ (0.62787,0.485674)(0.565855,0.476055)
+\psset{fillcolor=cmy_7474ff}%
+\psset{linecolor=rgb_1b1b8a}%
+\pspolygon[fillstyle=solid](0.842212,0.450088)(0.800716,0.529938)
+ (0.896933,0.475736)(0.991097,0.4096)(0.99284,0.379708)
+ (0.917852,0.418332)(0.842212,0.450088)
+\psset{fillcolor=cmy_6a6aff}%
+\psset{linecolor=rgb_1d1d94}%
+\pspolygon[fillstyle=solid](0.695551,0.484744)(0.613978,0.585437)
+ (0.705338,0.567542)(0.800716,0.529938)(0.842212,0.450088)
+ (0.767541,0.472718)(0.695551,0.484744)
+\psset{fillcolor=cmy_7878ff}%
+\psset{linecolor=rgb_1a1a86}%
+\pspolygon[fillstyle=solid](0.991097,0.4096)(0.989001,0.47266)
+ (1.09845,0.354344)(1.19745,0.237271)(1.16504,0.263219)
+ (1.08095,0.336955)(0.991097,0.4096)
+\psset{fillcolor=cmy_4f4fff}%
+\psset{linecolor=rgb_2323af}%
+\pspolygon[fillstyle=solid](0.337777,0.472291)(0.191195,0.545437)
+ (0.244003,0.635089)(0.314618,0.707241)(0.454699,0.560441)
+ (0.390602,0.522128)(0.337777,0.472291)
+\psset{fillcolor=cmy_6b6bff}%
+\psset{linecolor=rgb_1d1d93}%
+\pspolygon[fillstyle=solid](0.800716,0.529938)(0.747762,0.67368)
+ (0.870898,0.582631)(0.989001,0.47266)(0.991097,0.4096)
+ (0.896933,0.475736)(0.800716,0.529938)
+\psset{fillcolor=cmy_4f4fff}%
+\psset{linecolor=rgb_2323af}%
+\pspolygon[fillstyle=solid](0.454699,0.560441)(0.314618,0.707241)
+ (0.403301,0.752297)(0.50809,0.762937)(0.613978,0.585437)
+ (0.52964,0.582636)(0.454699,0.560441)
+\psset{fillcolor=cmy_5c5cff}%
+\psset{linecolor=rgb_2020a2}%
+\pspolygon[fillstyle=solid](0.613978,0.585437)(0.50809,0.762937)
+ (0.624809,0.736041)(0.747762,0.67368)(0.800716,0.529938)
+ (0.705338,0.567542)(0.613978,0.585437)
+\end{pspicture}%
diff --git a/graphics/epix/doc/plotting2.xp b/graphics/epix/doc/plotting2.xp
new file mode 100644
index 0000000000..2a0ed661e5
--- /dev/null
+++ b/graphics/epix/doc/plotting2.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+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();
+
+ domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(8,80));
+
+ camera.at(3,1,2); // set the viewpoint
+
+ arrow(P(0,0,0), P(1.25,0,0));
+ arrow(P(0,0,0), P(0,1.25,0));
+
+ plain(Blue(1.2));
+ fill(Yellow()); // shade
+ surface(f, R);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/doc/plotting3.eepic b/graphics/epix/doc/plotting3.eepic
new file mode 100644
index 0000000000..d61bee76c4
--- /dev/null
+++ b/graphics/epix/doc/plotting3.eepic
@@ -0,0 +1,146 @@
+%% Generated from plotting3.xp on Tue Sep 25 18:08:09 EDT 2007 by
+%% ePiX-1.2.0
+%%
+%% Cartesian bounding box: [0,18.8496] x [-1,1]
+%% Actual size: 5 x 1in
+%% Figure offset: left by 0in, down by 0in
+%%
+%% usepackages epic,eepic,xcolor
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}%
+\xdefinecolor{rgb_0000ff}{rgb}{0,0,1}%
+\xdefinecolor{rgb_00ff00}{rgb}{0,1,0}%
+\xdefinecolor{rgb_3f00bf}{rgb}{0.247059,0,0.74902}%
+\xdefinecolor{rgb_7f007f}{rgb}{0.498039,0,0.498039}%
+\xdefinecolor{rgb_bf003f}{rgb}{0.74902,0,0.247059}%
+\setlength{\unitlength}{1in}%
+\begin{picture}(5,1)(0,0)%
+\path(0,0.5)(2.5,0.5)(5,0.5)
+\put(0,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}}
+\put(1.25,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}}
+\put(2.5,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}}
+\put(3.75,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}}
+\put(5,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}}
+\path(0,0)(0,0.5)(0,1)
+\put(0,0){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{6pt}{0.5pt}$}}}
+\put(0,1){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{6pt}{0.5pt}$}}}
+\allinethickness{0.8pt}%
+\color{rgb_00ff00}%
+\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508)
+ (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553)
+ (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528)
+ (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528)
+ (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553)
+ (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508)
+ (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783)
+ (0.916667,0.345492)(0.958333,0.273005)(1,0.206107)
+ (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967)
+ (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583)
+ (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915)
+ (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005)
+ (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578217)
+ (1.75,0.654508)(1.79167,0.726995)(1.83333,0.793893)(1.875,0.853553)
+ (1.91667,0.904508)(1.95833,0.945503)(2,0.975528)(2.04167,0.993844)
+ (2.08333,1)(2.125,0.993844)(2.16667,0.975528)(2.20833,0.945503)
+ (2.25,0.904508)(2.29167,0.853553)(2.33333,0.793893)(2.375,0.726995)
+ (2.41667,0.654508)(2.45833,0.578217)(2.5,0.5)(2.54167,0.421783)
+ (2.58333,0.345492)(2.625,0.273005)(2.66667,0.206107)
+ (2.70833,0.146447)(2.75,0.0954915)(2.79167,0.0544967)
+ (2.83333,0.0244717)(2.875,0.00615583)(2.91667,0)
+ (2.95833,0.00615583)(3,0.0244717)(3.04167,0.0544967)
+ (3.08333,0.0954915)(3.125,0.146447)(3.16667,0.206107)
+ (3.20833,0.273005)(3.25,0.345492)(3.29167,0.421783)(3.33333,0.5)
+ (3.375,0.578217)(3.41667,0.654508)(3.45833,0.726995)(3.5,0.793893)
+ (3.54167,0.853553)(3.58333,0.904508)(3.625,0.945503)
+ (3.66667,0.975528)(3.70833,0.993844)(3.75,1)(3.79167,0.993844)
+ (3.83333,0.975528)(3.875,0.945503)(3.91667,0.904508)
+ (3.95833,0.853553)(4,0.793893)(4.04167,0.726995)(4.08333,0.654508)
+ (4.125,0.578217)(4.16667,0.5)(4.20833,0.421783)(4.25,0.345492)
+ (4.29167,0.273005)(4.33333,0.206107)(4.375,0.146447)
+ (4.41667,0.0954915)(4.45833,0.0544967)(4.5,0.0244717)
+ (4.54167,0.00615583)(4.58333,0)(4.625,0.00615583)
+ (4.66667,0.0244717)(4.70833,0.0544967)(4.75,0.0954915)
+ (4.79167,0.146447)(4.83333,0.206107)(4.875,0.273005)
+ (4.91667,0.345492)(4.95833,0.421783)(5,0.5)
+\color{rgb_bf003f}%
+\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508)
+ (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553)
+ (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528)
+ (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528)
+ (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553)
+ (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508)
+ (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783)
+ (0.916667,0.345492)(0.958333,0.273005)(1,0.206107)
+ (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967)
+ (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583)
+ (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915)
+ (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005)
+ (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578217)
+ (1.75,0.654508)(1.79167,0.726995)(1.83333,0.793893)(1.875,0.853553)
+ (1.91667,0.904508)(1.95833,0.945503)(2,0.975528)(2.04167,0.993844)
+ (2.08333,1)(2.125,0.993844)(2.16667,0.975528)(2.20833,0.945503)
+ (2.25,0.904508)(2.29167,0.853553)(2.33333,0.793893)(2.375,0.726995)
+ (2.41667,0.654508)(2.45833,0.578217)(2.5,0.5)(2.54167,0.421783)
+ (2.58333,0.345491)(2.625,0.273005)(2.66667,0.206107)
+ (2.70833,0.146446)(2.75,0.0954902)(2.79167,0.0544945)
+ (2.83333,0.0244679)(2.875,0.00614921)(2.91667,0)
+ (2.95833,0.00613686)(3,0.02444)(3.04167,0.054444)
+ (3.08333,0.0954044)(3.125,0.146304)(3.16667,0.205875)
+ (3.20833,0.272628)(3.25,0.344886)(3.29167,0.420815)
+ (3.33333,0.498463)(3.375,0.57579)(3.41667,0.650696)
+ (3.45833,0.721039)(3.5,0.78464)(3.54167,0.839253)(3.58333,0.882522)
+ (3.625,0.911868)(3.66667,0.924325)(3.70833,0.916271)(3.75,0.883026)
+ (3.79167,0.818266)(3.83333,0.713166)(3.875,0.555181)
+ (3.91667,0.326308)(3.95833,0.000641819)(3.95839,0)
+\color{rgb_7f007f}%
+\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508)
+ (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553)
+ (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528)
+ (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528)
+ (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553)
+ (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508)
+ (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783)
+ (0.916667,0.345492)(0.958333,0.273005)(1,0.206107)
+ (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967)
+ (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583)
+ (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915)
+ (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005)
+ (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578218)
+ (1.75,0.654509)(1.79167,0.726996)(1.83333,0.793895)(1.875,0.853557)
+ (1.91667,0.904515)(1.95833,0.945515)(2,0.975549)(2.04167,0.993881)
+ (2.08291,1)
+\path(2.08376,1)(2.125,0.993951)(2.16667,0.975708)
+ (2.20833,0.945803)(2.25,0.905003)(2.29167,0.854363)
+ (2.33333,0.795206)(2.375,0.729106)(2.41667,0.657874)
+ (2.45833,0.583539)(2.5,0.50835)(2.54167,0.434785)(2.58333,0.365591)
+ (2.625,0.303858)(2.66667,0.253144)(2.70833,0.21768)(2.75,0.202677)
+ (2.79167,0.214776)(2.83333,0.262697)(2.875,0.358157)
+ (2.91667,0.51715)(2.95833,0.761732)(2.98586,1)
+\color{rgb_3f00bf}%
+\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508)
+ (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553)
+ (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528)
+ (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528)
+ (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553)
+ (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508)
+ (0.791667,0.578217)(0.833333,0.5)(0.875,0.421782)(0.916667,0.34549)
+ (0.958333,0.273001)(1,0.206099)(1.04167,0.14643)(1.08333,0.0954587)
+ (1.125,0.0544347)(1.16667,0.0243571)(1.20833,0.00594841)
+ (1.24757,0)
+\path(1.2526,0)(1.29167,0.00551665)(1.33333,0.02338)
+ (1.375,0.0526628)(1.41667,0.0924591)(1.45833,0.141506)
+ (1.5,0.198171)(1.54167,0.260422)(1.58333,0.325792)(1.625,0.391305)
+ (1.66667,0.453377)(1.70833,0.507659)(1.75,0.548813)
+ (1.79167,0.570203)(1.83333,0.563454)(1.875,0.517876)
+ (1.91667,0.419672)(1.95833,0.250906)(1.99812,0)
+\color{rgb_0000ff}%
+\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654509)
+ (0.125,0.726996)(0.166667,0.793896)(0.208333,0.853572)
+ (0.25,0.904573)(0.291667,0.945693)(0.333333,0.976009)
+ (0.375,0.994933)(0.403805,1)
+\path(0.439996,1)(0.458333,0.998222)
+ (0.5,0.983515)(0.541667,0.959373)(0.583333,0.927598)
+ (0.625,0.890616)(0.666667,0.851521)(0.708333,0.814127)
+ (0.75,0.783009)(0.791667,0.763557)(0.833333,0.762022)
+ (0.875,0.785563)(0.916667,0.842295)(0.958333,0.941339)(0.974464,1)
+\end{picture}%
diff --git a/graphics/epix/doc/plotting3.xp b/graphics/epix/doc/plotting3.xp
new file mode 100644
index 0000000000..e5d1088978
--- /dev/null
+++ b/graphics/epix/doc/plotting3.xp
@@ -0,0 +1,43 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P sin_n(double x, double n) // Taylor polynomial of sin x
+{
+ const int N((int) floor(n)); // convert y to an index bound
+ const double sqx(-pow(x, 2)); // store -x^2 for efficiency
+ double val(x), summand(x); // places to store results of evaluation
+
+ // step through odd numbers from 1 to 2N+1
+ 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();
+
+ set_crop();
+ h_axis(4);
+ v_axis(1);
+
+ bold();
+ green();
+ plot(Sin, 0, xmax(), 120);
+
+ domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40));
+ for (int i=3; 0 <= i; --i)
+ {
+ rgb(0.25*i, 0, 1-0.25*i);
+ plot(sin_n, R.slice2(5*i+1));
+ }
+
+ end();
+}
diff --git a/graphics/epix/doc/scaling.eepic b/graphics/epix/doc/scaling.eepic
new file mode 100644
index 0000000000..0b6231c4ee
--- /dev/null
+++ b/graphics/epix/doc/scaling.eepic
@@ -0,0 +1,56 @@
+%% Generated from scaling.xp on Sat Sep 1 14:17:35 EDT 2007 by
+%% ePiX-1.1.15
+%%
+%% Cartesian bounding box: [0,4] x [0,1]
+%% Actual size: 4 x 0.75in
+%% Figure offset: left by 0in, down by 0in
+%%
+%% usepackages epic,eepic,xcolor
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}%
+\setlength{\unitlength}{1in}%
+\begin{picture}(4,0.75)(0,0)%
+\path(1.75,0.375)(2.75,0.375)
+\path(2.63584,0.359433)(2.66438,0.359433)
+\path(2.63584,0.364622)(2.69292,0.364622)
+\path(2.63584,0.369811)(2.72146,0.369811)
+\path(2.63584,0.375)(2.75,0.375)
+\path(2.63584,0.380189)(2.72146,0.380189)
+\path(2.63584,0.385378)(2.69292,0.385378)
+\path(2.63584,0.390567)(2.66438,0.390567)
+\path(2.74456,0.374012)(2.74456,0.375988)
+\path(2.73913,0.373023)(2.73913,0.376977)
+\path(2.73369,0.372035)(2.73369,0.377965)
+\path(2.72826,0.371047)(2.72826,0.378953)
+\path(2.72282,0.370058)(2.72282,0.379942)
+\path(2.71738,0.36907)(2.71738,0.38093)
+\path(2.71195,0.368081)(2.71195,0.381919)
+\path(2.70651,0.367093)(2.70651,0.382907)
+\path(2.70108,0.366105)(2.70108,0.383895)
+\path(2.69564,0.365116)(2.69564,0.384884)
+\path(2.6902,0.364128)(2.6902,0.385872)
+\path(2.68477,0.36314)(2.68477,0.38686)
+\path(2.67933,0.362151)(2.67933,0.387849)
+\path(2.6739,0.361163)(2.6739,0.388837)
+\path(2.66846,0.360175)(2.66846,0.389825)
+\path(2.66302,0.359186)(2.66302,0.390814)
+\path(2.65759,0.358198)(2.65759,0.391802)
+\path(2.65215,0.35721)(2.65215,0.39279)
+\path(2.64672,0.356221)(2.64672,0.393779)
+\path(2.64128,0.355233)(2.64128,0.394767)
+\path(2.63584,0.354244)(2.63584,0.395756)
+\path(2.63584,0.375)(2.63584,0.354244)(2.75,0.375)
+ (2.63584,0.395756)(2.63584,0.375)
+\put(0.027674,0.121424){\makebox(0,0)[bl]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(x_\mathrm{min},y_\mathrm{min})$}}}}
+\put(0,0.09375){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}}
+\put(1.47233,0.722326){\makebox(0,0)[tr]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(x_\mathrm{max},y_\mathrm{max})$}}}}
+\put(1.5,0.75){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}}
+\put(0.75,0.038402){\makebox(0,0)[t]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize Canvas (virtual)}}}}
+\path(1.5,0.09375)(1.5,0.75)(0,0.75)(0,0.09375)(1.5,0.09375)
+\put(3.02767,0.121424){\makebox(0,0)[bl]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(0,0)$}}}}
+\put(3,0.09375){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}}
+\put(3.97233,0.628576){\makebox(0,0)[tr]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(h_\mathrm{size}, v_\mathrm{size})$}}}}
+\put(4,0.65625){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}}
+\put(3.5,0.038402){\makebox(0,0)[t]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize Page (actual)}}}}
+\path(4,0.09375)(4,0.65625)(3,0.65625)(3,0.09375)(4,0.09375)
+\end{picture}%
diff --git a/graphics/epix/doc/scaling.xp b/graphics/epix/doc/scaling.xp
new file mode 100644
index 0000000000..7d243caabc
--- /dev/null
+++ b/graphics/epix/doc/scaling.xp
@@ -0,0 +1,37 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(0,0), P(4,1), "4x0.75in");
+
+ begin();
+
+ font_size("scriptsize");
+
+ screen canv(P(0,0), P(1,1));
+ activate(canv);
+
+ border();
+ ddot(canv.bl(), P(2,2), "$(x_\\mathrm{min},y_\\mathrm{min})$", tr);
+ ddot(canv.tr(), P(-2,-2), "$(x_\\mathrm{max},y_\\mathrm{max})$", bl);
+ label(canv.b(), P(0,-4), "Canvas (virtual)", b);
+ deactivate(canv);
+
+ screen pg(P(0,0), P(1,1));
+ activate(pg);
+
+ border();
+ ddot(pg.bl(), P(2,2), "$(0,0)$", tr);
+ ddot(pg.tr(), P(-2,-2), "$(h_\\mathrm{size}, v_\\mathrm{size})$", bl);
+ label(pg.b(), P(0,-4), "Page (actual)", b);
+ deactivate(pg);
+
+ arrow(P(1.75, 0.5), P(2.75,0.5));
+
+ inset(canv, P(0,0.125), P(1.5, 1));
+ inset(pg, P(3,0.125), P(4,0.875));
+
+ end();
+}
diff --git a/graphics/epix/doc/sgn.eepic b/graphics/epix/doc/sgn.eepic
new file mode 100644
index 0000000000..0aafc5d5af
--- /dev/null
+++ b/graphics/epix/doc/sgn.eepic
@@ -0,0 +1,30 @@
+%% Generated from sgn.xp on Tue Jan 4 15:32:30 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 1.5in x 0.75in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(1.5,0.75)(-0,-0)
+%% ---
+\path(0,0.375)(1.5,0.375)
+\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+%% ---
+\path(0.75,0)(0.75,0.75)
+\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+%% ---
+\thicklines
+\path(0,0)(0.75,0)
+\path(1.5,0.75)(0.75,0.75)
+\thinlines
+\put(0.75,0.375){\makebox(0,0)[c]{{\circle*{0.041511}}}}
+\whiten\put(0.75,0){\makebox(0,0)[c]{{\circle{0.041511}}}}
+\whiten\put(0.75,0.75){\makebox(0,0)[c]{{\circle{0.041511}}}}
+\put(0.75,-0.055348){\makebox(0,0)[t]{\code{sgn}}}
+\end{picture}
diff --git a/graphics/epix/doc/sgn.xp b/graphics/epix/doc/sgn.xp
new file mode 100644
index 0000000000..5296973ba4
--- /dev/null
+++ b/graphics/epix/doc/sgn.xp
@@ -0,0 +1,28 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ bounding_box(P(-2,-1),P(2,1));
+ unitlength("1in");
+ picture(1.5,0.75);
+
+ begin();
+
+ h_axis(4);
+ v_axis(1);
+
+ bold();
+ line(P(x_min,-1), P(0,-1));
+ line(P(x_max, 1), P(0, 1));
+
+ plain();
+ dot(P(0,0));
+ circ(P(0,-1));
+ circ(P(0,1));
+
+ label(P(0,y_min), P(0,-4), "\\code{sgn}", b);
+
+ end();
+}
diff --git a/graphics/epix/doc/sinx.eepic b/graphics/epix/doc/sinx.eepic
new file mode 100644
index 0000000000..c62bf19e00
--- /dev/null
+++ b/graphics/epix/doc/sinx.eepic
@@ -0,0 +1,40 @@
+%% Generated from sinx.xp on Tue Jan 4 15:32:32 EST 2005 by
+%% ePiX-1.0.3
+%%
+%% Cartesian bounding box: [-2,2] x [-1,1]
+%% Actual size: 1.5in x 0.75in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(1.5,0.75)(-0,-0)
+%% ---
+\path(0,0.375)(1.5,0.375)
+\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}}
+%% ---
+\path(0.75,0)(0.75,0.75)
+\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}}
+%% ---
+\thicklines
+\path(0,0.375)(0.025,0.362444)(0.05,0.351239)(0.075,0.343466)(0.1,0.340756)
+ (0.125,0.343988)(0.15,0.353074)(0.175,0.366907)(0.2,0.383461)
+ (0.225,0.400058)(0.25,0.413765)(0.275,0.42186)(0.3,0.422302)
+ (0.325,0.414135)(0.35,0.397758)(0.375,0.375)(0.4,0.348991)
+ (0.425,0.323823)(0.45,0.304047)(0.475,0.29406)(0.5,0.297469)
+ (0.525,0.316532)(0.55,0.351733)(0.575,0.40159)(0.6,0.462702)
+ (0.625,0.530061)(0.65,0.597586)(0.675,0.65881)(0.7,0.707649)
+ (0.725,0.73913)(0.75,0.75)(0.775,0.73913)(0.8,0.707649)(0.825,0.65881)
+ (0.85,0.597586)(0.875,0.530061)(0.9,0.462702)(0.925,0.40159)
+ (0.95,0.351733)(0.975,0.316532)(1,0.297469)(1.025,0.29406)(1.05,0.304047)
+ (1.075,0.323823)(1.1,0.348991)(1.125,0.375)(1.15,0.397758)
+ (1.175,0.414135)(1.2,0.422302)(1.225,0.42186)(1.25,0.413765)
+ (1.275,0.400058)(1.3,0.383461)(1.325,0.366907)(1.35,0.353074)
+ (1.375,0.343988)(1.4,0.340756)(1.425,0.343466)(1.45,0.351239)
+ (1.475,0.362444)(1.5,0.375)
+\path(1.5,0.375)
+\put(0.75,-0.055348){\makebox(0,0)[t]{\code{sinx}}}
+\end{picture}
diff --git a/graphics/epix/doc/sinx.xp b/graphics/epix/doc/sinx.xp
new file mode 100644
index 0000000000..62c08bbc48
--- /dev/null
+++ b/graphics/epix/doc/sinx.xp
@@ -0,0 +1,23 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ bounding_box(P(-2,-1),P(2,1));
+ unitlength("1in");
+ picture(1.5,0.75);
+
+ begin();
+ revolutions();
+
+ h_axis(4);
+ v_axis(1);
+
+ bold();
+ plot(sinx, x_min, x_max, 60);
+
+ label(P(0,y_min), P(0,-4), "\\code{sinx}", b);
+
+ end();
+}
diff --git a/graphics/epix/doc/slices.eepic b/graphics/epix/doc/slices.eepic
new file mode 100644
index 0000000000..4aebe69de4
--- /dev/null
+++ b/graphics/epix/doc/slices.eepic
@@ -0,0 +1,45 @@
+%% Generated from slices.xp on Sun Dec 31 13:11:11 EST 2006 by
+%% ePiX-1.0.22
+%%
+%% Cartesian bounding box: [0,7] x [0,2]
+%% Actual size: 5in x 0.75in
+%% Figure offset: right by 0in, up by 0in
+%%
+\setlength{\unitlength}{1in}
+\begin{picture}(5,0.75)(-0,-0)
+%% ---
+\thicklines
+\path(0,0)(0,0.75)
+\path(0.178571,0)(0.178571,0.75)
+\path(0.357143,0)(0.357143,0.75)
+\path(0.535714,0)(0.535714,0.75)
+\path(0.714286,0)(0.714286,0.75)
+\path(0.892857,0)(0.892857,0.75)
+\path(1.07143,0)(1.07143,0.75)
+\path(1.25,0)(1.25,0.75)
+\path(1.42857,0)(1.42857,0.75)
+\path(0,0)(1.42857,0)
+\path(0,0.107143)(1.42857,0.107143)
+\path(0,0.214286)(1.42857,0.214286)
+\path(0,0.321429)(1.42857,0.321429)
+\path(0,0.428571)(1.42857,0.428571)
+\path(0,0.535714)(1.42857,0.535714)
+\path(0,0.642857)(1.42857,0.642857)
+\path(0,0.75)(1.42857,0.75)
+\put(0.714286,-0.055348){\makebox(0,0)[t]{\code{R}}}
+\path(1.78571,0)(1.78571,0.75)
+\path(1.96429,0)(1.96429,0.75)
+\path(2.14286,0)(2.14286,0.75)
+\path(2.32143,0)(2.32143,0.75)
+\path(2.5,0)(2.5,0.75)
+\path(2.67857,0)(2.67857,0.75)
+\path(2.85714,0)(2.85714,0.75)
+\path(3.03571,0)(3.03571,0.75)
+\path(3.21429,0)(3.21429,0.75)
+\put(2.5,-0.055348){\makebox(0,0)[t]{\code{R.slices1()}}}
+\path(3.57143,0)(5,0)
+\path(3.57143,0.25)(5,0.25)
+\path(3.57143,0.5)(5,0.5)
+\path(3.57143,0.75)(5,0.75)
+\put(4.28571,-0.055348){\makebox(0,0)[t]{\code{R.slices2(3)}}}
+\end{picture}
diff --git a/graphics/epix/doc/slices.xp b/graphics/epix/doc/slices.xp
new file mode 100644
index 0000000000..c67dddf876
--- /dev/null
+++ b/graphics/epix/doc/slices.xp
@@ -0,0 +1,39 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+void my_grid(const P& loc, int N1, int N2, std::string lab)
+{
+ if (0 < N1)
+ {
+ const double dx(1.0/N1);
+ for (int i=-N1; i<= N1; ++i)
+ line(loc+P(i*dx,0), loc+P(i*dx,2));
+ }
+
+ if (0 < N2)
+ {
+ const double dy(1.0/N2);
+ for (int i=0; i<= N2; ++i)
+ line(loc+P(-1,2*i*dy), loc+P(1,2*i*dy));
+ }
+
+ label(loc, P(0,-4), "\\code{"+lab+"}", b);
+}
+
+int main()
+{
+ bounding_box(P(0,0),P(7,2));
+ unitlength("1in");
+ picture(5,0.75);
+
+ begin();
+
+ bold();
+
+ my_grid(P(1,0), 4, 7, "R");
+ my_grid(P(3.5,0), 4, 0, "R.slices1()");
+ my_grid(P(6,0), 0, 3, "R.slices2(3)");
+
+ end();
+}
diff --git a/graphics/epix/domain.cc b/graphics/epix/domain.cc
new file mode 100644
index 0000000000..cbb86a4d42
--- /dev/null
+++ b/graphics/epix/domain.cc
@@ -0,0 +1,370 @@
+/*
+ * domain.cc -- ePiX domain slicing operations
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August09, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+#include <list>
+#include <iostream>
+
+#include "constants.h"
+#include "triples.h"
+#include "functions.h"
+
+#include "domain.h"
+
+namespace ePiX {
+
+ typedef std::list<domain>::const_iterator dolci;
+ const double EPS(EPIX_EPSILON);
+
+ mesh::mesh(int n1, int n2, int n3)
+ : n_1((int)max(1, fabs(n1))),
+ n_2((int)max(1, fabs(n2))),
+ n_3((int)max(1, fabs(n3))) { }
+
+ mesh::mesh(int n)
+ : n_1((int)max(1, fabs(n))),
+ n_2((int)max(1, fabs(n))),
+ n_3((int)max(1, fabs(n))) { }
+
+ mesh::mesh() : n_1(1), n_2(1), n_3(1) { }
+
+
+ domain::domain(const P& arg1, const P& arg2, const mesh& c, const mesh& f)
+ : m_corner1(arg1), m_corner2(arg2)
+ {
+ int c1(c.n1()), c2(c.n2()), c3(c.n3());
+ int f1(f.n1()), f2(f.n2()), f3(f.n3());
+
+ if (m_corner1.x1() == m_corner2.x1()) { c1 = f1 = 1; }
+ if (m_corner1.x2() == m_corner2.x2()) { c2 = f2 = 1; }
+ if (m_corner1.x3() == m_corner2.x3()) { c3 = f3 = 1; }
+
+ m_coarse = mesh(c1,c2,c3);
+ m_fine = mesh(f1,f2,f3);
+ }
+
+ domain::domain(const P& arg1, const P& arg2, const mesh& c)
+ : m_corner1(arg1), m_corner2(arg2)
+ {
+ int c1(c.n1()), c2(c.n2()), c3(c.n3());
+
+ if (m_corner1.x1() == m_corner2.x1()) { c1 = 1; }
+ if (m_corner1.x2() == m_corner2.x2()) { c2 = 1; }
+ if (m_corner1.x3() == m_corner2.x3()) { c3 = 1; }
+
+ m_coarse = mesh(c1,c2,c3);
+ m_fine = mesh(c1,c2,c3);
+ }
+
+ // 1-dim'l domain
+ domain::domain(double t_min, double t_max, int num_pts)
+ : m_corner1(t_min), m_corner2(t_max), m_coarse(num_pts), m_fine(num_pts)
+ { }
+
+
+ int domain::dim() const
+ {
+ int D(0);
+ if (fabs(m_corner2.x1() - m_corner1.x1()) > EPIX_EPSILON)
+ ++D;
+ if (fabs(m_corner2.x2() - m_corner1.x2()) > EPIX_EPSILON)
+ ++D;
+ if (fabs(m_corner2.x3() - m_corner1.x3()) > EPIX_EPSILON)
+ ++D;
+
+ return D;
+ }
+
+ double domain::step1() const
+ {
+ return (m_corner2.x1() - m_corner1.x1())/m_coarse.n1();
+ }
+
+ double domain::step2() const
+ {
+ return (m_corner2.x2() - m_corner1.x2())/m_coarse.n2();
+ }
+
+ double domain::step3() const
+ {
+ return (m_corner2.x3() - m_corner1.x3())/m_coarse.n3();
+ }
+
+ double domain::dx1() const
+ {
+ return (m_corner2.x1() - m_corner1.x1())/m_fine.n1();
+ }
+
+ double domain::dx2() const
+ {
+ return (m_corner2.x2() - m_corner1.x2())/m_fine.n2();
+ }
+
+ double domain::dx3() const
+ {
+ return (m_corner2.x3() - m_corner1.x3())/m_fine.n3();
+ }
+
+
+ // resizing attempts to preserve real resolution
+ domain domain::resize1(double a1, double b1) const
+ {
+ P new_corner1(a1, m_corner1.x2(), m_corner1.x3());
+ P new_corner2(b1, m_corner2.x2(), m_corner2.x3());
+
+ // hack to avoid spurious round-down; should never cause round-up
+ double ratio((b1-a1)/(m_corner2.x1()-m_corner1.x1()) + EPS);
+ mesh new_c((int)floor(ratio*m_coarse.n1()), m_coarse.n2(), m_coarse.n3());
+ mesh new_f((int)floor(ratio*m_fine.n1()), m_fine.n2(), m_fine.n3());
+
+ if (step1() == 0)
+ {
+ new_c = mesh(1, m_coarse.n2(), m_coarse.n3());
+ new_f = mesh(1, m_fine.n2(), m_fine.n3());
+ }
+
+ return domain(new_corner1, new_corner2, new_c, new_f);
+ }
+
+ domain domain::resize2(double a2, double b2) const
+ {
+ P new_corner1(m_corner1.x1(), a2, m_corner1.x3());
+ P new_corner2(m_corner2.x1(), b2, m_corner2.x3());
+
+ double ratio((b2-a2)/(m_corner2.x2()-m_corner1.x2()) + EPS);
+ mesh new_c(m_coarse.n1(), (int)floor(ratio*m_coarse.n2()), m_coarse.n3());
+ mesh new_f( m_fine.n1(), (int)floor(ratio*m_fine.n2()), m_fine.n3());
+
+ if (step2() == 0)
+ {
+ new_c = mesh(m_coarse.n1(), 1, m_coarse.n3());
+ new_f = mesh( m_fine.n1(), 1, m_fine.n3());
+ }
+
+ return domain(new_corner1, new_corner2, new_c, new_f);
+ }
+
+ domain domain::resize3(double a3, double b3) const
+ {
+ P new_corner1(m_corner1.x1(), m_corner1.x2(), a3);
+ P new_corner2(m_corner2.x1(), m_corner2.x2(), b3);
+
+ double ratio((b3-a3)/(m_corner2.x3()-m_corner1.x3()) + EPS);
+ mesh new_c(m_coarse.n1(), m_coarse.n2(), (int)floor(ratio*m_coarse.n3()));
+ mesh new_f( m_fine.n1(), m_fine.n2(), (int)floor(ratio*m_fine.n3()));
+
+ if (step3() == 0)
+ {
+ new_c = mesh(m_coarse.n1(), m_coarse.n2(), 1);
+ new_f = mesh( m_fine.n1(), m_fine.n2(), 1);
+ }
+
+ return domain(new_corner1, new_corner2, new_c, new_f);
+ }
+
+
+ // "snip_to" is defined in functions.h and performs the "obvious"
+ // truncation: snip_to(x, a, b) = x, min(a,b), or max(a,b)
+
+ // one slice
+ domain domain::slice1(double a1) const
+ {
+ a1 = snip_to(a1, m_corner1.x1(), m_corner2.x1());
+
+ return domain(P(a1, m_corner1.x2(), m_corner1.x3()),
+ P(a1, m_corner2.x2(), m_corner2.x3()),
+ mesh(1, m_coarse.n2(), m_coarse.n3()),
+ mesh(1, m_fine.n2(), m_fine.n3()));
+ }
+
+ domain domain::slice2(double a2) const
+ {
+ a2 = snip_to(a2, m_corner1.x2(), m_corner2.x2());
+
+ return domain(P(m_corner1.x1(), a2, m_corner1.x3()),
+ P(m_corner2.x1(), a2, m_corner2.x3()),
+ mesh(m_coarse.n1(), 1, m_coarse.n3()),
+ mesh( m_fine.n1(), 1, m_fine.n3()));
+ }
+
+ domain domain::slice3(double a3) const
+ {
+ a3 = snip_to(a3, m_corner1.x3(), m_corner2.x3());
+
+ return domain(P(m_corner1.x1(), m_corner1.x2(), a3),
+ P(m_corner2.x1(), m_corner2.x2(), a3),
+ mesh(m_coarse.n1(), m_coarse.n2(), 1),
+ mesh( m_fine.n1(), m_fine.n2(), 1));
+ }
+
+
+ // coordinate slices
+ std::list<domain> domain::slices1(const unsigned int n) const
+ {
+ unsigned int N(m_coarse.n1());
+ double du(step1());
+
+ if (n > 0)
+ {
+ du *= N*1.0/n;
+ N = n;
+ }
+
+ std::list<domain> val;
+
+ for (unsigned int i=0; i <= N; ++i)
+ val.push_back(slice1(m_corner1.x1() + i*du));
+
+ return val;
+ }
+
+ std::list<domain> domain::slices2(const unsigned int n) const
+ {
+ unsigned int N(m_coarse.n2());
+ double du(step2());
+
+ if (n > 0)
+ {
+ du *= N*1.0/n;
+ N = n;
+ }
+
+ std::list<domain> val;
+
+ for (unsigned int i=0; i <= N; ++i)
+ val.push_back(slice2(m_corner1.x2() + i*du));
+
+ return val;
+ }
+
+ std::list<domain> domain::slices3(const unsigned int n) const
+ {
+ unsigned int N(m_coarse.n3());
+ double du(step3());
+
+ if (n > 0)
+ {
+ du *= N*1.0/n;
+ N = n;
+ }
+
+ std::list<domain> val;
+
+ for (unsigned int i=0; i <= N; ++i)
+ val.push_back(slice3(m_corner1.x3() + i*du));
+
+ return val;
+ }
+
+ P domain::corner1() const
+ {
+ return m_corner1;
+ }
+ P domain::corner2() const
+ {
+ return m_corner2;
+ }
+
+ double domain::corner1_x1() const
+ {
+ return m_corner1.x1();
+ }
+ double domain::corner1_x2() const
+ {
+ return m_corner1.x2();
+ }
+ double domain::corner1_x3() const
+ {
+ return m_corner1.x3();
+ }
+
+ double domain::corner2_x1() const
+ {
+ return m_corner2.x1();
+ }
+ double domain::corner2_x2() const
+ {
+ return m_corner2.x2();
+ }
+ double domain::corner2_x3() const
+ {
+ return m_corner2.x3();
+ }
+
+
+ int domain::coarse_n1() const
+ {
+ return m_coarse.n1();
+ }
+ int domain::coarse_n2() const
+ {
+ return m_coarse.n2();
+ }
+ int domain::coarse_n3() const
+ {
+ return m_coarse.n3();
+ }
+
+ int domain::fine_n1() const
+ {
+ return m_fine.n1();
+ }
+ int domain::fine_n2() const
+ {
+ return m_fine.n2();
+ }
+ int domain::fine_n3() const
+ {
+ return m_fine.n3();
+ }
+
+
+ domain_list::domain_list(std::list<domain> arg)
+ : m_list(arg) { }
+
+ domain_list& domain_list::add(const domain& arg)
+ {
+ m_list.push_back(arg);
+ return *this;
+ }
+
+ domain_list& domain_list::add(const domain_list& arg)
+ {
+ // Less efficient than m_list.splice(m_list.end(), arg), but preserves arg
+ for (dolci p=arg.m_list.begin(); p != arg.m_list.end(); ++p)
+ m_list.push_back(*p);
+
+ return *this;
+ }
+} // end of namespace
diff --git a/graphics/epix/domain.h b/graphics/epix/domain.h
new file mode 100644
index 0000000000..d0b2bf70ea
--- /dev/null
+++ b/graphics/epix/domain.h
@@ -0,0 +1,143 @@
+/*
+ * domain.h -- ePiX mesh and domain classes
+ *
+ * This file is part of ePiX, a preprocessor for creating high-quality
+ * line figures in LaTeX
+ *
+ * Version 1.1.6
+ * Last Change: July 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_DOMAIN
+#define EPIX_DOMAIN
+
+#include <list>
+
+#include "triples.h"
+#include "functions.h"
+
+namespace ePiX {
+
+ class mesh {
+ public:
+ mesh(int n1, int n2, int n3=1);
+ mesh(int n); // mesh(n, n, n);
+ mesh(); // mesh(1, 1, 1);
+
+ int n1() const { return n_1; }
+ int n2() const { return n_2; }
+ int n3() const { return n_3; }
+
+ private:
+ int n_1;
+ int n_2;
+ int n_3;
+ }; // end of class mesh
+
+ // A domain is a gridded coordinate box with specified corners
+ // and coarse/fine meshes, used for plotting. The "coarse" step
+ // sizes are step1, etc., and the "fine" step sizes are dx1, etc.
+ // Steps may be negative.
+ //
+ // A domain may be "sliced" by setting one of its coordinates to
+ // a specified constant.
+ //
+ // Data members are public for convenience; each member ensures
+ // its own well-constructedness.
+ //
+ class domain {
+ public:
+ domain(const P& arg1, const P& arg2, const mesh& c, const mesh& f);
+ domain(const P& arg1, const P& arg2, const mesh& c);
+
+ // 1-dim'l domain
+ domain(double t_min, double t_max, int num_pts);
+
+ int dim() const; // dimension
+
+ // big and small steps
+ double step1() const;
+ double step2() const;
+ double step3() const;
+
+ double dx1() const;
+ double dx2() const;
+ double dx3() const;
+
+ // resizing attempts to preserve real resolution
+ domain resize1(double a1, double b1) const;
+ domain resize2(double a2, double b2) const;
+ domain resize3(double a3, double b3) const;
+
+ // coordinate slices
+ domain slice1(double a1) const;
+ domain slice2(double a2) const;
+ domain slice3(double a3) const;
+
+ // "n=0": use number from coarse mesh
+ std::list<domain> slices1(const unsigned int n=0) const;
+ std::list<domain> slices2(const unsigned int n=0) const;
+ std::list<domain> slices3(const unsigned int n=0) const;
+
+ // state functions for internal use
+ P corner1() const;
+ P corner2() const;
+
+ double corner1_x1() const;
+ double corner1_x2() const;
+ double corner1_x3() const;
+
+ double corner2_x1() const;
+ double corner2_x2() const;
+ double corner2_x3() const;
+
+ int coarse_n1() const;
+ int coarse_n2() const;
+ int coarse_n3() const;
+
+ int fine_n1() const;
+ int fine_n2() const;
+ int fine_n3() const;
+
+ private:
+ P m_corner1;
+ P m_corner2;
+ mesh m_coarse;
+ mesh m_fine;
+ }; // end of class domain
+
+ class domain_list {
+ public:
+ domain_list(std::list<domain>); // implicitly converts "slices" output
+ domain_list& add(const domain&);
+ domain_list& add(const domain_list&);
+
+ std::list<domain> m_list; // public: we're a simple wrapper
+ }; // end of class domain_list
+} // end of namespace
+
+#endif /* EPIX_DOMAIN */
diff --git a/graphics/epix/edge_data.h b/graphics/epix/edge_data.h
new file mode 100644
index 0000000000..60d7a8bf56
--- /dev/null
+++ b/graphics/epix/edge_data.h
@@ -0,0 +1,75 @@
+/*
+ * edge_data.h -- ePiX::edge implementation classes for polyline/polygon
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_EDGE_DATA
+#define EPIX_EDGE_DATA
+#include <algorithm>
+
+#include "triples.h"
+#include "pairs.h"
+
+namespace ePiX {
+
+ // basic edge data: ordered endpoints and visibility flag
+ template<typename T> class edge_data {
+ public:
+ edge_data(const T& fm, const T& to, bool seen)
+ : m_tail(fm), m_head(to), m_seen(seen) { }
+
+ T tail() const { return m_tail; }
+ T head() const { return m_head; }
+ bool is_seen() const { return m_seen; }
+ bool is_null() const { return m_tail == m_head; }
+
+ edge_data& reverse()
+ {
+ std::swap(m_tail, m_head);
+ return *this;
+ }
+
+ double length() const
+ {
+ return norm(m_head - m_tail);
+ }
+
+ void seen(bool S) { m_seen=S; }
+
+ private:
+ T m_tail;
+ T m_head;
+ bool m_seen;
+ };
+
+ typedef edge_data<P> edge3d;
+ typedef edge_data<pair> edge2d;
+} // end of namespace
+
+#endif /* EPIX_EDGE_DATA */
diff --git a/graphics/epix/eepic.cc b/graphics/epix/eepic.cc
new file mode 100644
index 0000000000..eaed35a653
--- /dev/null
+++ b/graphics/epix/eepic.cc
@@ -0,0 +1,297 @@
+/*
+ * eepic.cc -- ePiX's eepic output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <list>
+
+#include <string>
+#include <sstream>
+
+#include <set> // for pallet
+
+#include "constants.h"
+
+#include "functions.h"
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "Color.h"
+
+#include "path_style.h"
+#include "pen_data.h"
+
+#include "hatching.h"
+
+#include "format.h"
+#include "eepic.h"
+
+namespace ePiX {
+
+ // rotate successive hatches this much to avoid parallelity
+ const double d_hatch_theta(111.24612); // ~90*(sqrt(5)-1)
+
+ eepic::eepic()
+ : m_ink(Black()), m_nib(PLAIN_WIDTH), m_hatch(0) { }
+
+ eepic* eepic::clone() const
+ {
+ return new eepic(*this);
+ }
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string eepic::print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fc,
+ const pen_data& line,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ // set angle
+ const double hatch_angle(m_hatch);
+ m_hatch += d_hatch_theta;
+
+ // draw hatch lines separated by pen.width(), actual line width
+ // scaled by density
+ double dens(fc.alpha()); // transparency
+ if (dens < EPIX_EPSILON)
+ return "";
+
+ // else
+ length hatch_width(length(PLAIN_WIDTH).to(len));
+
+ path_state style; // solid
+
+ if (EPIX_EPSILON < dens*hatch_width.magnitude())
+ {
+ // Use fill color, draw thin lines to simulate transparency.
+ // Area covered by double-hatching is (supposed to be) dens.
+ pen_data fill_pen(fc, (1-sqrt(1-dens))*hatch_width);
+
+ // draw hatch-filled edges
+ hatch_data bd1(hatch_angle, hatch_width.magnitude(), edges);
+ for (unsigned int i=0; i < bd1.data().size(); ++i)
+ obuf << format::print_line(bd1.data().at(i), offset,
+ fill_pen, style, std::string(""), len);
+
+ // re-draw hatch lines at right angles...
+ hatch_data bd2(hatch_angle+90, hatch_width.magnitude(), edges);
+ for (unsigned int i=0; i < bd2.data().size(); ++i)
+ obuf << format::print_line(bd2.data().at(i), offset,
+ fill_pen, style, "", len);
+ }
+
+ obuf << set_pen_state(line);
+ obuf << print_paths(edges, offset, "", len);
+
+ return obuf.str();
+ } // end of eepic::print_fill()
+
+
+ // may assume line is visible
+ std::string eepic::print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line,
+ const pen_data& base,
+ const path_state& style,
+ const std::string& len) const
+ {
+ std::string value;
+
+ // draw *solid* base first if necessary
+ if (line.width() < base.width() && !base.color().is_unset())
+ value += format::print_line(edges, offset, base, path_state(), "", len);
+
+ return value += format::print_line(edges, offset, line, style, "", len);
+ }
+
+
+ std::string eepic::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2, double d3) const
+ {
+ return format::xdefinecolor(model, name, d1, d2, d3);
+ }
+
+ std::string eepic::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3, double d4) const
+ {
+ return format::xdefinecolor(model, name, d1, d2, d3, d4);
+ }
+
+ // one-line comment
+ std::string eepic::print_comment(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << "%% " << msg << std::endl;
+
+ return obuf.str();
+ }
+
+ // verbatim string, newline protected
+ std::string eepic::print_verbatim(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << msg << "%" << std::endl;
+
+ return obuf.str();
+ }
+
+ void eepic::reset_state() const
+ {
+ m_ink = Neutral();
+ m_nib = length(0);
+ }
+
+
+ //// private member functions ////
+ std::string eepic::start_picture(const pair& sz, const pair& offset) const
+ {
+ std::stringstream obuf;
+ obuf << "\\begin{picture}"
+ << format::print(sz) << format::print(-offset) << "%" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string eepic::end_picture() const
+ {
+ std::stringstream obuf;
+ obuf << "\\end{picture}%" << std::endl;
+ return obuf.str();
+ }
+
+ std::string eepic::set_unitlength(const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl;
+
+ return obuf.str();
+ }
+
+
+ std::string eepic::usepackages() const
+ {
+ return "usepackages epic,eepic,xcolor";
+ }
+
+ // string argument for passing attributes local to this path/loop
+ std::string eepic::start_open_path(const std::string& attribs) const
+ {
+ return "\\path";
+ }
+
+ std::string eepic::end_open_path(const std::string& attribs) const
+ {
+ std::stringstream obuf;
+ obuf << std::endl;
+ return obuf.str();
+ }
+
+ std::string eepic::start_closed_path(const std::string& attribs) const
+ {
+ return "\\path";
+ }
+
+ std::string eepic::end_closed_path(const std::string& attribs) const
+ {
+ std::stringstream obuf;
+ obuf << std::endl;
+ return obuf.str();
+ }
+
+ std::string eepic::set_fill_state(const Color& col) const // unused
+ {
+ std::stringstream obuf;
+
+ if (m_ink != col)
+ {
+ m_ink = col;
+ obuf << "\\color{" << m_ink.name() << "}%" << std::endl;
+ }
+
+ return obuf.str();
+ }
+
+ std::string eepic::set_pen_state(const pen_data& pen) const
+ {
+ std::stringstream obuf;
+
+ if (m_nib != pen.width())
+ {
+ m_nib = pen.width();
+ obuf << "\\allinethickness{" << m_nib.name() << "}%" << std::endl;
+ }
+
+ if (m_ink != pen.color())
+ {
+ m_ink = pen.color();
+ obuf << "\\color{" << m_ink.name() << "}%" << std::endl;
+ }
+
+ return obuf.str();
+ }
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string eepic::put_box(const pair& loc, const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << "\\put" << print(loc) << "{" << msg << "}" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string eepic::print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+ obuf << "\\put" << print(here)
+ << "{\\color{" << print(color) << "}$";
+
+ if (fill)
+ obuf << "\\allinethickness{" << 0.5*diam << len << "}"
+ << "\\circle{" << 0.5*diam << "}";
+
+ else
+ obuf << "\\circle{" << diam << "}";
+
+ obuf << "$}%" << std::endl;
+
+ return obuf.str();
+ }
+} // end of namespace
diff --git a/graphics/epix/eepic.h b/graphics/epix/eepic.h
new file mode 100644
index 0000000000..08d37e4874
--- /dev/null
+++ b/graphics/epix/eepic.h
@@ -0,0 +1,127 @@
+/*
+ * eepic.h -- ePiX's eepic output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 07, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_EEPIC
+#define EPIX_EEPIC
+
+#include <string>
+#include <list>
+#include <set>
+
+#include "Color.h"
+#include "length.h"
+
+#include "edge_data.h"
+#include "format.h"
+
+namespace ePiX {
+
+ class path_state;
+ class pen_data;
+
+ class eepic : public format {
+ public:
+ eepic();
+
+ eepic* clone() const;
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const;
+
+ // Unfilled region, specified Cartesian edges. Should generally be
+ // trivially implemented using one-pen function (supplied).
+ std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line_pen,
+ const pen_data& base_pen,
+ const path_state& style,
+ const std::string& len) const;
+
+ // Print color declaration strings: model, name, densities
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const;
+
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const;
+
+ // One-line comment
+ std::string print_comment(const std::string&) const;
+
+ // Verbatim output
+ std::string print_verbatim(const std::string&) const;
+
+ void reset_state() const;
+
+ private:
+ mutable Color m_ink;
+ mutable length m_nib;
+ mutable double m_hatch;
+
+ std::string start_picture(const pair&, const pair&) const;
+ std::string end_picture() const;
+
+ std::string set_unitlength(const std::string& len) const;
+
+ std::string usepackages() const;
+
+ // string argument for passing attributes local to this path/loop
+ std::string start_open_path(const std::string&) const;
+ std::string end_open_path(const std::string&) const;
+
+ std::string start_closed_path(const std::string&) const;
+ std::string end_closed_path(const std::string&) const;
+
+ // print declarations to set state of output format
+ std::string set_fill_state(const Color&) const;
+ std::string set_pen_state(const pen_data&) const;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string put_box(const pair&, const std::string&) const;
+
+ std::string print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const;
+ }; // end of class eepic
+} // end of namespace
+
+#endif /* EPIX_EEPIC */
diff --git a/graphics/epix/elaps.1 b/graphics/epix/elaps.1
new file mode 100644
index 0000000000..4430a02037
--- /dev/null
+++ b/graphics/epix/elaps.1
@@ -0,0 +1 @@
+.so man1/epix.1
diff --git a/graphics/epix/elaps.in b/graphics/epix/elaps.in
new file mode 100644
index 0000000000..6e8041f3d3
--- /dev/null
+++ b/graphics/epix/elaps.in
@@ -0,0 +1,485 @@
+#! /bin/bash
+#
+# elaps: Convert an epix file to encapsulated Postscript, i.e. epix2eps
+#
+# Options: --help for usage, --version for version and license
+#
+# Compiler flags may be specified on the command line or in the config
+# file ~/.epixrc. The script attempts to deal intelligently with missing
+# or multiple extensions. If the input file has a recognized extension,
+# there's no issue. If only the root name <infile> is given, the script
+# searches for completions in the order of preference dictated by the
+# variable EPIX_EXTENSIONS. A warning is issued for multiple matches.
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Andrew D. Hwang <For address, do "elaps -V">
+#
+
+. "@pkglibdir@/epix-lib.sh"
+
+EPIX_CONFIG_FILE="$HOME/.epixrc"
+# Search these extensions in order of preference
+ELAPS_EXTENSIONS="eepic xp flx cc c C cpp" # or NULL
+ELAPS_DOT_EXT=".${ELAPS_EXTENSIONS// /|.}" # for usage message
+
+# default options
+ELAPS_PKGS="latexsym,amsmath,rotating"
+declare ELAPS_PSTCOL
+ELAPS_SIZE=12 # figure compiled in [12pt]{article}
+
+ELAPS_PDF="no" # Create PDF file?
+ELAPS_PS="no" # Create PS file instead of EPS?
+
+declare -a EPIX_OPTS
+declare -a DVIPS_OPTS
+
+LATEX_BIN=latex # elaps only uses [huge]latex, not pdflatex or pslatex
+LATEX_INTERACT="scrollmode"
+
+# auxiliary programs
+PS2EPS="ps2epsi"
+
+# internal filenames
+PID=$$
+ELAPS_TEMP_EEPIC="$PROG-$PID".eepic
+ELAPS_TEMP_LATEX="$PROG-$PID".tex
+ELAPS_TEMP_DVI="$PROG-$PID".dvi
+ELAPS_TEMP_PS="$PROG-$PID".ps
+ELAPS_TEMP_EPSI="$PROG-$PID".epsi
+
+# globals to pass tokens
+ELAPS_USER_OUT="no" # user specified output file?
+
+declare -a ELAPS_FILE_LIST
+declare -a TMP_CMD
+
+declare -a TEMPFILES
+trap '[ -n "${TEMPFILES[*]}" ] && rm -f "${TEMPFILES[@]}"' 0 1 2 3 7 10 13 15
+
+TEMPFILES=("$ELAPS_TEMP_EEPIC" "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_DVI" \
+ "$ELAPS_TEMP_PS" "$ELAPS_TEMP_EPSI" )
+
+function elaps_help()
+{
+cat <<"HELP"
+Options:
+ -h, --help
+ Show this message and exit
+
+ -V, --version, --gpl
+ Show version and license
+
+ -v, --verbose
+ Show success/failure messages
+
+ -H, --huge
+ Use hugelatex (if available)
+
+ -i, --interactive
+ Run LaTeX interactively (implies verbose)
+
+ -n, --no-config
+ Ignore $(HOME)/.dvipsrc
+
+ -o, --output
+ Specify output file (ONLY for use with a single input file)
+
+ --pst
+ Write eepic file using PSTricks macros
+
+ --tikz
+ Write eepic file using tikz macros
+
+ --eepic
+ Write eepic file using eepic macros
+
+ -p, --pkg <LaTeX package>
+ Use an additional LaTeX package in the temporary LaTeX file, e.g.
+ "-p floatflt". Multiple packages are specified one per "-p" flag.
+
+ -pdf, --pdf
+ Create PDF file instead of EPS
+
+ -ps, --ps
+ Create standalone PostScript file (overrides --pdf)
+
+ --pstcol
+ Use (obsolete) pstcol package instead of pstricks
+
+ -P<printer>
+ dvips printer options, e.g. "-Pamz", may be given on the command
+ line. They are also read from ~/.dvipsrc if this file exists.
+
+ --size
+ Set default font size: 10, 11, or 12 (default)
+
+ Other options are passed to epix (q.v.).
+
+HELP
+ePiX_bugreport
+
+} # End of elaps_help
+
+# Generate US letter-friendly LaTeX file
+function elaps_make_latex ()
+{
+ ALL_LATEX_PKGS="$ELAPS_PKGS"
+
+# Get LATEX_PKGS from input file
+ ePiX_usepackages $2
+ if [ ! -z "$LATEX_PKGS" ]; then # should always be true...
+ ALL_LATEX_PKGS="$ALL_LATEX_PKGS,$LATEX_PKGS"
+ else # compatibility fallback
+ ALL_LATEX_PKGS="$ALL_LATEX_PKGS,epic,eepic,pstricks"
+ fi
+
+# Clear global
+ unset LATEX_PKGS
+
+# No effect unless file requires pstricks
+ if [ ! -z "$ELAPS_PSTCOL" ]; then
+ ALL_LATEX_PKGS="${ALL_LATEX_PKGS/pstricks/$ELAPS_PSTCOL/}"
+ fi
+
+cat <<LaTeX >> $1
+\documentclass[${ELAPS_SIZE}pt]{article}
+\usepackage{$ALL_LATEX_PKGS}
+\setlength{\textwidth}{7.5in}
+\setlength{\textheight}{9.5in}
+\setlength{\oddsidemargin}{-0.5in}
+\setlength{\topmargin}{0in}
+\pagestyle{empty}
+
+\begin{document}
+\vfil
+\begin{center}
+\input{$2}
+\end{center}
+\vfil
+\end{document}
+
+LaTeX
+} # End of elaps_make_latex
+
+
+function elaps_parse_options ()
+{
+ while [ "$1" != "${1#-}" ]; do
+ case "$1" in
+
+ -h|--help)
+ ePiX_usage elaps $ELAPS_DOT_EXT
+ elaps_help
+ exit 0
+ ;;
+
+ -H|--huge)
+ if [ $(which hugelatex 2> /dev/null) ]; then
+ LATEX_BIN=hugelatex
+ else
+ ePiX_warn " hugelatex not available, ignoring \"$1\" option"
+ fi
+ shift
+ ;;
+
+ -i|--interactive)
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ LATEX_INTERACT="errorstopmode"
+ shift
+ ;;
+
+ -n|--no-config) # do not use ~/.dvipsrc
+ export DVIPSRC="$SYSTEM_DEVNULL"
+ shift
+ ;;
+
+ -o|--output)
+ if [ "$2" = "${2%%.eps}.eps" ]; then
+ EPIX_OUTROOT="${2%%.eps}"
+
+ elif [ "$2" = "${2%%.pdf}.pdf" ]; then
+ ELAPS_PDF="yes"
+ EPIX_OUTROOT="${2%%.pdf}"
+
+ else
+ EPIX_OUTROOT="$2"
+ fi
+ ELAPS_USER_OUT="yes"
+ shift 2
+ ;;
+
+ --pst)
+ EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_PSTRICKS")
+ shift; continue
+ ;;
+
+ --tikz)
+ EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_TIKZ")
+ shift; continue
+ ;;
+
+ --eepic)
+ EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_EEPIC")
+ shift; continue
+ ;;
+
+ -P)
+ DVIPS_OPTS=("${DVIPS_OPTS[@]}" "-P$2")
+ shift 2
+ ;;
+
+ -P*)
+ DVIPS_OPTS=("${DVIPS_OPTS[@]}" "$1")
+ shift
+ ;;
+
+ -pdf|--pdf)
+ ELAPS_PDF="yes"
+ shift
+ ;;
+
+ -ps|--ps)
+ ELAPS_PS="yes"
+ ELAPS_PDF="no" # redundant; enforced by logic later
+ shift
+ ;;
+
+ --pstcol)
+ ELAPS_PSTCOL="pstcol,xcolor"
+ shift
+ ;;
+
+ -p|--pkg)
+ if [ "$2" != "${2#-}" ]; then
+ ePiX_warn "\"$1\" cannot be followed by \"$2\"; skipping"
+ shift 1
+ else
+ ELAPS_PKGS="$ELAPS_PKGS,$2"
+ shift 2
+ fi
+ ;;
+
+ -p*)
+ ELAPS_PKGS="$ELAPS_PKGS,${1#-p}"
+ shift
+ ;;
+
+ # Deliberately undocumented; run silently, no log file
+ -q|--quiet)
+ EPIX_STDOUT="$SYSTEM_DEVNULL"
+ EPIX_STDERR="$SYSTEM_DEVNULL"
+ LATEX_INTERACT="batchmode"
+ shift; continue
+ ;;
+
+ --size)
+ ELAPS_SIZE="$2"
+ shift 2
+ ;;
+
+ -V|--version|--gpl)
+ ePiX_version elaps
+ ePiX_license
+ exit 0
+ ;;
+
+ -v|--verbose)
+ if [ -z "$2" ]; then
+ echo "Please use -V for version"
+ exit 0
+ fi
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ shift
+ ;;
+
+ -vv)
+ echo "Discontinued option -vv; please use -v for verbose output"
+ exit 0
+ ;;
+
+
+ # pass other options to epix
+ -i*|-u|-x|-I|-L|-l|-W)
+ EPIX_OPTS=("${EPIX_OPTS[@]}" "$1" "$2")
+ shift 2
+ ;;
+
+ -b)
+ ePiX_warn "Skipping option \"$1 $2\""
+ shift 2
+ ;;
+
+ *)
+ EPIX_OPTS=("${EPIX_OPTS[@]}" "$1")
+ shift
+ ;;
+ esac
+ done
+
+ # Assume remaining parameters are input files
+ INFILE_COUNT=$#
+
+ if [ "$ELAPS_USER_OUT" = "yes" -a $INFILE_COUNT -gt 1 ]; then
+ shift $(($INFILE_COUNT - 1))
+ ePiX_warn "Output file specified with multiple input files. Skipping all but \"$*\""
+ fi
+
+ ELAPS_FILE_LIST=("$@")
+} # end of elaps_parse_options()
+
+
+function elaps_process_files()
+{
+ if [ -z "$1" ]; then
+ ePiX_die "No input file specified"
+ fi
+
+ # file counts
+ local processed=0
+ local success=0
+ local failure=0
+
+ for EPIX_INFILE in "${ELAPS_FILE_LIST[@]}"; do
+
+ # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE
+ epix_parse_filename "$EPIX_INFILE" "$ELAPS_EXTENSIONS"
+ let processed=processed+1
+
+ if [ "$EPIX_NOTFOUND" = "yes" ]; then
+ let failure=failure+1
+ continue
+ fi
+
+ : ${EPIX_OUTROOT:=$EPIX_INROOT}
+ EPIX_OUTFILE="$EPIX_OUTROOT".eepic
+
+ # Create eepic file if necessary
+ if [ "$EPIX_SUFFIX" != "eepic" ]; then
+ if [ -f "$EPIX_OUTFILE" ]; then # back up existing file
+ mv -f "$EPIX_OUTFILE" "${EPIX_OUTFILE}~"
+ fi
+
+ TMP_CMD=(@bindir@/epix "${EPIX_OPTS[@]}" -o "$EPIX_OUTFILE" "$EPIX_INFILE")
+
+ ePiX_command "${TMP_CMD[@]}"
+ echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ if [ "$EPIX_INFILE" -nt "$EPIX_OUTFILE" ]; then
+ ePiX_warn "\"${TMP_CMD[*]}\" failed"
+ unset EPIX_OUTFILE
+ unset EPIX_OUTROOT
+ let failure=failure+1
+ continue
+
+ else
+ ln -s "$EPIX_OUTFILE" "$ELAPS_TEMP_EEPIC"
+ fi
+
+ else # we were passed an eepic file name
+ ln -s "$EPIX_INFILE" "$ELAPS_TEMP_EEPIC"
+ fi
+
+ elaps_make_latex "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_EEPIC"
+
+ # Create $ELAPS_TEMP_PS
+ TMP_CMD=($LATEX_BIN -interaction=$LATEX_INTERACT "$ELAPS_TEMP_LATEX")
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ "$ELAPS_TEMP_LATEX" -nt "$ELAPS_TEMP_DVI" ]; then
+ # Report informative (but fake) command line
+ ePiX_warn "\"$LATEX_BIN -interaction=$LATEX_INTERACT ${EPIX_INROOT}.tex\" failed"
+ rm -f "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_EEPIC" # clean temps
+ unset EPIX_OUTFILE
+ unset EPIX_OUTROOT
+ let failure=failure+1
+ continue
+ else
+ echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ fi
+
+ TMP_CMD=(dvips "${DVIPS_OPTS[@]}" -f -o "$ELAPS_TEMP_PS" "$ELAPS_TEMP_DVI")
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ "$ELAPS_TEMP_DVI" -nt "$ELAPS_TEMP_PS" ]; then
+ # Report informative (but fake) command line
+ ePiX_warn "\"dvips ${DVIPS_OPTS[@]} -f -o ${EPIX_INROOT}.ps ${EPIX_INROOT}.dvi\" failed"
+
+ unset EPIX_OUTFILE
+ unset EPIX_OUTROOT
+ let failure=failure+1
+ continue
+ else
+ echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ fi
+
+ if [ "$ELAPS_PS" = "yes" ]; then
+ # fix title; can't conveniently put sed command into ePiX_command
+ echo -n "sed \"s/$PROG-$PID/$EPIX_INROOT/g\" \"$ELAPS_TEMP_PS\"" \
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ echo " > \"$EPIX_OUTROOT.ps\"" \
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ sed "s/$PROG-$PID/$EPIX_INROOT/g" "$ELAPS_TEMP_PS" \
+ > "$EPIX_OUTROOT.ps"
+
+ else
+ # Create eps file,
+ TMP_CMD=("$PS2EPS" "$ELAPS_TEMP_PS")
+ ePiX_command "${TMP_CMD[@]}"
+
+ # fix title,
+ echo -n "sed \"s/$PROG-$PID/$EPIX_INROOT/g\" \"$ELAPS_TEMP_EPSI\""\
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ echo " > \"$EPIX_OUTROOT.eps\"" \
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ sed "s/$PROG-$PID/$EPIX_INROOT/g" \
+ "$ELAPS_TEMP_EPSI" > "$EPIX_OUTROOT.eps" &&
+ rm -f "$ELAPS_TEMP_EPSI"
+
+ # create pdf if requested,
+ if [ "$ELAPS_PDF" = "yes" ]; then
+ echo -n "grep -v \"^%%Orientation:\" \"$EPIX_OUTROOT.eps\"" \
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ echo " | epstopdf --filter --outfile=\"$EPIX_OUTROOT.pdf\"" \
+ | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+ # avoid ghostscript rotation bug
+ grep -v "^%%Orientation:" "$EPIX_OUTROOT.eps" \
+ | epstopdf --filter --outfile="$EPIX_OUTROOT.pdf"
+ rm -f "$EPIX_OUTROOT.eps" # clean up eps
+ fi
+ fi
+
+ let success=success+1
+ unset EPIX_OUTFILE
+ unset EPIX_OUTROOT
+
+ # and clean up
+ rm -f "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_DVI" "$ELAPS_TEMP_PS" \
+ "$ELAPS_TEMP_EEPIC" "$PROG-$PID.aux" "$PROG-$PID.log"
+
+ echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ done # for EPIX_INFILE in $INFILE_LIST
+
+ if [ $processed -gt 1 ]; then
+ echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR"
+ fi
+} # elaps_process_files()
+
+
+## Script proper starts here ##
+
+if [ $# -eq 0 ]; then
+ ePiX_usage elaps $ELAPS_DOT_EXT
+ elaps_help
+ exit 0
+fi
+
+elaps_parse_options "$@"
+
+elaps_process_files "${ELAPS_FILE_LIST[@]}"
+
+exit 0
diff --git a/graphics/epix/enums.h b/graphics/epix/enums.h
new file mode 100644
index 0000000000..1da13b67b1
--- /dev/null
+++ b/graphics/epix/enums.h
@@ -0,0 +1,52 @@
+/*
+ * enums.h -- ePiX's user-visible enumeration types
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 10, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_ENUMS
+#define EPIX_ENUMS
+
+namespace ePiX {
+
+ enum epix_mark_type {PATH, CIRC, SPOT, RING, DOT, DDOT, PLUS, OPLUS,
+ TIMES, OTIMES, DIAMOND, UP, DOWN, BOX, BBOX,
+ HTICK, VTICK, TEXT};
+
+ enum epix_label_posn {none, c, r, tr, rt, t, tl, lt, l, bl, lb, b, br, rb};
+
+ enum epix_integral_type {LEFT, RIGHT, UPPER, LOWER, TRAP, MIDPT};
+
+ enum epix_field_type {SLOPE, DART, VECTOR};
+
+} // end of namespace
+
+#endif /* EPIX_ENUMS */
diff --git a/graphics/epix/epix-lib.sh b/graphics/epix/epix-lib.sh
new file mode 100644
index 0000000000..422b2e7e16
--- /dev/null
+++ b/graphics/epix/epix-lib.sh
@@ -0,0 +1,179 @@
+# Common functions for ePiX's shell scripts
+#
+PROG=$(basename $0)
+
+# global variables for all scripts
+EPIX_PID=$$
+
+# Needn't be secure
+EPIX_TEMPDIR=${PROG}-${EPIX_PID}
+
+# Caution: Common logfile name for all ${PROG} processes in cwd,
+# used until we've parsed command-line options. Will assign a
+# unique name once we have an input file name.
+EPIX_LOGFILE=${PROG}.log
+if [ -f "${EPIX_LOGFILE}" ]; then rm -f "${EPIX_LOGFILE}"; fi
+
+# These may need to be modified
+declare -r SYSTEM_STDOUT=/dev/stdout
+declare -r SYSTEM_STDERR=/dev/stderr
+declare -r SYSTEM_DEVNULL=/dev/null
+
+EPIX_STDOUT=$SYSTEM_DEVNULL
+EPIX_STDERR=$SYSTEM_STDERR
+
+declare EPIX_NOTFOUND
+
+declare LATEX_PKGS
+
+# in increasing order of severity
+function ePiX_msg {
+ echo -e "$PROG: $@" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+}
+
+function ePiX_warn {
+ echo -e "$PROG: WARNING: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR"
+}
+
+function ePiX_fail {
+ echo -e "$PROG: WARNING: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR"
+ if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi
+ let failure=failure+1
+}
+
+function ePiX_die {
+ echo -e "$PROG: ERROR: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR"
+ echo -e "Transcript written on ${EPIX_LOGFILE}\n"
+ exit 1;
+}
+
+# Echo command to stderr/stdout and logfile, then run command
+#
+function ePiX_command {
+ ePiX_msg "$@"
+ ("$@" 2>&1) | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT"
+}
+
+
+# epix_parse_filename EPIX_INFILE MY_EXTENSIONS:
+#
+# Attempt to decompose EPIX_INFILE into EPIX_INROOT.EPIX_SUFFIX, with
+# EPIX_SUFFIX in MY_EXTENSIONS, then check for existence of file.
+# If EPIX_INFILE has no suffix, the first match (if any) wins.
+# If no file is found, EPIX_NOTFOUND="yes"
+#
+function epix_parse_filename {
+ EPIX_INFILE="$1"
+ shift;
+ MY_EXTENSIONS="$@"
+
+ unset EPIX_INROOT
+ unset EPIX_SUFFIX
+ unset EPIX_NOTFOUND
+
+ local FOUND_CT=0
+
+ # Check for recognized extension
+ for EXT in $MY_EXTENSIONS; do
+ TMP_ROOT="${EPIX_INFILE%.$EXT}"
+ if [ "$EPIX_INFILE" = "$TMP_ROOT.$EXT" ]; then
+ EPIX_INROOT="$TMP_ROOT"
+ EPIX_SUFFIX="$EXT"
+ break
+ fi
+ done
+
+ # None found; were we given just the root?
+ if [ -z "$EPIX_SUFFIX" ]; then
+ EPIX_INROOT="${EPIX_INFILE%%.}"
+
+ # Search for (and count) completions
+ for EXT in $MY_EXTENSIONS; do
+ if [ -f "$EPIX_INROOT.$EXT" ]; then
+ if [ $FOUND_CT -eq 0 ]; then # first match wins
+ EPIX_INFILE="$EPIX_INROOT.$EXT"
+ EPIX_SUFFIX="$EXT"
+ fi
+
+ let FOUND_CT=FOUND_CT+1
+ fi
+ done
+
+ # no match
+ if [ $FOUND_CT -eq 0 ]; then EPIX_NOTFOUND="yes"; fi
+
+ # Found suffix, check for input file
+ else
+ if [ -f "$EPIX_INFILE" ]; then
+ let FOUND_CT=FOUND_CT+1
+ else
+ EPIX_NOTFOUND="yes"
+ fi
+ fi # if $EPIX_SUFFIX=""
+
+ # initialize logfile
+ EPIX_LOGFILE="${EPIX_INROOT}_${EPIX_SUFFIX}.log"
+ if [ -f "$EPIX_LOGFILE" ]; then rm "$EPIX_LOGFILE"; fi
+ touch "$EPIX_LOGFILE"
+
+ # Print status messages
+ ePiX_msg "Processing $EPIX_INFILE:"
+
+ if [ $FOUND_CT -eq 0 ]; then
+ ePiX_warn " No completion of \"$EPIX_INROOT\" found"
+
+ elif [ $FOUND_CT -ge 2 ]; then
+ ePiX_warn " Found $FOUND_CT completions of \"$EPIX_INROOT\", using $EPIX_INFILE"
+
+ elif [ "$EPIX_NOTFOUND" = "yes" ]; then
+ ePiX_warn " \"$EPIX_INFILE\" not found"
+ fi
+} # end of epix_parse_filename
+
+
+# Get extra LaTeX package names from file
+function ePiX_usepackages()
+{
+ TMP_PKGS=$(grep "%% usepackages " $1)
+ LATEX_PKGS=${TMP_PKGS#"%% usepackages "}
+}
+
+function ePiX_usage()
+{
+cat <<HELP
+Usage: $1 [options] <file(s)>[$2]
+
+HELP
+}
+
+
+function ePiX_version()
+{
+cat <<VERSION
+$1 (ePiX 1.2.1)
+
+Copyright (C) 2007 Andrew D. Hwang
+
+VERSION
+}
+
+function ePiX_license()
+{
+cat <<LICENSE
+License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
+ePiX is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+LICENSE
+}
+
+function ePiX_bugreport()
+{
+ my_decode="tr '[a-m][n-z]' '[n-z][a-m]'" # Mac OS X has no 'rot'
+ SPAMMY="<$(echo nujnat|$my_decode)@$(echo zngupf|$my_decode)."
+ SPAMMY="${SPAMMY}$(echo ubylpebff|$my_decode).$(echo rqh|$my_decode)>"
+
+cat <<BUG
+Please report bugs to $SPAMMY
+BUG
+} \ No newline at end of file
diff --git a/graphics/epix/epix.1.in b/graphics/epix/epix.1.in
new file mode 100644
index 0000000000..45c5085666
--- /dev/null
+++ b/graphics/epix/epix.1.in
@@ -0,0 +1,50 @@
+.TH ePiX 1 "January 06, 2004"
+.LO 1
+.fi
+.SH NAME
+ePiX \- Utilities for creating mathematically accurate figures
+.SH SYNOPSIS
+.in +7n
+.ti -7n
+epix [options] file(s)[.xp]
+.P
+elaps [options] file(s)[.eepic|.xp]
+.P
+laps [options] file(s)[.tex]
+.P
+flix [options] file[.flx]
+.in -7n
+.P
+All scripts have built-in (terse and verbose) help.
+.P
+.SH ONLINE RESOURCES
+Project page:
+
+ http://mathcs.holycross.edu/~ahwang/current/ePiX.html
+
+Public CVS server:
+
+ https://savannah.nongnu.org/projects/epix
+
+CTAN:
+
+ http://www.ctan.org/tex-archive/graphics/epix
+
+Mailing lists:
+
+ http://lists.nongnu.org/mail/?group=epix
+
+.SH DOCUMENTATION
+Sample files and an extensive tutorial introduction/reference manual
+come with the source code. Please look in
+.B @docdir@
+for these materials. The documentation can be downloaded separately.
+Please consult the project page.
+
+.SH "AUTHOR"
+.nf
+.na
+Andrew D. Hwang (ahwang -at- mathcs -dot- holycross -dot- edu)
+Department of Mathematics and Computer Science
+College of the Holy Cross
+Worcester, MA 01610-2395, USA
diff --git a/graphics/epix/epix.el.in b/graphics/epix/epix.el.in
new file mode 100644
index 0000000000..19d69c2155
--- /dev/null
+++ b/graphics/epix/epix.el.in
@@ -0,0 +1,1068 @@
+;;; epix.el --- A major mode for working with ePiX files.
+
+;; Copyright (C) 2002, 2007 Jay Belanger
+
+;; Author: Jay Belanger
+;; Maintainer: Jay Belanger <belanger@truman.edu>
+
+;; Keywords: epix
+
+;; This program 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.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+;;
+;;
+;; Please send suggestions and bug reports to <belanger@truman.edu>.
+
+;;; Commentary:
+
+;; Quick intro
+
+;; epix-mode is an extension of c++-mode with some extra commands for
+;; editing ePiX files. The commands are
+;; C-cC-x run epix on the current file (x for epiX, I guess)
+;; C-cC-l run elaps on the current file (l for eLaps)
+;; The output of the run can be seen by
+;; C-cC-r show the output buffer (r for Results)
+;; and in case of errors, they can be jumped to, in sequence, with
+;; C-c` go to the next error
+;; The file created by elaps can be viewed with
+;; C-cC-v view the output file (v for View)
+;; By default, the output will be encapsulated postscript. This
+;; can be changed by changing the customizable variable
+;; `epix-elaps-output-format'. This can be changed for the current
+;; emacs session with `C-cC-r'.
+;; An unwanted ePiX process can be killed with
+;; C-cC-k
+;; A reminder of some ePiX commands will be given with
+;; C-cC-h get help on ePiX
+;; If the file extension is .flx, then there will also be the commands
+;; C-cC-f run flix on the current file
+;; C-cC-w view the mng file.
+;;
+;; To install, put both epix.el and epix.info in the emacs load path.
+;; Adding the lines
+;; (autoload 'epix-mode "epix" "ePiX editing mode" t)
+;; (autoload 'flix-mode "epix" "flix editing mode" t)
+;; to your .emacs file will ensure that the command is always available.
+;; Adding the lines
+;; (setq auto-mode-alist (cons '("\\.xp" . epix-mode) auto-mode-alist))
+;; (setq auto-mode-alist (cons '("\\.flx" . flix-mode) auto-mode-alist))
+;; will ensure that any file ending in .xp or .flx will be recognized as
+;; an ePiX file or flix file, and started in the proper mode.
+;;
+;; Some variables that the user may wish to change (via customization
+;; or otherwise) are
+;; epix-postscript-viewer (default "gv")
+;; The command used to view postscript files.
+;; epix-mng-viewer (default "display")
+;; The command used to view mng files.
+;; epix-mark-files-as-epix (default nil)
+;; Setting this to t will ensure that any file in ePiX mode
+;; will be marked with a /* -*-ePiX-* */ so that next
+;; time it is opened, it will be put in epix-mode. (This isn't necessary
+;; if auto-mode-alist is set up properly.)
+;; epix-mark-files-as-flix (default nil)
+;; Setting this to t will ensure that any file in flix mode
+;; will be marked with a /* -*-flix-* */ so that next
+;; time it is opened, it will be put in flix-mode. (This isn't necessary
+;; if auto-mode-alist is set up properly.)
+;; epix-insert-template-in-empty-buffer (default nil)
+;; Setting this to t will cause any empty buffer which is put in
+;; ePiX mode to have a skeleton of commands inserted into it.
+;; The skeleton can be inserted at any time with the command
+;; epix-insert-template
+;; epix-template
+;; This is the skeleton which will inserted.
+;; By default, it is
+;; #include \"epix.h\"
+;; using namespace ePiX;
+;;
+;; int main()
+;; {
+;; picture(P(,), P(,), \"\");
+;;
+;; begin();
+;;
+;; end();
+;; }
+;;
+;; epix-flix-template
+;; This is the skeleton which will inserted.
+;; By default, it is
+;; #include \"epix.h\"
+;; using namespace ePiX;
+;;
+;; int main(int argc, char* argv[])
+;; {
+;; if (argc == 3)
+;; {
+;; char* arg;
+;; double temp1, temp2;
+;; temp1=strtod(argv[1], &arg);
+;; temp2=strtod(argv[2], &arg);
+;;
+;; tix()=temp1/temp2;
+;; }
+;; picture(P(,), P(,), \"\");
+;;
+;; begin();
+;;
+;; end();
+;; }
+
+;;; Require
+(require 'cc-mode)
+
+;;; Customization
+
+(defgroup epix nil
+ "ePiX mode"
+ :prefix "epix-"
+ :tag "ePiX")
+
+(defcustom epix-elaps-output-format 'eps
+ "The output format for elaps."
+ :group 'epix
+ :type '(choice (const :tag "EPS" eps)
+ (const :tag "PS" ps)
+ (const :tag "PDF" pdf)))
+
+(defcustom epix-info-file "@docdir@/epix.info.bz2"
+ "The info file for ePiX."
+ :group 'epix
+ :type 'file)
+
+(defcustom epix-mark-files-as-epix nil
+ "Non-nil means to make sure that any ePiX file is marked as such."
+ :group 'epix
+ :type 'boolean)
+
+(defcustom epix-mark-files-as-flix nil
+ "Non-nil means to make sure that any flix file is marked as such."
+ :group 'epix
+ :type 'boolean)
+
+(defcustom epix-template
+"#include \"epix.h\"
+using namespace ePiX;
+
+int main()
+{
+picture(P(,), P(,), \"\");
+
+begin();
+
+end();
+}
+"
+ "The information to enter into an empty ePiX buffer."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-template-start "P("
+ "The place to start the point in the template."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-flix-template
+"#include \"epix.h\"
+using namespace ePiX;
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg));
+
+ tix()=temp1/temp2;
+ }
+picture(P(,), P(,), \"\");
+
+begin();
+
+end();
+}
+"
+ "The information to enter into an empty ePiX buffer."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-flix-template-start "P("
+ "The place to start the point in the template."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-insert-template-in-empty-buffer nil
+ "Non-nil means to insert the template into an empty ePiX buffer."
+ :group 'epix
+ :type 'boolean)
+
+(defcustom epix-command-name "epix"
+ "The name of the ePiX program."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-command-args ""
+ "Arguments to pass to epix"
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-elaps-command-name "elaps"
+ "The name of the elaps program."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-elaps-command-args ""
+ "Arguments to pass to elaps"
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-flix-command-name "flix"
+ "The name of the flix program."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-flix-command-args ""
+ "Arguments to pass to flix"
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-postscript-viewer "gv"
+ "The name of the program used to view postscript files."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-pdf-viewer "xpdf"
+ "The name of the program used to view pdf files."
+ :group 'epix
+ :type 'string)
+
+(defcustom epix-mng-viewer "display"
+ "The name of the program used to view mng files."
+ :group 'epix
+ :type 'string)
+
+;;; Some utility variables
+
+(defvar epix-output-buffer nil)
+(make-variable-buffer-local 'epix-output-buffer)
+
+(defvar epix-error-point nil)
+(make-variable-buffer-local 'epix-error-point)
+
+(defvar epix-elaps-output-format-list
+ '((ps " -ps" ".ps")
+ (pdf " -pdf" ".pdf")
+ (eps "" ".eps")))
+
+(defun epix-change-elaps-output-format ()
+ "Change the output format for elaps."
+ (interactive)
+ (let ((newformat
+ (read-string
+ "New output format (ps,eps,pdf): ")))
+ (cond
+ ((string= newformat "pdf")
+ (setq epix-elaps-output-format 'pdf))
+ ((string= newformat "ps")
+ (setq epix-elaps-output-format 'ps))
+ ((string= newformat "eps")
+ (setq epix-elaps-output-format 'eps))
+ (t
+ (message "Not an acceptable format.")))))
+
+;;; Functions to run epix and friends
+
+(defun epix-check-process ()
+ "See if there is a process associated with the output buffer.
+If there is and it is running, offer to kill it."
+ (let ((epp)
+ (epix-proc (get-buffer-process epix-output-buffer)))
+ (if epix-proc (setq epp t) (setq epp nil))
+ (if (and
+ epix-proc
+ (y-or-n-p "There is an ePiX process running. Kill it? "))
+ (progn
+ (kill-process epix-proc)
+ (setq epp nil)))
+ epp))
+
+(defun epix-kill-process ()
+ "Kill any epix process running."
+ (interactive)
+ (let ((epix-proc (get-buffer-process epix-output-buffer)))
+ (if (and
+ epix-proc
+ (y-or-n-p "Really kill ePiX process? "))
+ (kill-process epix-proc))))
+
+
+(defun epix-check-buffer ()
+ "See if the buffer has been modified since it was last saved.
+If it has been, offer to save it."
+ (if (and
+ (buffer-modified-p)
+ (y-or-n-p (concat "Save file " (buffer-file-name) "?")))
+ (save-buffer)))
+
+(defun epix-run-command (command file &optional args)
+ "Create a process to run COMMAND on FILE.
+Return the new process."
+ (let ((buffer epix-output-buffer))
+ (epix-check-buffer)
+ (unless (epix-check-process)
+ (set-buffer (get-buffer-create buffer))
+ (setq epix-error-point nil)
+ (erase-buffer)
+ (insert "Running `" command "' on `" file "\n")
+ (message "Type `C-c C-r' to display results of compilation.")
+ (let ((process)
+ (cmd))
+ (if (not (string= args ""))
+ (setq cmd
+ (append
+ (list 'start-process "ePiX" buffer "/bin/sh" command)
+ (split-string args)
+ (list file)))
+ (setq cmd (list 'start-process "ePiX" buffer "/bin/sh" command file)))
+ (setq process (eval cmd))
+ (set-process-filter process 'epix-command-filter)
+ (set-process-sentinel process 'epix-command-sentinel)
+ (set-marker (process-mark process) (point-max))
+ process))))
+
+(defun epix-command-sentinel (process event)
+ (when (string-match "finished" event)
+ (message "ePiX process finished")
+ (set-buffer epix-output-buffer)
+ (goto-char (point-max))
+ (insert "\nePiX process finished\n")))
+
+(defun epix-command-filter (process string)
+ "Filter to process normal output."
+ (save-excursion
+ (set-buffer (process-buffer process))
+ (save-excursion
+ (goto-char (process-mark process))
+ (insert-before-markers string)
+ (set-marker (process-mark process) (point))))
+ (if (string-match "Compilation failed" string)
+ (message (concat "ePiX errors in `" (buffer-name)
+ "'. Use C-c ` to display."))))
+(defun epix-run-epix ()
+ "Run epix on the current file."
+ (interactive)
+ (let ((file (file-name-nondirectory (buffer-file-name))))
+ (epix-run-command epix-command-name file epix-command-args)))
+
+(defun epix-run-elaps ()
+ "Run elaps on the current file."
+ (interactive)
+ (let ((file (file-name-nondirectory (buffer-file-name))))
+ (epix-run-command epix-elaps-command-name file
+ (concat
+ epix-elaps-command-args
+ (nth 1 (assoc epix-elaps-output-format
+ epix-elaps-output-format-list))))))
+
+(defun epix-run-flix ()
+ "Run flix on the current file."
+ (interactive)
+ (let ((file (file-name-nondirectory (buffer-file-name))))
+ (epix-run-command epix-flix-command-name file epix-flix-command-args)))
+
+(defun epix-view-elaps-output ()
+ "View the eps output of the file."
+ (interactive)
+ (let ((filename (file-name-nondirectory (buffer-file-name)))
+ (file nil)
+ (extension (nth 2 (assoc epix-elaps-output-format
+ epix-elaps-output-format-list))))
+ (if (file-name-extension filename)
+ (setq file (concat (file-name-sans-extension filename) extension)))
+ (unless (file-exists-p file)
+ (setq file (concat filename extension)))
+ (message file)
+ (if (file-exists-p file)
+ (call-process
+ (if (eq epix-elaps-output-format 'pdf)
+ epix-pdf-viewer
+ epix-postscript-viewer)
+ nil epix-output-buffer nil file)
+ (message (concat "No file " file ". Run elaps first.")))))
+
+(defun epix-view-mng ()
+ "View the mng output of the file."
+ (interactive)
+ (let ((filename (file-name-nondirectory (buffer-file-name)))
+ (file nil))
+ (if (file-name-extension filename)
+ (setq file (concat (file-name-sans-extension filename) ".mng")))
+ (unless (file-exists-p file)
+ (setq file (concat filename ".mng")))
+ (message file)
+ (if (file-exists-p file)
+ (call-process epix-mng-viewer nil epix-output-buffer nil file)
+ (message (concat "No file " file ". Run flix first.")))))
+
+;;; Dealing with output
+
+(defun epix-show-output-buffer ()
+ "Show the epix output buffer."
+ (interactive)
+ (let ((buf (current-buffer)))
+ (if (get-buffer epix-output-buffer)
+ (progn
+ (pop-to-buffer epix-output-buffer t)
+ (bury-buffer buf)
+ (goto-char (point-max))
+ (recenter (/ (window-height) 2))
+ (pop-to-buffer buf))
+ (message "No output buffer."))))
+
+(defun epix-find-error (arg)
+ "Go to the next ePiX error."
+ (interactive "P")
+ (if arg
+ (save-excursion
+ (set-buffer epix-output-buffer)
+ (setq epix-error-point nil)))
+ (let ((ln)
+ (col)
+ (epix-error-end)
+ (buf (current-buffer)))
+ (switch-to-buffer-other-window epix-output-buffer)
+ (widen)
+ (if epix-error-point
+ (goto-char epix-error-point)
+ (goto-char (point-min)))
+ (if (re-search-forward ":\\([0-9]+\\):\\([0-9]+\\):" (point-max) t)
+ (progn
+ (setq epix-error-point (point))
+ (setq ln (string-to-int (match-string 1)))
+ (setq col (string-to-int (match-string 2)))
+ (save-excursion
+ (if (re-search-forward ":[0-9]+:[0-9]+:" (point-max) t)
+ (setq epix-error-end (line-beginning-position))
+ (if (search-forward "Compilation failed" (point-max) t)
+ (setq epix-error-end (line-beginning-position))
+ (setq epix-error-end (point-max)))))
+ (recenter)
+ (beginning-of-line)
+ (if (looking-at "epix: Compiling...")
+ (forward-char (length "epix: Compiling...")))
+ (narrow-to-region (point) epix-error-end)
+ (switch-to-buffer-other-window buf)
+ (goto-line ln)
+ (move-to-column col))
+ (switch-to-buffer-other-window buf)
+ (message "No more errors."))))
+
+
+;;; Auxiliary functions
+
+(defun epix-mark-file-as-epix ()
+ "Mark the file as an ePiX buffer.
+The next time the file is loaded, it will then be in ePiX mode"
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (unless (looking-at ".*-\\*-ePiX-\\*-")
+ (insert "/* -*-ePiX-*- */\n"))))
+
+(defun epix-mark-file-as-flix ()
+ "Mark the file as a flix buffer.
+The next time the file is loaded, it will then be in flix mode"
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (unless (looking-at ".*-\\*-flix-\\*-")
+ (insert "/* -*-flix-*- */\n"))))
+
+(defun epix-insert-epix-template ()
+ "Insert a template."
+ (interactive)
+ (if (looking-at ".*-\\*-ePiX-\\*-")
+ (forward-line 1))
+ (let ((beg (point)))
+ (insert epix-template)
+ (indent-region beg (point) nil)
+ (goto-char beg)
+ (search-forward epix-template-start)))
+
+(defun epix-insert-flix-template ()
+ "Insert a template."
+ (interactive)
+ (if (looking-at ".*-\\*-flix-\\*-")
+ (forward-line 1))
+ (let ((beg (point)))
+ (insert epix-flix-template)
+ (indent-region beg (point) nil)
+ (goto-char beg)
+ (search-forward epix-flix-template-start)))
+
+(defun epix-help ()
+ "Read an ePiX info file"
+ (interactive)
+ (info-other-window epix-info-file))
+
+(require 'info-look)
+(info-lookup-maybe-add-help
+ :mode 'epix-mode
+ :ignore-case nil
+ :regexp "[_a-zA-Z0-9./+-]+"
+ :doc-spec (list
+ (list
+ (concat "("
+ epix-info-file
+ ")Function Index"))))
+; nil
+; "^ -+ [^:]+:[ ]+\\(\\[[^=]*=[ ]+\\)?" nil)))
+
+
+;;; To take care of the different types
+
+(defvar epix-preface
+"int[ \t\n]*main()[ \t\n]*{")
+
+(defvar epix-flix-preface
+"int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg));
+
+ tix()=temp1/temp2;
+ }")
+
+(defun epix-epix-to-flix ()
+ "Change some of the buffer to accomodate flix."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (replace-regexp "-\\*-ePiX-\\*-" "-*-flix-*-")
+ (goto-char (point-min))
+ (replace-regexp epix-preface epix-flix-preface))
+ (flix-mode))
+
+;;; ePiX mode
+
+(defvar epix-mode-map nil
+ "The keymap for ePiX mode.")
+
+(if epix-mode-map
+ nil
+ (let ((map (copy-keymap c++-mode-map)))
+ (define-key map "\C-c\C-k" 'epix-kill-process)
+ (define-key map "\C-c\C-x" 'epix-run-epix)
+ (define-key map "\C-c\C-l" 'epix-run-elaps)
+ (define-key map "\C-c\C-r" 'epix-show-output-buffer)
+ (define-key map "\C-c\C-v" 'epix-view-elaps-output)
+ (define-key map "\C-c\C-r" 'epix-change-elaps-output-format)
+ (define-key map "\C-c\C-h" 'epix-help)
+ (define-key map "\C-c\C-i" 'info-complete-symbol)
+ (define-key map "\C-c`" 'epix-find-error)
+ (setq epix-mode-map map)))
+
+(easy-menu-define epix-mode-menu epix-mode-map
+ "ePiX mode menu"
+ '("ePiX"
+ ["Run ePiX" epix-run-epix t]
+ ["Run elaps" epix-run-elaps t]
+ ["View the eps file" epix-view-elaps-output t]
+ ["Change the output format" epix-change-elaps-output-format t]
+ ["Get help on ePiX" epix-help t]
+ ["Show the output buffer" epix-show-output-buffer t]))
+
+(define-derived-mode epix-mode c++-mode "ePiX"
+ "ePiX mode is a major mode for editing ePiX files.
+It is C++ mode with a couple of extra commands:
+
+Run epix on the file being visited: C-cC-x
+Run elaps on the file being visited: C-cC-l
+View the output: C-cC-v
+Change the output format: C-cC-r
+Get help on ePiX: C-cC-h
+Complete the ePiX symbol under point: C-cTAB
+
+In the case of errors:
+Go to the (next) error: C-c`
+
+SUMMARY OF EPIX COMMANDS
+------------------------
+
+Preamble
+--------
+picture(P(a,b), P(c,d), \"height[dim] x width dim\");
+
+The actual picture commands need to be between
+begin();
+and
+end();
+
+Colors
+------
+RGB(r,g,b);
+Red(d); Green(d); Blue(d); Black(d); White(d);
+
+CMY(c,m,y);
+Cyan(d); Magenta(d); Yellow(d); CMY_Black(d); CMY_White(d);
+
+CMYK(c,m,y,k);
+CyanK(d); MagentaK(d); YellowK(d); CMYK_Black(d); CMYK_White(d);
+
+Primary densities interpolate linearly between anti-saturation (-1),
+no color(0), full saturation (1), and saturation on all channels (2
+or -2). Densities are meaningful mod 4. Colors can be superposed,
+blended, inverted, filtered, and scaled.
+
+Line and fill styles
+-----------
+Widths: plain([Color]); bold([Color]); bbold([Color]);
+ pen(Color, [len]); pen(len);
+ base(Color, [len]); base(len);
+Styles: solid(); dashed(); dotted();
+ line_style(string);
+Fill: fill(Color); fill(bool); nofill();
+
+The base pen draws an underlayer/border if wider than the line pen.
+line_style accepts a WYSIWYG pattern of spaces, dashes, and periods.
+
+Lines
+-----
+line(P(a,b),P(c,d));
+Line(P(a,b),P(c,d));
+Line(P(a,b),m);
+
+The line goes from one point to the other,
+the Line is that part of the entire line which lies inside the
+bounding box.
+
+Polygons
+--------
+triangle(P(a,b),P(c,d),P(e,f));
+rect(P(a,b),P(c,d));
+quad(P(a,b),P(c,d),P(e,f),P(g,h));
+
+Axes
+----
+h_axis(P(a,b),P(c,d),n);
+v_axis(P(a,b),P(c,d),n);
+h_log_axis(P(a,b),P(c,d),n);
+v_log_axis(P(a,b),P(c,d),n);
+
+h_axis_labels(P(a,b),P(c,d),n,P(u,v));
+v_axis_labels(P(a,b),P(c,d),n,P(u,v));
+h_log_axis_labels(P(a,b),P(c,d),n,P(u,v));
+v_log_axis_labels(P(a,b),P(c,d),n,P(u,v));
+
+h_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+v_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+h_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+v_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+
+The axis commands will put n+1 evenly spaced tick marks on the line.
+The labeling commands will put n+1 evenly spaced labels,
+masklabels will put the label on an opaque white rectangle.
+
+Points
+------
+spot(P(a,b)); dot(P(a,b)); ddot(P(a,b)); box(P(a,b)); bbox(P(a,b));
+circ(P(a,b));
+ring(P(a,b));
+
+spot, dot and ddot are various sized (in decreasing order) dots.
+A circ is a small circle with white interior.
+A ring is a small circle with transparent interior.
+
+Arrows
+------
+arrow(P(a,b),P(c,d));
+dart(P(a,b),P(c,d));
+
+A dart is a small arrow.
+
+Labels
+------
+label(P(a,b),P(u,v),\"label\");
+label(P(a,b),\"label\");
+label(P(a,b),P(u,v),\"label\",posn);
+masklabel(P(a,b),P(u,v),\"label\");
+masklabel(P(a,b),\"label\");
+masklabel(P(a,b),P(u,v),\"label\",posn);
+
+These commands put a label at the point P(a,b).
+P(u,v) is an offset (in true points).
+posn will specify the position of the label relative to the basepoint,
+and can be c(enter), l(eft), r(ight), t(op), b(ottom) or an
+appropriate pair.
+
+Text attributes
+---------------
+label_color(Color); label_mask(Color); label_pad(len);
+label_border(Color, [len]); label_border(len); no_label_border();
+font_size(LaTeX size); font_face(face);
+label_angle(theta);
+
+The LaTeX size is a string such as \"Huge\" or \"scriptsize\". The
+font face is one of \"rm\" (default), \"bf\", \"sc\", or \"tt\".
+
+Curves
+------
+ellipse(P(a,b),P(c,d),P(e,f),tmin,tmax);
+circle(P(a,b),r);
+circle(P(a,b),P(c,d),P(e,f));
+
+Ellipse draws (a,b)+Cos(t)*(c,d)+Sin(t)*(e,f) for tmin <= t <= tmax.
+
+Arcs
+----
+arc(P(a,b),r,theta1,theta2);
+arc_arrow(P(a,b),r,theta1,theta2);
+
+The angles are measured in current angle units (radians by default).
+
+Splines
+-------
+spline(P(a,b),P(c,d),P(e,f));
+spline(P(a,b),P(c,d),P(e,f),P(g,h));
+
+Plotting
+--------
+plot(f,a,b,n);
+
+This plots the function f from a to b using n+1 evenly spaced points.
+If f is P-valued, then this will be a parametric plot.
+
+Calc plotting
+-------------
+plot(Deriv(f),a,b,n);
+plot(Integral(f),a,b,n);
+plot(Integral(f),x0,a,b,n);
+
+plot(Deriv(f)...) plots f'.
+plot(Integral(f)...) plots int_a^x f (or if x0 is given, int_x0^x f).
+
+Tangents
+--------
+tan_line(f,t);
+envelope(f,t_min,t_max,n);
+tan_field(f,t_min,t_max,n);
+
+tan_line will plot the tangent Line to the graph.
+envelope will plot n+1 tangent Lines.
+tan_field will plot n+1 tangent vectors.
+Here, as above, f can be P-valued.
+
+Vector fields
+-------------
+slope_field(F,P(a,b),P(c,d),n1,n2);
+dart_field(F,P(a,b),P(c,d),n1,n2);
+vector_field(F,P(a,b),P(c,d),n1,n2);
+
+The slope_field elements will have fixed length, no arrows.
+The dart_field elements will have fixed length, small arrows.
+The vector_field elements will have true length.
+
+Fractals
+--------
+const int seed[] = {N, k1, k2, k3, ... , kn};
+fractal(P(a,b),P(c,d),D,seed);
+
+seed determines a path made up of equal space line segments, each of
+which can point in the direction 2 pi k/N. Each integer after N in seed
+will specify the direction of the next segment.
+fractal will recursively replace each segment in seed by a copy of the
+original, up to a depth of D, and draw it from P(a,b) to P(c,d)."
+ (setq font-lock-defaults
+ '((c++-font-lock-keywords
+ c++-font-lock-keywords-1
+ c++-font-lock-keywords-2
+ c++-font-lock-keywords-3)
+ nil nil ((?_ . "w")) beginning-of-defun
+ (font-lock-mark-block-function . mark-defun)))
+ (setq epix-output-buffer (concat "*" (buffer-file-name) " output*"))
+ (use-local-map epix-mode-map)
+ (if (and epix-insert-template-in-empty-buffer
+ (= (point-min) (point-max)))
+ (progn
+ (if epix-mark-files-as-epix
+ (epix-mark-file-as-epix))
+ (epix-insert-epix-template))
+ (if epix-mark-files-as-epix
+ (epix-mark-file-as-epix)))
+ (run-hooks 'epix-mode-hook))
+
+;;; flix mode
+
+(defvar flix-mode-map nil
+ "The keymap for flix mode.")
+
+(if flix-mode-map
+ nil
+ (let ((map (copy-keymap c++-mode-map)))
+ (define-key map "\C-c\C-k" 'epix-kill-process)
+ (define-key map "\C-c\C-x" 'epix-run-epix)
+ (define-key map "\C-c\C-l" 'epix-run-elaps)
+ (define-key map "\C-c\C-r" 'epix-show-output-buffer)
+ (define-key map "\C-c\C-v" 'epix-view-elaps-output)
+ (define-key map "\C-c\C-h" 'epix-help)
+ (define-key map "\C-c`" 'epix-find-error)
+ (define-key map "\C-c\C-f" 'epix-run-flix)
+ (define-key map "\C-c\C-w" 'epix-view-mng)
+ (setq flix-mode-map map)))
+
+(easy-menu-define flix-mode-menu flix-mode-map
+ "flix mode menu"
+ '("flix"
+ ["Run flix" epix-run-flix t]
+ ["View the mng file" epix-view-mng t]
+ ["Get help on flix/ePiX" epix-help t]
+ ["Show the output buffer" epix-show-output-buffer t]
+ ("ePiX"
+ ["Run ePiX" epix-run-epix t]
+ ["Run elaps" epix-run-elaps t]
+ ["View the eps file" epix-view-elaps-output t])))
+
+(define-derived-mode flix-mode c++-mode "flix"
+ "flix mode is a major mode for editing flix files.
+It is C++ mode with a couple of extra commands:
+
+Run flix on the file being visited: C-cC-f
+View the mng output: C-cC-w
+Get help on flix: C-cC-h
+
+Since a flix file is a valid ePiX file, the
+following commands are also available:
+Run epix on the file being visited: C-cC-x
+Run elaps on the file being visited: C-cC-l
+View the postscript output: C-cC-v
+In the case of errors:
+Go to the (next) error: C-c`
+
+An ePiX file isn't necessarily a flix file,
+but the command
+M-x epix-epix-to-flix
+will try to turn an ePiX file into a flix file.
+
+SUMMARY OF FLIX/EPIX COMMANDS
+------------------------
+
+Preamble
+--------
+picture(P(a,b), P(c,d), \"height[dim] x width dim\");
+
+The actual picture commands need to be between
+begin();
+and
+end();
+
+Colors
+------
+RGB(r,g,b);
+Red(d); Green(d); Blue(d); Black(d); White(d);
+
+CMY(c,m,y);
+Cyan(d); Magenta(d); Yellow(d); CMY_Black(d); CMY_White(d);
+
+CMYK(c,m,y,k);
+CyanK(d); MagentaK(d); YellowK(d); CMYK_Black(d); CMYK_White(d);
+
+Primary densities interpolate linearly between anti-saturation (-1),
+no color(0), full saturation (1), and saturation on all channels (2
+or -2). Densities are meaningful mod 4. Colors can be superposed,
+blended, inverted, filtered, and scaled.
+
+Line and fill styles
+-----------
+Widths: plain([Color]); bold([Color]); bbold([Color]);
+ pen(Color, [len]); pen(len);
+ base(Color, [len]); base(len);
+Styles: solid(); dashed(); dotted();
+ line_style(string);
+Fill: fill(Color); fill(bool); nofill();
+
+The base pen draws an underlayer/border if wider than the line pen.
+line_style accepts a WYSIWYG pattern of spaces, dashes, and periods.
+
+Lines
+-----
+line(P(a,b),P(c,d));
+Line(P(a,b),P(c,d));
+Line(P(a,b),m);
+
+The line goes from one point to the other,
+the Line is that part of the entire line which lies inside the
+bounding box.
+
+Polygons
+--------
+triangle(P(a,b),P(c,d),P(e,f));
+rect(P(a,b),P(c,d));
+quad(P(a,b),P(c,d),P(e,f),P(g,h));
+
+Axes
+----
+h_axis(P(a,b),P(c,d),n);
+v_axis(P(a,b),P(c,d),n);
+h_log_axis(P(a,b),P(c,d),n);
+v_log_axis(P(a,b),P(c,d),n);
+
+h_axis_labels(P(a,b),P(c,d),n,P(u,v));
+v_axis_labels(P(a,b),P(c,d),n,P(u,v));
+h_log_axis_labels(P(a,b),P(c,d),n,P(u,v));
+v_log_axis_labels(P(a,b),P(c,d),n,P(u,v));
+
+h_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+v_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+h_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+v_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v));
+
+The axis commands will put n+1 evenly spaced tick marks on the line.
+The labeling commands will put n+1 evenly spaced labels,
+masklabels will put the label on an opaque white rectangle.
+
+Points
+------
+spot(P(a,b)); dot(P(a,b)); ddot(P(a,b)); box(P(a,b)); bbox(P(a,b));
+circ(P(a,b));
+ring(P(a,b));
+
+spot, dot and ddot are various sized (in decreasing order) dots.
+A circ is a small circle with white interior.
+A ring is a small circle with transparent interior.
+
+Arrows
+------
+arrow(P(a,b),P(c,d));
+dart(P(a,b),P(c,d));
+
+A dart is a small arrow.
+
+Labels
+------
+label(P(a,b),P(u,v),\"label\");
+label(P(a,b),\"label\");
+label(P(a,b),P(u,v),\"label\",posn);
+masklabel(P(a,b),P(u,v),\"label\");
+masklabel(P(a,b),\"label\");
+masklabel(P(a,b),P(u,v),\"label\",posn);
+
+These commands put a label at the point P(a,b).
+P(u,v) is an offset (in true points).
+posn will specify the position of the label relative to the basepoint,
+and can be c(enter), l(eft), r(ight), t(op), b(ottom) or an
+appropriate pair.
+
+Text attributes
+---------------
+label_color(Color); label_mask(Color); label_pad(len);
+label_border(Color, [len]); label_border(len); no_label_border();
+font_size(LaTeX size); font_face(face);
+label_angle(theta);
+
+The LaTeX size is a string such as \"Huge\" or \"scriptsize\". The
+font face is one of \"rm\" (default), \"bf\", \"sc\", or \"tt\".
+
+Curves
+------
+ellipse(P(a,b),P(c,d),P(e,f),tmin,tmax);
+circle(P(a,b),r);
+circle(P(a,b),P(c,d),P(e,f));
+
+Ellipse draws (a,b)+Cos(t)*(c,d)+Sin(t)*(e,f) for tmin <= t <= tmax.
+
+Arcs
+----
+arc(P(a,b),r,theta1,theta2);
+arc_arrow(P(a,b),r,theta1,theta2);
+
+The angles are measured in current angle units (radians by default).
+
+Splines
+-------
+spline(P(a,b),P(c,d),P(e,f));
+spline(P(a,b),P(c,d),P(e,f),P(g,h));
+
+Plotting
+--------
+plot(f,a,b,n);
+
+This plots the function f from a to b using n+1 evenly spaced points.
+If f is P-valued, then this will be a parametric plot.
+
+Calc plotting
+-------------
+plot(Deriv(f),a,b,n);
+plot(Integral(f),a,b,n);
+plot(Integral(f),x0,a,b,n);
+
+plot(Deriv(f)...) plots f'.
+plot(Integral(f)...) plots int_a^x f (or if x0 is given, int_x0^x f).
+
+Tangents
+--------
+tan_line(f,t);
+envelope(f,t_min,t_max,n);
+tan_field(f,t_min,t_max,n);
+
+tan_line will plot the tangent Line to the graph.
+envelope will plot n+1 tangent Lines.
+tan_field will plot n+1 tangent vectors.
+Here, as above, f can be P-valued.
+
+Vector fields
+-------------
+slope_field(F,P(a,b),P(c,d),n1,n2);
+dart_field(F,P(a,b),P(c,d),n1,n2);
+vector_field(F,P(a,b),P(c,d),n1,n2);
+
+The slope_field elements will have fixed length, no arrows.
+The dart_field elements will have fixed length, small arrows.
+The vector_field elements will have true length.
+
+Fractals
+--------
+const int seed[] = {N, k1, k2, k3, ... , kn};
+fractal(P(a,b),P(c,d),D,seed);
+
+seed determines a path made up of equal space line segments, each of
+which can point in the direction 2 pi k/N. Each integer after N in seed
+will specify the direction of the next segment.
+fractal will recursively replace each segment in seed by a copy of the
+original, up to a depth of D, and draw it from P(a,b) to P(c,d)."
+ (setq font-lock-defaults
+ '((c++-font-lock-keywords
+ c++-font-lock-keywords-1
+ c++-font-lock-keywords-2
+ c++-font-lock-keywords-3)
+ nil nil ((?_ . "w")) beginning-of-defun
+ (font-lock-mark-block-function . mark-defun)))
+ (setq epix-output-buffer (concat "*" (buffer-file-name) " output*"))
+ (use-local-map flix-mode-map)
+ (if (and epix-insert-template-in-empty-buffer
+ (= (point-min) (point-max)))
+ (progn
+ (if epix-mark-files-as-epix
+ (epix-mark-file-as-flix))
+ (epix-insert-flix-template))
+ (if epix-mark-files-as-epix
+ (epix-mark-file-as-flix)))
+ (run-hooks 'epix-mode-hook)
+ (run-hooks 'flix-mode-hook))
+
+(provide 'epix)
diff --git a/graphics/epix/epix.in b/graphics/epix/epix.in
new file mode 100644
index 0000000000..d5c302cbbb
--- /dev/null
+++ b/graphics/epix/epix.in
@@ -0,0 +1,340 @@
+#! /bin/bash
+#
+# epix: wrapper script for ePiX
+#
+# Options: --help for usage, --version for version and license
+#
+# Compiler flags may be specified on the command line or in the config
+# file ~/.epixrc. The script attempts to deal intelligently with missing
+# or multiple extensions. If the input file has a recognized extension,
+# there's no issue. If only the root name <infile> is given, the script
+# searches for completions in the order of preference dictated by the
+# variable EPIX_EXTENSIONS. A warning is issued for multiple matches.
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Andrew D. Hwang <For address, do "epix -V">
+#
+
+. "@pkglibdir@/epix-lib.sh"
+
+EPIX_CONFIG_FILE="$HOME/.epixrc"
+# Search these extensions in order of preference
+EPIX_EXTENSIONS="xp flx cc c C cpp" # or NULL
+EPIX_DOT_EXT=".${EPIX_EXTENSIONS// /|.}" # for usage message
+
+# Default inc/lib directories and compiler
+DEFAULT_INC="-I@includedir@"
+DEFAULT_LIB="-L@pkglibdir@"
+COMPILER="@RUNTIME_COMPILER@"
+
+# Use default library unless we're called by version number
+LIBS="-lm"
+POSTLIBS="-lepix"
+EPIX_SRC_EXT=cc
+
+declare EPIX_MYINCLUDES
+declare EPIX_MYLIBDIRS
+declare EPIX_MYLIBS
+declare EPIX_MYWARNS
+declare EPIX_MYFLAGS
+
+declare -a EPIX_FILE_LIST
+
+declare -a TEMPFILES
+trap '[ -n "${TEMPFILES[*]}" ] && rm -f "${TEMPFILES[@]}"' 0 1 2 3 7 10 13 15
+
+function epix_help()
+{
+cat <<"HELP"
+Options:
+ -h, --help
+ Show this message and exit
+
+ -V, --version
+ Show version and exit
+
+ -v, --verbose
+ Show success/failure messages
+
+ --gpl
+ Show license
+
+ -o, --output
+ Specify output file name (ONLY for use with a single input file)
+
+ --pst
+ Write output file using PSTricks macros
+
+ --tikz
+ Write output file using tikz macros
+
+ --eepic
+ Write output file using eepic macros
+
+ -I<include>
+ Append include directory
+
+ -L<library>
+ Append library directory
+
+ -l<lib>
+ Link against lib
+
+ --no-defaults
+ Do not use default include/library directories or libraries
+
+ -cc, --compiler)
+ Specify the compiler (e.g., gcc)
+
+ All other options are passed to the compiler. Valid options,
+ one per line, may be placed in $HOME/.epixrc.
+
+HELP
+ePiX_bugreport
+
+} # End of epix_help
+
+
+# Parse command line/config file for compiler flags/options
+function epix_parse_options {
+while [ "$1" != "${1#-}" ]; do
+ case "$1" in
+
+ -I)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_MYINCLUDES="$EPIX_MYINCLUDES -I$2"; shift 2; continue
+ ;;
+
+ -L)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_MYLIBDIRS="$EPIX_MYLIBDIRS -L$2"; shift 2; continue
+ ;;
+
+ -l)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_MYLIBS="$EPIX_MYLIBS -l$2"; shift 2; continue
+ ;;
+
+ -W)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_MYWARNS="$EPIX_MYWARNS -W$2"; shift 2; continue
+ ;;
+
+ -I*)
+ EPIX_MYINCLUDES="$EPIX_MYINCLUDES $1"; shift; continue
+ ;;
+
+ -L*)
+ EPIX_MYLIBDIRS="$EPIX_MYLIBDIRS $1"; shift; continue
+ ;;
+
+ -l*)
+ EPIX_MYLIBS="$EPIX_MYLIBS $1"; shift; continue
+ ;;
+
+ -W*)
+ EPIX_MYWARNS="$EPIX_MYWARNS $1"; shift; continue
+ ;;
+
+ -i*|-u|-x)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_MYFLAGS="$EPIX_MYFLAGS $1 $2"; shift 2; continue
+ ;;
+
+ -b)
+ ePiX_warn "Skipping option \"$1 $2\""
+ shift 2; continue
+ ;;
+
+ -o|--output)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ EPIX_OUTFILE="$2"
+ EPIX_OUTROOT="${EPIX_OUTFILE%%.eepic}"
+ shift 2; continue
+ ;;
+
+ --pst)
+ EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_PSTRICKS"
+ shift; continue
+ ;;
+
+ --tikz)
+ EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_TIKZ"
+ shift; continue
+ ;;
+
+ --eepic)
+ EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_EEPIC"
+ shift; continue
+ ;;
+
+ # Deliberately undocumented
+ -q|--quiet)
+ EPIX_STDOUT="$SYSTEM_DEVNULL"
+ EPIX_STDERR="$SYSTEM_DEVNULL"
+ shift; continue
+ ;;
+
+ -v|--verbose)
+ if [ -z "$2" ]; then
+ echo "Please use -V for version"
+ exit 0
+ fi
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ EPIX_STDERR="$SYSTEM_STDERR"
+ shift; continue
+ ;;
+
+ -vv)
+ echo "Discontinued option -vv; please use -v for verbose output"
+ exit 0
+ ;;
+
+
+ -h|--help)
+ ePiX_usage epix $EPIX_DOT_EXT
+ epix_help
+ exit 0
+ ;;
+
+ -V|--version|--gpl)
+ ePiX_version epix
+ ePiX_license
+ exit 0
+ ;;
+
+ --no-defaults)
+ POSTLIBS=
+ DEFAULT_INC=
+ DEFAULT_LIB=
+ shift; continue
+ ;;
+
+ -cc|--compiler)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ COMPILER=$2
+ COMP_NAME=$(basename "$COMPILER")
+ if [ "${COMP_NAME: -2}" = cc ]; then EPIX_SRC_EXT=c; fi
+ shift 2; continue
+ ;;
+
+ *)
+ EPIX_MYFLAGS="$EPIX_MYFLAGS $1"; shift; continue
+ ;;
+ esac
+
+done
+
+# Assume remaining parameters are input files
+EPIX_FILE_LIST=("$@")
+} # End of epix_parse_options
+
+
+# Compile specified files to eepic
+function epix_compile_files {
+
+ if [ -z "$1" ]; then
+ ePiX_die "No input file specified"
+ fi
+
+ mkdir "$EPIX_TEMPDIR" || ePiX_die "Can't create \"${EPIX_TEMPDIR}\""
+
+ # file counts
+ local processed=0
+ local success=0
+ local failure=0
+
+ for EPIX_INFILE in "${EPIX_FILE_LIST[@]}"; do
+
+ # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE
+ epix_parse_filename "$EPIX_INFILE" "$EPIX_EXTENSIONS"
+ let processed=processed+1
+
+ if [ "$EPIX_NOTFOUND" = "yes" ]; then ePiX_fail && continue; fi
+
+ : ${EPIX_OUTROOT:=$EPIX_INROOT}
+ EPIX_OUTFILE="$EPIX_OUTROOT".eepic
+
+ { TEMP_BIN="$EPIX_INROOT" &&
+ touch "${EPIX_TEMPDIR}/$TEMP_BIN" &&
+ TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_BIN") ; } ||
+ { ePiX_fail "Couldn't create \"$EPIX_TEMPDIR/$TEMP_BIN\"" && continue;}
+
+ # Create symlink to input file with appropriate extension for compiler
+ TEMP_INPUT="${TEMP_BIN}-tmp.$EPIX_SRC_EXT"
+
+ TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_INPUT")
+
+ { cd ${EPIX_TEMPDIR} && \
+ ln -s "../$EPIX_INFILE" "$TEMP_INPUT" && cd .. ; } ||
+ { ePiX_fail "Couldn't create \"${EPIX_TEMPDIR}/$TEMP_INPUT\"" && \
+ continue; }
+
+ # Log message, and compile executable
+ TMP_CMD=($COMPILER "${EPIX_TEMPDIR}/${TEMP_INPUT}" $EPIX_MYWARNS \
+ -o "${EPIX_TEMPDIR}/${TEMP_BIN}" \
+ $EPIX_MYFLAGS $EPIX_MYINCLUDES $DEFAULT_INC $EPIX_MYLIBDIRS \
+ $DEFAULT_LIB $LIBS $EPIX_MYLIBS $POSTLIBS)
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ # Write eepic file
+ if [ -x "$EPIX_TEMPDIR/$TEMP_BIN" ]; then
+ echo "%% Generated from $EPIX_INFILE on $(date) by" \
+ > "$EPIX_OUTFILE"
+ ePiX_msg "Writing eepic file: ./$EPIX_TEMPDIR/$TEMP_BIN > $EPIX_OUTFILE"
+ ./$EPIX_TEMPDIR/"$TEMP_BIN" >> "$EPIX_OUTFILE"
+
+ if [ $? -ne 0 ]; then
+ ePiX_warn "Could not create $EPIX_OUTFILE"
+ let failure=failure+1
+ else
+ let success=success+1
+ fi
+
+ else
+ ePiX_warn "Compilation of $EPIX_INFILE failed"
+ let failure=failure+1
+ fi
+
+ # Clean up; for multiple input files, clear output name
+ rm -f "$EPIX_TEMPDIR/$TEMP_BIN" "$EPIX_TEMPDIR/$TEMP_INPUT"
+ if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi
+
+ echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ done # for EPIX_INFILE in $INFILE_LIST
+
+ if [ $processed -gt 1 ]; then
+ echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR"
+ fi
+
+ if [ -d "$EPIX_TEMPDIR" ]; then rm -Rf "$EPIX_TEMPDIR"; fi
+} # end of epix_compile_files
+
+## Script proper starts here ##
+
+if [ $# -eq 0 ]; then
+ ePiX_usage epix $EPIX_DOT_EXT
+ epix_help
+ exit 0
+fi
+
+# Read options from the config file, if any
+if [ -f "$EPIX_CONFIG_FILE" ]; then
+ cat "$EPIX_CONFIG_FILE" | grep -v "#" | \
+ while read line; do
+ epix_parse_options "$line"
+ done
+fi
+
+# Command line options override config file options
+epix_parse_options "$@"
+
+# Suppress all warnings if none are requested
+if [ "$EPIX_MYWARNS" = "" ]; then EPIX_MYWARNS="-w"; fi
+
+# Remaining option(s) assumed to be input file(s)
+epix_compile_files "${EPIX_FILE_LIST[@]}"
+
+exit 0
diff --git a/graphics/epix/errors.h b/graphics/epix/errors.h
new file mode 100644
index 0000000000..7867e22686
--- /dev/null
+++ b/graphics/epix/errors.h
@@ -0,0 +1,55 @@
+/*
+ * errors.h -- ePiX warning/error functions
+ *
+ * This file is part of ePiX, a preprocessor for creating high-quality
+ * line figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_ERRORS
+#define EPIX_ERRORS
+
+#include <iostream>
+#include <string>
+
+namespace ePiX {
+
+ inline void epix_warning(std::string msg)
+ {
+ std::cerr << "ePiX WARNING: " << msg << std::endl;
+ }
+
+ inline void epix_error(std::string msg)
+ {
+ std::cerr << "ePiX ERROR: " << msg << std::endl;
+ exit(1);
+ }
+} // end of namespace
+
+#endif /* EPIX_ERRORS */
diff --git a/graphics/epix/facet.cc b/graphics/epix/facet.cc
new file mode 100644
index 0000000000..3b808d1b59
--- /dev/null
+++ b/graphics/epix/facet.cc
@@ -0,0 +1,505 @@
+/*
+ * facet.cc -- Utility classes for shaded surface plotting
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "constants.h"
+#include "errors.h"
+#include "functions.h"
+
+#include "frame.h"
+#include "camera.h"
+
+#include "Color.h"
+#include "paint_style.h"
+
+#include "facet.h"
+
+namespace ePiX {
+
+ facet::facet(P f(double, double),
+ double u0, double v0,
+ double du, double dv,
+ const unsigned int N1, const unsigned int N2)
+ : m_tint(the_paint_style().fill_color()),
+ m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0, v0)),
+ pt2(f(u0 + N1*du, v0)),
+ pt3(f(u0 + N1*du, v0 + N2*dv)),
+ pt4(f(u0, v0 + N2*dv)),
+ center(0.25*(pt1 + pt2 + pt3 + pt4)),
+ direction(center-cam().viewpt()),
+ distance(norm(direction))
+ {
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0 + j*dv));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + (N2-j)*dv));
+
+ bd.close().fill(!m_tint.is_unset());
+ }
+
+
+ // facet constructor for f(double, double, double)
+ facet::facet(P f(double, double, double),
+ double u0, double v0, double w0,
+ double du, double dv, double dw,
+ const unsigned int N1, const unsigned int N2)
+ : m_tint(the_paint_style().fill_color()),
+ m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0, v0, w0))
+ {
+ if (du == 0) // (y,z)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0, v0 + i*dv, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + N1*dv, w0 + j*dw));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0, v0 + (N1-i)*dv, w0 + N2*dw));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0, w0 + (N2-j)*dw));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0, v0 + N1*dv, w0);
+ pt3 = f(u0, v0 + N1*dv, w0 + N2*dw);
+ pt4 = f(u0, v0, w0 + N2*dw);
+ }
+
+ else if (dv == 0) // (x,z)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0, w0 + j*dw));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0, w0 + N2*dw));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0, w0 + (N2-j)*dw));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0 + N1*du, v0, w0);
+ pt3 = f(u0 + N1*du, v0, w0 + N2*dw);
+ pt4 = f(u0, v0, w0 + N2*dw);
+ }
+
+ else if (dw == 0) // (x,y)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0 + j*dv, w0));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv, w0));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + (N2-j)*dv, w0));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0 + N1*du, v0, w0);
+ pt3 = f(u0 + N1*du, v0 + N2*dv, w0);
+ pt4 = f(u0, v0 + N2*dv, w0);
+ }
+
+ else
+ epix_error("Bad call to facet constructor"); // exits
+
+ bd.close().fill(!m_tint.is_unset());
+
+ center = 0.25*(pt1 + pt2 + pt3 + pt4);
+
+ direction = center-cam().viewpt();
+ distance = norm(direction);
+
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ } // end of facet(f(double, double, double), ...)
+
+
+ // for surface of rotation
+ facet::facet(double f(double), double g(double),
+ double u0, double v0,
+ double du, double dv,
+ const unsigned int N1, const unsigned int N2,
+ const frame& coords)
+ : m_tint(the_paint_style().fill_color()),
+ m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0)*coords.sea() +
+ g(u0)*Cos(v0)*coords.sky() +
+ g(u0)*Sin(v0)*coords.eye()),
+ pt2(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0)*coords.eye()),
+ pt3(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0 + N2*dv)*coords.eye()),
+ pt4(f(u0)*coords.sea() +
+ g(u0)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0)*Sin(v0 + N2*dv)*coords.eye()),
+ center(0.25*(pt1 + pt2 + pt3 + pt4)),
+ direction(center-cam().viewpt()), distance(norm(direction))
+ {
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du)*coords.sea() +
+ g(u0 + i*du)*Cos(v0)*coords.sky() +
+ g(u0 + i*du)*Sin(v0)*coords.eye());
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0 + j*dv)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0 + j*dv)*coords.eye());
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du)*coords.sea() +
+ g(u0 + (N1-i)*du)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0 + (N1-i)*du)*Sin(v0 + N2*dv)*coords.eye());
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0)*coords.sea() +
+ g(u0)*Cos(v0 + (N2-j)*dv)*coords.sky() +
+ g(u0)*Sin(v0 + (N2-j)*dv)*coords.eye());
+
+ bd.close().fill(!m_tint.is_unset());
+ }
+
+ //// Color-dependent constructors
+ facet::facet(P f(double, double),
+ double u0, double v0,
+ double du, double dv,
+ const unsigned int N1, const unsigned int N2,
+ const Color& tint)
+ : m_tint(tint), m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0, v0)),
+ pt2(f(u0 + N1*du, v0)),
+ pt3(f(u0 + N1*du, v0 + N2*dv)),
+ pt4(f(u0, v0 + N2*dv)),
+ center(0.25*(pt1 + pt2 + pt3 + pt4)),
+ direction(center-cam().viewpt()),
+ distance(norm(direction))
+ {
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0 + j*dv));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + (N2-j)*dv));
+
+ bd.close().fill(!m_tint.is_unset());
+ }
+
+
+ // facet constructor for f(double, double, double)
+ facet::facet(P f(double, double, double),
+ double u0, double v0, double w0,
+ double du, double dv, double dw,
+ const unsigned int N1, const unsigned int N2,
+ const Color& tint)
+ : m_tint(tint), m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0, v0, w0))
+ {
+ if (du == 0) // (y,z)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0, v0 + i*dv, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + N1*dv, w0 + j*dw));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0, v0 + (N1-i)*dv, w0 + N2*dw));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0, w0 + (N2-j)*dw));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0, v0 + N1*dv, w0);
+ pt3 = f(u0, v0 + N1*dv, w0 + N2*dw);
+ pt4 = f(u0, v0, w0 + N2*dw);
+ }
+
+ else if (dv == 0) // (x,z)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0, w0 + j*dw));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0, w0 + N2*dw));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0, w0 + (N2-j)*dw));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0 + N1*du, v0, w0);
+ pt3 = f(u0 + N1*du, v0, w0 + N2*dw);
+ pt4 = f(u0, v0, w0 + N2*dw);
+ }
+
+ else if (dw == 0) // (x,y)
+ {
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du, v0, w0));
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du, v0 + j*dv, w0));
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv, w0));
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0, v0 + (N2-j)*dv, w0));
+
+ // use corners to approximate distance to camera
+ pt2 = f(u0 + N1*du, v0, w0);
+ pt3 = f(u0 + N1*du, v0 + N2*dv, w0);
+ pt4 = f(u0, v0 + N2*dv, w0);
+ }
+
+ else
+ epix_error("Bad call to facet constructor"); // exits
+
+ bd.close().fill(!m_tint.is_unset());
+
+ center = 0.25*(pt1 + pt2 + pt3 + pt4);
+
+ direction = center-cam().viewpt();
+ distance = norm(direction);
+
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ } // end of facet(f(double, double, double), ...)
+
+
+ // for surface of rotation
+ facet::facet(double f(double), double g(double),
+ double u0, double v0,
+ double du, double dv,
+ const unsigned int N1, const unsigned int N2,
+ const Color& tint, const frame& coords)
+ : m_tint(tint), m_line(the_paint_style().line_pen()),
+ m_fill(the_paint_style().fill_flag()),
+ pt1(f(u0)*coords.sea() +
+ g(u0)*Cos(v0)*coords.sky() +
+ g(u0)*Sin(v0)*coords.eye()),
+ pt2(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0)*coords.eye()),
+ pt3(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0 + N2*dv)*coords.eye()),
+ pt4(f(u0)*coords.sea() +
+ g(u0)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0)*Sin(v0 + N2*dv)*coords.eye()),
+ center(0.25*(pt1 + pt2 + pt3 + pt4)),
+ direction(center-cam().viewpt()), distance(norm(direction))
+ {
+ perp = ((pt2 - center)*(pt1 - center));
+
+ if (norm(perp) < EPIX_EPSILON)
+ perp = (pt4 - center)*(pt3 - center);
+
+ perp *= recip(norm(perp));
+
+ // bottom edge
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + i*du)*coords.sea() +
+ g(u0 + i*du)*Cos(v0)*coords.sky() +
+ g(u0 + i*du)*Sin(v0)*coords.eye());
+
+ // right edge
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0 + N1*du)*coords.sea() +
+ g(u0 + N1*du)*Cos(v0 + j*dv)*coords.sky() +
+ g(u0 + N1*du)*Sin(v0 + j*dv)*coords.eye());
+
+ // top edge (backward)
+ for (unsigned int i=0; i<N1; ++i)
+ bd.pt(f(u0 + (N1-i)*du)*coords.sea() +
+ g(u0 + (N1-i)*du)*Cos(v0 + N2*dv)*coords.sky() +
+ g(u0 + (N1-i)*du)*Sin(v0 + N2*dv)*coords.eye());
+
+ // left edge (downward)
+ for (unsigned int j=0; j<N2; ++j)
+ bd.pt(f(u0)*coords.sea() +
+ g(u0)*Cos(v0 + (N2-j)*dv)*coords.sky() +
+ g(u0)*Sin(v0 + (N2-j)*dv)*coords.eye());
+
+ bd.close().fill(!m_tint.is_unset());
+ }
+
+
+ facet* facet::clone() const
+ {
+ return new facet(*this);
+ }
+
+ double facet::how_far() const { return distance; }
+
+ bool facet::front_facing() const
+ {
+ return (-direction|perp) > -EPIX_EPSILON;
+ }
+
+ // N.B. We assume the fill state is stored by our caller
+ void facet::draw(int cull) const
+ {
+ if (( cull == 1 && front_facing() ) || ( cull == -1 && !front_facing() ))
+ return;
+
+ // else
+ Color paint(m_tint);
+ if (paint.is_unset())
+ paint = White();
+
+ Color ink(m_line.color());
+ if (ink.is_unset())
+ ink = paint;
+
+ if (m_fill)
+ {
+ // calculate cosine^2 of normal angle
+ // Magic formula (simulated ambient lighting)
+ const double dens(0.5*(1+pow(perp|(recip(distance)*direction), 2)));
+
+ paint *= dens;
+ ink *= dens;
+ }
+
+ bd.draw(paint, pen_data(ink, m_line.width()));
+ } // end of facet::draw(bool, int)
+
+
+ bool by_distance::operator() (const facet& arg1, const facet& arg2)
+ {
+ return arg1.how_far() > arg2.how_far();
+ }
+
+ bool by_distance::operator() (const facet* arg1, const facet* arg2)
+ {
+ return arg1->how_far() > arg2->how_far();
+ }
+} // end of namespace
diff --git a/graphics/epix/facet.h b/graphics/epix/facet.h
new file mode 100644
index 0000000000..0e118da181
--- /dev/null
+++ b/graphics/epix/facet.h
@@ -0,0 +1,105 @@
+/*
+ * facet.h -- Utility classes for shaded surface plotting
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "triples.h"
+#include "frame.h"
+
+#include "path.h"
+
+#include "Color.h"
+#include "pen_data.h"
+
+namespace ePiX {
+
+ class facet {
+ public:
+ // create quasi-planar region bounded by path segments in f(R)
+ facet(P f(double, double),
+ double u0, double v0, double du, double dv,
+ const unsigned int N1, const unsigned int N2);
+
+ facet(P f(double, double, double),
+ double u0, double v0, double w0,
+ double du, double dv, double dw,
+ const unsigned int N1, const unsigned int N2);
+
+ // for surfaces of rotation
+ facet(double f(double), double g(double),
+ double u0, double v0, double du, double dv,
+ const unsigned int N1, const unsigned int N2,
+ const frame& coords=frame());
+
+
+ facet(P f(double, double),
+ double u0, double v0, double du, double dv,
+ const unsigned int N1, const unsigned int N2, const Color&);
+
+ facet(P f(double, double, double),
+ double u0, double v0, double w0,
+ double du, double dv, double dw,
+ const unsigned int N1, const unsigned int N2, const Color&);
+
+ // for surfaces of rotation
+ facet(double f(double), double g(double),
+ double u0, double v0, double du, double dv,
+ const unsigned int N1, const unsigned int N2, const Color&,
+ const frame& coords=frame());
+
+
+ facet* clone() const;
+
+ double how_far() const;
+
+ bool front_facing() const;
+
+ void draw(int cull) const;
+
+ private:
+ Color m_tint;
+ pen_data m_line;
+ bool m_fill;
+
+ P pt1, pt2, pt3, pt4, center, direction, perp;
+ double distance;
+
+ path bd;
+ };
+
+
+ class by_distance {
+ public:
+ bool operator() (const facet&, const facet&);
+ bool operator() (const facet*, const facet*);
+ };
+} // end of namespace
diff --git a/graphics/epix/files b/graphics/epix/files
new file mode 100644
index 0000000000..4997b1e7ba
--- /dev/null
+++ b/graphics/epix/files
@@ -0,0 +1,224 @@
+# Version 1.2.1
+AUTHORS
+BUGS
+ChangeLog
+COPYING
+INSTALL
+Makefile.am
+Makefile.in
+NEWS
+POST-INSTALL
+README
+THANKS
+TODO
+VERSION
+aclocal.m4
+active_screen.cc
+active_screen.h
+affine.cc
+affine.h
+angle_units.cc
+angle_units.h
+arrow_data.cc
+arrow_data.h
+arrow_style.cc
+arrow_style.h
+axis.cc
+axis.h
+bash_completions
+camera.cc
+camera.h
+circle.cc
+circle.h
+clipping.cc
+clipping.h
+Color.cc
+Color.h
+Color_Base.cc
+Color_Base.h
+Color_CMY.cc
+Color_CMY.h
+Color_CMYK.cc
+Color_CMYK.h
+Color_Gray.cc
+Color_Gray.h
+#Color_Named.cc
+#Color_Named.h
+Color_Neutral.cc
+Color_Neutral.h
+Color_RGB.cc
+Color_RGB.h
+Color_Sep.cc
+Color_Sep.h
+Color_Utils.cc
+Color_Utils.h
+#color.cc
+#color.h
+config.guess
+config.sub
+configure
+configure.ac
+#configure.in
+constants.h
+crop_algorithms.h
+cropping.h
+cropping.cc
+curves.cc
+curves.h
+data_bins.cc
+data_bins.h
+data_file.cc
+data_file.h
+data_mask.cc
+data_mask.h
+#dataplot.cc
+#dataplot.h
+debug.h
+depcomp
+deriv.h
+domain.cc
+domain.h
+edge_data.h
+eepic.cc
+eepic.h
+elaps.1
+elaps.in
+enums.h
+#epix.1
+epix.1.in
+#epix.ebuild
+epix.el.in
+epix.in
+#epix.spec
+epix-lib.sh
+errors.h
+facet.cc
+facet.h
+files
+flix.1
+flix.in
+fmt_template.cc
+fmt_template.h
+format.cc
+format.h
+frac.cc
+frac.h
+frame.cc
+frame.h
+functions.cc
+functions.h
+geometry.cc
+geometry.h
+#globals.cc
+#globals.h
+glyph.cc
+glyph.h
+halfspace.cc
+halfspace.h
+hatching.cc
+hatching.h
+install-sh
+intersections.cc
+intersections.h
+interval.cc
+interval.h
+label_data.cc
+label_data.h
+label_style.cc
+label_style.h
+#Label.cc
+#Label.h
+laps.1
+laps.in
+legend.cc
+legend.h
+legend_item.cc
+legend_item.h
+legend_tile.cc
+legend_tile.h
+length.cc
+length.h
+lens.cc
+lens.h
+make_header
+map.h
+markers.cc
+markers.h
+marker_style.cc
+marker_style.h
+mask_diamond.cc
+mask_diamond.h
+mask_ellipse.cc
+mask_ellipse.h
+mask_rectangle.cc
+mask_rectangle.h
+missing
+mkinstalldirs
+#objects.cc
+#objects.h
+#output.cc
+#output.h
+paint_style.cc
+paint_style.h
+pairs.cc
+pairs.h
+path.h
+path.cc
+path_data.cc
+path_data.h
+path_style.cc
+path_style.h
+pen_arrow.cc
+pen_arrow.h
+pen_data.cc
+pen_data.h
+pen_fill.cc
+pen_fill.h
+pen_line.cc
+pen_line.h
+picture.cc
+picture.h
+picture_data.cc
+picture_data.h
+plane.cc
+plane.h
+plot_algorithms.h
+plots.cc
+plots.h
+#polygon.cc
+#polygon.h
+#polyhedron.cc
+#polyhedron.h
+pst.cc
+pst.h
+screen.cc
+screen.h
+screen_crop.cc
+screen_crop.h
+screen_data.cc
+screen_data.h
+screen_mask.cc
+screen_mask.h
+segment.cc
+segment.h
+sphere.cc
+sphere.h
+spline_data.h
+spline.cc
+spline.h
+state.cc
+state.h
+#state_data.cc
+#state_data.h
+surface.cc
+surface.h
+tikz.cc
+tikz.h
+tile.cc
+tile.h
+triples.cc
+triples.h
+utils.cc
+utils.h
+verbatim.cc
+verbatim.h
diff --git a/graphics/epix/flix.1 b/graphics/epix/flix.1
new file mode 100644
index 0000000000..4430a02037
--- /dev/null
+++ b/graphics/epix/flix.1
@@ -0,0 +1 @@
+.so man1/epix.1
diff --git a/graphics/epix/flix.in b/graphics/epix/flix.in
new file mode 100644
index 0000000000..5c011ab3af
--- /dev/null
+++ b/graphics/epix/flix.in
@@ -0,0 +1,563 @@
+#! /bin/bash
+#
+# flix: Convert ePiX file(s) to png/mng/gif
+#
+# Options: --help for usage, --version for version and license
+#
+# Compiler flags may be specified on the command line or in the config
+# file ~/.epixrc, just as for epix.
+#
+# LaTeX packages may be specified on the command line or in the config
+# file ~/.dvipsrc, just as for elaps
+#
+# Copyright (C) 2004, 2005, 2006, 2007
+# Andrew D. Hwang <For address, do "flix -V">
+#
+
+. "@pkglibdir@/epix-lib.sh"
+
+EPIX_CONFIG_FILE="$HOME/.epixrc"
+FLIX_CONFIG_FILE="$HOME/.flixrc"
+
+# Search these extensions in order of preference
+FLIX_EXTENSIONS="flx xp cc c C cpp" # or NULL
+FLIX_DOT_EXT=".${FLIX_EXTENSIONS// /|.}" # for usage message
+
+# Path to standard header and library and compiler
+HDR_PATH="-I@includedir@"
+LIB_PATH="-L@pkglibdir@"
+COMPILER="@RUNTIME_COMPILER@"
+
+# default values
+FLIX_TMAX=1
+FLIX_FRAME_COUNT=24
+FLIX_DELAY=8
+
+# filename variables
+declare FLIX_FRAME # $EPIX_INROOT-frameXX
+declare FLIX_MOVIE # actual output filename
+
+FLIX_SUFFIX=mng
+
+# flags
+FLIX_PROGRESS="yes" # Show progress bar?
+FLIX_ONLY_EEPIC="no" # Create eepic files only?
+FLIX_ONLY_PNG="no" # Create png and eepic files only?
+FLIX_SAVE_EEPIC="no" # Save eepic files after run?
+FLIX_SAVE_PNG="no" # Save png files after run?
+
+FLIX_FRAME_PAD="" # zero or more zeros, dep. on number of frames
+FLIX_1ST_FRAME= # filename, to test success of compile
+
+trap '[ -n "$EPIX_TEMPDIR" ] && rm -rf "$EPIX_TEMPDIR"' 0 1 2 3 7 10 13 15
+
+# options for external programs
+declare -a ELAPS_OPTS
+
+# compiler variables
+declare GXX_INCLUDES
+declare GXX_LIBDIRS
+GXX_LIBS="-lm"
+GXX_POSTLIBS="-lepix"
+declare -a GXX_DEFINES
+
+function flix_help
+{
+cat <<HELP
+Options:
+ -h, --help
+ Show this message and exit
+
+ -V, --version, --gpl
+ Show version and license
+
+ -v, --verbose
+ Show success/failure messages
+
+ -d, --delay
+ Set frame delay in 1/100 sec (default 8)
+
+ --frames
+ Set number of frames (default 24).
+
+ --gif
+ Create gif output instead of mng
+
+ --no-defaults
+ Do not use default include/library directories or libraries
+
+ --pst
+ Write frames using PSTricks macros (useful only with --save-eepic)
+
+ --tikz
+ Write frames using tikz macros (useful only with --save-eepic)
+
+ --eepic
+ Write frames using eepic macros (useful only with --save-eepic)
+
+ --only-eepic
+ Create only eepic files (default no); implies --save-eepic
+
+ --only-png
+ Create only png files (default no); implies --save-png
+
+ -o, --output
+ Specify output file explicitly (extension optional)
+
+ --save-eepic
+ Save eepic files (default no)
+
+ --save-png
+ Save png files (default no)
+
+ -t, --tmax
+ Set maximum time on animation interval (default 1.0).
+
+ -H, --huge
+ Use hugelatex (if available) to compile frames
+
+ -D*
+ Pass preprocessor definition to the compiler
+
+ -I*, -L*, -l*, -W*, -i*, -u, -x
+ Passed to g++ (q.v.)
+
+ Other options are passed to elaps (q.v.)
+
+HELP
+ePiX_bugreport
+
+} # End of flix_help
+
+
+function flix_pad_init()
+{
+ let TMP_CT=$((FLIX_FRAME_COUNT/10))
+ while [ $TMP_CT -ne 0 ]
+ do
+ let TMP_CT=$((TMP_CT/10))
+ FLIX_FRAME_PAD="0$FLIX_FRAME_PAD"
+ done
+}
+
+
+# Parse command line/config file for compiler flags/options
+function flix_parse_options
+{
+while [ "$1" != "${1#-}" ]; do
+ case "$1" in
+
+ -v|--verbose)
+ if [ -z "$2" ]; then
+ echo "Please use -V for version"
+ exit 0
+ fi
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ FLIX_PROGRESS="no"
+ shift; continue
+ ;;
+
+ -vv)
+ echo "Discontinued option -vv; please use -v for verbose output"
+ exit 0
+ ;;
+
+ -h|--help)
+ ePiX_usage flix $FLIX_DOT_EXT
+ flix_help
+ exit 0
+ ;;
+
+ -V|--version|--gpl)
+ ePiX_version flix
+ ePiX_license
+ exit 0
+ ;;
+
+ -d|--delay)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_DELAY="$2"
+ shift 2; continue
+ ;;
+
+ --frames)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_FRAME_COUNT="$2"
+ shift 2; continue
+ ;;
+
+ --gif)
+ FLIX_SUFFIX=gif
+ shift; continue
+ ;;
+
+ --no-defaults)
+ GXX_POSTLIBS=
+ HDR_PATH=
+ LIB_PATH=
+ ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1")
+ shift; continue
+ ;;
+
+ --pst)
+ GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_PSTRICKS")
+ shift; continue
+ ;;
+
+ --tikz)
+ GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_TIKZ")
+ shift; continue
+ ;;
+
+ --eepic)
+ GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_EEPIC")
+ shift; continue
+ ;;
+
+ --only-eepic)
+ FLIX_ONLY_EEPIC="yes"
+ FLIX_SAVE_EEPIC="yes"
+ shift; continue
+ ;;
+
+ --only-png)
+ FLIX_ONLY_PNG="yes"
+ FLIX_SAVE_PNG="yes"
+ shift; continue
+ ;;
+
+ -o|--output)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_OUTFILE="$2"
+ if [ "$FLIX_OUTFILE" = "${FLIX_OUTFILE%.mng}.mng" ]; then
+ FLIX_SUFFIX=mng
+ EPIX_OUTROOT="${FLIX_OUTFILE%.mng}"
+
+ elif [ "$FLIX_OUTFILE" = "${FLIX_OUTFILE%.gif}.gif" ]; then
+ FLIX_SUFFIX=gif
+ EPIX_OUTROOT="${FLIX_OUTFILE%.gif}"
+
+ else
+ EPIX_OUTROOT="$FLIX_OUTFILE"
+
+ fi
+ shift 2; continue
+ ;;
+
+ # Deliberately undocumented
+ -q|--quiet)
+ EPIX_STDERR="$SYSTEM_DEVNULL"
+ shift; continue
+ ;;
+
+ --save-eepic)
+ FLIX_SAVE_EEPIC="yes"
+ shift; continue
+ ;;
+
+ --save-png)
+ FLIX_SAVE_PNG="yes"
+ shift; continue
+ ;;
+
+ -t|--tmax)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_TMAX="$2"
+ shift 2; continue
+ ;;
+
+ -H|--huge)
+ ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1")
+ shift 1; continue
+ ;;
+
+ -D)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ if [ "$2" != "${2#-}" ]; then
+ GXX_DEFINES=("${GXX_DEFINES[@]}" "-D$2")
+ shift 2; continue
+ else
+ ePiX_warn "Ignoring option \"$1\" followed by \"$2\""
+ shift 1; continue
+ fi
+ ;;
+
+ -D*)
+ GXX_DEFINES=("${GXX_DEFINES[@]}" "$1")
+ shift 1; continue
+ ;;
+
+ -I)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ GXX_INCLUDES="$GXX_INCLUDES -I$2"; shift 2; continue
+ ;;
+
+ -L)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ GXX_LIBDIRS="$GXX_LIBDIRS -L$2"; shift 2; continue
+ ;;
+
+ -l)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ GXX_LIBS="$GXX_LIBS -l$2"; shift 2; continue
+ ;;
+
+ -W)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_WARNS="$FLIX_WARNS -W$2"; shift 2; continue
+ ;;
+
+ -I*)
+ GXX_INCLUDES="$GXX_INCLUDES $1"; shift; continue
+ ;;
+
+ -L*)
+ GXX_LIBDIRS="$GXX_LIBDIRS $1"; shift; continue
+ ;;
+
+ -l*)
+ GXX_LIBS="$GXX_LIBS $1"; shift; continue
+ ;;
+
+ -W*)
+ FLIX_WARNS="$FLIX_WARNS $1"; shift; continue
+ ;;
+
+ # Relatively obscure compiler options
+ -i*|-u|-x)
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ FLIX_FLAGS="$FLIX_FLAGS $1 $2"; shift 2; continue
+ ;;
+
+ *) # Pass other options to elaps
+ if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi
+ if [ "$2" != "${2#-}" ]; then
+ ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1")
+ shift 1; continue
+ else
+ ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1" "$2")
+ shift 2; continue
+ fi
+ ;;
+ esac
+done
+
+# Assume remaining parameters are input files
+FLIX_FILE_LIST=("$@")
+} # End of flix_parse_options
+
+
+# compile infile outfile.exe
+function flix_compile_files()
+{
+ if [ -z "$1" ]; then
+ ePiX_die "No input file specified"
+ fi
+
+ # See epix-lib.sh
+ mkdir "$EPIX_TEMPDIR" || ePiX_die "Can't create \"${EPIX_TEMPDIR}\""
+
+ # file counts
+ local processed=0
+ local success=0
+ local failure=0
+
+ # N.B. Global variables named EPIX_XX
+ for EPIX_INFILE in "${FLIX_FILE_LIST[@]}"; do
+
+ epix_parse_filename "$EPIX_INFILE" "$FLIX_EXTENSIONS"
+ let processed=processed+1
+
+ if [ "$EPIX_NOTFOUND" = "yes" ]; then ePiX_fail && continue ; fi
+
+ : ${EPIX_OUTROOT=$EPIX_INROOT}
+ FLIX_FRAME="$EPIX_OUTROOT"-frame
+
+ # Temporary binary
+ { TEMP_BIN="$EPIX_INROOT" && touch "${EPIX_TEMPDIR}/$TEMP_BIN" ; } ||
+ { ePiX_fail "No write permission in \"${EPIX_TEMPDIR}\"?!" && \
+ continue ; }
+
+ TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_BIN")
+
+ # Create symlink to input file with appropriate extension for compiler
+ TEMP_INPUT="${TEMP_BIN}-tmp.cc"
+
+ TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_INPUT")
+
+ { cd ${EPIX_TEMPDIR} && \
+ ln -s "../$EPIX_INFILE" "$TEMP_INPUT" && cd .. ; } ||
+ { ePiX_fail "Couldn't create \"${EPIX_TEMPDIR}/$TEMP_INPUT\"" && \
+ continue ; }
+
+ # Compile executable
+ TMP_CMD=($COMPILER "${EPIX_TEMPDIR}/$TEMP_INPUT" $FLIX_WARNS \
+ "${GXX_DEFINES[@]}" -o "${EPIX_TEMPDIR}/$TEMP_BIN" \
+ $HDR_PATH $GXX_INCLUDES $LIB_PATH $GXX_LIBDIRS $GXX_LIBS \
+ $GXX_POSTLIBS $FLIX_FLAGS)
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ # Write animation frames
+ if [ ! -x "${EPIX_TEMPDIR}/$TEMP_BIN" ]; then
+ ePiX_fail "Couldn't compile executable \"${EPIX_TEMPDIR}/$TEMP_BIN\""
+ continue
+ fi
+
+ # purge old files
+ rm -f "$FLIX_FRAME"*.eepic # eepics always overwritten
+
+ if [ "$FLIX_ONLY_EEPIC" = "no" ]; then
+ # some pngs clobbered => remove all
+ rm -f "$FLIX_FRAME"*.png
+ fi
+
+ # and create new frames
+ for i in $(seq 1 $FLIX_FRAME_COUNT); do
+ flix_png "${EPIX_TEMPDIR}/$TEMP_BIN" $i
+
+ # bomb out if we can't create first new frame
+ if [ ! -f "${FLIX_1ST_FRAME}" ]; then
+ ePiX_fail "Couldn't create frames"
+ continue 2
+ fi
+ done
+
+ if [ "$FLIX_ONLY_PNG" = "no" -a "$FLIX_ONLY_EEPIC" = "no" ]; then
+ FLIX_MOVIE="${EPIX_OUTROOT}.$FLIX_SUFFIX"
+ TMP_CMD=(convert -delay $FLIX_DELAY "$FLIX_FRAME"*.png "$FLIX_MOVIE")
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ -f "$FLIX_MOVIE" ]; then
+ let success=success+1
+ else
+ ePiX_fail "Couldn't assemble frames"
+ continue
+ fi
+ fi
+
+ echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ # clean up
+ if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi
+
+ rm -f "$FLIX_FRAME"*.eps "$FLIX_FRAME"*.log
+
+ if [ "$FLIX_SAVE_EEPIC" = "no" ]; then
+ rm -f "$FLIX_FRAME"*.eepic
+ fi
+
+ if [ "$FLIX_SAVE_PNG" = "no" ]; then
+ rm -f "$FLIX_FRAME"*.png
+ fi
+
+ # Newline after progress bar?
+ if [ "$FLIX_PROGRESS" = "yes" ]; then echo; fi
+
+ done # for EPIX_INFILE in $FLIX_INFILE_LIST
+
+ if [ $processed -gt 1 ]; then
+ echo "$processed files processed: $success movie(s) written, $failure failed" > "$EPIX_STDERR"
+ fi
+
+ if [ -d "$EPIX_TEMPDIR" ]; then rm -Rf "$EPIX_TEMPDIR"; fi
+} # end of flix_compile_files()
+
+
+# Prints ....|....10....|....20
+function progress_bar()
+{
+ if [ $(($1 % 10)) -eq 0 ]; then
+ echo -n "$1"
+ elif [ $(($1 % 5)) -eq 0 ]; then
+ echo -n "|"
+ else
+ echo -n "."
+ fi
+}
+
+
+# Create a single eepic, eps, and/or png file:
+# flix_png file.exe frame_number
+function flix_png()
+{
+ local TEMP_BIN="$1"
+ local INDEX="$2"
+
+ TIME=$(echo ${FLIX_TMAX}*${INDEX} | bc)
+
+ # Calculate number of 0s in output filename
+ TMP_CT=$(( ${INDEX}/10 ))
+ TMP_PAD="$FLIX_FRAME_PAD"
+
+ # progress bar
+ if [ "$FLIX_PROGRESS" = "yes" ]; then
+ progress_bar $INDEX
+ else
+ ePiX_msg "Frame $INDEX.eps"
+ fi
+
+ # each time we're divisible by ten, remove a 0 from padding
+ while [ $TMP_CT -ne 0 ]
+ do
+ TMP_CT=$(($TMP_CT/10))
+ TMP_PAD="${TMP_PAD%%0}"
+ done
+
+ INDEX="$TMP_PAD$INDEX" # pad with 0s
+ if [ $2 -eq 1 ]; then FLIX_1ST_FRAME="$FLIX_FRAME"${TMP_PAD}1.eepic; fi
+
+ TMP_NAME="${FLIX_FRAME}${INDEX}"
+
+ "./$TEMP_BIN" $TIME $FLIX_FRAME_COUNT > "$TMP_NAME".eepic
+
+ if [ $? -ne 0 ]; then
+ ePiX_warn "Could not create frames"
+ return
+ fi
+
+ if [ "$FLIX_ONLY_EEPIC" = "no" ]; then # create eps
+ TEMPFILES=("{TEMPFILES[@]}" "$TMP_NAME".eps)
+
+ TMP_CMD=(elaps "${ELAPS_OPTS[@]}" -o "$TMP_NAME".eps "$TMP_NAME".eepic)
+ ePiX_command "${TMP_CMD[@]}"
+
+ TMP_CMD=(convert "$TMP_NAME".eps "$TMP_NAME".png)
+ ePiX_command "${TMP_CMD[@]}"
+ fi
+} # end of flix_png()
+
+## Script proper starts here ##
+
+if [ $# -eq 0 ]; then
+ ePiX_usage flix $FLIX_DOT_EXT
+ flix_help
+ exit 0
+fi
+
+# Read options from config files, if any
+if [ -f "$EPIX_CONFIG_FILE" ]; then
+ cat "$EPIX_CONFIG_FILE" | grep -v "#" | \
+ while read line; do
+ flix_parse_options "$line"
+ done
+fi
+
+if [ -f "$FLIX_CONFIG_FILE" ]; then
+ cat "$FLIX_CONFIG_FILE" | grep -v "#" | \
+ while read line; do
+ flix_parse_options "$line"
+ done
+fi
+
+flix_parse_options "$@"
+
+flix_pad_init
+
+# Suppress all warnings if none are requested
+if [ "$FLIX_WARNS" = "" ]; then FLIX_WARNS="-w"; fi
+
+flix_compile_files "${FLIX_FILE_LIST[@]}"
+
+exit 0
diff --git a/graphics/epix/fmt_template.cc b/graphics/epix/fmt_template.cc
new file mode 100644
index 0000000000..3b7e423070
--- /dev/null
+++ b/graphics/epix/fmt_template.cc
@@ -0,0 +1,177 @@
+/*
+ * fmt.cc -- ePiX::fmt output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 08, 2007
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <list>
+
+#include <string>
+#include <sstream>
+
+#include <set>
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "Color.h"
+
+#include "path_style.h"
+#include "pen_data.h"
+
+#include "format.h"
+#include "fmt.h"
+
+namespace ePiX {
+
+ fmt::fmt() { } // modify as necessary
+
+ fmt* fmt::clone() const
+ {
+ return new fmt(*this);
+ }
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string fmt::print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const
+ {
+ // Use print_paths to represent a closed polygon bounded by
+ // "edges", drawn with "line" and solid "fill"-ed.
+ }
+
+ // Unfilled region, specified Cartesian edges. Should generally be
+ // trivially implemented using one-pen function (supplied).
+ std::string fmt::print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line_pen,
+ const pen_data& base_pen,
+ const path_state& style,
+ const std::string& len) const
+ {
+ // Use print_paths (solid) or format::print_edges (otherwise) to
+ // represent a (closed or open) polygon bounded by "edges", drawn
+ // with "line" and "base" pens in the line "style".
+ }
+
+ /*
+ * Default implementations provided, see format.cc. If default works
+ * for the new format, remove these declarations.
+ // Picture start and finish:
+ // Size and offset in page units,
+ // pallet (set of colors contained in the screen),
+ // unitlength
+ std::string fmt::pic_header(const pair& sizes,
+ const pair& offsets,
+ const std::set<Color>& pallet,
+ const std::string& len) const
+ {
+ // Print commands to draw a picture of specified true size and offset
+ }
+
+ std::string fmt::pic_footer() const
+ {
+ // Close/end the picture
+ }
+ */
+
+ // Print color declaration strings: model, name, densities;
+ // may simply return xdefinecolor(...) if appropriate
+ std::string fmt::print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const;
+
+ std::string fmt::print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const;
+
+ // One-line comment
+ std::string fmt::print_comment(const std::string&) const;
+
+ // Verbatim output
+ std::string fmt::print_verbatim(const std::string&) const;
+
+
+ // start/end a picture-like environment, set unit length
+ std::string fmt::start_picture(const pair&, const pair&) const;
+ std::string fmt::end_picture() const;
+
+ std::string fmt::set_unitlength(const std::string& len) const;
+
+ // reset internal state date to null
+ void fmt::reset_state() const;
+
+ //// private member functions ////
+
+ // returns "usepackages" + [SPACE] + "comma-separated LaTeX packages"
+ std::string fmt::usepackages() const
+ {
+ return "usepackages fmt";
+ }
+
+ // string argument for passing attributes local to this path/loop
+ std::string fmt::start_open_path(const std::string&) const;
+ std::string fmt::end_open_path(const std::string&) const;
+
+ std::string fmt::start_closed_path(const std::string&) const;
+ std::string fmt::end_closed_path(const std::string&) const;
+
+ // print declarations to set state of output format
+ std::string fmt::set_fill_state(const Color&) const;
+ std::string fmt::set_pen_state(const pen_data&) const;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string fmt::put_box(const pair&, const std::string&) const;
+
+ // draw a filled or hollow circle of specified diam, color
+ std::string fmt::print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const;
+
+ //// "Optional" (implemented, but reimplementable) functions ////
+ // Used to format line breaks in long paths (e.g. newline and two spaces)
+ // std::string fmt::path_break() const;
+
+ // Used between points in paths (e.g. "" or "--")
+ // std::string fmt::path_connector() const;
+
+ // std::string fmt::print_pallet(const std::set<Color>& pallet) const;
+
+ // Represent a pair, length, or Color as a string
+ // std::string fmt::print(const pair&) const; // Default: "(a,b)"
+ // std::string fmt::print(const length&) const; // Default: "3.5cm", e.g.
+ // std::string fmt::print(const Color&) const; // Default: color name
+
+} // end of namespace
diff --git a/graphics/epix/fmt_template.h b/graphics/epix/fmt_template.h
new file mode 100644
index 0000000000..a50b3a3855
--- /dev/null
+++ b/graphics/epix/fmt_template.h
@@ -0,0 +1,170 @@
+/*
+ * fmt.h -- ePiX::fmt output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 08, 2007
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * To create files foo.h, foo.cc for output format "foo", do
+ *
+ * for suff in cc h; do
+ * sed 's/fmt/foo/g' format_template.$suff > foo.$suff
+ * done
+ *
+ * The include guards and initial comments should be updated manually.
+ */
+
+#ifndef EPIX_FMT
+#define EPIX_FMT
+
+#include <set>
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class Color;
+ class pair;
+ class path_state;
+ class pen_data;
+
+ class fmt : public format {
+ public:
+
+ fmt(); // some constructor mandatory, needn't have this signature
+
+ // Return a copy of this
+ fmt* clone() const;
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const;
+
+ // Unfilled region, specified Cartesian edges. Should generally be
+ // trivially implemented using one-pen function (supplied).
+ std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line_pen,
+ const pen_data& base_pen,
+ const path_state& style,
+ const std::string& len) const;
+
+ /*
+ * Picture start and finish:
+ * Size and offset in page units,
+ * pallet (set of colors contained in the screen),
+ * unitlength
+ *
+ * These functions have default implementations, see format.cc.
+ * If the new format can use the default implementation, these
+ * functions declarations should be removed.
+ *
+ std::string pic_header(const pair& sizes,
+ const pair& offsets,
+ const std::set<Color>& pallet,
+ const std::string& len) const;
+
+ std::string pic_footer() const;
+ */
+
+ // Print color declaration strings: model, name, densities
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const;
+
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const;
+
+ // One-line comment
+ std::string print_comment(const std::string&) const;
+
+ // Verbatim output
+ std::string print_verbatim(const std::string&) const;
+
+
+ // begin and end a picture-like environment, set the unit length
+ std::string start_picture(const pair&, const pair&) const;
+ std::string end_picture() const;
+
+ std::string set_unitlength(const std::string& len) const;
+
+ // State data, if any, must be mutable
+ void reset_state() const;
+
+ private:
+
+ std::string usepackages() const;
+
+ // string argument for passing attributes local to this path/loop
+ std::string start_open_path(const std::string&) const;
+ std::string end_open_path(const std::string&) const;
+
+ std::string start_closed_path(const std::string&) const;
+ std::string end_closed_path(const std::string&) const;
+
+ // print declarations to set state of output format
+ std::string set_fill_state(const Color&) const;
+ std::string set_pen_state(const pen_data&) const;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string put_box(const pair&, const std::string&) const;
+
+ // draw a filled or hollow circle of specified diam, color
+ std::string print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const;
+
+ //// "Optional" (implemented, but reimplementable) functions ////
+ // inserted in long paths, defaults to <newline> and two spaces
+ // std::string path_break() const;
+
+ // inserted between path points, deaults to ""
+ // std::string path_break() const;
+
+ // std::string print_pallet(const std::set<Color>&) const;
+
+ // Represent a pair, length, or Color as a string
+ // std::string print(const pair&) const; // Default: "(a,b)"
+ // std::string print(const length&) const; // Default: "3.5cm", e.g.
+ // std::string print(const Color&) const; // Default: color name
+
+ }; // end of class fmt
+} // end of namespace
+
+#endif /* EPIX_FMT */
diff --git a/graphics/epix/format.cc b/graphics/epix/format.cc
new file mode 100644
index 0000000000..f799baa7a4
--- /dev/null
+++ b/graphics/epix/format.cc
@@ -0,0 +1,720 @@
+/*
+ * format.cc -- ePiX output format interface and label-writing functions
+ *
+ * This file is part of ePiX, a c++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <list>
+
+#include "enums.h"
+#include "constants.h"
+
+#include "errors.h"
+#include "utils.h"
+
+#include "functions.h"
+
+#include "marker_style.h"
+#include "label_style.h"
+#include "path_style.h"
+#include "Color.h"
+
+#include "pen_data.h"
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "length.h"
+
+#include "picture.h" // circ may need to add White to pallet
+#include "picture_data.h"
+
+#include "format.h"
+
+namespace ePiX {
+ // public, non-virtual
+ // LaTeX label-generating commands written in terms of protected interface
+ std::string format::print_mark(const pair& here, const pair& offset,
+ const epix_mark_type mk,
+ const marker_sizes& sz,
+ const label_state& style,
+ const std::string& len) const
+ {
+ // convert dotsize to len
+ length true_diam(sz.dot_size());
+ double diam(true_diam.to(len).magnitude());
+
+ // set diameter
+ if (mk == DOT || mk == CIRC)
+ diam *= 0.75;
+ else if (mk == DDOT)
+ diam *= 0.5;
+
+ // and print
+ if (mk == SPOT || mk == DOT || mk == DDOT)
+ return print_circle_marker(here + pt_to_len(offset, len), diam, true,
+ style.text_color(), len);
+
+ else if (mk == CIRC) // Draw filled dot, then ring
+ {
+ Color bk(style.mask_color());
+ // use White for unset mask
+ if (bk.is_unset())
+ {
+ bk = White();
+ the_picture().add_to_pallet(bk);
+ }
+
+ return print_circle_marker(here + pt_to_len(offset, len), diam, true,
+ bk, len)
+ + print_circle_marker(here + pt_to_len(offset, len), diam, false,
+ style.text_color(), len);
+ }
+
+ else if (mk == RING)
+ return print_circle_marker(here + pt_to_len(offset, len), diam, false,
+ style.text_color(), len);
+
+ else
+ return put_box(here + pt_to_len(offset, len),
+ print_latex_label(style, print_latex_marker(mk, sz, len),
+ false)); // no mask or box
+ }
+
+ // public, non-virtual
+ std::string format::print_text(const pair& here, const pair& offset,
+ const std::string& label,
+ const label_state& style,
+ const std::string& len) const
+ {
+ return put_box(here + pt_to_len(offset, len),
+ print_latex_label(style, label, true));
+ }
+
+
+ // public, non-virtual
+ std::string format::print_line(const edge2d& e,
+ const pair& offset,
+ const pen_data& line,
+ const pen_data& base,
+ const path_state& style,
+ const std::string& len) const
+ {
+ if ((line.width() < length(EPIX_EPSILON))
+ || (line.color().is_unset())
+ || !e.is_seen() )
+ return "";
+
+ // else
+ std::list<edge2d> edges;
+ edges.push_back(e);
+ return print_line(edges, offset, line, base, style, len);
+ }
+
+
+ // public, non-virtual (file header comment block)
+ std::string format::file_comments(const std::string& units,
+ const length& hoffset,
+ const length& voffset,
+ double Xmin, double Xmax,
+ double Ymin, double Ymax,
+ double Hsize, double Vsize) const
+ {
+ std::ostringstream obuf;
+
+ const std::string hoff_dir(length(0) < hoffset ? "right" : "left");
+ const std::string voff_dir(length(0) < voffset ? "up" : "down");
+
+ const double hoff(hoffset.magnitude());
+ const double voff(voffset.magnitude());
+
+ std::stringstream bd_box, act_sz, fg_off;
+ bd_box << " Cartesian bounding box: ["
+ << Xmin << "," << Xmax << "] x [" << Ymin << "," << Ymax<< "]";
+
+ act_sz << " Actual size: " << Hsize << " x " << Vsize << units;
+
+ fg_off << " Figure offset: "
+ << hoff_dir << " by " << hoff << units << ", "
+ << voff_dir << " by " << voff << units;
+
+ obuf << print_comment("ePiX-" + epix_version())
+ << print_comment("")
+ << print_comment(bd_box.str())
+ << print_comment(act_sz.str())
+ << print_comment(fg_off.str())
+ << print_comment("")
+ << print_comment(usepackages())
+ << print_comment("");
+
+ return obuf.str();
+ } // end of file_comments()
+
+
+ // public, virtual
+ std::string format::pic_header(const pair& sizes,
+ const pair& offsets,
+ const std::set<Color>& pallet,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+ obuf << print_pallet(pallet)
+ << set_unitlength(len)
+ << start_picture(sizes, offsets);
+
+ return obuf.str();
+ }
+
+ // public, virtual
+ std::string format::pic_footer() const
+ {
+ return end_picture();
+ }
+
+ // public, non-virtual
+ std::string format::print_color(const std::string& model,
+ const std::string& name,
+ const std::vector<double>& dens) const
+ {
+ if (dens.size() == 3)
+ return print_color(model, name, dens.at(0), dens.at(1), dens.at(2));
+
+ else if (dens.size() == 4)
+ return print_color(model, name,
+ dens.at(0), dens.at(1), dens.at(2), dens.at(3));
+
+ else if (dens.size() == 0) // Neutral()
+ return "";
+
+ else
+ {
+ epix_warning("format::print_color(): Internal error");
+ return print_color("rgb", "rgb_000000", 0, 0, 0);
+ }
+ }
+
+ // protected, non-virtual (one-pen version)
+ std::string format::print_line(const std::list<edge2d>& edges,
+ const pair& offset, const pen_data& line,
+ const path_state& style,
+ const std::string& attribs,
+ const std::string& len) const
+ {
+ if ( (line.width() < length(EPIX_EPSILON))
+ || (line.color().is_unset())
+ || edges.begin() == edges.end() )
+ return "";
+
+ // else
+ std::stringstream value, obuf;
+
+ obuf << set_pen_state(line);
+
+ if (style.is_solid())
+ obuf << print_paths(edges, offset, attribs, len);
+
+ else // not solid
+ {
+ // compute diameter of dots
+ length lw(line.width());
+ lw.to(len);
+
+ // compute unit length in pt
+ length units("1"+len);
+ units.to("pt");
+ double in_pt(units.magnitude());
+
+ double pattern_size(style.separation()); // in pt
+
+ // split each edge into pattern_size chunks if necessary
+ for (std::list<edge2d>::const_iterator ep = edges.begin();
+ ep != edges.end(); ++ep)
+ {
+ double curr_len(((*ep).length())*in_pt);
+
+ // number of dash patterns *ep can hold
+ unsigned int N((unsigned int) ceil(curr_len/pattern_size));
+ if (N == 1)
+ obuf << print_edge((*ep), offset, style.breakpts(),
+ lw.magnitude(), line.color(), attribs, len);
+
+ if (N > 1)
+ {
+ pair T((*ep).tail()), dir((1.0/N)*((*ep).head() - T));
+ for (unsigned int i=0; i<N; ++i)
+ obuf << print_edge(edge2d(T+i*dir, T+(i+1)*dir,
+ (*ep).is_seen()),
+ offset, style.breakpts(),
+ lw.magnitude(), line.color(),
+ attribs, len);
+ }
+ }
+ } // end of !solid
+
+ return obuf.str();
+ } // end of print_line(edges, offset, line, style, attribs, len)
+
+
+ std::string format::print_line(const edge2d& e,
+ const pair& offset,
+ const pen_data& line,
+ const path_state& style,
+ const std::string& attribs,
+ const std::string& len) const
+ {
+ if ( (line.width() < length(EPIX_EPSILON)) ||
+ (line.color().is_unset()) ||
+ !e.is_seen() )
+ return "";
+
+ std::list<edge2d> edges;
+ edges.push_back(e);
+ return print_line(edges, offset, line, style, attribs, len);
+ }
+
+
+ // local to this file
+ std::string __epix_rule(double x, double y)
+ {
+ std::stringstream buf;
+ buf << "\\rule{" << x << "pt}{" << y << "pt}";
+
+ return buf.str();
+ }
+
+
+ // protected, non-virtual
+ std::string format::xdefinecolor(const std::string& model,
+ const std::string& name,
+ double d1, double d2, double d3) const
+ {
+ std::stringstream obuf;
+ obuf << "\\xdefinecolor{" << name << "}";
+
+ if (model == "cmy")
+ {
+ double bk(min(min(d1,d2),d3));
+
+ obuf << "{cmyk}{"
+ << d1-bk << "," << d2-bk << "," << d3-bk << "," << bk << "}%"
+ << std::endl;
+ }
+
+ else
+ obuf << "{" << model << "}{" << d1 << "," << d2 << "," << d3 << "}%"
+ << std::endl;
+
+ return obuf.str();
+ }
+
+ // protected, non-virtual
+ std::string format::xdefinecolor(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3, double d4) const
+ {
+ std::stringstream obuf;
+ obuf << "\\xdefinecolor{" << name << "}{cmyk}{"
+ << d1 << "," << d2 << "," << d3 << "," << d4 << "}%"
+ << std::endl;
+
+ return obuf.str();
+ }
+
+ // protected, virtual
+ std::string format::print_pallet(const std::set<Color>& pallet) const
+ {
+ std::stringstream obuf;
+
+ for (std::set<Color>::const_iterator cp=pallet.begin();
+ cp!=pallet.end(); ++cp)
+ obuf << print_color((*cp).model(), (*cp).name(), (*cp).densities());
+
+ return obuf.str();
+ }
+
+ // protected, virtual
+ std::string format::print(const pair& arg) const
+ {
+ std::stringstream o;
+ o << "(" << truncate(arg.x1()) << "," << truncate(arg.x2()) << ")";
+ return o.str();
+ }
+
+ // protected, virtual
+ std::string format::print(const length& len) const
+ {
+ return len.name();
+ }
+
+ // protected, virtual
+ std::string format::print(const Color& col) const
+ {
+ return col.name();
+ }
+
+ // protected, non-virtual (print non-solid edge as segments and dots)
+ std::string format::print_edge(const edge2d& edge, const pair& offset,
+ const std::vector<double> bkpts,
+ double diam, const Color& col,
+ const std::string& attribs,
+ const std::string& len) const
+ {
+ if (!edge.is_seen())
+ return "";
+
+ if (bkpts.size() % 2 != 0)
+ {
+ epix_warning("Internal error in path pattern");
+ return "";
+ }
+
+ // else
+ std::stringstream obuf;
+
+ const pair T(edge.tail() + pt_to_len(offset, len));
+ const pair dir(edge.head() - edge.tail());
+
+ for (unsigned int i=0; i < bkpts.size(); i += 2)
+ {
+ double curr(bkpts.at(i)), next(bkpts.at(i+1));
+
+ if (EPIX_EPSILON < next - curr) // dash
+ obuf << start_open_path(attribs)
+ << print(T + curr*dir)
+ << path_connector()
+ << print(T + next*dir)
+ << end_open_path(attribs);
+
+ else // dot
+ obuf << print_circle_marker(T + curr*dir, diam, true, col, len);
+ }
+
+ return obuf.str();
+ }
+
+
+ // protected, non-virtual (solid path, handle (offset) data only)
+ std::string format::print_paths(const std::list<edge2d>& edges,
+ const pair& offset,
+ const std::string& attribs,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ std::list<edge2d>::const_iterator ep(edges.begin());
+
+ const pair shift(pt_to_len(offset, len));
+
+ bool all_visible(true); // all edges visible?
+
+ // Assume not for now
+ const std::string pname(start_open_path(attribs));
+
+ // print contiguous lists of visible edges
+ while (ep != edges.end())
+ {
+ if ((*ep).is_seen()) // print contiguous visible path
+ {
+ obuf << pname
+ << print((*ep).tail() + shift)
+ << path_connector()
+ << print((*ep).head() + shift);
+ ++ep;
+
+ while ((*ep).is_seen() && ep != edges.end())
+ obuf << path_connector() << print((*ep++).head() + shift);
+
+ obuf << end_open_path(attribs);
+ }
+
+ else // invisible edge
+ {
+ ++ep;
+ all_visible = false;
+ }
+ }
+
+ std::string value(obuf.str());
+
+ --ep; // last edge
+
+ // if we're a closed loop of visible edges, adjust open/close path
+ if (all_visible && (*edges.begin()).tail() == (*ep).head())
+ {
+ value.replace(0,
+ start_open_path(attribs).size(),
+ start_closed_path(attribs));
+
+ value.replace(value.size()-end_open_path(attribs).size(),
+ end_open_path(attribs).size(),
+ end_closed_path(attribs));
+ }
+
+ return break_lines(value, path_break());
+ }
+
+
+ //// Label and marker functions ////
+ // protected, non-virtual (print LaTeX command for marker of specified size)
+ std::string format::print_latex_marker(const epix_mark_type mark,
+ const marker_sizes& sz,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ obuf << "$";
+
+ switch(mark)
+ {
+ case PLUS:
+ obuf << "+";
+ break;
+ case OPLUS:
+ obuf << "\\oplus";
+ break;
+ case TIMES:
+ obuf << "\\times";
+ break;
+ case OTIMES:
+ obuf << "\\otimes";
+ break;
+ case DIAMOND:
+ obuf << "\\diamond";
+ break;
+ case UP:
+ obuf << "\\bigtriangleup";
+ break;
+ case DOWN:
+ obuf << "\\bigtriangledown";
+ break;
+ case BOX:
+ obuf << __epix_rule(0.75*sz.dot_size(), 0.75*sz.dot_size());
+ break;
+ case BBOX:
+ obuf << __epix_rule(0.5*sz.dot_size(), 0.5*sz.dot_size());
+ break;
+ case HTICK:
+ obuf << __epix_rule(0.5, 2*sz.tick_size());
+ break;
+ case VTICK:
+ obuf << __epix_rule(2*sz.tick_size(), 0.5);
+ break;
+ // should never see these cases
+ case SPOT:
+ case DOT:
+ case DDOT:
+ case CIRC:
+ case RING:
+ epix_warning("Mark type internal error"); // fall through
+ case PATH: // fall through
+ case TEXT:
+ default:
+ return ""; // N.B. return
+ }
+
+ obuf << "$";
+
+ return obuf.str();
+ }
+
+
+ // public, non-virtual
+ // handles font face, size, and color
+ std::string format::print_latex_hbox(const label_state& style,
+ const std::string& label) const
+ {
+ std::stringstream text_buf;
+
+ bool need_ff(style.fontface() != "rm"); // roman
+ bool need_fs(style.fontsize() != "nsz"); // normalsize
+
+ text_buf << "\\hbox{\\color{" << print(style.text_color()) << "}";
+
+ if (need_ff)
+ text_buf << "\\text" << style.fontface() << "{";
+
+ if (need_fs)
+ text_buf << "\\" << style.fontsize() << " ";
+
+ text_buf << label;
+
+ if (need_ff)
+ text_buf << "}";
+
+ text_buf << "}";
+
+ return text_buf.str();
+ }
+
+
+ // protected, virtual
+ std::string format::path_break() const
+ {
+ std::stringstream buf;
+ buf << std::endl << " ";
+
+ return buf.str();
+ }
+
+ // inserted between points of a path
+ std::string format::path_connector() const
+ {
+ return "";
+ }
+
+ // protected, non-virtual
+ // handles rotation, masking, border, and alignment
+ std::string format::print_latex_label(const label_state& style,
+ const std::string& label,
+ bool boxed) const
+ {
+ std::stringstream obuf;
+
+ // need rotatebox?
+ bool rotated(EPIX_EPSILON < fabs(style.label_angle()));
+
+ // need colorbox?
+ bool masked(boxed && style.is_masked());
+
+ // need extra fcolorbox?
+ bool padded(style.label_padding() != length(0));
+
+ obuf << "\\makebox(0,0)"
+ << print(style.align_to()); // "none" -> ""
+
+ obuf << "{";
+
+ if (rotated)
+ obuf << "\\rotatebox{" << style.label_angle() << "}{";
+
+ if (masked)
+ {
+ pen_data bpen(style.label_border());
+
+ // draw border?
+ if (!bpen.color().is_unset() && length(EPIX_EPSILON) < bpen.width())
+ obuf << "\\fboxrule" << print(bpen.width()) << "%" << std::endl
+ << "\\fcolorbox{" << print(bpen.color()) << "}{"
+ << print(style.mask_color()) << "}";
+
+ else
+ obuf << "\\colorbox{" << print(style.mask_color()) << "}";
+
+ if (padded)
+ {
+ // cancel off the xcolor default
+ length extra_pad(style.label_padding() + length(-3));
+
+ obuf << "{\\fboxrule" << print(extra_pad) << "%" << std::endl
+ << "\\fcolorbox{" << print(style.mask_color()) << "}{"
+ << print(style.mask_color()) << "}";
+ }
+
+ obuf << "{";
+ }
+
+ // finally, the payload
+ obuf << print_latex_hbox(style, label);
+
+ // close wrappers
+ if (masked)
+ {
+ obuf << "}";
+
+ if (padded)
+ obuf << "}";
+ }
+
+ if (rotated)
+ obuf << "}";
+
+ obuf << "}";
+
+ return obuf.str();
+ } // end of print_latex_label
+
+ // private (convert an epix_label_posn to a string)
+ std::string format::print(const epix_label_posn arg) const
+ {
+ std::string val;
+ switch(arg)
+ {
+ case none:
+ return ""; // other cases return at bottom
+
+ case c:
+ val="c";
+ break;
+ case r:
+ val="l"; // opposite of LaTeX
+ break;
+ case tr:
+ case rt:
+ val="bl";
+ break;
+ case t:
+ val="b";
+ break;
+ case tl:
+ case lt:
+ val="br";
+ break;
+ case l:
+ val="r";
+ break;
+ case bl:
+ case lb:
+ val="tr";
+ break;
+ case b:
+ val="t";
+ break;
+ case br:
+ case rb:
+ val="tl";
+ break;
+ }
+
+ return "[" + val + "]";
+ } // end of format::print(align_type)
+
+
+ // private (true pt offset to len)
+ pair format::pt_to_len(pair offset, const std::string& len) const
+ {
+ return offset *= length("1pt").to(len).magnitude();
+ }
+} // end of namespace
diff --git a/graphics/epix/format.h b/graphics/epix/format.h
new file mode 100644
index 0000000000..7432526ac9
--- /dev/null
+++ b/graphics/epix/format.h
@@ -0,0 +1,300 @@
+/*
+ * format.h -- ePiX::output format interface
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines ePiX's output interface. The fmt_template
+ * files contain skeleton code for a new format. The command
+ *
+ * for suff in cc h; do
+ * sed 's/fmt/foo/g' fmt_template.$suff > foo.$suff
+ * done
+ *
+ * (or manual search-and-replace) creates "blank" files containing
+ * declarations and pseudocode. (The include guards should also be
+ * changed.) Please consult pst.cc and eepic.cc for complete examples.
+ *
+ * The pure virtual functions in this file *must* be implemented by
+ * derived classes. They are signified by the keyword "virtual" and
+ * the definition "= 0" after their declaration. They are also found
+ * in the skeleton class mentioned above.
+ *
+ * The seven ordinary virtual functions (the destructor, pic_header and
+ * pic_footer, and four low-level functions for printing a pallet, pair,
+ * Color, or length) _may_ be overridden by derived classes, but will
+ * not be (unless the format has unusual conventions).
+ *
+ * No other functions should be re-implemented by derived classes.
+ */
+
+#ifndef EPIX_FORMAT
+#define EPIX_FORMAT
+
+#include <set>
+#include <list>
+#include <vector>
+#include <string>
+
+#include "enums.h"
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class Color;
+ class label_state;
+ class length;
+
+ class marker_sizes;
+ class pair;
+ class path_state;
+ class pen_data;
+
+ class format {
+ public:
+ // Free resources allocated by the constructor (usually unnecessary)
+ virtual ~format() { }
+
+ // Return a copy of this
+ virtual format* clone() const = 0;
+
+
+ // LaTeX symbol with specified location, offset and alignment
+ std::string print_mark(const pair& location,
+ const pair& offset,
+ const epix_mark_type mark,
+ const marker_sizes& sizes,
+ const label_state& style,
+ const std::string& len) const;
+
+ // Label text with specified location, offset, and alignment
+ std::string print_text(const pair& location,
+ const pair& offset,
+ const std::string& text,
+ const label_state& style,
+ const std::string& len) const;
+
+
+ // Filled region with specified Cartesian edges, offset, and color
+ virtual std::string print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const = 0;
+
+
+ // Unfilled region, specified Cartesian edges. Should generally be
+ // trivially implemented using one-pen function (supplied).
+ virtual std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line_pen,
+ const pen_data& base_pen,
+ const path_state& style,
+ const std::string& len) const = 0;
+
+ // implemented using previous function
+ std::string print_line(const edge2d&,
+ const pair&,
+ const pen_data&,
+ const pen_data&,
+ const path_state&,
+ const std::string&) const;
+
+
+ // File comment and information block
+ std::string file_comments(const std::string& units,
+ const length& hoff,
+ const length& voff,
+ double Xmin, double Xmax,
+ double Ymin, double Ymax,
+ double Hsize, double Vsize) const;
+
+
+ // Picture start and finish:
+ // Size and offset in page units,
+ // pallet (set of colors contained in the screen),
+ // unitlength
+ virtual std::string pic_header(const pair& sizes,
+ const pair& offsets,
+ const std::set<Color>& pallet,
+ const std::string& len) const;
+
+ virtual std::string pic_footer() const;
+
+
+ // Print color declaration strings: model, name, densities
+ std::string print_color(const std::string&,
+ const std::string&,
+ const std::vector<double>&) const;
+
+ // One-line comment
+ virtual std::string print_comment(const std::string&) const = 0;
+
+ // Verbatim output
+ virtual std::string print_verbatim(const std::string&) const = 0;
+
+
+ // print text with color, font in an hbox
+ std::string print_latex_hbox(const label_state& style,
+ const std::string& label) const;
+
+ // Derived classes use functions below to implement the public interface.
+ // The first two are needed to print screen_data for legend items.
+ virtual std::string start_picture(const pair&, const pair&) const = 0;
+ virtual std::string end_picture() const = 0;
+
+ virtual std::string set_unitlength(const std::string& len) const = 0;
+
+ // If child maintains drawing state, this function clears it.
+ virtual void reset_state() const = 0;
+
+ protected:
+ // inserted between points when breaking lines
+ virtual std::string path_break() const;
+ // inserted between points of a path
+ virtual std::string path_connector() const;
+
+ // names of LaTeX packages required to process our output
+ virtual std::string usepackages() const = 0;
+
+ // string argument for passing attributes local to this path/loop
+ virtual std::string start_open_path(const std::string&) const = 0;
+ virtual std::string end_open_path(const std::string&) const = 0;
+
+ virtual std::string start_closed_path(const std::string&) const = 0;
+ virtual std::string end_closed_path(const std::string&) const = 0;
+
+ // print declarations to set state of output format
+ virtual std::string set_fill_state(const Color&) const = 0;
+ virtual std::string set_pen_state(const pen_data&) const = 0;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ virtual std::string put_box(const pair&, const std::string&) const = 0;
+
+ // too idiosyncratic to handle format-independently
+ virtual std::string print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const = 0;
+
+ // xcolor definition strings
+ std::string xdefinecolor(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const;
+
+ std::string xdefinecolor(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const;
+
+ virtual std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const = 0;
+
+ virtual std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const = 0;
+
+ // Define all colors in the picture
+ virtual std::string print_pallet(const std::set<Color>& pallet) const;
+
+ // Represent a pair, length, or Color as a string
+ virtual std::string print(const pair&) const; // Default: "(a,b)"
+ virtual std::string print(const length&) const; // Default: "3.5cm", e.g.
+ virtual std::string print(const Color&) const; // Default: color name
+
+
+ // one-pen version
+ std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line,
+ const path_state& style,
+ const std::string& attribs,
+ const std::string& len) const;
+
+ // for single edge; wrap in list and pass to previous function
+ std::string print_line(const edge2d& e,
+ const pair& offset,
+ const pen_data& line,
+ const path_state& style,
+ const std::string& attribs,
+ const std::string& len) const;
+
+ // Print a non-solid edge, using the virtual interface
+ std::string print_edge(const edge2d& edge, const pair& offset,
+ const std::vector<double> bkpts,
+ double diam,
+ const Color& col,
+ const std::string& attribs,
+ const std::string& len) const;
+
+ // Print an edge list as offset path segments, or as a loop
+ // if all edges are visible and path is closed.
+ std::string print_paths(const std::list<edge2d>& edges,
+ const pair& offset,
+ const std::string& attribs,
+ const std::string& len) const;
+
+ /*
+ * Text in an ePiX output file is assumed to be typeset with
+ * LaTeX. The functions below perform LaTeX-specific low-level
+ * formatting. For uniformity and simplicity, these functions are
+ * format-independent: Implementations are provided and these
+ * functions are non-virtual. Format-specific masking, padding,
+ * and bordering capabilities (e.g. in PSTricks) are not used.
+ */
+ // label style, text, masking flag
+ std::string print_latex_label(const label_state&,
+ const std::string&,
+ bool) const;
+
+ // Print LaTeX command for marker symbol; 3rd (len) argument for scaling
+ std::string print_latex_marker(const epix_mark_type,
+ const marker_sizes&,
+ const std::string&) const;
+
+ private:
+ // convert an epix_label_posn to string
+ std::string print(const epix_label_posn arg) const;
+
+ // convert true pt offset to len
+ pair pt_to_len(pair offset, const std::string& len) const;
+
+ }; // end of base class format
+} // end of namespace
+
+#endif /* EPIX_FORMAT */
diff --git a/graphics/epix/frac.cc b/graphics/epix/frac.cc
new file mode 100644
index 0000000000..6fadd246af
--- /dev/null
+++ b/graphics/epix/frac.cc
@@ -0,0 +1,262 @@
+/*
+ * frac.cc -- ePiX rational number class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "frac.h"
+
+namespace ePiX {
+
+ const int MAX_DENOM(10000);
+ const double EPS(1.0/MAX_DENOM);
+
+ unsigned int __epix_gcd (int i, unsigned int j);
+
+ frac::frac(const int n, const unsigned int d)
+ : m_num(n), m_denom(d) { }
+
+ // express arg as a fraction with denominator no larger than MAX_DENOM
+ frac::frac(double arg)
+ {
+ unsigned int denom(1);
+ if (fabs(arg) < EPS)
+ {
+ m_num = 0;
+ m_denom = 1;
+ }
+
+ else
+ {
+ int sgn(arg < 0 ? -1 : 1);
+ double abs_arg(sgn*arg);
+
+ // store best approximation
+ int best_num(0);
+ double running_error(0.5);
+
+ while (denom <= 1+MAX_DENOM)
+ {
+ const double tmp(abs_arg*denom);
+
+ int tmp_lo((int) floor(tmp));
+
+ if (tmp - tmp_lo < EPS) // good approx
+ {
+ best_num = tmp_lo;
+ break;
+ }
+
+ else if (tmp - tmp_lo < running_error) // improved approx
+ {
+ best_num = tmp_lo;
+ running_error = tmp - best_num;
+ }
+
+ int tmp_hi((int) ceil(tmp));
+ if (tmp_hi - tmp < EPS)
+ {
+ best_num = tmp_hi;
+ break;
+ }
+
+ else if (tmp_hi - tmp < running_error)
+ {
+ best_num = tmp_hi;
+ running_error = best_num - tmp;
+ }
+
+ ++denom;
+ }
+
+ m_num = sgn*best_num;
+ m_denom = denom;
+ }
+ } // end of frac::frac(double arg)
+
+
+ // increment operators
+ frac& frac::operator += (const frac& arg)
+ {
+ m_num *= arg.m_denom;
+ m_num += m_denom*arg.m_num;
+ m_denom *= arg.m_denom;
+
+ return *this;
+ }
+
+ frac& frac::operator -= (const frac& arg)
+ {
+ m_num *= arg.m_denom;
+ m_num -= m_denom*arg.m_num;
+ m_denom *= arg.m_denom;
+
+ return *this;
+ }
+
+ frac& frac::operator *= (const frac& arg)
+ {
+ m_num *= arg.m_num;
+ m_denom *= arg.m_denom;
+
+ return *this;
+ }
+
+ frac& frac::operator /= (const frac& arg)
+ {
+ unsigned int arg_num(arg.m_num < 0 ? -arg.m_num : arg.m_num);
+
+ m_num *= arg.m_denom;
+ m_denom *= arg_num;
+
+ if (arg.m_num < 0)
+ m_num = -1;
+
+ return *this;
+ }
+
+ frac& frac::reduce()
+ {
+ unsigned int factor(__epix_gcd(m_num, m_denom));
+ m_num /= factor;
+ m_denom /= factor;
+
+ return *this;
+ }
+
+ double frac::eval() const
+ {
+ double temp(m_num);
+ return temp /= m_denom;
+ }
+
+ int frac::num() const
+ {
+ return m_num;
+ }
+
+ unsigned int frac::denom() const
+ {
+ return m_denom;
+ }
+
+ bool frac::is_int() const
+ {
+ return __epix_gcd(m_num, m_denom) == m_denom;
+ }
+
+
+ frac operator+ (frac arg1, const frac& arg2)
+ {
+ return arg1 += arg2;
+ }
+
+ frac operator- (frac arg1)
+ {
+ return arg1 *= -1;
+ }
+
+ frac operator- (frac arg1, const frac& arg2)
+ {
+ return arg1 -= arg2;
+ }
+
+ frac operator* (frac arg1, const frac& arg2)
+ {
+ return arg1 *= arg2;
+ }
+
+ frac operator/ (frac arg1, const frac& arg2)
+ {
+ return arg1 /= arg2;
+ }
+
+ // (in)equality
+ bool operator == (const frac& u, const frac& v)
+ {
+ return u.num()*v.denom() == v.num()*u.denom();
+ }
+
+ bool operator != (const frac& u, const frac& v)
+ {
+ return !(u == v);
+ }
+
+ // denoms are unsigned
+ bool operator < (const frac& u, const frac& v)
+ {
+ return u.num()*v.denom() < v.num()*u.denom();
+ }
+
+ bool operator > (const frac& u, const frac& v)
+ {
+ return u.num()*v.denom() > v.num()*u.denom();
+ }
+
+ bool operator <= (const frac& u, const frac& v)
+ {
+ return u.num()*v.denom() <= v.num()*u.denom();
+ }
+
+ bool operator >= (const frac& u, const frac& v)
+ {
+ return u.num()*v.denom() >= v.num()*u.denom();
+ }
+
+ // N.B.: gcd(0,i) = |i|
+ unsigned int __epix_gcd (int i, unsigned int j)
+ {
+ unsigned int new_i(i<0 ? -i : i);
+ unsigned int temp;
+
+ if (new_i==0 || j==0) // (1,0) and (0,1) coprime, others not
+ return new_i + j;
+
+ else {
+ if (j < new_i) // swap them
+ {
+ temp = j;
+ j = new_i;
+ new_i = temp;
+ }
+ // Euclidean algorithm
+ while ((temp = j%new_i)) // i does not evenly divide j
+ {
+ j = new_i;
+ new_i = temp;
+ }
+
+ return new_i;
+ }
+ }
+} // end of namespace
+
diff --git a/graphics/epix/frac.h b/graphics/epix/frac.h
new file mode 100644
index 0000000000..c76d469852
--- /dev/null
+++ b/graphics/epix/frac.h
@@ -0,0 +1,81 @@
+/*
+ * frac.h -- ePiX::rational number class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 07, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_FRACTION
+#define EPIX_FRACTION
+
+namespace ePiX {
+
+ class frac {
+ public:
+ frac(const int n, const unsigned int d=1);
+ explicit frac(double);
+
+ // increment operators
+ frac& operator += (const frac& arg);
+ frac& operator -= (const frac& arg);
+ frac& operator *= (const frac& arg);
+ frac& operator /= (const frac& arg);
+
+ frac& reduce();
+ double eval() const;
+
+ int num() const;
+ unsigned int denom() const;
+
+ bool is_int() const;
+
+ private:
+ int m_num;
+ unsigned int m_denom;
+ }; // end of class frac
+
+ frac operator+ (frac arg1, const frac& arg2);
+ frac operator- (frac arg1);
+ frac operator- (frac arg1, const frac& arg2);
+ frac operator* (frac arg1, const frac& arg2);
+ frac operator/ (frac arg1, const frac& arg2);
+
+ // (in)equality
+ bool operator == (const frac& u, const frac& v);
+ bool operator != (const frac& u, const frac& v);
+
+ bool operator < (const frac& u, const frac& v);
+ bool operator > (const frac& u, const frac& v);
+
+ bool operator <= (const frac& u, const frac& v);
+ bool operator >= (const frac& u, const frac& v);
+
+} // end of namespace
+
+#endif /* EPIX_FRACTION */
diff --git a/graphics/epix/frame.cc b/graphics/epix/frame.cc
new file mode 100644
index 0000000000..176025ffe0
--- /dev/null
+++ b/graphics/epix/frame.cc
@@ -0,0 +1,114 @@
+/*
+ * frame.cc -- ePiX orthonormal basis
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 10, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "constants.h"
+#include "functions.h"
+
+#include "errors.h"
+#include "triples.h"
+#include "frame.h"
+
+namespace ePiX {
+
+ // standard basis
+ frame::frame()
+ : m_e1(E_1), m_e2(E_2), m_e3(E_3) { }
+
+ // frame constructor, suitable for (sea,sky,eye) frames: Usually we
+ // know the eye vector and want to preserve its direction. The frame
+ // is guaranteed to be right-handed, and the first arg is immaterial.
+ frame::frame(P arg1, P arg2, P arg3)
+ {
+ if (norm(arg2*arg3) < EPIX_EPSILON) // too nearly linearly dependent
+ epix_error("Linearly dependent arguments to frame");
+
+ // partial Gram-Schmidt
+ arg3 *= 1/norm(arg3); // normalize eye
+
+ arg2 %= arg3; // orthogonalize sky_vector, preserving screen direction
+ arg2 *= 1/norm(arg2); // and normalize
+
+ m_e1 = arg2*arg3;
+ m_e2 = arg2;
+ m_e3 = arg3;
+ }
+
+
+ frame& frame::rot1(double angle)
+ {
+ P temp2(m_e2);
+ P temp3(m_e3);
+
+ m_e2 = (Cos(angle)*(temp2)) - (Sin(angle)*(temp3));
+ m_e3 = (Sin(angle)*(temp2)) + (Cos(angle)*(temp3));
+
+ return *this;
+ }
+
+
+ frame& frame::rot2(double angle)
+ {
+ P temp3(m_e3);
+ P temp1(m_e1);
+
+ m_e3 = (Cos(angle)*(temp3)) - (Sin(angle)*(temp1));
+ m_e1 = (Sin(angle)*(temp3)) + (Cos(angle)*(temp1));
+
+ return *this;
+ }
+
+ frame& frame::rot3(double angle)
+ {
+ P temp1(m_e1);
+ P temp2(m_e2);
+
+ m_e1 = (Cos(angle)*(temp1)) - (Sin(angle)*(temp2));
+ m_e2 = (Sin(angle)*(temp1)) + (Cos(angle)*(temp2));
+
+ return *this;
+ }
+
+ // frame elements
+ P frame::sea() const
+ {
+ return m_e1;
+ }
+ P frame::sky() const
+ {
+ return m_e2;
+ }
+ P frame::eye() const
+ {
+ return m_e3;
+ }
+} // end of namespace
diff --git a/graphics/epix/frame.h b/graphics/epix/frame.h
new file mode 100644
index 0000000000..fa70c3d16d
--- /dev/null
+++ b/graphics/epix/frame.h
@@ -0,0 +1,82 @@
+/*
+ * frame.h -- Orthonormal basis
+ *
+ * This file is part of ePiX, a preprocessor for creating high-quality
+ * line figures in LaTeX
+ *
+ * Version 1.0.15
+ * Last Change: October 10, 2006
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * In geometry, a "frame" is a right-handed orthonormal basis, that is,
+ * an ordered set of three mututally perpendicular unit vectors, oriented
+ * according to the right-hand rule. A frame has nothing to do with
+ * picture frames.
+ *
+ *
+ * This file provides:
+ * - the frame class, and routines for rotating a frame about the axes
+ * determined by its elements. (Note that there are no methods for
+ * rotating about fixed coordinate axes, and that rotations in R^3 do
+ * not generally commute.
+ */
+
+#ifndef EPIX_FRAME
+#define EPIX_FRAME
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class frame {
+ public:
+ // standard basis
+ frame();
+
+ // Gram-Schmidt
+ frame(P arg1, P arg2, P arg3); // need args by value
+
+ // frame elements
+ P sea() const;
+ P sky() const;
+ P eye() const;
+
+ // rotations about frame elements
+ frame& rot1(double angle);
+ frame& rot2(double angle);
+ frame& rot3(double angle);
+
+ private:
+ P m_e1; // sea
+ P m_e2; // sky
+ P m_e3; // eye
+ }; // end of class frame
+
+} // end of namespace
+
+#endif /* EPIX_FRAME */
diff --git a/graphics/epix/functions.cc b/graphics/epix/functions.cc
new file mode 100644
index 0000000000..ae1c9649ae
--- /dev/null
+++ b/graphics/epix/functions.cc
@@ -0,0 +1,398 @@
+/*
+ * functions.cc -- non-standard mathematical functions
+ *
+ * This file is part of ePiX, a preprocessor for creating high-quality
+ * line figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+
+#include "constants.h"
+#include "errors.h"
+#include "deriv.h"
+
+#include "angle_units.h"
+#include "triples.h"
+
+#include "functions.h"
+
+namespace ePiX {
+
+ // trig functions with angle units
+ double Cos(double t)
+ {
+ return std::cos(the_angle_style().to_radians(t));
+ }
+
+ double Sin(double t)
+ {
+ return std::sin(the_angle_style().to_radians(t));
+ }
+
+ double Tan(double t)
+ {
+ return std::tan(the_angle_style().to_radians(t));
+ }
+
+ double Sec(double t)
+ {
+ return 1.0/std::cos(the_angle_style().to_radians(t));
+ }
+
+ double Csc(double t)
+ {
+ return 1.0/std::sin(the_angle_style().to_radians(t));
+ }
+
+ double Cot(double t)
+ {
+ return 1.0/std::tan(the_angle_style().to_radians(t));
+ }
+
+ // and inverses
+ double Acos(double arg)
+ {
+ return std::acos(arg)/the_angle_style().to_radians(1);
+ }
+
+ double Asin(double arg)
+ {
+ return std::asin(arg)/the_angle_style().to_radians(1);
+ }
+
+ double Atan(double arg)
+ {
+ return std::atan(arg)/the_angle_style().to_radians(1);
+ }
+
+ double Atan2(double y, double x)
+ {
+ return std::atan2(y, x)/the_angle_style().to_radians(1);
+ }
+
+ // Additional hyperbolic tric functions and inverses
+ double sech(double x)
+ {
+ return 1.0/cosh(x);
+ }
+
+ double csch(double x)
+ {
+ return 1.0/sinh(x);
+ }
+
+ double coth(double x)
+ {
+ return 1.0/tanh(x);
+ }
+
+ double asech(double x)
+ {
+ return log((1+sqrt((1-x)*(1+x)))/x);
+ }
+
+ double acsch(double x)
+ {
+ return log((1+sqrt(1+x*x))/x);
+ }
+
+ double acoth(double x)
+ {
+ return 0.5*log((x+1)/(x-1));
+ }
+
+ double zero(double arg)
+ {
+ return 0;
+ }
+
+ double zero(double x, double y)
+ {
+ return 0;
+ }
+
+ double zero(double x, double y, double z)
+ {
+ return 0;
+ }
+
+ double zero(const P& arg)
+ {
+ return 0;
+ }
+
+ P xyz(double x, double y, double z)
+ {
+ return P(x, y, z);
+ }
+
+ P cyl(double r, double t, double z)
+ {
+ return P(r*Cos(t), r*Sin(t), z);
+ }
+
+ P sph(double r, double t, double phi)
+ {
+ return P(r*(Cos(t))*(Cos(phi)), r*(Sin(t))*(Cos(phi)), r*(Sin(phi)));
+ }
+
+ P log_log(double x, double y, double z)
+ {
+ return P(log10(x), log10(y), z);
+ }
+
+ P log_lin(double x, double y, double z)
+ {
+ return P(log10(x), y, z);
+ }
+
+ P lin_log(double x, double y, double z)
+ {
+ return P(x, log10(y), z);
+ }
+
+
+ // for plot templates, arg mustn't be const P&
+ P cylindrical(P arg)
+ {
+ return cyl(arg.x1(), arg.x2(), arg.x3());
+ }
+
+ P spherical(P arg)
+ {
+ return sph(arg.x1(), arg.x2(), arg.x3());
+ }
+
+ P polar(double r, double t)
+ {
+ return cyl(r, t, 0);
+ }
+
+ P cis(double t)
+ {
+ return cyl(1, t, 0);
+ }
+
+ double recip (double x)
+ {
+ return 1.0/x;
+ }
+
+ // sin(x)/x
+ double sinx (double x)
+ {
+ if (1. + x*x == 1.) // from Don Hatch
+ return 1.;
+ else
+ return Sin(x)/the_angle_style().to_radians(x);
+ }
+
+ // signum, x/|x|, defined to be 0 at 0
+ double sgn (double x)
+ {
+ if (x > 0)
+ return 1;
+ else if (x < 0)
+ return -1;
+ else
+ return 0;
+ }
+
+ // Charlie Brown: Period-2 extension of |x| on [-1,1] /\/\/\/\/\/
+ double cb (double x)
+ {
+ x = fabs(x);
+ x -= 2*floor(0.5*x);
+ return min(x, 2-x);
+ }
+
+ // N.B.: gcd(0,i) = |i|
+ int gcd (int i, int j)
+ {
+ int temp;
+
+ i=abs(i);
+ j=abs(j);
+
+ if (i==0 || j==0) // (1,0) and (0,1) coprime, others not
+ return i+j;
+
+ else {
+ if (j < i) // swap them
+ {
+ temp = j;
+ j=i;
+ i=temp;
+ }
+ // Euclidean algorithm
+ while ((temp = j%i)) // i does not evenly divide j
+ {
+ j=i;
+ i=temp;
+ }
+
+ return i;
+ }
+ }
+
+ double min(double a, double b)
+ {
+ return a < b ? a : b;
+ }
+
+ double max(double a, double b)
+ {
+ return b < a ? a : b;
+ }
+
+ double snip_to(double var, double arg1, double arg2)
+ {
+ if (var < min(arg1, arg2))
+ var = min(arg1,arg2);
+ else if (var > max(arg1, arg2))
+ var = max(arg1,arg2);
+ return var;
+ }
+
+ // inf and sup of f on [a,b]
+ double inf (double f(double), double a, double b)
+ {
+ const int N((int) ceil(fabs(b-a))); // N >= 1 unless a=b
+ double y(f(a));
+ const double dx((b-a)/(N*EPIX_ITERATIONS));
+
+ for (unsigned int i=1; i <= N*EPIX_ITERATIONS; ++i)
+ y = min(y, f(a + i*dx));
+
+ return y;
+ }
+
+ double sup (double f(double), double a, double b)
+ {
+ const int N((int) ceil(fabs(b-a))); // N >= 1 unless a=b
+ double y(f(a));
+ const double dx((b-a)/(N*EPIX_ITERATIONS));
+
+ for (unsigned int i=1; i <= N*EPIX_ITERATIONS; ++i)
+ y = max(y, f(a + i*dx));
+
+ return y;
+ }
+
+ // Integral class helper
+ double integrand(double f(double), double t, double dt)
+ {
+ return (1.0/6)*(f(t) + 4*f(t+0.5*dt)+f(t + dt))*dt;
+ } // Simpson's rule
+
+ Integral::Integral(double func(double), double a)
+ : f(func), x0(a) { }
+
+ double Integral::eval(double t) const
+ {
+ double sum(0);
+ const int N(16*(int)ceil(fabs(t - x0))); // hardwired constant 16
+
+ if (N > 0)
+ {
+ const double dx((t - x0)/N);
+
+ for (int i=0; i < N; ++i)
+ sum += integrand(f, x0+i*dx, dx);
+ }
+
+ return sum;
+ }
+
+ P Integral::operator() (const P& arg) const
+ {
+ double t(arg.x1());
+ return P(t, eval(t), 0);
+ }
+
+ double newton (double f(double), double g(double), double start)
+ {
+ double guess(start);
+ int count(0); // number of iterations
+
+ // Magic number 5
+ const int ITERS(5);
+ while ( (fabs(f(guess)-g(guess)) > EPIX_EPSILON) && (count < ITERS) )
+ {
+ if (fabs(deriv(f, guess)-deriv(g, guess)) < EPIX_EPSILON)
+ {
+ epix_warning("Returning critical point in Newton's method");
+ return guess;
+ }
+
+ guess -= (f(guess)-g(guess))/(deriv(f, guess)-deriv(g, guess));
+ ++count;
+ }
+
+ if (count == ITERS)
+ epix_warning("Maximum number of iterations in Newton's method");
+
+ return guess;
+ }
+
+ double newton (double f(double), double start)
+ {
+ return newton(f, zero, start);
+ }
+
+ // Member functions
+ Deriv::Deriv(double func(double))
+ : f(func), dt(EPIX_EPSILON) { }
+
+ Deriv::Deriv(double func(double), double eps)
+ : f(func), dt(eps) { }
+
+ P Deriv::operator() (const P& arg) const
+ {
+ double t(arg.x1());
+ return P(t, deriv(f, t, dt), 0);
+ }
+
+ double Deriv::eval(double t) const
+ {
+ return deriv(f, t, dt);
+ }
+
+ // one-sided derivatives
+ double Deriv::right(double t) const
+ {
+ return (2.0/dt)*(f(t+0.5*dt) - f(t));
+ }
+
+ double Deriv::left(double t) const
+ {
+ return (2.0/dt)*(f(t) - f(t-0.5*dt));
+ }
+} // end of namespace
diff --git a/graphics/epix/functions.h b/graphics/epix/functions.h
new file mode 100644
index 0000000000..40726a8f12
--- /dev/null
+++ b/graphics/epix/functions.h
@@ -0,0 +1,147 @@
+/*
+ * functions.h -- ePiX auxiliary functions; Deriv, Integral classes
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_FUNCTIONS
+#define EPIX_FUNCTIONS
+
+namespace ePiX {
+
+ class P;
+
+ // sensitive to angle units
+ double Cos(double t);
+ double Sin(double t);
+ double Tan(double t);
+
+ double Sec(double t);
+ double Csc(double t);
+ double Cot(double t);
+
+ double Acos(double t);
+ double Asin(double t);
+ double Atan(double t);
+
+ double Atan2(double y, double x);
+
+ // additional hyperbolic functions and inverses
+ double sech(double);
+ double csch(double);
+ double coth(double);
+
+ double asech(double);
+ double acsch(double);
+ double acoth(double);
+
+ // zero functions
+ double zero(double);
+ double zero(double, double);
+ double zero(double, double, double);
+ double zero(const P&);
+
+ // P constructors
+ P xyz(double x, double y, double z=0);
+ P cyl(double r, double t, double z);
+ P sph(double r, double t, double phi);
+
+ // for log data plotting
+ P log_log(double x, double y, double z=0);
+ P log_lin(double x, double y, double z=0);
+ P lin_log(double x, double y, double z=0);
+
+ P cylindrical(P); // not const P&
+ P spherical(P);
+
+ P polar(double r, double t);
+ P cis(double t);
+
+ // utility functions
+ double recip (double);
+ double sinx (double); // discontinuity removed
+ double sgn (double);
+
+ // period-2 extension of absolute value on [-1,1]: \/\/\/
+ double cb (double);
+
+ int gcd (int, int);
+
+ double min(double, double);
+ double max(double, double);
+
+ double snip_to(double var, double arg1, double arg2);
+
+ double inf (double f(double), double, double);
+ double sup (double f(double), double, double);
+
+
+ // derivative class
+ class Deriv {
+ private:
+ double (*f)(double);
+ double dt;
+
+ public:
+ Deriv(double func(double));
+ Deriv(double func(double), double eps);
+
+ P operator() (const P&) const; // for plotting
+
+ // numerical values
+ double eval(double t) const;
+
+ // one-sided derivatives
+ double right(double t) const;
+ double left(double t) const;
+ }; // end of class Deriv
+
+
+ // definite integral class
+ class Integral {
+ private:
+ double (*f)(double);
+ double x0; // lower limit
+
+ public:
+ Integral(double func(double), double a=0);
+
+ P operator() (const P&) const;
+
+ double eval(double) const;
+ }; // end of class Integral
+
+ double newton (double f(double), double g(double), double start);
+ double newton (double f(double), double start);
+
+} // end of namespace
+
+#endif /* EPIX_FUNCTIONS */
diff --git a/graphics/epix/geometry.cc b/graphics/epix/geometry.cc
new file mode 100644
index 0000000000..dec6342fc2
--- /dev/null
+++ b/graphics/epix/geometry.cc
@@ -0,0 +1,804 @@
+/*
+ * geometry.cc -- spherical and hyperbolic geometry
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+#include <vector>
+
+#include "constants.h"
+#include "errors.h"
+#include "functions.h"
+
+#include "triples.h"
+#include "frame.h"
+
+#include "state.h"
+
+#include "camera.h"
+
+#include "path.h"
+
+#include "sphere.h"
+#include "curves.h"
+
+#include "geometry.h"
+
+namespace ePiX {
+
+ //// Static utility functions ////
+
+ // Flag for type of projection to the sphere
+ enum sphere_proj_type {RADIAL, STEREO_N, STEREO_S};
+
+ // point constructor in geographic coords on specified sphere/frame
+ P sphere_posn(double lat, double lngtd, const Sphere& S, const frame& coords)
+ {
+ double rad(S.radius());
+
+ return S.center() +
+ rad*Cos(lat)*(Cos(lngtd)*coords.sea() + Sin(lngtd)*coords.sky()) +
+ rad*Sin(lat)*coords.eye();
+ }
+
+ // latitudes and longitudes
+ void draw_latitude(double lat, double lngtd_min, double lngtd_max,
+ bool front, const Sphere& S, const frame& coords)
+ {
+ P center(S.center() + (S.radius()*Sin(lat)*coords.eye()));
+ double radius(S.radius()*Cos(lat));
+
+ path temp(center, radius*coords.sea(), radius*coords.sky(),
+ lngtd_min, lngtd_max);
+
+ temp.clip_to(S, cam().viewpt(), front);
+ temp.draw();
+ }
+
+ // draw portion of longitude line
+ void draw_longitude(double lngtd, double lat_min, double lat_max,
+ bool front, const Sphere& S, const frame& coords)
+ {
+ P center(S.center());
+ double radius(S.radius());
+
+ path temp(center,
+ radius*(Cos(lngtd)*coords.sea()+Sin(lngtd)*coords.sky() ),
+ radius*coords.eye(), lat_min, lat_max);
+
+ temp.clip_to(S, cam().viewpt(), front);
+ temp.draw();
+ }
+
+
+ // Spherical geometry
+ P proj_to_sphere(const P& arg, const Sphere& S, sphere_proj_type TYPE)
+ {
+ P O(S.center());
+ double rad(S.radius());
+ P loc(arg - O); // location relative to O
+
+ if (TYPE == RADIAL)
+ return O + (rad/norm(loc))*loc;
+
+ else if (TYPE == STEREO_N)
+ {
+ P temp(loc%E_3);
+ double rho(temp|temp);
+ return O + (rad/(rho+1))*P(2*temp.x1(), 2*temp.x2(), rho-1);
+ }
+
+ else if (TYPE == STEREO_S)
+ {
+ P temp(loc%E_3);
+ double rho(temp|temp);
+ return O + (rad/(rho+1))*P(2*temp.x1(), 2*temp.x2(), 1-rho);
+ }
+
+ else // Return center on erroneous projection type
+ return O;
+ }
+
+ void draw_sphereplot(double f1(double),double f2(double),double f3(double),
+ double t_min, double t_max, int num_pts, bool front,
+ sphere_proj_type TYPE, const Sphere& S)
+ {
+ std::vector<P> data(num_pts+1);
+ double t(t_min);
+ const double dt((t_max - t_min)/num_pts);
+
+ for (int i=0; i <= num_pts; ++i, t += dt)
+ data.at(i) = proj_to_sphere(P(f1(t), f2(t), f3(t)), S, TYPE);
+
+ path temp(data, false, false);
+ temp.clip_to(S, cam().viewpt(), front);
+ temp.draw();
+ } // end of draw_sphereplot
+
+ void draw_sphereplot(P Phi(double), double t_min, double t_max,
+ int num_pts, bool front, sphere_proj_type TYPE,
+ const Sphere& S)
+ {
+ std::vector<P> data(num_pts+1);
+ double t(t_min);
+ const double dt((t_max - t_min)/num_pts);
+
+ for (int i=0; i <= num_pts; ++i, t += dt)
+ data.at(i) = proj_to_sphere(Phi(t), S, TYPE);
+
+ path temp(data, false, false);
+ temp.clip_to(S, cam().viewpt(), front);
+ temp.draw();
+ } // end of draw_sphereplot
+
+
+ // segment mapping class
+ class seg {
+ public:
+ seg(const P& tail, const P& head)
+ : m_tail(tail), m_head(head) { }
+
+ // so we can be plotted
+ P operator() (double t) const
+ {
+ return m_tail + t*(m_head - m_tail);
+ }
+
+ private:
+ P m_tail;
+ P m_head;
+ }; // end of class seg
+
+
+ // assumes seg contains the actual (scaled, translated) endpoints
+ void draw_sphere_arc(const seg& sgmt, double t_min, double t_max,
+ bool front, sphere_proj_type TYPE, const Sphere& S)
+ {
+ P tail(sgmt(t_min)), head(sgmt(t_max));
+ double cos_theta(((head-S.center())|(tail-S.center()))/pow(S.radius(),2));
+ if (1-cos_theta < EPIX_EPSILON) // endpoints equal
+ return; // draw nothing
+
+ else if (1+cos_theta < EPIX_EPSILON) // endpoints antipodal
+ {
+ epix_warning("Spherical arc joins antipodes, no output");
+ return;
+ }
+ // else
+
+ int num_pts((int) ceil(EPIX_NUM_PTS*Acos(cos_theta)/full_turn()));
+ if (num_pts < 2)
+ num_pts=2;
+
+ std::vector<P> data(num_pts+1);
+ double t(t_min);
+ const double dt((t_max - t_min)/num_pts);
+
+ P O(S.center());
+ double rad(S.radius());
+
+ for (int i=0; i <= num_pts; ++i, t += dt)
+ {
+ P loc(sgmt(t) - O); // location relative to O
+ data.at(i) = S.center() + rad*recip(norm(loc))*loc;
+ }
+
+ path temp(data, false, false);
+ temp.clip_to(S, cam().viewpt(), front);
+ temp.draw();
+ } // end of draw_sphere_arc
+
+
+ //// "Geography" and spherical plotting ////
+ void latitude(double lat, double lngtd_min, double lngtd_max,
+ const Sphere& S, const frame& coords)
+ {
+ draw_latitude(lat, lngtd_min, lngtd_max, true, S, coords);
+ }
+
+
+ void longitude(double lngtd, double lat_min, double lat_max,
+ const Sphere& S, const frame& coords)
+ {
+ draw_longitude(lngtd, lat_min, lat_max, true, S, coords);
+ }
+
+ void back_latitude(double lat, double lngtd_min, double lngtd_max,
+ const Sphere& S, const frame& coords)
+ {
+ draw_latitude(lat, lngtd_min, lngtd_max, false, S, coords);
+ }
+
+ void back_longitude(double lngtd, double lat_min, double lat_max,
+ const Sphere& S, const frame& coords)
+ {
+ draw_longitude(lngtd, lat_min, lat_max, false, S, coords);
+ }
+
+
+ // spherical plotting
+ void frontplot_N(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S)
+ {
+ draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, true, STEREO_N, S);
+ }
+
+ void backplot_N(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S)
+ {
+ draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, false, STEREO_N, S);
+ }
+
+ void frontplot_S(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S)
+ {
+ draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, true, STEREO_S, S);
+ }
+
+ void backplot_S(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S)
+ {
+ draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, false, STEREO_S, S);
+ }
+
+
+ // Radial projection from center
+ void frontplot_R(P phi(double), double t_min, double t_max,
+ int num_pts, const Sphere& S)
+ {
+ draw_sphereplot(phi, t_min, t_max, num_pts, true, RADIAL, S);
+ }
+
+ void backplot_R(P phi(double), double t_min, double t_max,
+ int num_pts, const Sphere& S)
+ {
+ draw_sphereplot(phi, t_min, t_max, num_pts, false, RADIAL, S);
+ }
+
+
+ //// Spherical geometry -- arcs and polyhedra ////
+ // arc of great circle between non-antipodal points
+ void arc(const P& tail, const P& head, const bool front, const Sphere& S)
+ {
+ draw_sphere_arc(seg(tail, head), 0, 1, front, RADIAL, S);
+ }
+
+
+ // user-space functions
+ void front_arc(const P& p1, const P& p2, const Sphere& S)
+ {
+ const P ctr(S.center());
+ const double rad(S.radius());
+
+ arc(ctr+(rad/norm(p1))*p1, ctr+(rad/norm(p2))*p2, true, S);
+ }
+
+ void back_arc(const P& p1, const P& p2, const Sphere& S)
+ {
+ const P ctr(S.center());
+ const double rad(S.radius());
+
+ arc(ctr+(rad/norm(p1))*p1, ctr+(rad/norm(p2))*p2, false, S);
+ }
+
+ // join p1 to -p1 through p2
+ void front_arc2(const P& p1, const P& p2, const Sphere& S)
+ {
+ front_arc(p1, p2, S);
+ front_arc(p2, -p1, S);
+ }
+
+ void back_arc2(const P& p1, const P& p2, const Sphere& S)
+ {
+ back_arc(p1, p2, S);
+ back_arc(p2, -p1, S);
+ }
+
+ void front_line(const P& p1, const P& p2, const Sphere& S)
+ {
+ front_arc( p1, p2, S);
+ front_arc( p2, -p1, S);
+ front_arc(-p1, -p2, S);
+ front_arc(-p2, p1, S);
+ }
+
+
+ void back_line(const P& p1, const P& p2, const Sphere& S)
+ {
+ back_arc( p1, p2, S);
+ back_arc( p2, -p1, S);
+ back_arc(-p1, -p2, S);
+ back_arc(-p2, p1, S);
+ }
+
+
+ void front_triangle(const P& p1, const P& p2, const P& p3, const Sphere& S)
+ {
+ front_arc(p1, p2, S);
+ front_arc(p2, p3, S);
+ front_arc(p3, p1, S);
+ }
+
+ void back_triangle(const P& p1, const P& p2, const P& p3, const Sphere& S)
+ {
+ back_arc(p1, p2, S);
+ back_arc(p2, p3, S);
+ back_arc(p3, p1, S);
+ }
+
+ // local to this file
+ void front_dual(const P& p1, const P& p2, const P& p3, const Sphere& S)
+ {
+ const P ctr(0.3333*(p1+p2+p3));
+
+ front_arc(ctr, 0.5*(p1+p2), S);
+ front_arc(ctr, 0.5*(p2+p3), S);
+ front_arc(ctr, 0.5*(p3+p1), S);
+ }
+
+ void back_dual(const P& p1, const P& p2, const P& p3, const Sphere& S)
+ {
+ const P ctr(0.3333*(p1+p2+p3));
+
+ back_arc(ctr, 0.5*(p1+p2), S);
+ back_arc(ctr, 0.5*(p2+p3), S);
+ back_arc(ctr, 0.5*(p3+p1), S);
+ }
+
+
+ // spherical polyhedra
+ void front_tetra(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+
+ const P ppp( f1+f2+f3);
+ const P pnn( f1-f2-f3);
+ const P npn(-f1+f2-f3);
+ const P nnp(-f1-f2+f3);
+
+ front_triangle(ppp,pnn,npn,S);
+ front_triangle(ppp,npn,nnp,S);
+ front_triangle(ppp,nnp,pnn,S);
+ front_triangle(nnp,pnn,npn,S);
+ }
+ void back_tetra(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+
+ const P ppp( f1+f2+f3);
+ const P pnn( f1-f2-f3);
+ const P npn(-f1+f2-f3);
+ const P nnp(-f1-f2+f3);
+
+ back_triangle(ppp,pnn,npn,S);
+ back_triangle(ppp,npn,nnp,S);
+ back_triangle(ppp,nnp,pnn,S);
+ back_triangle(nnp,pnn,npn,S);
+ }
+
+ void front_cube(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+
+ const P ppp( f1+f2+f3);
+ const P npp(-f1+f2+f3);
+ const P nnp(-f1-f2+f3);
+ const P pnp( f1-f2+f3);
+
+ const P ppn( f1+f2-f3);
+ const P npn(-f1+f2-f3);
+ const P nnn(-f1-f2-f3);
+ const P pnn( f1-f2-f3);
+
+ front_arc(ppp,npp,S);
+ front_arc(npp,nnp,S);
+ front_arc(nnp,pnp,S);
+ front_arc(pnp,ppp,S);
+
+ front_arc(ppn,npn,S);
+ front_arc(npn,nnn,S);
+ front_arc(nnn,pnn,S);
+ front_arc(pnn,ppn,S);
+
+ front_arc(ppp,ppn,S);
+ front_arc(npp,npn,S);
+ front_arc(nnp,nnn,S);
+ front_arc(pnp,pnn,S);
+ }
+ void back_cube(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+
+ const P ppp( f1+f2+f3);
+ const P npp(-f1+f2+f3);
+ const P nnp(-f1-f2+f3);
+ const P pnp( f1-f2+f3);
+
+ const P ppn( f1+f2-f3);
+ const P npn(-f1+f2-f3);
+ const P nnn(-f1-f2-f3);
+ const P pnn( f1-f2-f3);
+
+ back_arc(ppp,npp,S);
+ back_arc(npp,nnp,S);
+ back_arc(nnp,pnp,S);
+ back_arc(pnp,ppp,S);
+
+ back_arc(ppn,npn,S);
+ back_arc(npn,nnn,S);
+ back_arc(nnn,pnn,S);
+ back_arc(pnn,ppn,S);
+
+ back_arc(ppp,ppn,S);
+ back_arc(npp,npn,S);
+ back_arc(nnp,nnn,S);
+ back_arc(pnp,pnn,S);
+ }
+
+ void front_octa(const Sphere& S, const frame& coords)
+ {
+ const P p1(coords.sea());
+ const P p2(coords.sky());
+ const P p3(coords.eye());
+
+ const P m1(-coords.sea());
+ const P m2(-coords.sky());
+ const P m3(-coords.eye());
+
+ // draw "even parity" triangles only
+ front_triangle(p1,p2,p3,S);
+ front_triangle(m1,m2,p3,S);
+
+ front_triangle(m1,p2,m3,S);
+ front_triangle(p1,m2,m3,S);
+ }
+ void back_octa(const Sphere& S, const frame& coords)
+ {
+ const P p1(coords.sea());
+ const P p2(coords.sky());
+ const P p3(coords.eye());
+
+ const P m1(-coords.sea());
+ const P m2(-coords.sky());
+ const P m3(-coords.eye());
+
+ // draw "even parity" triangles only
+ back_triangle(p1,p2,p3,S);
+ back_triangle(m1,m2,p3,S);
+
+ back_triangle(m1,p2,m3,S);
+ back_triangle(p1,m2,m3,S);
+ }
+
+
+ void front_dodeca(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+ const double gam(0.5*(1+sqrt(5)));
+
+ const P pop( gam*f1 + f3);
+ const P pom( gam*f1 - f3);
+ const P mom(-gam*f1 - f3);
+ const P mop(-gam*f1 + f3);
+
+ const P ppo( f1 + gam*f2);
+ const P pmo( f1 - gam*f2);
+ const P mmo(-f1 - gam*f2);
+ const P mpo(-f1 + gam*f2);
+
+ const P opp( f2 + gam*f3);
+ const P opm( f2 - gam*f3);
+ const P omm(-f2 - gam*f3);
+ const P omp(-f2 + gam*f3);
+
+ // faces surrounding pop
+ front_dual(pop, ppo, opp, S);
+ front_dual(pop, opp, omp, S);
+ front_dual(pop, omp, pmo, S);
+ front_dual(pop, pmo, pom, S);
+ front_dual(pop, pom, ppo, S);
+
+ // respective reflections about link of pop
+ front_dual(opp, ppo, mpo, S);
+ front_dual(omp, opp, mop, S);
+ front_dual(pmo, omp, mmo, S);
+ front_dual(pom, pmo, omm, S);
+ front_dual(ppo, pom, opm, S);
+
+ // and their antipodes
+ front_dual(mom, omm, mmo, S);
+ front_dual(mom, opm, omm, S);
+ front_dual(mom, mpo, opm, S);
+ front_dual(mom, mop, mpo, S);
+ front_dual(mom, mmo, mop, S);
+
+ front_dual(omm, pmo, mmo, S);
+ front_dual(opm, pom, omm, S);
+ front_dual(mpo, ppo, opm, S);
+ front_dual(mop, opp, mpo, S);
+ front_dual(mmo, omp, mop, S);
+ }
+
+ void back_dodeca(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+ const double gam(0.5*(1+sqrt(5)));
+
+ const P pop( gam*f1 + f3);
+ const P pom( gam*f1 - f3);
+ const P mom(-gam*f1 - f3);
+ const P mop(-gam*f1 + f3);
+
+ const P ppo( f1 + gam*f2);
+ const P pmo( f1 - gam*f2);
+ const P mmo(-f1 - gam*f2);
+ const P mpo(-f1 + gam*f2);
+
+ const P opp( f2 + gam*f3);
+ const P opm( f2 - gam*f3);
+ const P omm(-f2 - gam*f3);
+ const P omp(-f2 + gam*f3);
+
+ // faces surrounding pop
+ back_dual(pop, ppo, opp, S);
+ back_dual(pop, opp, omp, S);
+ back_dual(pop, omp, pmo, S);
+ back_dual(pop, pmo, pom, S);
+ back_dual(pop, pom, ppo, S);
+
+ // respective reflections about link of pop
+ back_dual(opp, ppo, mpo, S);
+ back_dual(omp, opp, mop, S);
+ back_dual(pmo, omp, mmo, S);
+ back_dual(pom, pmo, omm, S);
+ back_dual(ppo, pom, opm, S);
+
+ // and their antipodes
+ back_dual(mom, omm, mmo, S);
+ back_dual(mom, opm, omm, S);
+ back_dual(mom, mpo, opm, S);
+ back_dual(mom, mop, mpo, S);
+ back_dual(mom, mmo, mop, S);
+
+ back_dual(omm, pmo, mmo, S);
+ back_dual(opm, pom, omm, S);
+ back_dual(mpo, ppo, opm, S);
+ back_dual(mop, opp, mpo, S);
+ back_dual(mmo, omp, mop, S);
+ }
+
+
+ void front_icosa(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+ const double gam(0.5*(1+sqrt(5)));
+
+ const P pop( gam*f1 + f3);
+ const P pom( gam*f1 - f3);
+ const P mom(-gam*f1 - f3);
+ const P mop(-gam*f1 + f3);
+
+ const P ppo( f1 + gam*f2);
+ const P pmo( f1 - gam*f2);
+ const P mmo(-f1 - gam*f2);
+ const P mpo(-f1 + gam*f2);
+
+ const P opp( f2 + gam*f3);
+ const P opm( f2 - gam*f3);
+ const P omm(-f2 - gam*f3);
+ const P omp(-f2 + gam*f3);
+
+ // faces surrounding pop
+ front_triangle(pop, ppo, opp, S);
+ front_triangle(pop, opp, omp, S);
+ front_triangle(pop, omp, pmo, S);
+ front_triangle(pop, pmo, pom, S);
+ front_triangle(pop, pom, ppo, S);
+
+ // respective reflections about link of pop
+ front_triangle(opp, ppo, mpo, S);
+ front_triangle(omp, opp, mop, S);
+ front_triangle(pmo, omp, mmo, S);
+ front_triangle(pom, pmo, omm, S);
+ front_triangle(ppo, pom, opm, S);
+
+ // and their antipodes
+ front_triangle(mom, omm, mmo, S);
+ front_triangle(mom, opm, omm, S);
+ front_triangle(mom, mpo, opm, S);
+ front_triangle(mom, mop, mpo, S);
+ front_triangle(mom, mmo, mop, S);
+
+ front_triangle(omm, pmo, mmo, S);
+ front_triangle(opm, pom, omm, S);
+ front_triangle(mpo, ppo, opm, S);
+ front_triangle(mop, opp, mpo, S);
+ front_triangle(mmo, omp, mop, S);
+ }
+
+ void back_icosa(const Sphere& S, const frame& coords)
+ {
+ const P f1(coords.sea());
+ const P f2(coords.sky());
+ const P f3(coords.eye());
+ const double gam(0.5*(1+sqrt(5)));
+
+ const P pop( gam*f1 + f3);
+ const P pom( gam*f1 - f3);
+ const P mom(-gam*f1 - f3);
+ const P mop(-gam*f1 + f3);
+
+ const P ppo( f1 + gam*f2);
+ const P pmo( f1 - gam*f2);
+ const P mmo(-f1 - gam*f2);
+ const P mpo(-f1 + gam*f2);
+
+ const P opp( f2 + gam*f3);
+ const P opm( f2 - gam*f3);
+ const P omm(-f2 - gam*f3);
+ const P omp(-f2 + gam*f3);
+
+ // faces surrounding pop
+ back_triangle(pop, ppo, opp, S);
+ back_triangle(pop, opp, omp, S);
+ back_triangle(pop, omp, pmo, S);
+ back_triangle(pop, pmo, pom, S);
+ back_triangle(pop, pom, ppo, S);
+
+ // respective reflections about link of pop
+ back_triangle(opp, ppo, mpo, S);
+ back_triangle(omp, opp, mop, S);
+ back_triangle(pmo, omp, mmo, S);
+ back_triangle(pom, pmo, omm, S);
+ back_triangle(ppo, pom, opm, S);
+
+ // and their antipodes
+ back_triangle(mom, omm, mmo, S);
+ back_triangle(mom, opm, omm, S);
+ back_triangle(mom, mpo, opm, S);
+ back_triangle(mom, mop, mpo, S);
+ back_triangle(mom, mmo, mop, S);
+
+ back_triangle(omm, pmo, mmo, S);
+ back_triangle(opm, pom, omm, S);
+ back_triangle(mpo, ppo, opm, S);
+ back_triangle(mop, opp, mpo, S);
+ back_triangle(mmo, omp, mop, S);
+ }
+
+
+
+ // Hyperbolic lines in upper half space
+ // For compatibility with 2-D geometry, the boundary is the (x1,x3)-plane
+
+ void hyperbolic_line(const P& tail, const P& head)
+ {
+ if ( (tail.x2() < 0) || (head.x2() < 0) )
+ epix_warning("Endpoint not in upper half-space");
+
+ P sh_tail(tail%E_2); // shadow of tail
+ P sh_head(head%E_2);
+ double ht_tail(tail|E_2), ht_head(head|E_2);
+ double dist(norm(sh_head - sh_tail)); // dist btw projections to boundary
+
+ if (dist < EPIX_EPSILON)
+ line(tail, head);
+
+ else
+ {
+ // use similar triangles to find center; get basis; draw arc
+ double diff((ht_head - ht_tail)*(ht_head + ht_tail)/dist);
+ double frac(0.5*(diff + dist));
+ P center((1-frac/dist)*sh_tail + (frac/dist)*sh_head);
+ P e1(tail - center);
+ double rad(norm(e1));
+
+ P e2(E_2%e1);
+ e2 *= rad/norm(e2);
+ double theta(Acos(((head-center)|e1)/(rad*rad)));
+
+ ellipse(center, e1, e2, 0, theta);
+ }
+ } // end of hyperbolic_line
+
+
+ // Lines in Poincare disk model.
+ //
+ // Consider the "positive" portion of the standard hyperboloid of two
+ // sheets: x^2 + y^2 + 1 = z^2, z>0, and consider copies of the unit
+ // disk in the planes z=0 (D0) and z=1 (D1). The Klein model of the disk
+ // is gotten by stereographic projection from the origin to D1, while the
+ // Poincare model is gotten by stereographic projection from (0,0,-1) to
+ // D0. Appropriate compositions of these projection maps are hyperbolic
+ // isometries. The algorithm for drawing lines in the disk model is to
+ // find the images of the endpoints in the Klein model, draw the line
+ // between them, and map this line back to the Poincare model. Because
+ // the isometry is "square-root-like" in the radial direction at the
+ // unit circle, the points on the Klein line are spaced quadratically
+ // close together at the endpoints of the segment (the variable "s") so
+ // their images will be roughly equally-spaced in the Poincare model.
+ // There is no visual harm if one or both endpoints are far from the
+ // circle, and the result is acceptable if both points are on or near the
+ // circle. The number of points to draw is determined both by the true
+ // distance between the endpoints and by how close they are to the circle.
+
+ P poincare_klein(P pt)
+ {
+ return (2.0/(1+(pt|pt)))*pt;
+ }
+
+ P klein_poincare(P pt)
+ {
+ return (1.0/(1+sqrt(1-(pt|pt))))*pt;
+ }
+
+ P p_line(const P& tail, const P& head, double t)
+ {
+ double s(0.5*(1+std::cos(M_PI*t))); // s in [0,1]
+
+ P current((s*poincare_klein(tail)) + ((1-s)*poincare_klein(head)));
+ return klein_poincare(current);
+ }
+
+ void disk_line(const P& tail, const P& head)
+ {
+ const int N(EPIX_NUM_PTS);
+ std::vector<P> data(N+1);
+
+ double t(0);
+
+ for (int i=0; i <= N; ++i, t += 1.0/N)
+ data.at(i) = p_line(tail, head, t);
+
+ path temp(data, false, false);
+ temp.draw();
+ }
+
+} // end of namespace
diff --git a/graphics/epix/geometry.h b/graphics/epix/geometry.h
new file mode 100644
index 0000000000..60afb8af9c
--- /dev/null
+++ b/graphics/epix/geometry.h
@@ -0,0 +1,125 @@
+/*
+ * geometry.h
+ *
+ * This file is part of ePiX, a preprocessor for creating high-quality
+ * line figures in LaTeX
+ *
+ * Version 1.1.6
+ * Last Change: June 28, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_GEOMETRY
+#define EPIX_GEOMETRY
+
+#include "frame.h"
+#include "sphere.h"
+
+namespace ePiX {
+ class P;
+
+ // latitude, longitude lines with hiding
+ void latitude(double lat, double long_min, double long_max,
+ const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void longitude(double lngtd, double lat_min, double lat_max,
+ const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void back_latitude(double lat, double long_min, double long_max,
+ const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void back_longitude(double lngtd, double lat_min, double lat_max,
+ const Sphere& S=Sphere(), const frame& coords=frame());
+
+
+ // stereographic projection; path first projected vertically
+ void frontplot_N(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S = Sphere());
+
+ void backplot_N(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S = Sphere());
+
+ void frontplot_S(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S = Sphere());
+
+ void backplot_S(double f1(double), double f2(double),
+ double t_min, double t_max, int num_pts,
+ const Sphere& S = Sphere());
+
+ // Radial projection from center
+ void frontplot_R(P phi(double), double t_min, double t_max,
+ int num_pts, const Sphere& S = Sphere());
+
+ void backplot_R(P phi(double), double t_min, double t_max,
+ int num_pts, const Sphere& S = Sphere());
+
+
+ // All sphere line functions treat point arguments as unscaled
+ // displacements from the center of the sphere, not as absolute
+ // spatial locations. If the center or radius of the sphere
+ // changes, the line automatically adjusts as expected.
+
+ // front portion of spherical segment joining p1 to p2
+ void front_arc(const P& p1, const P& p2, const Sphere& S = Sphere());
+ void back_arc(const P& p1, const P& p2, const Sphere& S = Sphere());
+
+ // half-line joining p1 to -p1 through p2
+ void front_arc2(const P&, const P&, const Sphere& S=Sphere());
+ void back_arc2(const P&, const P&, const Sphere& S=Sphere());
+
+ // great circle through p1 and p2
+ void front_line(const P&, const P&, const Sphere& S=Sphere());
+ void back_line(const P&, const P&, const Sphere& S=Sphere());
+
+ void front_triangle(const P&, const P&, const P&, const Sphere& S=Sphere());
+ void back_triangle(const P&, const P&, const P&, const Sphere& S=Sphere());
+
+ // spherical polyhedra
+ void front_tetra(const Sphere& S=Sphere(), const frame& coords=frame());
+ void back_tetra(const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void front_cube(const Sphere& S=Sphere(), const frame& coords=frame());
+ void back_cube(const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void front_octa(const Sphere& S=Sphere(), const frame& coords=frame());
+ void back_octa(const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void front_dodeca(const Sphere& S=Sphere(), const frame& coords=frame());
+ void back_dodeca(const Sphere& S=Sphere(), const frame& coords=frame());
+
+ void front_icosa(const Sphere& S=Sphere(), const frame& coords=frame());
+ void back_icosa(const Sphere& S=Sphere(), const frame& coords=frame());
+
+ // Hyperbolic lines
+ void hyperbolic_line (const P&, const P&);
+ void disk_line (const P&, const P&);
+
+} // end of namespace
+
+#endif /* EPIX_GEOMETRY */
diff --git a/graphics/epix/glyph.cc b/graphics/epix/glyph.cc
new file mode 100644
index 0000000000..db4e0f2b37
--- /dev/null
+++ b/graphics/epix/glyph.cc
@@ -0,0 +1,145 @@
+/*
+ * glyph.cc -- ePiX screen implemenation for labels and markers
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+#include <sstream>
+
+#include "constants.h"
+#include "angle_units.h"
+
+#include "functions.h"
+
+#include "pairs.h"
+#include "affine.h"
+#include "screen_mask.h"
+
+#include "length.h"
+
+#include "marker_style.h"
+#include "label_style.h"
+
+#include "format.h"
+#include "state.h"
+
+#include "picture_data.h"
+#include "picture.h"
+
+#include "glyph.h"
+
+namespace ePiX {
+
+ glyph::glyph(const pair& here, const pair& offset,
+ const std::string& label, const epix_mark_type mark,
+ const marker_sizes& sizes,
+ const label_state& style, const bool seen)
+ : m_here(here), m_offset(offset),
+ m_label(label), m_mark(mark), m_sizes(sizes),
+ m_style(style), m_seen(seen) { }
+
+ glyph& glyph::map_by(const affine& f)
+ {
+ m_here = f(m_here); // new location
+
+ // map offset, preserving length
+ const double old_norm(norm(m_offset));
+ m_offset = f(m_offset) - f(pair(0,0)); // new displacement
+
+ const double new_norm(norm(m_offset));
+ if (EPIX_EPSILON < new_norm)
+ m_offset *= old_norm/new_norm; // scale to preserve page length
+
+ // compute new label angle; work in radians for safety/efficiency
+ const double th(PI_180*m_style.label_angle()); // old angle in radians
+
+ // new baseline direction
+ const pair tmp_dir(f(pair(std::cos(th), std::sin(th))) - f(pair(0,0)));
+
+ // no change if old baseline maps to zero
+ if (EPIX_EPSILON < norm(tmp_dir))
+ {
+ // new angle in current units
+ double theta(Atan2(tmp_dir.x2(), tmp_dir.x1()));
+
+ // effectively, reflect label; works well stylistically
+ if (f.reverses_orientation())
+ theta -= 0.5*full_turn();
+
+ m_style.label_angle(theta);
+ }
+
+ return *this;
+ }
+
+ glyph& glyph::crop_to(const screen_mask& M)
+ {
+ if (M.crops(m_here))
+ m_seen = false;
+
+ return *this;
+ }
+
+ glyph* glyph::clone() const
+ {
+ return new glyph(*this);
+ }
+
+ bool glyph::is_empty() const
+ {
+ return !m_seen;
+ }
+
+
+ std::string glyph::print_to(const format& fmt, const std::string& len) const
+ {
+ if (is_empty())
+ return "";
+
+ std::stringstream obuf;
+ // print (masked) label, if any, before mark.
+ if (m_label != "")
+ obuf << fmt.print_text(m_here, m_offset, m_label, m_style, len);
+
+ if (m_mark != TEXT && m_mark != PATH)
+ obuf << fmt.print_mark(m_here, m_offset, m_mark, m_sizes, m_style, len);
+
+ return obuf.str();
+ }
+
+ void glyph::add_to_pallet() const
+ {
+ the_picture().add_to_pallet(m_style.text_color())
+ .add_to_pallet(m_style.mask_color())
+ .add_to_pallet(m_style.label_border().color());
+ }
+} // end of namespace
diff --git a/graphics/epix/glyph.h b/graphics/epix/glyph.h
new file mode 100644
index 0000000000..44f7fb8cec
--- /dev/null
+++ b/graphics/epix/glyph.h
@@ -0,0 +1,85 @@
+/*
+ * glyph.h -- ePiX screen implemenation for labels and markers
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 16, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_GLYPH
+#define EPIX_GLYPH
+
+#include <string>
+
+#include "pairs.h"
+#include "length.h"
+#include "Color.h"
+
+#include "marker_style.h"
+#include "label_style.h"
+#include "tile.h"
+
+namespace ePiX {
+
+ class format;
+ class affine;
+ class screen_mask;
+
+ class glyph : public tile {
+ public:
+ // location, offsets, contents, mark type, visibility
+ glyph(const pair& here, const pair& offset,
+ const std::string& label, const epix_mark_type mark,
+ const marker_sizes& sizes,
+ const label_state& style, const bool seen);
+
+ glyph& map_by(const affine&);
+ glyph& crop_to(const screen_mask&);
+
+ glyph* clone() const;
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ private:
+ pair m_here;
+ pair m_offset;
+
+ std::string m_label;
+ epix_mark_type m_mark;
+
+ marker_sizes m_sizes;
+ label_state m_style;
+
+ bool m_seen;
+ }; // end of class glyph
+
+} // end of namespace
+
+#endif /* EPIX_GLYPH */
diff --git a/graphics/epix/halfspace.cc b/graphics/epix/halfspace.cc
new file mode 100644
index 0000000000..4be13a979c
--- /dev/null
+++ b/graphics/epix/halfspace.cc
@@ -0,0 +1,67 @@
+/*
+ * halfspace.cc -- ePiX::halfspace class for clipping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+
+#include "triples.h"
+#include "edge_data.h"
+#include "crop_algorithms.h"
+
+#include "halfspace.h"
+
+namespace ePiX {
+
+ halfspace::halfspace(const P& base, const P& perp)
+ : m_base(base), m_perp((1.0/norm(perp))*perp) { }
+
+ halfspace& halfspace::reverse()
+ {
+ m_perp *= -1;
+ return *this;
+ }
+
+ bool halfspace::clips(const P& arg) const
+ {
+ return height(m_perp, m_base, arg) < -EPIX_EPSILON;
+ }
+
+ std::list<edge3d>& halfspace::clip_path(std::list<edge3d>& L) const
+ {
+ return chop_path<P>(m_perp, m_base, L);
+ }
+
+ std::list<edge3d>& halfspace::clip_loop(std::list<edge3d>& L) const
+ {
+ return chop_loop<P>(m_perp, m_base, L);
+ }
+} // end of namespace
diff --git a/graphics/epix/halfspace.h b/graphics/epix/halfspace.h
new file mode 100644
index 0000000000..44f4a8a89c
--- /dev/null
+++ b/graphics/epix/halfspace.h
@@ -0,0 +1,67 @@
+/*
+ * halfspace.h -- ePiX::halfspace class for clipping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides the halfspace class for path clipping.
+ * A halfspace contains a base point p and a unit vector n, and defines the
+ * affine half space (x-p)|n > 0; n points "inward".
+ */
+#ifndef EPIX_HALFSPACE
+#define EPIX_HALFSPACE
+
+#include <list>
+
+#include "triples.h"
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class halfspace {
+ public:
+ halfspace(const P& base, const P& perp);
+
+ halfspace& reverse();
+
+ bool clips(const P&) const;
+
+ std::list<edge3d>& clip_path(std::list<edge3d>&) const;
+ std::list<edge3d>& clip_loop(std::list<edge3d>&) const;
+
+ private:
+ P m_base;
+ P m_perp;
+ }; // end of class halfspace
+} // end of namespace
+
+#endif /* EPIX_HALFSPACE */
diff --git a/graphics/epix/hatching.cc b/graphics/epix/hatching.cc
new file mode 100644
index 0000000000..00fe64b7a3
--- /dev/null
+++ b/graphics/epix/hatching.cc
@@ -0,0 +1,258 @@
+/*
+ * hatching.cc -- ePiX's internal data for filled polygons
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+#include <vector>
+#include <cmath>
+
+#include "errors.h"
+
+#include "constants.h"
+#include "functions.h"
+#include "pairs.h"
+
+#include "edge_data.h"
+
+#include "state.h"
+#include "hatching.h"
+
+namespace ePiX {
+
+ bd_edge::bd_edge(const edge2d& edge, double ht1, double ht2, int orient)
+ : m_edge(edge), m_lo(min(ht1, ht2)), m_hi(max(ht1, ht2)),
+ m_orient(orient) { }
+
+ pair bd_edge::tail() const
+ {
+ return m_edge.tail();
+ }
+
+ pair bd_edge::head() const
+ {
+ return m_edge.head();
+ }
+
+ pair bd_edge::dir() const
+ {
+ return m_edge.head() - m_edge.tail();
+ }
+
+ double bd_edge::lo() const
+ {
+ return m_lo;
+ }
+
+ double bd_edge::hi() const
+ {
+ return m_hi;
+ }
+
+ int bd_edge::orient() const
+ {
+ return m_orient;
+ }
+
+
+ cut::cut(pair loc, int sign)
+ : m_loc(loc), m_sign(sign) { }
+
+ pair cut::loc() const
+ {
+ return m_loc;
+ }
+
+ int cut::sign() const
+ {
+ return m_sign;
+ }
+
+
+ // (h-t) assumed unit
+ scan_line::scan_line(const pair& t, const pair& h)
+ : m_perp(J(t - h)), m_ht(h.x1()*t.x2() - h.x2()*t.x1()) { }
+
+
+ // keep m_cuts sorted by x
+ void scan_line::add_cut(const cut& crossing)
+ {
+ if (EPIX_EPSILON < fabs((m_perp|crossing.loc()) + m_ht))
+ return;
+
+ const double x(J(m_perp)|crossing.loc());
+
+ std::list<cut>::iterator p(m_cuts.begin());
+
+ while (p != m_cuts.end() && (J(m_perp)|(*p).loc()) < x)
+ ++p;
+
+ m_cuts.insert(p, crossing);
+ }
+
+
+ // add scans to value
+ void scan_line::draw(std::vector<edge2d>& value) const
+ {
+ std::list<cut>::const_iterator p(m_cuts.begin());
+
+ if (p == m_cuts.end()) // redundant guard
+ return;
+
+ int winding((*p).sign());
+
+ pair start((*p).loc());
+ pair end(start);
+
+ while (p != m_cuts.end())
+ {
+ // non-zero winding rule
+ while (winding != 0 && ++p != m_cuts.end())
+ {
+ end = (*p).loc();
+ winding += (*p).sign();
+ }
+
+ if (start != end)
+ value.push_back(edge2d(start, end, true));
+
+ // seek to next start
+ while (winding == 0 && ++p != m_cuts.end())
+ {
+ start = (*p).loc();
+ winding += (*p).sign();
+ }
+ }
+ } // end of scan_line::draw
+
+
+ // private function; assumes horiz is unit
+ void hatch_data::hatch_init(const pair& horiz,
+ double sep,
+ std::list<edge2d> polygon)
+ {
+ const pair vert(J(horiz));
+
+ // initialize loop with first edge
+ std::list<edge2d>::iterator p(polygon.begin());
+
+ // first pass: Get min, max vertex heights; remove horizontal edges
+ double min_ht((*p).tail()|vert);
+ double max_ht(min_ht);
+
+ for (p = polygon.begin(); p != polygon.end(); ) // increment at bottom
+ {
+ double tmp_tl((*p).tail()|vert);
+ double tmp_hd((*p).head()|vert);
+
+ if (fabs(tmp_hd - tmp_tl) < EPIX_EPSILON) // horizontal edge
+ p = polygon.erase(p);
+
+ else
+ {
+ // running extrema from head height
+ min_ht = min(min_ht, tmp_hd);
+ max_ht = max(max_ht, tmp_hd);
+
+ int up(tmp_tl < tmp_hd ? 1 : -1); // get edge orientation
+ m_edges.push_back(bd_edge(*p, tmp_tl, tmp_hd, up));
+ ++p;
+ }
+ }
+
+ // compute subdivision heights, initialize vector of scan_lines
+ unsigned int num_cuts((unsigned int) ceil((max_ht - min_ht)/sep));
+ const double true_sep((max_ht - min_ht)/num_cuts);
+
+ // initialize hatch lines
+ for (unsigned int i=0; i <= num_cuts; ++i)
+ {
+ double ht(min_ht + i*true_sep);
+ m_scans.push_back(scan_line(ht*vert, horiz + ht*vert));
+ }
+
+ // Second pass: add scan line cuts
+ for (std::list<bd_edge>::iterator ep=m_edges.begin();
+ ep != m_edges.end(); ++ep)
+ {
+ // indices of scan lines we cross
+ unsigned int i_min((unsigned int) ceil(((*ep).lo()-min_ht)/true_sep));
+ unsigned int i_max((unsigned int) floor(((*ep).hi()-min_ht)/true_sep));
+
+ // compute parameters once per edge
+ const pair tl((*ep).tail());
+ const pair dir((*ep).dir());
+
+ // relative heights of endpoints
+ const double ht_hd((*ep).head()|vert);
+ const double ht_tl(tl|vert);
+
+ const int up((*ep).orient());
+
+ for (unsigned int i = i_min; i <= i_max; ++i)
+ {
+ const double t((min_ht + i*true_sep - ht_tl)/(ht_hd - ht_tl));
+ m_scans.at(i).add_cut(cut(tl + t*dir, up));
+ }
+ }
+ } // end of hatch_init
+
+
+ // user-visible constructors
+ hatch_data::hatch_data(double dir_x, double dir_y,
+ double sep, const std::list<edge2d>& polygon)
+ {
+ pair dir(dir_x, dir_y);
+ dir *= 1.0/norm(dir);
+
+ hatch_init(dir, sep, polygon);
+ }
+
+ hatch_data::hatch_data(double th, double sep,
+ const std::list<edge2d>& polygon)
+ {
+ const double theta(th*PI_180); // th in radians
+
+ // orthonormal basis; horiz along cuts, vert perp to cuts
+ hatch_init(pair(std::cos(theta), std::sin(theta)), sep, polygon);
+ }
+
+
+ std::vector<edge2d> hatch_data::data() const
+ {
+ std::vector<edge2d> value;
+
+ for (unsigned int i=0; i < m_scans.size(); ++i)
+ m_scans.at(i).draw(value);
+
+ return value;
+ }
+} // end of namespace
diff --git a/graphics/epix/hatching.h b/graphics/epix/hatching.h
new file mode 100644
index 0000000000..877efde8c8
--- /dev/null
+++ b/graphics/epix/hatching.h
@@ -0,0 +1,123 @@
+/*
+ * hatching.h -- ePiX hatched region data structures
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.13
+ * Last Change: August 29, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_HATCHING
+#define EPIX_HATCHING
+
+#include <list>
+#include <vector>
+
+#include "pairs.h"
+#include "edge_data.h"
+
+namespace ePiX {
+
+ // edge, endpoint heights, orientation (+/-1 = up/down)
+ class bd_edge {
+ public:
+ bd_edge(const edge2d&, double, double, int);
+
+ pair tail() const;
+ pair head() const;
+ pair dir() const;
+
+ double lo() const;
+ double hi() const;
+
+ int orient() const;
+
+ private:
+ edge2d m_edge;
+
+ double m_lo;
+ double m_hi;
+
+ int m_orient;
+ };
+
+ // location where scan line crosses bd_edge
+ class cut {
+ public:
+ cut(pair loc, int sign);
+
+ pair loc() const;
+ int sign() const;
+
+ private:
+ pair m_loc; // location
+ int m_sign; // orientation
+ };
+
+ // ax + by + c = 0
+ class scan_line {
+ public:
+ scan_line(const pair& t, const pair& h);
+
+ void add_cut(const cut&);
+
+ // store what we find in value
+ void draw(std::vector<edge2d>& value) const;
+
+ private:
+ pair m_perp; // (a, b)
+ double m_ht; // c
+
+ std::list<cut> m_cuts;
+ }; // end of class scan_line
+
+
+ // ctor converts a list of edge2d into a (large) vector of scan lines
+ class hatch_data {
+ public:
+ // components of hatch direction, scanline separation, polygon to fill
+ hatch_data(double, double,
+ double sep, const std::list<edge2d>&);
+
+ // angle, scanline separation, polygon to fill
+ hatch_data(double th, double sep, const std::list<edge2d>&);
+
+ std::vector<edge2d> data() const;
+
+ private:
+ std::list<bd_edge> m_edges;
+ std::vector<scan_line> m_scans;
+
+ // convert polygon to scan lines parallel to dir, common to both ctors
+ void hatch_init(const pair& dir,
+ double sep,
+ std::list<edge2d> polygon);
+ }; // end of class hatch_data
+
+} // end of namespace
+
+#endif /* EPIX_HATCHING */
diff --git a/graphics/epix/install-sh b/graphics/epix/install-sh
new file mode 100644
index 0000000000..4d4a9519ea
--- /dev/null
+++ b/graphics/epix/install-sh
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-05-14.22
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ *) # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ test -n "$dir_arg$dstarg" && break
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+ break;;
+ esac
+done
+
+if test -z "$1"; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ src=
+
+ if test -d "$dst"; then
+ mkdircmd=:
+ chmodcmd=
+ else
+ mkdircmd=$mkdirprog
+ fi
+ else
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dst=$dst/`basename "$src"`
+ fi
+ fi
+
+ # This sed command emulates the dirname command.
+ dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+ # Make sure that the destination directory exists.
+
+ # Skip lots of stat calls in the usual case.
+ if test ! -d "$dstdir"; then
+ defaultIFS='
+ '
+ IFS="${IFS-$defaultIFS}"
+
+ oIFS=$IFS
+ # Some sh's can't handle IFS=/ for some reason.
+ IFS='%'
+ set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+ shift
+ IFS=$oIFS
+
+ pathcomp=
+
+ while test $# -ne 0 ; do
+ pathcomp=$pathcomp$1
+ shift
+ if test ! -d "$pathcomp"; then
+ $mkdirprog "$pathcomp"
+ # mkdir can fail with a `File exist' error in case several
+ # install-sh are creating the directory concurrently. This
+ # is OK.
+ test -d "$pathcomp" || exit
+ fi
+ pathcomp=$pathcomp/
+ done
+ fi
+
+ if test -n "$dir_arg"; then
+ $doit $mkdircmd "$dst" \
+ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+ else
+ dstfile=`basename "$dst"`
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Copy the file name to the temp name.
+ $doit $cpprog "$src" "$dsttmp" &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+ # Now rename the file to the real destination.
+ { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+ || {
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ if test -f "$dstdir/$dstfile"; then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+ || {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit 1
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+ }
+ }
+ fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+ (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/graphics/epix/intersections.cc b/graphics/epix/intersections.cc
new file mode 100644
index 0000000000..6789e64dbe
--- /dev/null
+++ b/graphics/epix/intersections.cc
@@ -0,0 +1,318 @@
+/*
+ * intersections.cc -- ePiX's intersection operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "constants.h"
+#include "errors.h"
+
+#include "circle.h"
+#include "plane.h"
+#include "segment.h"
+#include "sphere.h"
+
+#include "intersections.h"
+
+namespace ePiX {
+
+ static const double EPS(EPIX_EPSILON);
+
+ Segment operator* (const Circle& arg1, const Circle& arg2)
+ {
+ if (arg1.malformed() || arg2.malformed())
+ return Segment(true);
+
+ const P p2(arg2.center());
+ const P n2(arg2.perp());
+
+ P dir(p2 - arg1.center()); // displacement between centers
+
+ const double r1(arg1.radius());
+ const double r2(arg2.radius());
+ const double rad_diff(fabs(r2 - r1));
+ const double rad_sum(r2 + r1);
+ const double sep(norm(dir));
+
+ if ( EPS < norm(arg1.perp()*arg2.perp()) || // non-coplanar
+ rad_sum <= sep || // separated
+ sep <= rad_diff ) // concentric, catches equality
+ return Segment(true);
+
+ // else
+ dir *= 1.0/sep;
+
+ const double COS(((r1-r2)*(r1+r2) - sep*sep)/(2*r2*sep));
+ const double SIN(sqrt((1-COS)*(1+COS)));
+
+ return Segment(p2 + r2*(COS*dir + SIN*(n2*dir)),
+ p2 + r2*(COS*dir - SIN*(n2*dir)));
+ }
+
+
+ Segment operator* (const Circle& circ, const Plane& pl)
+ {
+ if (circ.malformed() || pl.malformed())
+ return Segment(true);
+
+ // else
+ P bi_perp(circ.perp()*pl.perp());
+ const double denom(norm(bi_perp));
+
+ if (denom < EPS) // parallel
+ return Segment(true);
+
+ // else
+ bi_perp *= 1.0/denom;
+
+ const P dir(bi_perp*circ.perp()); // unit vector toward pl in circ plane
+
+ // shortest distance from circ.center() to pl in circ plane
+ const double x(-((circ.center() - pl.pt())|pl.perp())/(dir|pl.perp()));
+
+ const double rad(circ.radius());
+
+ if (rad <= fabs(x)) // disjoint
+ return Segment(true);
+
+ // else
+ const P vec_y(sqrt((rad-x)*(rad+x))*bi_perp);
+ const P midpt(circ.center() + x*dir);
+
+ return Segment(midpt - vec_y, midpt + vec_y);
+ }
+
+ // Extend seg into a line, look for two crossings
+ Segment operator* (const Circle& circ, const Segment& seg)
+ {
+ if (seg.malformed() || circ.malformed())
+ return Segment(true);
+
+ // else
+ const P dir(seg.end2() - seg.end1());
+
+ if (EPS < fabs(dir|circ.perp()))
+ return Segment(true);
+
+ // else
+ P to_ctr(circ.center() - seg.end1());
+ P perp(circ.perp()*dir);
+
+ const double dist((to_ctr|perp)/norm(perp));
+ const double rad(circ.radius());
+
+ if (rad <= fabs(dist))
+ return Segment(true);
+
+ // else
+ const P vec_x(circ.center() - (dist/norm(perp))*perp);
+ const P vec_y((sqrt((rad-dist)*(rad+dist))/norm(dir))*dir);
+
+ return Segment(vec_x + vec_y, vec_x - vec_y);
+ }
+
+
+ // cut plane of circ by S, intersect
+ Segment operator* (const Circle& circ, const Sphere& S)
+ {
+ Plane pl(circ.center(), circ.perp());
+ return circ*(pl*S);
+ }
+
+ Segment operator* (const Plane& pl1, const Plane& pl2)
+ {
+ if (pl1.malformed() || pl2.malformed())
+ return Segment(true);
+
+ // else
+ P N3((pl1.perp())*(pl2.perp()));
+ const double temp(norm(N3));
+
+ if (temp < EPS) // parallel
+ return Segment(true);
+
+ // else N3 non-zero, parallel to intersection
+ N3 *= 1/temp; // normalize
+
+ P perp((pl1.perp())*N3); // unit vector in pl, perp to intersection
+ P pt(pl1.pt() + (((pl2.pt()-pl1.pt())|pl2.perp())/(perp|pl2.perp()))*perp);
+ P ctr(pt %= N3); // closest pt to origin on line
+ // P ctr(pt - (pt|N3)*N3);
+
+ return Segment(ctr - EPIX_INFTY*N3, ctr + EPIX_INFTY*N3);
+ }
+
+
+ P operator* (const Plane& pl, const Segment& seg)
+ {
+ if (pl.malformed() || seg.malformed())
+ epix_warning("Malformed argument(s) to Plane*Segment");
+
+ const P tail(seg.end1());
+ const P head(seg.end2());
+
+ const double ptail((tail - pl.pt())|pl.perp());
+ const double phead((head - pl.pt())|pl.perp());
+
+ if (fabs(phead - ptail) < EPS)
+ epix_warning("Plane parallel to Segment in intersection");
+
+ return tail + (ptail/(ptail-phead))*(head-tail);
+ }
+
+
+ Circle operator* (const Plane& pl, const Sphere& S)
+ {
+ if (pl.malformed() || S.malformed())
+ return Circle(true);
+
+ // else
+ const double rad(S.radius());
+ const double ht((pl.pt() - S.center())|pl.perp());
+
+ if (rad <= fabs(ht)) // disjoint
+ return Circle(true);
+
+ else
+ return Circle(S.center() + ht*pl.perp(),
+ sqrt((rad - ht)*(rad + ht)),
+ pl.perp());
+ }
+
+
+ P operator* (const Segment& seg1, const Segment& seg2)
+ {
+ if (seg1.malformed() || seg2.malformed())
+ epix_warning("Malformed argument(s) in Segment intersection");
+
+ const P p1(seg1.end1());
+ const P dir1(seg1.end2() - p1);
+
+ const P p3(seg2.end1());
+ const P p4(seg2.end2());
+ const P dir2(p4 - p3);
+
+ P perp(dir1*dir2);
+ double normal_length();
+
+ // non-coplanar or parallel
+ if (EPS < fabs((dir1*(p3 - p1)) | (p4 - p1)) || norm(perp) < EPS)
+ epix_warning("Non-generic arguments in Segment intersection");
+
+ // perp lies in plane of segments, is orthog to dir2
+ perp *= dir2;
+
+ // get t so that normal|(X - p3) = (normal|(p1 - p3 + t*dir1)) = 0.
+ // note: X may not lie on either segment
+ return p1 + ((perp|(p3-p1))/(perp|dir1))*dir1;
+ }
+
+ // extend seg into a line
+ Segment operator* (const Segment& seg, const Sphere& S)
+ {
+ if (seg.malformed() || S.malformed())
+ return Segment(true);
+
+ // else
+ P dir(seg.end2() - seg.end1());
+ dir *= 1.0/norm(dir);
+
+ const P posn(S.center() - seg.end1());
+ const P perp(posn%dir);
+
+ if (S.radius() <= norm(perp)) // disjoint
+ return Segment(true);
+
+ // else
+ const double B(dir|posn);
+ const double C((posn|posn)-pow(S.radius(), 2));
+ const double discrim(sqrt(B*B - C)); // [sic]
+
+ return Segment(seg.end1() + (B-discrim)*dir,
+ seg.end1() + (B+discrim)*dir);
+ }
+
+ Circle operator* (const Sphere& sph1, const Sphere& sph2)
+ {
+ if (sph1.malformed() || sph2.malformed())
+ return Circle(true);
+
+ // else
+ const double r1(sph1.radius());
+ const double r2(sph2.radius());
+ P dir(sph2.center() - sph1.center());
+
+ const double dist(norm(dir));
+
+ // separated, tangent, or concentric
+ if (r1+r2 <= dist || dist <= fabs(r2-r1))
+ return Circle(true);
+
+ // else
+ const double x(0.5*(dist + (r1-r2)*(r1+r2)/dist));
+ const P perp((1/dist)*dir);
+
+ return Circle(sph1.center() + x*perp, sqrt((r1-x)*(r1+x)), perp);
+ }
+
+
+ // derived operators
+ Segment operator* (const Plane& pl, const Circle& circ)
+ {
+ return circ*pl;
+ }
+
+ Segment operator* (const Segment& seg, const Circle& circ)
+ {
+ return circ*seg;
+ }
+
+ Segment operator* (const Sphere& S, const Circle& circ)
+ {
+ return circ*S;
+ }
+
+ P operator* (const Segment& seg, const Plane& pl)
+ {
+ return pl*seg;
+ }
+
+ Circle operator* (const Sphere& S, const Plane& pl)
+ {
+ return pl*S;
+ }
+
+ Segment operator* (const Sphere& S, const Segment& seg)
+ {
+ return seg*S;
+ }
+} // end of namespace
diff --git a/graphics/epix/intersections.h b/graphics/epix/intersections.h
new file mode 100644
index 0000000000..edf7b05569
--- /dev/null
+++ b/graphics/epix/intersections.h
@@ -0,0 +1,70 @@
+/*
+ * intersections.h -- Circle, Plane, Segment, Sphere intersection operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_INTERSECTIONS
+#define EPIX_INTERSECTIONS
+
+namespace ePiX {
+
+ class Circle;
+ class Plane;
+ class Segment;
+ class Sphere;
+
+ Segment operator* (const Circle&, const Circle&);
+ Segment operator* (const Circle&, const Plane&);
+ Segment operator* (const Circle&, const Segment&);
+ Segment operator* (const Circle&, const Sphere&);
+
+ Segment operator* (const Plane&, const Plane&);
+ P operator* (const Plane&, const Segment&);
+ Circle operator* (const Plane&, const Sphere&);
+
+ P operator* (const Segment&, const Segment&);
+ Segment operator* (const Segment&, const Sphere&);
+
+ Circle operator* (const Sphere&, const Sphere&);
+
+ // derived operators with reversed argument order
+ Segment operator* (const Plane&, const Circle&);
+ Segment operator* (const Segment&, const Circle&);
+ Segment operator* (const Sphere&, const Circle&);
+
+ P operator* (const Segment&, const Plane&);
+ Circle operator* (const Sphere&, const Plane&);
+
+ Segment operator* (const Sphere&, const Segment&);
+
+} // end of namespace
+
+#endif /* EPIX_INTERSECTIONS */
diff --git a/graphics/epix/interval.cc b/graphics/epix/interval.cc
new file mode 100644
index 0000000000..11f7a2aace
--- /dev/null
+++ b/graphics/epix/interval.cc
@@ -0,0 +1,228 @@
+/*
+ * interval.cc -- ePiX::interval class functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ *
+ */
+#include <cstdlib>
+#include <string>
+
+#include "functions.h"
+#include "interval.h"
+
+namespace ePiX {
+
+ // expect arg of the form (a,b), [a,b), (a,b], or [a,b]
+ interval::interval(std::string arg)
+ : m_closed_l(true), m_closed_r(true)
+ {
+ std::string::size_type i(arg.find_first_of("[("));
+
+ if (i == std::string::npos) // return "empty interval"
+ {
+ m_rmin=1;
+ m_rmax=0;
+ return;
+ }
+
+ // else
+ arg.erase(0, i);
+
+ if (arg.at(0) == '(')
+ m_closed_l = false;
+
+ // expect numerical argument
+ i = arg.find_first_of("-0123456789.");
+ if (i == std::string::npos)
+ {
+ m_rmin=1;
+ m_rmax=0;
+ return;
+ }
+
+ arg.erase(0, i);
+
+ // get left endpoint
+ const char* tmp1(arg.c_str());
+ char* new_arg;
+ m_rmin = strtod(tmp1, &new_arg);
+ arg=new_arg;
+
+ i = arg.find_first_of(",");
+ if (i == std::string::npos)
+ {
+ m_rmax=0;
+ m_rmin=1;
+ return;
+ }
+
+ arg.erase(0, i);
+
+ // expect another numerical argument
+ i = arg.find_first_of("-0123456789.");
+ if (i == std::string::npos)
+ {
+ m_rmax=0;
+ m_rmin=1;
+ return;
+ }
+
+ arg.erase(0, i);
+
+ const char* tmp2(arg.c_str());
+ m_rmax = strtod(tmp2, &new_arg);
+ arg=new_arg;
+
+ i = arg.find_first_of(")]");
+
+ if (i == std::string::npos)
+ {
+ m_rmax=0;
+ m_rmin=1;
+ return;
+ }
+
+ if (arg.at(0) == ')')
+ m_closed_r = false;
+ } // end of interval(std::string)
+
+
+ interval::interval(double a, double b)
+ : m_rmin(ePiX::min(a, b)), m_rmax(ePiX::max(a, b)),
+ m_closed_l(true), m_closed_r(true) { }
+
+ interval interval::literal(double a, double b)
+ {
+ interval value(a, a);
+ value.m_rmax = b;
+ return value;
+ }
+
+ interval interval::emptyset(literal(1,0));
+
+ double interval::min() const
+ {
+ return m_rmin;
+ }
+
+ double interval::max() const
+ {
+ return m_rmax;
+ }
+
+ double interval::avg() const
+ {
+ return 0.5*(m_rmin + m_rmax);
+ }
+
+
+ // Magic number
+ const double EPS(1.0e-10);
+
+ bool interval::contains(double x) const
+ {
+ // check bounds at each endpoint
+ return ( (m_closed_l ? (m_rmin - EPS <= x) : (m_rmin + EPS < x))
+ && (m_closed_r ? (x <= m_rmax + EPS) : (x < m_rmax - EPS)) );
+ }
+
+ // Minkowski sum
+ interval& interval::operator +=(const interval& I)
+ {
+ if (is_empty())
+ ;
+
+ else if (I.is_empty())
+ *this = interval::emptyset;
+
+ else
+ {
+ m_rmin += I.m_rmin;
+ m_rmax += I.m_rmax;
+
+ // sum contains endpoint iff both arguments do
+ m_closed_l &= I.m_closed_l;
+ m_closed_r &= I.m_closed_r;
+ }
+
+ return *this;
+ }
+
+ // intersection
+ interval& interval::operator *=(const interval& I)
+ {
+ if (!is_empty())
+ {
+ m_rmin = ePiX::max(m_rmin, I.m_rmin);
+ m_rmax = ePiX::min(m_rmax, I.m_rmax);
+
+ m_closed_l &= I.m_closed_l;
+ m_closed_r &= I.m_closed_r;
+ }
+
+ return *this;
+ }
+
+ bool interval::operator== (const interval& I) const
+ {
+ if (is_empty())
+ return (I.is_empty()); // both empty?
+
+ else
+ return ((m_rmin == I.m_rmin) && (m_rmax == I.m_rmax)
+ && (m_closed_l == I.m_closed_l) && (m_closed_r == I.m_closed_r));
+ }
+
+ bool interval::operator!= (const interval& I) const
+ {
+ return !(*this == I);
+ }
+
+ bool interval::is_empty() const
+ {
+ if ( (m_rmin < m_rmax)
+ || ( (m_rmin == m_rmax) && m_closed_l && m_closed_r ) )
+ return false;
+
+ else
+ return true;
+ }
+
+ // non-members
+ interval operator+ (interval I1, const interval& I2)
+ {
+ return I1 += I2;
+ }
+
+ interval operator* (interval I1, const interval& I2)
+ {
+ return I1 *= I2;
+ }
+
+} // end of namespace
diff --git a/graphics/epix/interval.h b/graphics/epix/interval.h
new file mode 100644
index 0000000000..465262c4da
--- /dev/null
+++ b/graphics/epix/interval.h
@@ -0,0 +1,81 @@
+/*
+ * interval.h -- ePiX::interval class and operations
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.25
+ * Last Change: May 20, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ *
+ *
+ * This file provides the interval class:
+ *
+ * - Minkowski sum, intersection
+ */
+
+#ifndef EPIX_INTERVAL
+#define EPIX_INTERVAL
+
+#include <string>
+
+namespace ePiX {
+
+ class interval {
+ public:
+ interval(std::string); // allow implicit conversion, must mangle argument
+ interval(double, double); // closed interval
+
+ static interval emptyset;
+
+ double min() const;
+ double max() const;
+ double avg() const;
+
+ bool contains(double) const;
+
+ // Minkowski sum
+ interval& operator +=(const interval&);
+
+ // intersection
+ interval& operator *=(const interval&);
+
+ bool operator== (const interval&) const;
+ bool operator!= (const interval&) const;
+ bool is_empty() const;
+
+ private:
+ double m_rmin, m_rmax;
+
+ bool m_closed_l, m_closed_r;
+
+ static interval literal(double a, double b); // can force b<a
+ }; // end of interval class
+
+ interval operator+ (interval I1, const interval& I2);
+ interval operator* (interval I1, const interval& I2);
+
+} // end of namespace
+
+#endif /* EPIX_INTERVAL */
diff --git a/graphics/epix/label_data.cc b/graphics/epix/label_data.cc
new file mode 100644
index 0000000000..7f0e8b20f2
--- /dev/null
+++ b/graphics/epix/label_data.cc
@@ -0,0 +1,140 @@
+/*
+ * label_data.cc -- ePiX::label_data class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+
+#include "enums.h"
+
+#include "triples.h"
+#include "pairs.h"
+
+#include "label_data.h"
+#include "camera.h"
+#include "screen_data.h"
+#include "screen.h"
+
+#include "clipping.h"
+
+#include "paint_style.h"
+
+#include "active_screen.h"
+#include "glyph.h"
+
+namespace ePiX {
+
+ label_data::label_data(const P& here, const P& offset,
+ const std::string& text, epix_mark_type mark)
+ : m_here(here), m_offset(offset.x1(), offset.x2()),
+ m_text(text), m_mark(mark), m_sizes(the_mark_size()),
+ m_style(the_label_style()), m_seen(!the_clip_box().clips(m_here))
+ {
+ // set axis tick color to line color; rotation ok if requested
+ if (m_mark == HTICK || m_mark == VTICK)
+ m_style.text_color(the_paint_style().line_color());
+ }
+
+ // generate label text from user-specified function of 2 or 3 variables
+ label_data::label_data(const P& here, const P& offset,
+ std::string f(double,double), epix_mark_type mark)
+ : m_here(here), m_offset(offset.x1(), offset.x2()),
+ m_text(f(here.x1(), here.x2())),
+ m_mark(mark), m_sizes(the_mark_size()), m_style(the_label_style()),
+ m_seen(!the_clip_box().clips(m_here))
+ {
+ if (m_mark == HTICK || m_mark == VTICK)
+ m_style.text_color(the_paint_style().line_color());
+ }
+
+ label_data::label_data(const P& here, const P& offset,
+ std::string f(double,double,double),
+ epix_mark_type mark)
+ : m_here(here), m_offset(offset.x1(), offset.x2()),
+ m_text(f(here.x1(), here.x2(), here.x3())),
+ m_mark(mark), m_sizes(the_mark_size()), m_style(the_label_style()),
+ m_seen(!the_clip_box().clips(m_here))
+ {
+ if (m_mark == HTICK || m_mark == VTICK)
+ m_style.text_color(the_paint_style().line_color());
+ }
+
+ // markers subject to masking, border
+ // Only this constructor aligns TICK marks, prevents their rotation
+ label_data::label_data(const P& here, epix_mark_type mark, epix_label_posn A)
+ : m_here(here), m_offset(0, 0),
+ m_text(""), m_mark(mark), m_sizes(the_mark_size()),
+ m_style(the_label_style()), m_seen(!the_clip_box().clips(m_here))
+ {
+ if (m_mark == HTICK || m_mark == VTICK)
+ {
+ m_style.text_color(the_paint_style().line_color());
+ m_style.label_angle(0); // no initial rotation
+
+ // prevent unseemly alignment; default is c, so needn't check
+ if (m_mark == HTICK && A == t || A == b)
+ m_style.align_to(A);
+
+ else if (A == l || A == r)
+ m_style.align_to(A);
+ }
+ }
+
+
+ label_data& label_data::text_color(const Color& col)
+ {
+ m_style.text_color(col);
+ return *this;
+ }
+
+ label_data& label_data::mask_color(const Color& col)
+ {
+ m_style.mask_color(col);
+ return *this;
+ }
+
+ label_data& label_data::align_to(epix_label_posn align)
+ {
+ m_style.align_to(align);
+ return *this;
+ }
+
+ // send colors through cam
+ void label_data::draw() const
+ {
+ if (m_seen)
+ (*active_screen()).m_screen->add_tile(glyph(cam()(m_here), m_offset,
+ m_text, m_mark, m_sizes,
+ m_style.seen_through(cam()),
+ true));
+ }
+} // end of namespace
diff --git a/graphics/epix/label_data.h b/graphics/epix/label_data.h
new file mode 100644
index 0000000000..53ccd0abe5
--- /dev/null
+++ b/graphics/epix/label_data.h
@@ -0,0 +1,97 @@
+/*
+ * label_data.h -- ePiX::label_data class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 16, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * label_data comprises spatial location, screen offsets, text (contents),
+ * mark type, and a label_style (q.v.). label_data can be constructed from
+ * string-valued functions of position; examples are given below.
+ */
+
+#ifndef EPIX_LABEL
+#define EPIX_LABEL
+
+#include <string>
+
+#include "enums.h"
+#include "triples.h"
+
+#include "pairs.h"
+
+#include "marker_style.h"
+#include "label_style.h"
+
+namespace ePiX {
+
+ class Camera;
+ class Color;
+ class screen;
+
+ class label_data {
+ public:
+ label_data(const P& here, const P& offset,
+ const std::string& text, epix_mark_type mark=TEXT);
+
+ // generate label text from user-specified function of 2 or 3 variables
+ label_data(const P& here, const P& offset,
+ std::string f(double,double), epix_mark_type mark=TEXT);
+
+ label_data(const P& here, const P& offset,
+ std::string f(double,double,double), epix_mark_type mark=TEXT);
+
+ // marker; alignment affects only TICK marks
+ label_data(const P& here, epix_mark_type mark, epix_label_posn align=c);
+
+ // pass through to m_style
+ label_data& text_color(const Color&);
+ label_data& mask_color(const Color&);
+ label_data& align_to(epix_label_posn);
+
+ void draw() const;
+
+ private:
+ P m_here;
+ pair m_offset;
+
+ std::string m_text;
+ epix_mark_type m_mark;
+
+ marker_sizes m_sizes;
+ label_state m_style;
+
+ bool m_seen;
+ }; // end of label_data class
+
+} // end of namespace
+
+#endif /* EPIX_LABEL */
diff --git a/graphics/epix/label_style.cc b/graphics/epix/label_style.cc
new file mode 100644
index 0000000000..ddd08f55ec
--- /dev/null
+++ b/graphics/epix/label_style.cc
@@ -0,0 +1,177 @@
+/*
+ * label_style.cc -- ePiX's current state for text and markers
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <string>
+
+#include "enums.h"
+#include "constants.h"
+#include "functions.h" // for snip_to
+
+#include "angle_units.h"
+
+#include "Color.h"
+#include "camera.h"
+#include "length.h"
+
+#include "label_style.h"
+
+namespace ePiX {
+
+ // Users can only construct the default style, since label angles
+ // are specified in current units but stored/returned in degrees.
+ label_state::label_state()
+ : the_text_color(Black()), the_mask_color(Neutral()),
+ the_padding(length(0)), the_label_border(Xfine()),
+ the_alignment(none), the_fontsize("nsz"),
+ the_fontface("rm"),
+ the_angle(0) { }
+
+ // set
+ void label_state::text_color(const Color& col)
+ {
+ the_text_color = col;
+ }
+
+ void label_state::mask_color(const Color& col)
+ {
+ the_mask_color = col;
+ }
+
+ void label_state::label_padding(const length& len)
+ {
+ the_padding=len;
+ }
+
+ void label_state::label_border(const pen_data& p)
+ {
+ the_label_border = p;
+ }
+
+ void label_state::align_to(const epix_label_posn a)
+ {
+ the_alignment = a;
+ }
+
+ void label_state::fontsize(const std::string& fs)
+ {
+ the_fontsize = fs;
+ }
+
+ void label_state::fontface(const std::string& ff)
+ {
+ the_fontface = ff;
+ }
+
+ // store label rotation angle internally in degrees
+ void label_state::label_angle(double th)
+ {
+ the_angle = the_angle_style().to_degrees(th);
+ }
+
+ // get
+ Color label_state::text_color() const
+ {
+ return the_text_color;
+ }
+
+ Color label_state::mask_color() const
+ {
+ return the_mask_color;
+ }
+
+ bool label_state::is_masked() const
+ {
+ return !the_mask_color.is_unset();
+ }
+
+ length label_state::label_padding() const
+ {
+ return the_padding;
+ }
+
+ pen_data label_state::label_border() const
+ {
+ return the_label_border;
+ }
+
+ epix_label_posn label_state::align_to() const
+ {
+ return the_alignment;
+ }
+
+ // e.g. "scriptsize"
+ std::string label_state::fontsize() const
+ {
+ return the_fontsize;
+ }
+
+ std::string label_state::fontface() const
+ {
+ return the_fontface;
+ }
+
+ double label_state::label_angle() const
+ {
+ return the_angle;
+ }
+
+ // map us through a camera filter
+ label_state label_state::seen_through(const Camera& mycam) const
+ {
+ return label_state(mycam(the_text_color), mycam(the_mask_color),
+ the_padding, the_label_border.seen_through(mycam),
+ the_alignment, the_fontsize, the_fontface,
+ the_angle);
+ }
+
+ // private constructor, for seen_through
+ label_state::label_state(const Color& text, const Color& mask,
+ const length& pad, const pen_data& border,
+ const epix_label_posn align,
+ const std::string& fontsize,
+ const std::string& fontface,
+ double th)
+ : the_text_color(text), the_mask_color(mask),
+ the_padding(pad), the_label_border(border),
+ the_alignment(align), the_fontsize(fontsize),
+ the_fontface(fontface),
+ the_angle(th) { }
+
+
+ label_state& the_label_style()
+ {
+ static label_state* the_label_state(new label_state());
+ return *the_label_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/label_style.h b/graphics/epix/label_style.h
new file mode 100644
index 0000000000..3d3461281f
--- /dev/null
+++ b/graphics/epix/label_style.h
@@ -0,0 +1,136 @@
+/*
+ * label_style.h -- ePiX's current state for text and markers
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file implements label_state:
+ *
+ * [] Text and mask color (Color x2)
+ * [] Alignment (epix_label_posn)
+ * [] Font face and size (strings)
+ * [] Label angle (double, in degrees)
+ *
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h, which modify the_label_style().
+ *
+ * This header is not part of epix.h.
+ */
+#ifndef EPIX_LABEL_STATE
+#define EPIX_LABEL_STATE
+
+#include <string>
+
+#include "enums.h"
+
+#include "Color.h"
+#include "length.h"
+
+#include "pen_data.h"
+
+namespace ePiX {
+
+ class Camera;
+
+ class label_state {
+ public:
+ // Clients can only construct the default state: black, unmasked,
+ // unbordered, basepoint-aligned, unrotated normalsize Roman text.
+ label_state();
+
+ // set
+ void text_color(const Color& col);
+ void mask_color(const Color& col);
+
+ void label_padding(const length& len);
+ void label_border(const pen_data& p);
+
+ void align_to(const epix_label_posn a);
+
+ void fontsize(const std::string& fs);
+ void fontface(const std::string& f);
+
+ // store label rotation angle internally in degrees
+ void label_angle(double th);
+
+ // get
+ Color text_color() const;
+ Color mask_color() const;
+
+ bool is_masked() const;
+
+ length label_padding() const;
+ pen_data label_border() const;
+
+ epix_label_posn align_to() const;
+
+ // e.g. "scriptsize"
+ std::string fontsize() const;
+ std::string fontface() const;
+
+ // return angle in degrees
+ double label_angle() const;
+
+ // map us through a camera filter
+ label_state seen_through(const Camera& cam) const;
+
+ private:
+ Color the_text_color;
+ Color the_mask_color;
+
+ length the_padding;
+ pen_data the_label_border;
+
+ epix_label_posn the_alignment;
+
+ std::string the_fontsize;
+ std::string the_fontface;
+
+ double the_angle; // stored in degrees
+
+ // text and background color, padding, border style,
+ // alignment, font size and face, angle (degrees)
+ label_state(const Color& text,
+ const Color& mask,
+ const length& pad,
+ const pen_data& border,
+ const epix_label_posn align,
+ const std::string& fontsize,
+ const std::string& fontface,
+ double th);
+ }; // end of label_state
+
+ label_state& the_label_style();
+
+} // end of namespace
+
+#endif /* EPIX_LABEL_STATE */
diff --git a/graphics/epix/laps.1 b/graphics/epix/laps.1
new file mode 100644
index 0000000000..4430a02037
--- /dev/null
+++ b/graphics/epix/laps.1
@@ -0,0 +1 @@
+.so man1/epix.1
diff --git a/graphics/epix/laps.in b/graphics/epix/laps.in
new file mode 100644
index 0000000000..8c8d8efe0f
--- /dev/null
+++ b/graphics/epix/laps.in
@@ -0,0 +1,259 @@
+#! /bin/bash
+#
+# laps: latex to Postscript/PDF
+#
+# Options: --help for usage, --version for version and license
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Andrew D. Hwang <For address, do "laps -V">
+#
+
+. "@pkglibdir@/epix-lib.sh"
+
+declare -a DVIPS_OPTS
+declare -a LAPS_FILE_LIST
+declare -i LAPS_FILE_COUNT
+
+PS2PDF="ps2pdf"
+LATEX="latex"
+LAPS_PDF=
+
+LATEX_INTERACT="batchmode"
+
+LAPS_EXTENSIONS="tex dtx ltx" # or NULL
+LAPS_DOT_EXT=".${LAPS_EXTENSIONS// /|.}" # for usage message
+LAPS_DEFAULT_EXT="tex"
+
+declare -a TMP_CMD
+
+
+function laps_help ()
+{
+cat <<"HELP"
+Options:
+ -h, --help
+ Show this message and exit
+
+ -V, --version, --gpl
+ Show version and license
+
+ -v, --verbose
+ Scroll output/error messages
+
+ -H, --huge
+ Use hugelatex (if available)
+
+ -i, -int, --interactive
+ Run (La)TeX interactively (implies --verbose)
+
+ -n, --no-config
+ Ignore $(HOME)/.dvipsrc
+
+ --pdf
+ Post-process ps file with ps2pdf
+
+ --pdf(la)tex
+ Use pdf(la)tex instead of latex.
+
+ -ps, --ps, --pslatex
+ Use pslatex instead of latex.
+
+ -P<printer>
+ dvips printer options, e.g. "-Pamz", may be given on the command
+ line. They are also read from ~/.dvipsrc if this file exists.
+
+ -t, --tex
+ Use tex instead of latex
+
+HELP
+ePiX_bugreport
+
+} # End of laps_help
+
+
+function laps_parse_options {
+# Command-line options start with "-"
+while [ "$1" != "${1#-}" ]; do
+ case "$1" in
+
+ -h|--help)
+ ePiX_usage laps $LAPS_DOT_EXT
+ laps_help
+ exit 0
+ ;;
+
+ -H|--huge)
+ if [ $(which hugelatex 2> /dev/null) ]; then
+ LATEX="hugelatex"
+ else
+ ePiX_warn " hugelatex not available, ignoring \"$1\" option"
+ fi
+ shift
+ ;;
+
+ -i|-int|--interactive)
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ LATEX_INTERACT="scrollmode"
+ shift
+ ;;
+
+ -n|--no-config) # do not use ~/.dvipsrc
+ export DVIPSRC="$SYSTEM_DEVNULL"
+ shift
+ ;;
+
+ -pdf|--pdf)
+ LATEX="${LATEX##pdf}"
+ LAPS_PDF="yes"
+ shift
+ ;;
+
+ --pdflatex)
+ LATEX="pdflatex"
+ LAPS_PDF=""
+ shift
+ ;;
+
+ --pdftex)
+ LATEX="pdftex"
+ LAPS_PDF=""
+ shift
+ ;;
+
+ -ps|--ps|--pslatex)
+ LATEX="pslatex"
+ shift
+ ;;
+
+ -P)
+ DVIPS_OPTS=("${DVIPS_OPTS[@]}" "-P$2")
+ shift 2
+ ;;
+
+ -P*)
+ DVIPS_OPTS=("${DVIPS_OPTS[@]}" "$1")
+ shift
+ ;;
+
+ -t|--tex)
+ LATEX="tex"
+ shift
+ ;;
+
+ -V|--version|--gpl)
+ ePiX_version laps
+ ePiX_license
+ exit 0
+ ;;
+
+ -v|--verbose)
+ if [ -z "$2" ]; then
+ echo "Please use -V for version"
+ exit 0
+ fi
+ EPIX_STDOUT="$SYSTEM_STDOUT"
+ shift
+ ;;
+
+ -vv)
+ echo "Discontinued option -vv; please use -v for verbose output"
+ exit 0
+ ;;
+
+ *)
+ ePiX_warn "Ignoring unknown option \"$1\""
+ shift
+ ;;
+ esac
+done
+
+LAPS_FILE_LIST=("$@")
+} # End of laps_parse_options
+
+
+function laps_compile_files()
+{
+ if [ -z "$1" ]; then ePiX_die "No input file specified"; fi
+
+ # file counts
+ local processed=0
+ local success=0
+ local failure=0
+
+ for EPIX_INFILE in "${LAPS_FILE_LIST[@]}"; do
+
+ # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE
+ epix_parse_filename "$EPIX_INFILE" "$LAPS_EXTENSIONS"
+
+ let processed=processed+1
+
+ if [ "$EPIX_NOTFOUND" = "yes" ]; then
+ let failure=failure+1
+ continue
+ fi
+
+ TMP_CMD=($LATEX -interaction=$LATEX_INTERACT "$EPIX_INROOT.$EPIX_SUFFIX")
+ TEMPFILES=("{TEMPFILES[@]}" "${EPIX_INROOT}.dvi" "${EPIX_INROOT}.log")
+
+ # aux file out of date
+ if [ "$EPIX_INROOT.$EPIX_SUFFIX" -nt "$EPIX_INROOT.aux" ]; then
+ ePiX_msg "aux file out of date"
+
+ ePiX_command "${TMP_CMD[@]}"
+ fi
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ "${EPIX_INROOT}.$EPIX_SUFFIX" -nt "$EPIX_INROOT.dvi" ]; then
+ ePiX_warn "\"${TMP_CMD[*]}\" failed"
+ let failure=failure+1
+ continue
+ fi
+
+ if [ "$LATEX" = "latex" -o "$LATEX" = "tex" ]; then
+ TMP_CMD=(dvips "${DVIPS_OPTS[@]}" -f -o "$EPIX_INROOT.ps" "$EPIX_INROOT.dvi")
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ "$EPIX_INROOT.dvi" -nt "$EPIX_INROOT.ps" ]; then
+ ePiX_warn "${TMP_CMD[*]} failed"
+ let failure=failure+1
+ continue
+ fi
+ fi
+
+ if [ "$LAPS_PDF" = "yes" ]; then
+ TMP_CMD=($PS2PDF "$EPIX_INROOT.ps")
+
+ ePiX_command "${TMP_CMD[@]}"
+
+ if [ "$EPIX_INROOT.ps" -nt "$EPIX_INROOT.pdf" ]; then
+ ePiX_warn "${TMP_CMD[*]} failed"
+ let failure=failure+1
+ continue
+ fi
+ fi
+
+ let success=success+1
+ echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT"
+
+ done # for EPIX_INFILE in $LAPS_INFILE_LIST
+
+ if [ $processed -gt 1 ]; then
+ echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR"
+ fi
+}
+
+### main ###
+
+if [ $# -eq 0 ]; then
+ ePiX_usage laps $LAPS_DOT_EXT
+ laps_help
+ exit 0
+fi
+
+laps_parse_options "$@"
+
+laps_compile_files "${LAPS_FILE_LIST[@]}"
+
+exit 0
diff --git a/graphics/epix/legend.cc b/graphics/epix/legend.cc
new file mode 100644
index 0000000000..8f9b7c2054
--- /dev/null
+++ b/graphics/epix/legend.cc
@@ -0,0 +1,204 @@
+/*
+ * legend.cc -- ePiX legend class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.1
+ * Last Change: September 28, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+// #include <cmath>
+#include <string>
+#include <sstream>
+#include <list>
+
+#include "constants.h"
+
+#include "triples.h"
+
+#include "Color.h"
+
+#include "length.h"
+
+#include "camera.h"
+
+#include "curves.h"
+
+#include "screen.h"
+#include "active_screen.h"
+#include "screen_data.h"
+
+#include "label_data.h"
+#include "markers.h"
+
+#include "legend_item.h"
+#include "legend_tile.h"
+#include "legend.h"
+
+namespace ePiX {
+
+ legend::legend()
+ : m_backing(White()),
+ m_bord(Black()), m_bord_width(PLAIN_WIDTH.magnitude()),
+ m_item_bord(Black()), m_item_bord_width(0.5*PLAIN_WIDTH.magnitude()),
+ m_key_size(12), m_label_skip(6) { }
+
+ legend::legend(const legend& L)
+ : m_backing(L.m_backing), m_bord(L.m_bord), m_bord_width(L.m_bord_width),
+ m_item_bord(L.m_item_bord), m_item_bord_width(L.m_item_bord_width),
+ m_key_size(L.m_key_size), m_label_skip(L.m_label_skip)
+ {
+ for (std::list<legend_item*>::const_iterator ip = L.m_items.begin();
+ ip != L.m_items.end(); ++ip)
+ m_items.push_back((*ip)->clone());
+ }
+
+ legend& legend::operator=(const legend& L)
+ {
+ if (&L != this)
+ {
+ std::list<legend_item*> tmp;
+ for (std::list<legend_item*>::const_iterator ip = L.m_items.begin();
+ ip != L.m_items.end(); ++ip)
+ tmp.push_back((*ip)->clone());
+
+ m_backing = L.m_backing;
+ m_bord = L.m_bord;
+ m_bord_width = L.m_bord_width;
+
+ m_item_bord = L.m_item_bord;
+ m_item_bord_width = L.m_item_bord_width;
+
+ m_key_size = L.m_key_size;
+ m_label_skip = L.m_label_skip;
+
+ swap(m_items, tmp);
+ }
+
+ return *this;
+ }
+
+ legend::~legend()
+ {
+ for (std::list<legend_item*>::iterator ip = m_items.begin();
+ ip != m_items.end(); ++ip)
+ delete *ip;
+ }
+
+ // add items
+ legend& legend::fill_item(const std::string& text)
+ {
+ m_items.push_back(new ePiX::fill_item(text));
+ return *this;
+ }
+
+ legend& legend::path_item(const std::string& text)
+ {
+ m_items.push_back(new ePiX::path_item(text));
+ return *this;
+ }
+
+ legend& legend::mark_item(epix_mark_type mark, const std::string& text)
+ {
+ m_items.push_back(new ePiX::mark_item(mark, text));
+ return *this;
+ }
+
+ // decorations
+ legend& legend::backing(const Color& col)
+ {
+ m_backing = col;
+ return *this;
+ }
+
+ legend& legend::border(const Color& col, double len)
+ {
+ m_bord = col;
+ m_bord_width = len;
+
+ return *this;
+ }
+
+ legend& legend::border(double len)
+ {
+ m_bord = Black();
+ m_bord_width = len;
+
+ return *this;
+ }
+
+ // item attributes
+ legend& legend::item_border(const Color& col, double len)
+ {
+ m_item_bord = col;
+ m_item_bord_width = len;
+
+ return *this;
+ }
+
+ legend& legend::item_border(double len)
+ {
+ m_item_bord = Black();
+ m_item_bord_width = len;
+
+ return *this;
+ }
+
+ legend& legend::key_size(double len)
+ {
+ m_key_size = len;
+ return *this;
+ }
+
+ legend& legend::label_skip(double len)
+ {
+ m_label_skip = len;
+ return *this;
+ }
+
+ void legend::draw(const P& loc, const P& off, epix_label_posn align) const
+ {
+ std::list<legend_item*>::const_iterator ip(m_items.begin());
+ if (ip == m_items.end())
+ return;
+
+ // else
+ label_state ls(the_label_style());
+ ls.mask_color(m_backing);
+ ls.label_border(pen_data(m_bord, length(m_bord_width)));
+ ls.align_to(align);
+
+ active_screen()->m_screen
+ ->add_tile(legend_tile(pair(loc.x1(), loc.x2()),
+ pair(off.x1(), off.x2()),
+ align,
+ ls.seen_through(cam()),
+ pen_data(cam()(m_item_bord),
+ length(m_item_bord_width)),
+ m_key_size, m_label_skip, m_items));
+ }
+} // end of namespace
diff --git a/graphics/epix/legend.h b/graphics/epix/legend.h
new file mode 100644
index 0000000000..ca7e096015
--- /dev/null
+++ b/graphics/epix/legend.h
@@ -0,0 +1,94 @@
+/*
+ * legend.h -- Plot/figure legend class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.11
+ * Last Change: August 16, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_LEGEND
+#define EPIX_LEGEND
+
+#include <string>
+
+#include "enums.h"
+
+#include "Color.h"
+
+namespace ePiX {
+
+ class legend_item;
+ class P;
+
+ class legend {
+ public:
+ legend();
+
+ legend(const legend&);
+
+ legend& operator=(const legend&);
+
+ ~legend();
+
+ // add items; get key style from drawing state
+ legend& fill_item(const std::string&); // solid color
+ legend& path_item(const std::string&); // line
+ legend& mark_item(epix_mark_type, const std::string&); // marker
+
+ // decorations
+ legend& backing(const Color&);
+ legend& border(const Color&, double);
+ legend& border(double); // line width in pt
+
+ // item attributes
+ legend& item_border(const Color&, double);
+ legend& item_border(double);
+
+ legend& label_skip(double); //
+ legend& key_size(double); // size of legend keys in pt
+
+ void draw(const P& loc, const P& offset=P(0,0),
+ epix_label_posn align=tr) const;
+
+ private:
+ Color m_backing;
+ Color m_bord;
+ double m_bord_width;
+
+ Color m_item_bord;
+ double m_item_bord_width;
+
+ double m_key_size;
+ double m_label_skip;
+
+ std::list<legend_item*> m_items;
+ }; // end of legend class
+
+} // end of namespace
+
+#endif /* EPIX_LEGEND */
diff --git a/graphics/epix/legend_item.cc b/graphics/epix/legend_item.cc
new file mode 100644
index 0000000000..afbc5a8b65
--- /dev/null
+++ b/graphics/epix/legend_item.cc
@@ -0,0 +1,166 @@
+/*
+ * legend_item.cc -- ePiX legend_item implementations
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 16, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <string>
+#include <sstream>
+
+#include "enums.h"
+#include "Color.h"
+#include "pen_data.h"
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "camera.h"
+
+#include "format.h"
+
+#include "label_data.h"
+#include "markers.h"
+
+#include "paint_style.h"
+
+#include "screen_data.h"
+#include "glyph.h"
+#include "pen_line.h"
+
+#include "legend_item.h"
+
+namespace ePiX {
+
+ // Magic numbers
+ screen_data __epix_legend_key(double L)
+ {
+ return screen_data(pair(0, -0.075*L), pair(L, 0.925*L));
+ }
+
+ double legend_item::key_coord(double sz, const std::string& len) const
+ {
+ return sz*(length("1pt").to(len).magnitude());
+ }
+
+
+ // N.B. store raw fill color; "key" passes through camera
+ fill_item::fill_item(const std::string& text)
+ : m_fill(the_paint_style().fill_color()), m_text(text) { }
+
+ fill_item* fill_item::clone() const
+ {
+ return new fill_item(*this);
+ }
+
+ std::string fill_item::value() const
+ {
+ return m_text;
+ }
+
+ std::string fill_item::key(const format& fmt, double sz,
+ const pen_data& bpen,
+ const std::string& len) const
+ {
+ const double L(legend_item::key_coord(sz, len));
+
+ screen_data tmp(__epix_legend_key(L));
+
+ tmp.backing(m_fill).border(bpen.color(), bpen.width().name());
+
+ return tmp.print_to(fmt, len, true);
+ }
+
+
+ // N.B. Store pens passed through camera
+ path_item::path_item(const std::string& text)
+ : m_line(the_paint_style().line_pen().seen_through(cam())),
+ m_base(the_paint_style().base_pen().seen_through(cam())),
+ m_text(text) { }
+
+ path_item* path_item::clone() const
+ {
+ return new path_item(*this);
+ }
+
+ std::string path_item::value() const
+ {
+ return m_text;
+ }
+
+ std::string path_item::key(const format& fmt, double sz,
+ const pen_data& bpen,
+ const std::string& len) const
+ {
+ const double L(legend_item::key_coord(sz, len));
+
+ screen_data tmp(__epix_legend_key(L));
+ tmp.border(bpen.color(), bpen.width().name());
+
+ // draw a centered horizontal segment in the current line style
+ // Magic numbers
+ std::list<edge2d> edges;
+ edges.push_back(edge2d(tmp.l(), tmp.r(), true));
+
+ tmp.add_tile(pen_line(m_line, m_base, edges));
+ return tmp.print_to(fmt, len, true);
+ }
+
+
+ // key is a marker in the current style
+ mark_item::mark_item(epix_mark_type mark, const std::string& text)
+ : m_mark(mark), m_style(the_label_style().seen_through(cam())),
+ m_sizes(the_mark_size()), m_text(text) { }
+
+ mark_item* mark_item::clone() const
+ {
+ return new mark_item(*this);
+ }
+
+ std::string mark_item::value() const
+ {
+ return m_text;
+ }
+
+ std::string mark_item::key(const format& fmt, double sz,
+ const pen_data& bpen,
+ const std::string& len) const
+ {
+ const double L(legend_item::key_coord(sz, len));
+
+ screen_data tmp(__epix_legend_key(L));
+ tmp.border(bpen.color(), bpen.width().name());
+
+ tmp.add_tile(glyph(tmp.c(), pair(0,0), "",
+ m_mark, m_sizes, m_style, true));
+
+ return tmp.print_to(fmt, len, true); // encapsulate in a picture env.
+ }
+} // end of namespace
diff --git a/graphics/epix/legend_item.h b/graphics/epix/legend_item.h
new file mode 100644
index 0000000000..6250245ba3
--- /dev/null
+++ b/graphics/epix/legend_item.h
@@ -0,0 +1,120 @@
+/*
+ * legend_item.h -- ePiX legend_item base class and implementations
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.11
+ * Last Change: August 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_LEGEND_ITEM
+#define EPIX_LEGEND_ITEM
+
+#include <string>
+
+#include "enums.h"
+#include "Color.h"
+#include "pen_data.h"
+
+#include "label_data.h"
+#include "markers.h"
+
+namespace ePiX {
+
+ class format;
+
+ // used to represent legend items both in "space" and in the screen
+ class legend_item {
+ public:
+ virtual ~legend_item() { }
+ virtual legend_item* clone() const = 0;
+
+ virtual std::string value() const = 0;
+ virtual std::string key(const format& fmt, double sz,
+ const pen_data& bpen,
+ const std::string& len) const = 0;
+
+ double key_coord(double sz, const std::string& len) const;
+ }; // end of base class
+
+
+ // key is a solid filled square in current color
+ class fill_item : public legend_item {
+ public:
+ fill_item(const std::string& text);
+ fill_item* clone() const;
+
+ std::string value() const;
+ std::string key(const format&, double,
+ const pen_data&,
+ const std::string& len) const;
+
+ private:
+ Color m_fill;
+ std::string m_text;
+ }; // end of class fill_item
+
+
+ // key is a line segment in current line style
+ class path_item : public legend_item {
+ public:
+ path_item(const std::string& text);
+ path_item* clone() const;
+
+ std::string value() const;
+ std::string key(const format&, double sz, const pen_data&,
+ const std::string& len) const;
+
+ private:
+ pen_data m_line;
+ pen_data m_base;
+
+ std::string m_text;
+ }; // end of class path_item
+
+
+ // key is a marker in the current style
+ class mark_item : public legend_item {
+ public:
+ mark_item(epix_mark_type mark, const std::string& text);
+ mark_item* clone() const;
+
+ std::string value() const;
+ std::string key(const format&, double sz, const pen_data&,
+ const std::string& len) const;
+
+ private:
+ epix_mark_type m_mark;
+ label_state m_style;
+ marker_sizes m_sizes;
+
+ std::string m_text;
+ }; // end of class mark_item
+
+} // end of namespace
+
+#endif /* EPIX_LEGEND_ITEM */
diff --git a/graphics/epix/legend_tile.cc b/graphics/epix/legend_tile.cc
new file mode 100644
index 0000000000..546cf802b0
--- /dev/null
+++ b/graphics/epix/legend_tile.cc
@@ -0,0 +1,173 @@
+/*
+ * legend_tile.cc -- ePiX screen implemenation for legends
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.1
+ * Last Change: September 28, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <string>
+#include <sstream>
+#include <list>
+
+#include "enums.h"
+
+#include "length.h"
+
+#include "label_style.h"
+#include "pen_data.h"
+
+#include "functions.h"
+#include "pairs.h"
+#include "affine.h"
+#include "screen_mask.h"
+
+#include "picture.h"
+#include "picture_data.h"
+
+#include "format.h"
+
+#include "legend_item.h"
+#include "legend_tile.h"
+
+namespace ePiX {
+
+ // location, offsets, contents, mark type, visibility
+ legend_tile::legend_tile(const pair& here, const pair& offset,
+ epix_label_posn align, const label_state& style,
+ const pen_data& pen,
+ double key_size, double skip,
+ std::list<legend_item*> items)
+ : m_here(here), m_offset(offset), m_align(align), m_style(style),
+ m_item_border(pen), m_key_size(key_size), m_label_skip(skip)
+ {
+ for (std::list<legend_item*>::const_iterator li=items.begin();
+ li != items.end(); ++li)
+ m_items.push_back((*li)->clone());
+ }
+
+ legend_tile::legend_tile(const legend_tile& L)
+ : m_here(L.m_here), m_offset(L.m_offset), m_align(L.m_align),
+ m_style(L.m_style), m_item_border(L.m_item_border),
+ m_key_size(L.m_key_size), m_label_skip(L.m_label_skip)
+ {
+ for (std::list<legend_item*>::const_iterator ip = L.m_items.begin();
+ ip != L.m_items.end(); ++ip)
+ m_items.push_back((*ip)->clone());
+ }
+
+ legend_tile& legend_tile::operator=(const legend_tile& L)
+ {
+ if (&L != this)
+ {
+ std::list<legend_item*> tmp;
+ for (std::list<legend_item*>::const_iterator ip = L.m_items.begin();
+ ip != L.m_items.end(); ++ip)
+ tmp.push_back((*ip)->clone());
+
+ m_here = L.m_here;
+ m_offset = L.m_offset;
+
+ m_align = L.m_align;
+ m_style = L.m_style;
+
+ m_item_border = L.m_item_border;
+
+ m_key_size = L.m_key_size;
+ m_label_skip = L.m_label_skip;
+
+ swap(m_items, tmp);
+ }
+
+ return *this;
+ }
+
+ legend_tile::~legend_tile()
+ {
+ for (std::list<legend_item*>::iterator ip = m_items.begin();
+ ip != m_items.end(); ++ip)
+ delete *ip;
+ }
+
+
+ legend_tile& legend_tile::map_by(const affine& f)
+ {
+ m_here = f(m_here);
+ return *this;
+ }
+
+ // legends unaffected by cropping
+ legend_tile& legend_tile::crop_to(const screen_mask& M)
+ {
+ /*
+ if (M.crops(m_here))
+ m_seen = false;
+ */
+ return *this;
+ }
+
+ legend_tile* legend_tile::clone() const
+ {
+ return new legend_tile(*this);
+ }
+
+ bool legend_tile::is_empty() const
+ {
+ return false;
+ }
+
+ std::string legend_tile::print_to(const format& fmt,
+ const std::string& len) const
+ {
+ std::stringstream obuf, item_buf;
+
+ item_buf << "%" << std::endl << "\\begin{tabular}{l}%" << std::endl;
+
+ for (std::list<legend_item*>::const_iterator ip=m_items.begin();
+ ip != m_items.end(); ++ip)
+ item_buf << (*ip)->key(fmt, m_key_size, m_item_border, len)
+ << "\\hskip " << m_label_skip << "pt "
+ << fmt.print_latex_hbox(m_style, (*ip)->value())
+ << " \\\\" << std::endl;
+
+ item_buf << "\\end{tabular}%" << std::endl;
+
+ obuf << fmt.print_text(m_here, m_offset, item_buf.str(), m_style, len);
+
+ return obuf.str();
+ }
+
+ void legend_tile::add_to_pallet() const
+ {
+ the_picture().add_to_pallet(m_item_border.color())
+ .add_to_pallet(m_style.text_color())
+ .add_to_pallet(m_style.mask_color())
+ .add_to_pallet(m_style.label_border().color());
+ }
+} // end of namespace
diff --git a/graphics/epix/legend_tile.h b/graphics/epix/legend_tile.h
new file mode 100644
index 0000000000..37c5f97440
--- /dev/null
+++ b/graphics/epix/legend_tile.h
@@ -0,0 +1,94 @@
+/*
+ * legend_tile.h -- ePiX screen implemenation for legends
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.1
+ * Last Change: September 28, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_LEGEND_TILE
+#define EPIX_LEGEND_TILE
+#include <string>
+
+#include "enums.h"
+
+#include "pairs.h"
+#include "length.h"
+#include "Color.h"
+
+#include "label_style.h"
+#include "pen_data.h"
+
+#include "tile.h"
+
+namespace ePiX {
+
+ class format;
+ class legend_item;
+ class affine;
+ class screen_mask;
+
+ class legend_tile : public tile {
+ public:
+ legend_tile(const pair& here, const pair& offset,
+ epix_label_posn align, const label_state& style,
+ const pen_data& item_border, double key_size, double skip,
+ std::list<legend_item*> items);
+
+ legend_tile(const legend_tile&);
+ legend_tile& operator= (const legend_tile&);
+ ~legend_tile();
+
+ legend_tile& map_by(const affine&);
+ legend_tile& crop_to(const screen_mask&);
+
+ legend_tile* clone() const;
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ private:
+ pair m_here;
+ pair m_offset;
+
+ epix_label_posn m_align;
+
+ label_state m_style;
+
+ pen_data m_item_border;
+
+ double m_key_size; // dims of key boxes in pt
+ double m_label_skip; // \hskip between box and item value
+
+ std::list<legend_item*> m_items;
+ }; // end of class legend_tile
+
+} // end of namespace
+
+#endif /* EPIX_LEGEND_TILE */
diff --git a/graphics/epix/length.cc b/graphics/epix/length.cc
new file mode 100644
index 0000000000..431874ee92
--- /dev/null
+++ b/graphics/epix/length.cc
@@ -0,0 +1,277 @@
+/*
+ * length.cc -- the ePiX::length class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+#include <string>
+#include <sstream>
+
+#include "errors.h"
+#include "constants.h"
+#include "length.h"
+
+namespace ePiX {
+
+ // Inviolable "private" constants: number of pts per unit
+ const double IN(72.27); // the gold standard
+ const double CM(28.452755905512); // 2.54 cm = 72.27 pt
+ const double MM(2.8452755905512); // 25.4 mm = 72.27 pt
+ const double PC(6.0225); // 12 picas = 1 inch
+ const double BP(1.00375); // 72 big pt = 72.27 pt
+ // const double SP(0.0000152587890625); // 65536 scaled pt = 1 pt
+
+ // extract length from "double [spaces] length unit"
+ length::length(std::string arg)
+ {
+ char* tmp_units;
+ m_mag = strtod(arg.c_str(), &tmp_units);
+ std::string putative_units(tmp_units);
+
+ // skip spaces, get first two non-space characters
+ std::string::size_type i=putative_units.find_first_not_of(" ");
+
+ if (i == std::string::npos)
+ {
+ epix_warning("Missing units, using pt");
+ m_units = "pt";
+ }
+ else
+ m_units = putative_units.substr(i, 2);
+
+ // See what we found; ugly, but not going to change...
+ if (m_units == "pt")
+ pts_per_unit = 1.0;
+
+ else if (m_units == "in")
+ pts_per_unit = IN;
+
+ else if (m_units == "cm")
+ pts_per_unit = CM;
+
+ else if (m_units == "mm")
+ pts_per_unit = MM;
+
+ else if (m_units == "pc")
+ pts_per_unit = PC;
+
+ else if (m_units == "bp")
+ pts_per_unit = BP;
+ /*
+ else if (m_units == "sp")
+ pts_per_unit = SP;
+ */
+ else
+ {
+ std::string warn="Unrecognized units \""+m_units+"\", assuming pt";
+ epix_warning(warn);
+ pts_per_unit = 1.0;
+ m_units = "pt";
+ }
+ } // end of string constructor
+
+ length::length(double lgth)
+ : m_mag(lgth), pts_per_unit(1.0), m_units("pt") { }
+
+ length& length::operator+= (const length& increment)
+ {
+ m_mag += increment.m_mag*increment.pts_per_unit/pts_per_unit;
+ return *this;
+ }
+
+ length& length::operator*= (double scale)
+ {
+ m_mag *= scale;
+ return *this;
+ }
+
+ // convert to specified units
+ length& length::to(std::string units)
+ {
+ units = units.substr(0,2);
+
+ if (m_units == units)
+ return *this; // null conversion
+
+ if (units == "pt")
+ {
+ m_mag *= pts_per_unit;
+ pts_per_unit = 1.0;
+ m_units = units;
+ }
+
+ else if (units == "in")
+ {
+ m_mag *= pts_per_unit/IN;
+ pts_per_unit = IN;
+ m_units = units;
+ }
+
+ else if (units == "cm")
+ {
+ m_mag *= pts_per_unit/CM;
+ pts_per_unit = CM;
+ m_units = units;
+ }
+
+ else if (units == "mm")
+ {
+ m_mag *= pts_per_unit/MM;
+ pts_per_unit = MM;
+ m_units = units;
+ }
+
+ else if (units == "pc")
+ {
+ m_mag *= pts_per_unit/PC;
+ pts_per_unit = PC;
+ m_units = units;
+ }
+
+ else if (units == "bp")
+ {
+ m_mag *= pts_per_unit/BP;
+ pts_per_unit = BP;
+ m_units = units;
+ }
+
+ /*
+ else if (units == "sp")
+ {
+ m_mag *= pts_per_unit/SP;
+ pts_per_unit = SP;
+ m_units = units;
+ }
+ */
+ else
+ epix_warning("Ignoring conversion to unrecognized units \""+units+"\"");
+
+ return *this;
+ }
+
+ bool length::operator== (const length& L) const
+ {
+ return (fabs(m_mag*pts_per_unit - L.m_mag*L.pts_per_unit) < EPIX_EPSILON);
+ }
+
+ double length::magnitude() const
+ {
+ return m_mag;
+ }
+
+ std::string length::units() const
+ {
+ return m_units;
+ }
+
+ std::string length::name() const
+ {
+ std::stringstream buf;
+ buf << m_mag << m_units;
+ return buf.str();
+ }
+
+
+ // value-returning operators
+ length operator+ (length len1, const length& len2)
+ {
+ return len1 += len2;
+ }
+
+ length operator* (double sc, length len)
+ {
+ return len *= sc;
+ }
+
+
+ bool operator< (length arg1, length arg2)
+ {
+ return (arg1.to("pt").magnitude()) < (arg2.to("pt").magnitude());
+ }
+
+ // Parse a string into two lengths.
+ void get_lengths(std::string sz, length& length1, length& length2)
+ {
+ std::string units1;
+ std::string units2;
+
+ double len1(0), len2(0);
+
+ // find first digit
+ std::string::size_type i=sz.find_first_of("-0123456789.");
+
+ if (i == std::string::npos)
+ epix_warning("Invalid width in size string");
+
+ else
+ {
+ sz.erase(0, i); // remove initial garbage
+ const char* tmp = sz.c_str();
+ char* arg;
+ len1 = strtod(tmp, &arg);
+ sz=arg;
+ }
+
+ // expect either unitlength or multiplication character
+ i=sz.find_first_not_of(" ");
+ std::string::size_type j=sz.find_first_of("Xx*");
+ if (i != j)
+ units1 = sz.substr(i, 2);
+
+ // next digit
+ i=sz.find_first_of("-0123456789.");
+
+ if (i == std::string::npos)
+ epix_warning("Invalid height in size string");
+
+ else
+ {
+ sz.erase(0, i);
+ const char* tmp = sz.c_str();
+ char* arg;
+ len2 = strtod(tmp, &arg);
+ sz=arg;
+ i=sz.find_first_not_of(" ");
+ units2 = sz.substr(i, 2);
+ }
+
+ if (units1 == "") // e.g. sz = "4x6in"
+ units1 = units2;
+
+ // assign values
+ std::stringstream buf1;
+ buf1 << len1 << units1;
+ length1=length(buf1.str());
+
+ std::stringstream buf2;
+ buf2 << len2 << units2;
+ length2=length(buf2.str());
+ }
+} // end of namespace
diff --git a/graphics/epix/length.h b/graphics/epix/length.h
new file mode 100644
index 0000000000..d44b86cffa
--- /dev/null
+++ b/graphics/epix/length.h
@@ -0,0 +1,110 @@
+/*
+ * length.h -- ePiX true and LaTeX length manipulation
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides the length class from ePiX2:
+ *
+ * - length(std::string) assumes argument is "double [space(s)] unit"
+ * Recognized units are pt (points), in, cm, mm, pc (picas = 1/12 in),
+ * bp (big points = 1/72 in)
+ *
+ * Malformed strings are handled as follows:
+ * Missing doubles are assumed to be 0, units are assumed to be pt
+ *
+ * - length(double) sets length to specified number of pt
+ *
+ * - operator += Increments a length, returning answer in LHS units, e.g.
+ * 1cm+=2in is 6.08cm
+ * 2in+=1cm is 2.3937in
+ *
+ * - operator *= scales a length by a double
+ * - to(string) converts a length to specified units
+ * - operator< compares true lengths
+ * - get_lengths(string, length, length) parses a string into ht and width
+ *
+ * A length can be negative.
+ */
+
+#ifndef EPIX_LENGTH
+#define EPIX_LENGTH
+
+#include <string>
+
+namespace ePiX {
+
+ class length {
+ public:
+ length(std::string); // not const std::string&
+ explicit length(double = 0);
+
+ length& operator+= (const length&); // increment by another length
+ length& operator*= (double); // scale
+ length& to(std::string); // convert to specified units
+
+ // compare, with units conversion
+ bool operator== (const length&) const;
+ bool operator!= (const length& len) const { return !((*this) == len); }
+
+ // for output
+ double magnitude() const;
+ std::string units() const;
+ std::string name() const;
+
+ private:
+ double m_mag;
+ double pts_per_unit; // constants defined in length.cc
+ std::string m_units;
+ }; // end of class length
+
+ // value-returning operators
+ length operator+ (length, const length&);
+ length operator* (double, length len);
+
+ // Compare true size; must pass by value...
+ bool operator< (length arg1, length arg2);
+
+ /*
+ * Parse a string into two lengths (width and height).
+ *
+ * The "sz" argument is expected to look like "4in x 10cm" or "4 x 6 in",
+ * specifically a double, an optional two-letter unitlength, an "x", a
+ * double, and a two-letter unitlength (defaults to pt). Spaces are
+ * unimportant, as is initial or trailing garbage. Badly malformed input
+ * (e.g., "4,6 in") may confuse the parsing code on some platforms.
+ */
+ void get_lengths(std::string sz, length& length1, length& length2);
+
+} // end of namespace
+
+#endif /* EPIX_LENGTH */
diff --git a/graphics/epix/lens.cc b/graphics/epix/lens.cc
new file mode 100644
index 0000000000..cfca6df66b
--- /dev/null
+++ b/graphics/epix/lens.cc
@@ -0,0 +1,162 @@
+/*
+ * lens.cc -- ePiX::lens functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+// #include <cmath>
+
+#include "pairs.h"
+#include "triples.h"
+#include "frame.h"
+
+#include "lens.h"
+
+namespace ePiX {
+
+ Lens::~Lens() { }
+
+ pair Perspective::operator()
+ (const P& arg, const frame& orient, const P& viewpt,
+ double dist) const
+ {
+ P arg_vector(arg - viewpt);
+
+ // get arg's location in our coordinates
+ double u1(orient.sea()|arg_vector);
+ double u2(orient.sky()|arg_vector);
+ double u3(orient.eye()|arg_vector);
+
+ return (-dist/u3)*pair(u1, u2);
+ } // end of Camera::Perspective::operator()
+
+ bool Perspective::is_linear() const
+ {
+ return true;
+ }
+
+ bool Perspective::needs_clip() const
+ {
+ return true;
+ }
+
+ Perspective* Perspective::clone() const
+ {
+ return new Perspective(*this);
+ }
+
+
+ pair Orthog::operator()
+ (const P& arg, const frame& orient, const P& viewpt,
+ double dist) const
+ {
+ P arg_vector(arg - viewpt);
+ double u1(orient.sea()|arg_vector);
+ double u2(orient.sky()|arg_vector);
+
+ return pair(u1, u2);
+ } // end of Camera::Orthog::operator()
+
+ bool Orthog::is_linear() const
+ {
+ return true;
+ }
+
+ bool Orthog::needs_clip() const
+ {
+ return true;
+ }
+
+ Orthog* Orthog::clone() const
+ {
+ return new Orthog(*this);
+ }
+
+
+ pair Fisheye::operator()
+ (const P& arg, const frame& orient, const P& viewpt,
+ double dist) const
+ {
+ P arg_vector(arg - viewpt);
+ arg_vector *= 1.0/(norm(arg_vector));
+
+ double u1(orient.sea()|arg_vector);
+ double u2(orient.sky()|arg_vector);
+
+ // radial projection to camera sphere, then orthogonal projection
+ return dist*pair(u1, u2);
+ } // end of Camera::Fisheye::operator()
+
+ bool Fisheye::is_linear() const
+ {
+ return false;
+ }
+
+ bool Fisheye::needs_clip() const
+ {
+ return false;
+ }
+
+ Fisheye* Fisheye::clone() const
+ {
+ return new Fisheye(*this);
+ }
+
+
+ pair Bubble::operator()
+ (const P& arg, const frame& orient, const P& viewpt,
+ double dist) const
+ {
+ P arg_vector(arg - viewpt);
+ arg_vector *= 1.0/(norm(arg_vector));
+
+ double u1(orient.sea()|arg_vector);
+ double u2(orient.sky()|arg_vector);
+ double u3(orient.eye()|arg_vector);
+
+ // radial projection to camera sphere, then stereographic projection
+ return (2.0*dist/(1-u3))*pair(u1, u2);
+ } // end of Camera::Bubble::operator()
+
+ bool Bubble::is_linear() const
+ {
+ return false;
+ }
+
+ bool Bubble::needs_clip() const
+ {
+ return false;
+ }
+
+ Bubble* Bubble::clone() const
+ {
+ return new Bubble(*this);
+ }
+} // end of namespace
diff --git a/graphics/epix/lens.h b/graphics/epix/lens.h
new file mode 100644
index 0000000000..99281a51cc
--- /dev/null
+++ b/graphics/epix/lens.h
@@ -0,0 +1,99 @@
+/*
+ * lens.h -- ePiX::Lens interface ans implementations
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_LENS
+#define EPIX_LENS
+
+namespace ePiX {
+
+ class frame;
+ class P;
+ class pair;
+
+ class Lens {
+ public:
+ // lens map(arg, orient, viewpt, distance)
+ virtual pair operator() (const P&,
+ const frame&, const P&, double) const = 0;
+ virtual bool is_linear() const = 0; // lens preserves lines?
+ virtual bool needs_clip() const = 0; // lens needs scene pre-clipping?
+ virtual ~Lens();
+ virtual Lens* clone() const = 0;
+ }; // end of class Lens
+
+
+ // actual lenses
+ class Perspective : public Lens {
+ public:
+ pair operator()
+ (const P&, const frame&, const P&, double) const;
+
+ bool is_linear() const;
+ bool needs_clip() const;
+ Perspective* clone() const;
+ }; // end of class Perspective
+
+
+ class Orthog : public Lens {
+ public:
+ pair operator()
+ (const P&, const frame&, const P&, double) const;
+
+ bool is_linear() const;
+ bool needs_clip() const;
+ Orthog* clone() const;
+ }; // end of class Orthog
+
+
+ class Fisheye : public Lens {
+ public:
+ pair operator()
+ (const P&, const frame&, const P&, double) const;
+
+ bool is_linear() const;
+ bool needs_clip() const;
+ Fisheye* clone() const;
+ }; // end of class Fisheye
+
+
+ class Bubble : public Lens {
+ public:
+ pair operator()
+ (const P&, const frame&, const P&, double) const;
+
+ bool is_linear() const;
+ bool needs_clip() const;
+ Bubble* clone() const;
+ }; // end of class Bubble
+
+} // end of namespace
+
+#endif /* EPIX_LENS */
diff --git a/graphics/epix/make_header b/graphics/epix/make_header
new file mode 100644
index 0000000000..0041b4a92e
--- /dev/null
+++ b/graphics/epix/make_header
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+HEADER_FILE="epix.h"
+
+HEADERS="enums.h length.h interval.h triples.h functions.h pairs.h \
+ affine.h Color.h state.h frame.h domain.h camera.h screen.h picture.h \
+ markers.h axis.h legend.h path.h curves.h \
+ circle.h plane.h segment.h sphere.h intersections.h \
+ plots.h surface.h data_mask.h data_file.h data_bins.h geometry.h"
+
+# N.B. Spaces in 2nd line are properly adjusted
+cat <<HEADER_HEADER > $HEADER_FILE
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\
+ * $HEADER_FILE -- Automatically created on $(date) *
+\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <iostream>
+#include <vector>
+#include <list>
+#include <set>
+#include <string>
+#include <sstream>
+#include <cmath>
+
+#ifndef EPIX_H
+#define EPIX_H
+
+HEADER_HEADER
+
+cat $HEADERS | grep -v "\#include" >> $HEADER_FILE
+
+echo >> $HEADER_FILE
+echo "#endif /* EPIX_H */" >> $HEADER_FILE
+
+exit 0;
diff --git a/graphics/epix/map.h b/graphics/epix/map.h
new file mode 100644
index 0000000000..c0c57a38be
--- /dev/null
+++ b/graphics/epix/map.h
@@ -0,0 +1,167 @@
+/*
+ * map.h -- classes of map for function plotting
+ *
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ *
+ * Version 1.1.5
+ * Last Change: June 20, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides classes that represent mappings R -> R^3 or R x R -> R^3,
+ * both P-valued and assembled from double-valued components. Each class
+ * provides an evaluation operator that takes 1, 2, or 3 doubles and returns
+ * a P. Stubs for general coordinate systems are included.
+ *
+ * - path_map: R -> R^3
+ * - surface_map: R x R -> R^3
+ * - space_map: R x R x R -> R^3
+ *
+ * - column_1var: assemble R -> R^3 from components
+ * - column_2var: assemble R x R -> R^3 from components
+ *
+ * These classes are intended primarily for internal use, allowing the
+ * plot algorithms to be templated. In new code, maps should be defined
+ * as P-valued, rather than assembled from components; the "column" classes
+ * are provided solely for backward compatibility.
+ */
+
+#ifndef EPIX_MAP
+#define EPIX_MAP
+
+#include "triples.h"
+#include "functions.h"
+
+namespace ePiX {
+
+ // identity and coordinate projection functions
+ template<class T>T id(T arg) { return arg; }
+
+ template<class T1, class T2>T1 proj1(T1 arg1, T2 arg2) { return arg1; }
+ template<class T1, class T2>T2 proj2(T1 arg1, T2 arg2) { return arg2; }
+
+ // R -> R^3
+ class path_map {
+ private:
+ P (*y)(double);
+ P (*Y)(P);
+
+ public:
+ path_map(P f(double), P F(P) = id) : y(f), Y(F) { }
+
+ P operator() (const P& arg) const
+ {
+ return Y(y(arg.x1()));
+ }
+
+ }; // end of class path_map
+
+ // R x R -> R^3
+ class surface_map {
+ private:
+ P (*y)(double, double);
+ P (*Y)(P);
+
+ public:
+ surface_map(P f(double, double), P F(P) = id) : y(f), Y(F) { }
+ P operator() (const P& arg) const
+ {
+ return Y(y(arg.x1(), arg.x2()));
+ }
+
+ }; // end of class surface_map
+
+ // R x R x R -> R^3
+ class space_map {
+ private:
+ P (*y)(double, double, double);
+ P (*Y)(P);
+
+ public:
+ space_map(P f(double, double, double), P F(P) = id) : y(f), Y(F) { }
+ P operator() (const P& arg) const
+ {
+ return Y(y(arg.x1(), arg.x2(), arg.x3()));
+ }
+
+ }; // end of class space_map
+
+
+ // assemble R -> R^3 from components
+ class column_1var {
+ private:
+ double (*y1)(double);
+ double (*y2)(double);
+ double (*y3)(double);
+ P (*Y)(P);
+
+ public:
+ column_1var(double f1(double), double f2(double), double f3(double) = zero,
+ P F(P) = id) : y1(f1), y2(f2), y3(f3), Y(F) { }
+
+ // parameterized path from f:R -> R
+ column_1var(double f(double), P F(P) = id)
+ : y1(id), y2(f), y3(zero), Y(F) { }
+ P operator() (const P& arg) const
+ {
+ double t = arg.x1();
+ return Y(P(y1(t), y2(t), y3(t)));
+ }
+ }; // end of class column_1var
+
+ // assemble R x R -> R^3 from components
+ class column_2var {
+ private:
+ double (*y1)(double, double);
+ double (*y2)(double, double);
+ double (*y3)(double, double);
+ P (*Y)(P);
+
+ public:
+ column_2var(double f1(double, double),
+ double f2(double, double),
+ double f3(double, double),
+ P F(P) = id) : y1(f1), y2(f2), y3(f3), Y(F) { }
+
+ // omitted third component defaults to zero
+ column_2var(double f1(double, double),
+ double f2(double, double),
+ P F(P) = id) : y1(f1), y2(f2), y3(zero), Y(F) { }
+
+ // parameterized surface from f:R x R -> R
+ column_2var(double f(double, double), P F(P) = id)
+ : y1(proj1), y2(proj2), y3(f), Y(F) { }
+ P operator() (const P& arg) const
+ {
+ double u(arg.x1());
+ double v(arg.x2());
+ return Y(P(y1(u, v), y2(u, v), y3(u, v)));
+ }
+ }; // end of class column_2var
+} // end of namespace
+
+#endif /* EPIX_MAP */
diff --git a/graphics/epix/marker_style.cc b/graphics/epix/marker_style.cc
new file mode 100644
index 0000000000..7134a78ac9
--- /dev/null
+++ b/graphics/epix/marker_style.cc
@@ -0,0 +1,79 @@
+/*
+ * marker_style.cc -- ePiX's dot size and tick length
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 29, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "constants.h"
+
+#include "functions.h"
+#include "marker_style.h"
+
+namespace ePiX {
+
+ marker_sizes::marker_sizes()
+ : the_dotsize(AVG_DOT), the_ticksize(AVG_TICK) { }
+
+ marker_sizes& marker_sizes::dot_size(double diam)
+ {
+ if (0 < diam)
+ the_dotsize = snip_to(diam, MIN_DOT, MAX_DOT);
+ else
+ the_dotsize = AVG_DOT;
+
+ return *this;
+ }
+
+ marker_sizes& marker_sizes::tick_size(double len)
+ {
+ if (0 < len)
+ the_ticksize = snip_to(len, MIN_TICK, MAX_TICK);
+ else
+ the_ticksize = AVG_TICK;
+
+ return *this;
+ }
+
+ double marker_sizes::dot_size() const
+ {
+ return the_dotsize;
+ }
+
+ double marker_sizes::tick_size() const
+ {
+ return the_ticksize;
+ }
+
+ marker_sizes& the_mark_size()
+ {
+ static marker_sizes* the_mark_size(new marker_sizes());
+ return *the_mark_size;
+ }
+} // end of namespace
diff --git a/graphics/epix/marker_style.h b/graphics/epix/marker_style.h
new file mode 100644
index 0000000000..48b03193de
--- /dev/null
+++ b/graphics/epix/marker_style.h
@@ -0,0 +1,59 @@
+/*
+ * marker_style.h -- ePiX's dot size and tick mark length
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.19
+ * Last Change: September 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_MARKER_STYLE
+#define EPIX_MARKER_STYLE
+
+namespace ePiX {
+
+ class marker_sizes {
+ public:
+ marker_sizes();
+
+ marker_sizes& dot_size(double diam);
+ marker_sizes& tick_size(double len);
+
+ double dot_size() const;
+ double tick_size() const;
+
+ private:
+ double the_dotsize; // size of dots, 1 -- 36 pt
+ double the_ticksize; // (half-)size of tick marks, 1 -- 8 pt
+ };
+
+ marker_sizes& the_mark_size();
+
+} // end of namespace
+
+#endif /* EPIX_MARKER_STYLE */
diff --git a/graphics/epix/markers.cc b/graphics/epix/markers.cc
new file mode 100644
index 0000000000..ac418f8e1f
--- /dev/null
+++ b/graphics/epix/markers.cc
@@ -0,0 +1,308 @@
+/*
+ * markers.cc -- ePiX axes, grids, markers, and labels
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.19
+ * Last Change: September 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+
+#include "triples.h"
+#include "length.h"
+
+#include "functions.h"
+
+#include "path.h"
+#include "curves.h"
+#include "screen.h"
+#include "picture.h"
+
+#include "label_data.h"
+#include "markers.h"
+
+namespace ePiX {
+
+ static void __epix_label(const P& base, const P& offset,
+ const std::string& lbl,
+ epix_label_posn POSN, bool masked)
+ {
+ label_data val(base, offset, lbl);
+
+ if (masked)
+ {
+ // get mask color
+ Color my_mask(the_label_style().mask_color());
+
+ if (my_mask.is_unset())
+ my_mask = White();
+
+ val.mask_color(my_mask);
+ }
+
+ else // !masked
+ val.mask_color(Neutral());
+
+ val.align_to(POSN).draw();
+ }
+
+ // label -- put POSN-aligned string <label_text>
+ // at Cartesian position <base> translated by <offset> true points.
+ void label(const P& base, const P& offset, const std::string& lbl,
+ epix_label_posn POSN)
+ {
+ __epix_label(base, offset, lbl, POSN, the_label_style().is_masked());
+ }
+
+ // mask color comes from global style, falls back to White()
+ void masklabel(const P& base, const P& offset, const std::string& lbl,
+ epix_label_posn POSN)
+ {
+ __epix_label(base, offset, lbl, POSN, true);
+ }
+
+ void label(const P& base, const P& offset, const std::string& lbl)
+ {
+ __epix_label(base, offset, lbl, none, the_label_style().is_masked());
+ }
+
+ void masklabel(const P& base, const P& offset, const std::string& lbl)
+ {
+ __epix_label(base, offset, lbl, none, true);
+ }
+
+ // centered labels
+ void label(const P& base, const std::string& lbl)
+ {
+ __epix_label(base, P(0,0), lbl, c, the_label_style().is_masked());
+ }
+
+ void masklabel(const P& base, const std::string& lbl)
+ {
+ __epix_label(base, P(0,0), lbl, c, true);
+ }
+
+ // Marker aliases
+ void marker(const P& arg, epix_mark_type TYPE)
+ {
+ label_data(arg, TYPE).draw();
+ }
+
+ // Markers with labels
+ void circ(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, CIRC);
+ mk.draw();
+ }
+
+ void ring(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, RING);
+ mk.draw();
+ }
+
+ void spot(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, SPOT);
+ mk.draw();
+ }
+
+ void dot(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, DOT);
+ mk.draw();
+ }
+
+ void ddot(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, DDOT);
+ mk.draw();
+ }
+
+ void box(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, BOX);
+ mk.draw();
+ }
+
+ void bbox(const P& posn, const P& offset, const std::string& label_text,
+ epix_label_posn POSN)
+ {
+ if (label_text != "")
+ label(posn, offset, label_text, POSN);
+ label_data mk(posn, BBOX);
+ mk.draw();
+ }
+
+ // Axis ticks (h_tick = tall, thin rectangle, for a *horizontal* axis)
+ void h_axis_tick(const P& arg, epix_label_posn POSN)
+ {
+ label_data mk(arg, HTICK, POSN);
+ mk.draw();
+ }
+
+ void v_axis_tick(const P& arg, epix_label_posn POSN)
+ {
+ label_data mk(arg, VTICK, POSN);
+ mk.draw();
+ }
+
+
+ //// Curve-like elements
+ // arrow with label
+ void arrow(const P& tail, const P& head, const P& offset,
+ const std::string& label_text,
+ epix_label_posn POSN, double scale)
+ {
+ arrow(tail, head, scale);
+ label(tail, offset, label_text, POSN);
+ }
+
+ // fixed-size elements
+ void right_angle(const P& loc, P leg1, P leg2, double scale)
+ {
+ const double norm1(norm(leg1));
+ const double norm2(norm(leg2));
+
+ if (norm1 < EPIX_EPSILON || norm2 < EPIX_EPSILON)
+ return;
+
+ //else
+ const double mult(pt_to_screen(scale));
+ leg1 *= mult/norm1;
+ leg2 *= mult/norm2;
+
+ path bd;
+ bd.pt(loc + leg1).pt(loc + leg1 + leg2).pt(loc + leg2);
+ bd.draw();
+ }
+
+ // the *acute* angle
+ void arc_measure(const P& loc, P leg1, P leg2, const P& offset,
+ const std::string& text, epix_label_posn align,
+ double scale)
+ {
+ const double norm1(norm(leg1));
+ const double norm2(norm(leg2));
+
+ if (norm1 < EPIX_EPSILON || norm2 < EPIX_EPSILON)
+ return;
+
+ //else normalize
+ leg1 *= 1.0/norm1;
+ leg2 *= 1.0/norm2;
+
+ // check for parllelity
+ P perp(leg1*leg2);
+ const double norm3(norm(perp));
+
+ if (norm3 < EPIX_EPSILON)
+ return;
+
+ // else get small angle
+ const double th(Acos(leg1|leg2));
+
+ perp *= 1.0/norm3;
+ leg1 *= pt_to_screen(scale);
+
+ perp *= leg1; // perp to leg1 in plane of legs
+
+ ellipse(loc, leg1, perp, 0, th);
+
+ if (text != "")
+ label(loc + Cos(0.5*th)*leg1 + Sin(0.5*th)*perp, offset,
+ text, align);
+ }
+
+ void arc_measure(const P& loc, P leg1, P leg2, double scale)
+ {
+ arc_measure(loc, leg1, leg2, P(0,0), "", none, scale);
+ }
+
+ void axis_break(const P& tail, const P& head, double scale)
+ {
+ const P midpt(0.5*(head+tail));
+
+ P dir((head-tail)%E_3); // project to (x1,x2)-plane
+
+ if (norm(dir) < EPIX_EPSILON)
+ return;
+
+ // else
+ dir *= pt_to_screen(0.25*scale)/norm(dir); // zag is scale pt long
+
+ path bd;
+ bd.pt(tail).pt(midpt-2*dir).pt(midpt-dir+1.5*J(dir))
+ .pt(midpt+dir-1.5*J(dir)).pt(midpt+2*dir).pt(head);
+
+ bd.draw();
+ }
+
+ void h_error_bar(const P& loc, double err, epix_mark_type mk, double ht)
+ {
+ const P dy(0, pt_to_screen(0.5*ht));
+ const P bot(loc - P(err,0));
+ const P top(loc + P(err,0));
+
+ line(bot, top);
+ line(bot - dy, bot + dy);
+ line(top - dy, top + dy);
+ marker(loc, mk);
+ }
+
+ void v_error_bar(const P& loc, double err, epix_mark_type mk, double wd)
+ {
+ const P dx(pt_to_screen(0.5*wd), 0);
+ const P bot(loc - P(0,err));
+ const P top(loc + P(0,err));
+
+ line(bot, top);
+ line(bot - dx, bot + dx);
+ line(top - dx, top + dx);
+ marker(loc, mk);
+ }
+} // end of namespace
diff --git a/graphics/epix/markers.h b/graphics/epix/markers.h
new file mode 100644
index 0000000000..92b80f3660
--- /dev/null
+++ b/graphics/epix/markers.h
@@ -0,0 +1,119 @@
+/*
+ * markers.h -- ePiX markers and labels
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.16
+ * Last Change: September 09, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * label -- put string constant <label_text> at Cartesian position <base>
+ * translated by (offset.x1, offset.x2) true points (i.e., 3rd component
+ * of <offset> is discarded).
+ *
+ * Accepts an optional LaTeX-style positioning argument.
+ * 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.
+ */
+#ifndef EPIX_MARKERS
+#define EPIX_MARKERS
+
+#include <string>
+
+#include "enums.h"
+
+namespace ePiX {
+
+ class P;
+
+ // position, [offset], label text, [alignment]
+ void label(const P&, const P&, const std::string&);
+ void label(const P&, const std::string&);
+ void label(const P&, const P&, const std::string&, epix_label_posn);
+
+ void masklabel(const P&, const P&, const std::string&);
+ void masklabel(const P&, const std::string&);
+ void masklabel(const P&, const P&, const std::string&, epix_label_posn);
+
+
+ // Empty and filled LaTeX circles of diameter get_dotsize() true pt
+ void marker (const P&, epix_mark_type);
+
+ void circ(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none); // filled white circ
+
+ void ring(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none); // unfilled circ
+
+ void spot(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none);
+
+ void dot(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none);
+
+ void ddot(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none);
+
+ void box(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none);
+
+ void bbox(const P& posn, const P& offset=P(0,0),
+ const std::string& label_text="",
+ epix_label_posn align=none);
+
+ void h_axis_tick(const P& location, epix_label_posn align=c);
+ void v_axis_tick(const P& location, epix_label_posn align=c);
+
+ // Arrow with aligned label at tail
+ void arrow(const P& tail, const P& head, const P& offset,
+ const std::string& label_text,
+ epix_label_posn align, double scale=1);
+
+ //// Path-like glyphs ////
+ // angle indicators; default args are true sizes in pt
+ void right_angle(const P& loc, P leg1, P leg2, double scale=8);
+ void arc_measure(const P& loc, P leg1, P leg2,
+ const P& offset, const std::string&, epix_label_posn,
+ double scale=8);
+ void arc_measure(const P& loc, P leg1, P leg2, double scale=8);
+
+ void axis_break(const P& tail, const P& head, double scale=12);
+ void h_error_bar(const P& loc, double err, epix_mark_type mk, double ht=6);
+ void v_error_bar(const P& loc, double err, epix_mark_type mk, double wd=6);
+} // end of namespace
+
+#endif /* EPIX_MARKERS */
diff --git a/graphics/epix/mask_diamond.cc b/graphics/epix/mask_diamond.cc
new file mode 100644
index 0000000000..da11f29b50
--- /dev/null
+++ b/graphics/epix/mask_diamond.cc
@@ -0,0 +1,129 @@
+/*
+ * mask_diamond.cc -- ePiX diamond crop mask
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 09, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "functions.h"
+//#include "errors.h"
+
+#include "constants.h"
+
+#include "pairs.h"
+
+#include "Color.h"
+
+#include "paint_style.h"
+#include "length.h"
+
+#include "pen_line.h"
+#include "pen_fill.h"
+
+#include "edge_data.h"
+#include "screen_crop.h"
+
+#include "screen_mask.h"
+#include "mask_diamond.h"
+
+namespace ePiX {
+
+ mask_diamond::mask_diamond(const pair& arg1, const pair& arg2)
+ : m_hmin(min(arg1.x1(), arg2.x1())),
+ m_hmax(max(arg1.x1(), arg2.x1())),
+ m_vmin(min(arg1.x2(), arg2.x2())),
+ m_vmax(max(arg1.x2(), arg2.x2()))
+ {
+ m_border.push_back(edge2d(l(), b(), true));
+ m_border.push_back(edge2d(b(), r(), true));
+ m_border.push_back(edge2d(r(), t(), true));
+ m_border.push_back(edge2d(t(), l(), true));
+ }
+
+ mask_diamond* mask_diamond::clone() const
+ {
+ return new mask_diamond(*this);
+ }
+
+ // corners and midpoints
+ double mask_diamond::h_min() const { return m_hmin; }
+ double mask_diamond::v_min() const { return m_vmin; }
+
+ double mask_diamond::h_max() const { return m_hmax; }
+ double mask_diamond::v_max() const { return m_vmax; }
+
+ double mask_diamond::h_avg() const { return 0.5*(m_hmin+m_hmax); }
+ double mask_diamond::v_avg() const { return 0.5*(m_vmin+m_vmax); }
+
+ double mask_diamond::h_size() const { return m_hmax - m_hmin; }
+ double mask_diamond::v_size() const { return m_vmax - m_vmin; }
+
+ // diamond-specific functions
+ bool mask_diamond::crops(const pair& arg) const
+ {
+ const double x(fabs(arg.x1() - h_avg())/h_size());
+ const double y(fabs(arg.x2() - v_avg())/v_size());
+
+ return !((x + y) <= 0.5);
+ }
+
+ std::list<edge2d>& mask_diamond::crop_path(std::list<edge2d>& L) const
+ {
+ return crop_path_2nd(m_border, L);
+ }
+
+ std::list<edge2d>& mask_diamond::crop_loop(std::list<edge2d>& L) const
+ {
+ return crop_loop_2nd(m_border, L);
+ }
+
+ pen_line mask_diamond::border(const Color& col, const length& len) const
+ {
+ return pen_line(pen_data(col, len), Xfine(), m_border);
+ }
+
+ pen_fill mask_diamond::backing(const Color& col) const
+ {
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+
+ pen_line mask_diamond::border() const
+ {
+ return pen_line(the_paint_style().line_pen(),
+ the_paint_style().base_pen(), m_border);
+ }
+
+ pen_fill mask_diamond::backing() const
+ {
+ const Color& col(the_paint_style().fill_color());
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+} // end of ePiX namespace
diff --git a/graphics/epix/mask_diamond.h b/graphics/epix/mask_diamond.h
new file mode 100644
index 0000000000..8d4435f567
--- /dev/null
+++ b/graphics/epix/mask_diamond.h
@@ -0,0 +1,89 @@
+/*
+ * mask_diamond.h -- ePiX:: rectangular screen_mask for cropping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 05, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_MASK_DIAMOND
+#define EPIX_MASK_DIAMOND
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+#include "screen_mask.h"
+
+namespace ePiX {
+
+ class pair;
+
+ class Color;
+
+ class length;
+ class pen_fill;
+ class pen_line;
+
+ class mask_diamond : public screen_mask {
+ public:
+ // mask_diamond() { }
+ mask_diamond(const pair& arg1, const pair& arg2);
+
+ mask_diamond* clone() const;
+ double h_min() const;
+ double h_max() const;
+ double h_size() const;
+ double h_avg() const;
+
+ double v_min() const;
+ double v_max() const;
+ double v_size() const;
+ double v_avg() const;
+
+ bool crops(const pair& arg) const; // false if arg visible
+ std::list<edge2d>& crop_path(std::list<edge2d>&) const;
+ std::list<edge2d>& crop_loop(std::list<edge2d>&) const;
+
+ pen_line border(const Color&, const length&) const;
+ pen_fill backing(const Color&) const;
+
+ pen_line border() const;
+ pen_fill backing() const;
+
+ private:
+ double m_hmin, m_hmax;
+ double m_vmin, m_vmax;
+
+ std::list<edge2d> m_border;
+ }; // end of class mask_diamond
+
+} // end of namespace
+
+#endif /* EPIX_MASK_DIAMOND */
diff --git a/graphics/epix/mask_ellipse.cc b/graphics/epix/mask_ellipse.cc
new file mode 100644
index 0000000000..0eed28f94e
--- /dev/null
+++ b/graphics/epix/mask_ellipse.cc
@@ -0,0 +1,136 @@
+/*
+ * mask_ellipse.cc -- ePiX ellipse crop mask
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 09, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "functions.h"
+//#include "errors.h"
+
+#include "constants.h"
+
+#include "pairs.h"
+
+#include "Color.h"
+
+#include "paint_style.h"
+#include "length.h"
+
+#include "pen_line.h"
+#include "pen_fill.h"
+
+#include "edge_data.h"
+#include "screen_crop.h"
+
+#include "screen_mask.h"
+#include "mask_ellipse.h"
+
+namespace ePiX {
+
+ mask_ellipse::mask_ellipse(const pair& arg1, const pair& arg2)
+ : m_hmin(min(arg1.x1(), arg2.x1())),
+ m_hmax(max(arg1.x1(), arg2.x1())),
+ m_vmin(min(arg1.x2(), arg2.x2())),
+ m_vmax(max(arg1.x2(), arg2.x2()))
+ {
+ const double dt(2*M_PI/EPIX_NUM_PTS);
+
+ const pair ctr(0.5*(m_hmin + m_hmax), 0.5*(m_vmin + m_vmax));
+
+ const double hsz(0.5*(m_hmax - m_hmin));
+ const double vsz(0.5*(m_vmax - m_vmin));
+
+ for (unsigned int i=0; i<EPIX_NUM_PTS; ++i)
+ m_border.push_back(edge2d(ctr + pair(hsz*std::cos(i*dt),
+ vsz*std::sin(i*dt)),
+ ctr + pair(hsz*std::cos((i+1)*dt),
+ vsz*std::sin((i+1)*dt)), true));
+ }
+
+ mask_ellipse* mask_ellipse::clone() const
+ {
+ return new mask_ellipse(*this);
+ }
+
+ // corners and midpoints
+ double mask_ellipse::h_min() const { return m_hmin; }
+ double mask_ellipse::v_min() const { return m_vmin; }
+
+ double mask_ellipse::h_max() const { return m_hmax; }
+ double mask_ellipse::v_max() const { return m_vmax; }
+
+ double mask_ellipse::h_avg() const { return 0.5*(m_hmin+m_hmax); }
+ double mask_ellipse::v_avg() const { return 0.5*(m_vmin+m_vmax); }
+
+ double mask_ellipse::h_size() const { return m_hmax - m_hmin; }
+ double mask_ellipse::v_size() const { return m_vmax - m_vmin; }
+
+ // ellipse-specific functions
+ bool mask_ellipse::crops(const pair& arg) const
+ {
+ const double dx((arg.x1() - h_avg())/h_size());
+ const double dy((arg.x2() - v_avg())/v_size());
+ return !(dx*dx + dy*dy <= 0.25);
+ }
+
+ std::list<edge2d>& mask_ellipse::crop_path(std::list<edge2d>& L) const
+ {
+ return crop_path_2nd(m_border, L);
+ }
+
+ std::list<edge2d>& mask_ellipse::crop_loop(std::list<edge2d>& L) const
+ {
+ return crop_loop_2nd(m_border, L);
+ }
+
+ pen_line mask_ellipse::border(const Color& col, const length& len) const
+ {
+ return pen_line(pen_data(col, len), Xfine(), m_border);
+ }
+
+ pen_fill mask_ellipse::backing(const Color& col) const
+ {
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+
+ pen_line mask_ellipse::border() const
+ {
+ return pen_line(the_paint_style().line_pen(),
+ the_paint_style().base_pen(), m_border);
+ }
+
+ pen_fill mask_ellipse::backing() const
+ {
+ const Color col(the_paint_style().fill_color());
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+} // end of ePiX namespace
diff --git a/graphics/epix/mask_ellipse.h b/graphics/epix/mask_ellipse.h
new file mode 100644
index 0000000000..09279ba0f6
--- /dev/null
+++ b/graphics/epix/mask_ellipse.h
@@ -0,0 +1,89 @@
+/*
+ * mask_ellipse.h -- ePiX:: elliptical screen_mask for cropping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 05, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_MASK_ELLIPSE
+#define EPIX_MASK_ELLIPSE
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+#include "screen_mask.h"
+
+namespace ePiX {
+
+ class pair;
+
+ class Color;
+
+ class length;
+ class pen_fill;
+ class pen_line;
+
+ class mask_ellipse : public screen_mask {
+ public:
+ // mask_ellipse() { }
+ mask_ellipse(const pair& arg1, const pair& arg2);
+
+ mask_ellipse* clone() const;
+ double h_min() const;
+ double h_max() const;
+ double h_size() const;
+ double h_avg() const;
+
+ double v_min() const;
+ double v_max() const;
+ double v_size() const;
+ double v_avg() const;
+
+ bool crops(const pair& arg) const; // false if arg visible
+ std::list<edge2d>& crop_path(std::list<edge2d>&) const;
+ std::list<edge2d>& crop_loop(std::list<edge2d>&) const;
+
+ pen_line border(const Color&, const length&) const;
+ pen_fill backing(const Color&) const;
+
+ pen_line border() const;
+ pen_fill backing() const;
+
+ private:
+ double m_hmin, m_hmax;
+ double m_vmin, m_vmax;
+
+ std::list<edge2d> m_border;
+ }; // end of class mask_ellipse
+
+} // end of namespace
+
+#endif /* EPIX_MASK_ELLIPSE */
diff --git a/graphics/epix/mask_rectangle.cc b/graphics/epix/mask_rectangle.cc
new file mode 100644
index 0000000000..d54e934cee
--- /dev/null
+++ b/graphics/epix/mask_rectangle.cc
@@ -0,0 +1,129 @@
+/*
+ * mask_rectangle.cc -- ePiX rectangle crop mask
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 09, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "functions.h"
+//#include "errors.h"
+
+#include "constants.h"
+
+#include "pairs.h"
+
+#include "Color.h"
+
+#include "paint_style.h"
+#include "length.h"
+
+#include "pen_line.h"
+#include "pen_fill.h"
+
+#include "edge_data.h"
+#include "screen_crop.h"
+
+#include "screen_mask.h"
+#include "mask_rectangle.h"
+
+namespace ePiX {
+
+ mask_rectangle::mask_rectangle(const pair& arg1, const pair& arg2)
+ : m_hmin(min(arg1.x1(), arg2.x1())),
+ m_hmax(max(arg1.x1(), arg2.x1())),
+ m_vmin(min(arg1.x2(), arg2.x2())),
+ m_vmax(max(arg1.x2(), arg2.x2()))
+ {
+ m_border.push_back(edge2d(br(), tr(), true));
+ m_border.push_back(edge2d(tr(), tl(), true));
+ m_border.push_back(edge2d(tl(), bl(), true));
+ m_border.push_back(edge2d(bl(), br(), true));
+ }
+
+ mask_rectangle* mask_rectangle::clone() const
+ {
+ return new mask_rectangle(*this);
+ }
+
+ // corners and midpoints
+ double mask_rectangle::h_min() const { return m_hmin; }
+ double mask_rectangle::v_min() const { return m_vmin; }
+
+ double mask_rectangle::h_max() const { return m_hmax; }
+ double mask_rectangle::v_max() const { return m_vmax; }
+
+ double mask_rectangle::h_avg() const { return 0.5*(m_hmin+m_hmax); }
+ double mask_rectangle::v_avg() const { return 0.5*(m_vmin+m_vmax); }
+
+ double mask_rectangle::h_size() const { return m_hmax - m_hmin; }
+ double mask_rectangle::v_size() const { return m_vmax - m_vmin; }
+
+ // rectangle-specific functions
+ bool mask_rectangle::crops(const pair& arg) const
+ {
+ const double x(arg.x1());
+ const double y(arg.x2());
+ return !( (m_hmin <= x) && (x <= m_hmax)
+ && (m_vmin <= y) && (y <= m_vmax));
+ }
+
+ std::list<edge2d>& mask_rectangle::crop_path(std::list<edge2d>& L) const
+ {
+ return crop_path_2nd(m_border, L);
+ }
+
+ std::list<edge2d>& mask_rectangle::crop_loop(std::list<edge2d>& L) const
+ {
+ return crop_loop_2nd(m_border, L);
+ }
+
+ pen_line mask_rectangle::border(const Color& col, const length& len) const
+ {
+ return pen_line(pen_data(col, len), Xfine(), m_border);
+ }
+
+ pen_fill mask_rectangle::backing(const Color& col) const
+ {
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+
+ pen_line mask_rectangle::border() const
+ {
+ return pen_line(the_paint_style().line_pen(),
+ the_paint_style().base_pen(), m_border);
+ }
+
+ pen_fill mask_rectangle::backing() const
+ {
+ const Color& col(the_paint_style().fill_color());
+ return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border);
+ }
+} // end of ePiX namespace
diff --git a/graphics/epix/mask_rectangle.h b/graphics/epix/mask_rectangle.h
new file mode 100644
index 0000000000..13d23e4f28
--- /dev/null
+++ b/graphics/epix/mask_rectangle.h
@@ -0,0 +1,89 @@
+/*
+ * mask_rectangle.h -- ePiX:: rectangular screen_mask for cropping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 05, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_MASK_RECTANGLE
+#define EPIX_MASK_RECTANGLE
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+#include "screen_mask.h"
+
+namespace ePiX {
+
+ class pair;
+
+ class Color;
+
+ class length;
+ class pen_fill;
+ class pen_line;
+
+ class mask_rectangle : public screen_mask {
+ public:
+ // mask_rectangle() { }
+ mask_rectangle(const pair& arg1, const pair& arg2);
+
+ mask_rectangle* clone() const;
+ double h_min() const;
+ double h_max() const;
+ double h_size() const;
+ double h_avg() const;
+
+ double v_min() const;
+ double v_max() const;
+ double v_size() const;
+ double v_avg() const;
+
+ bool crops(const pair& arg) const; // false if arg visible
+ std::list<edge2d>& crop_path(std::list<edge2d>&) const;
+ std::list<edge2d>& crop_loop(std::list<edge2d>&) const;
+
+ pen_line border(const Color&, const length&) const;
+ pen_fill backing(const Color&) const;
+
+ pen_line border() const;
+ pen_fill backing() const;
+
+ private:
+ double m_hmin, m_hmax;
+ double m_vmin, m_vmax;
+
+ std::list<edge2d> m_border;
+ }; // end of class mask_rectangle
+
+} // end of namespace
+
+#endif /* EPIX_MASK_RECTANGLE */
diff --git a/graphics/epix/missing b/graphics/epix/missing
new file mode 100644
index 0000000000..894e786e16
--- /dev/null
+++ b/graphics/epix/missing
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program 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, or (at your option)
+# any later version.
+
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/graphics/epix/mkinstalldirs b/graphics/epix/mkinstalldirs
new file mode 100644
index 0000000000..259dbfcd35
--- /dev/null
+++ b/graphics/epix/mkinstalldirs
@@ -0,0 +1,158 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2005-06-29.22
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit $?
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit $?
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ case $file in
+ /*) pathcomp=/ ;;
+ *) pathcomp= ;;
+ esac
+ oIFS=$IFS
+ IFS=/
+ set fnord $file
+ shift
+ IFS=$oIFS
+
+ for d
+ do
+ test "x$d" = x && continue
+
+ pathcomp=$pathcomp$d
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp=$pathcomp/
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/graphics/epix/paint_style.cc b/graphics/epix/paint_style.cc
new file mode 100644
index 0000000000..56ac9e7129
--- /dev/null
+++ b/graphics/epix/paint_style.cc
@@ -0,0 +1,145 @@
+/*
+ * paint_style.cc -- ePiX's current line and fill style.
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "camera.h"
+#include "length.h"
+#include "pen_data.h"
+#include "paint_style.h"
+
+namespace ePiX {
+
+ // Magic numbers: initialization constants
+ paint_state::paint_state()
+ : m_line(pen_data()), m_base(Xfine()),
+ m_tint(Neutral()), m_filling(false) { }
+
+ paint_state* paint_state::clone() const
+ {
+ return new paint_state(*this);
+ }
+
+ // set
+ void paint_state::line_pen(const pen_data& pen)
+ {
+ m_line = pen;
+ }
+
+ void paint_state::line_color(const Color& col)
+ {
+ m_line.color(col);
+ }
+
+ void paint_state::line_width(const length& len)
+ {
+ m_line.width(len);
+ }
+
+ void paint_state::base_pen(const pen_data& pen)
+ {
+ m_base = pen;
+ }
+
+ void paint_state::base_color(const Color& col)
+ {
+ m_base.color(col);
+ }
+
+ void paint_state::base_width(const length& len)
+ {
+ m_base.width(len);
+ }
+
+ void paint_state::fill_color(const Color& col)
+ {
+ m_tint = col;
+ }
+
+ void paint_state::fill_flag(bool fill)
+ {
+ m_filling = fill;
+ }
+
+
+ // get
+ pen_data paint_state::line_pen() const
+ {
+ return m_line;
+ }
+ Color paint_state::line_color() const
+ {
+ return m_line.color();
+ }
+ length paint_state::line_width() const
+ {
+ return m_line.width();
+ }
+
+ pen_data paint_state::base_pen() const
+ {
+ return m_base;
+ }
+ Color paint_state::base_color() const
+ {
+ return m_base.color();
+ }
+ length paint_state::base_width() const
+ {
+ return m_base.width();
+ }
+
+ Color paint_state::fill_color() const
+ {
+ return m_tint;
+ }
+ bool paint_state::fill_flag() const
+ {
+ return m_filling;
+ }
+
+ paint_state paint_state::seen_through(const Camera& mycam) const
+ {
+ return paint_state(m_line.seen_through(mycam), m_base.seen_through(mycam),
+ mycam(m_tint), m_filling);
+ }
+
+ paint_state::paint_state(const pen_data& lp, const pen_data& bp,
+ const Color& fc, bool ff)
+ : m_line(lp), m_base(bp), m_tint(fc), m_filling(ff) { }
+
+
+ paint_state& the_paint_style()
+ {
+ static paint_state* the_paint_state(new paint_state());
+ return *the_paint_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/paint_style.h b/graphics/epix/paint_style.h
new file mode 100644
index 0000000000..95678f1706
--- /dev/null
+++ b/graphics/epix/paint_style.h
@@ -0,0 +1,103 @@
+/*
+ * paint_style.h -- ePiX's current line and fill style.
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.3
+ * Last Change: March 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file implements ePiX's "paint" style:
+ *
+ * [] Front pen, base pen (Color and width x2)
+ * [] Filling and fill color (bool, Color)
+ *
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h, which modify the_paint_style().
+ *
+ * This header is not part of epix.h.
+ */
+#ifndef EPIX_PAINT_STYLE
+#define EPIX_PAINT_STYLE
+
+#include "Color.h"
+#include "pen_data.h"
+
+namespace ePiX {
+
+ class Camera;
+ class length;
+
+ class paint_state {
+ public:
+ paint_state();
+
+ paint_state* clone() const;
+
+ // set
+ void line_pen(const pen_data& pen);
+ void line_color(const Color& col);
+ void line_width(const length& len);
+
+ void base_pen(const pen_data& pen);
+ void base_color(const Color& col);
+ void base_width(const length& len);
+
+ void fill_color(const Color& col);
+ void fill_flag(bool fill);
+
+ // get
+ pen_data line_pen() const;
+ Color line_color() const;
+ length line_width() const;
+
+ pen_data base_pen() const;
+ Color base_color() const;
+ length base_width() const;
+
+ Color fill_color() const;
+ bool fill_flag() const;
+
+ paint_state seen_through(const Camera& cam) const;
+
+ private:
+ pen_data m_line;
+ pen_data m_base;
+
+ Color m_tint;
+ bool m_filling;
+
+ paint_state(const pen_data&, const pen_data&, const Color&, bool fill);
+ }; // end of class paint_state
+
+ paint_state& the_paint_style();
+
+} // end of namespace
+
+#endif /* EPIX_PAINT_STYLE */
diff --git a/graphics/epix/pairs.cc b/graphics/epix/pairs.cc
new file mode 100644
index 0000000000..a2cf174825
--- /dev/null
+++ b/graphics/epix/pairs.cc
@@ -0,0 +1,158 @@
+/*
+ * pairs.cc -- ePiX pair:: class and mathematical operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+
+#include "constants.h"
+#include "triples.h"
+#include "pairs.h"
+
+namespace ePiX {
+ pair::pair(const P& arg)
+ {
+ m_x1 = arg.x1();
+ m_x2 = arg.x2();
+ }
+
+ // unary increment operators
+ pair& pair::operator += (const pair& arg)
+ {
+ m_x1 += arg.m_x1;
+ m_x2 += arg.m_x2;
+
+ return *this;
+ }
+
+ pair& pair::operator -= (const pair& arg)
+ {
+ m_x1 -= arg.m_x1;
+ m_x2 -= arg.m_x2;
+
+ return *this;
+ }
+
+ pair& pair::operator *= (double c)
+ {
+ m_x1 *= c;
+ m_x2 *= c;
+
+ return *this;
+ }
+
+ // complex multiplication and division
+ pair& pair::operator *= (const pair& arg)
+ {
+ double temp(m_x1);
+ m_x1 = temp * arg.m_x1 - m_x2 * arg.m_x2;
+ m_x2 = temp * arg.m_x2 + m_x2 * arg.m_x1;
+
+ return *this;
+ }
+
+ pair& pair::operator /= (const pair& arg)
+ {
+ double denom = (arg.m_x1)*(arg.m_x1)+(arg.m_x2)*(arg.m_x2);
+
+ double temp(m_x1);
+ m_x1 = (temp * arg.m_x1 + m_x2 * arg.m_x2)/denom;
+ m_x2 = (m_x2 * arg.m_x1 - temp * arg.m_x2)/denom;
+
+ return *this;
+ }
+
+ bool pair::operator== (const pair& u) const
+ {
+ return ( fabs(m_x1-u.m_x1) < EPIX_EPSILON
+ && fabs(m_x2-u.m_x2) < EPIX_EPSILON );
+ }
+
+ bool pair::operator!= (const pair& u) const
+ {
+ return !((*this) == u);
+ }
+
+ // non-member functions
+ pair operator- (pair u)
+ {
+ return u *= -1;
+ }
+
+ pair operator+ (pair u, const pair& v)
+ {
+ return u += v;
+ }
+
+ pair operator- (pair u, const pair& v)
+ {
+ return u -= v;
+ }
+
+ pair operator* (double c, pair u)
+ {
+ return u *= c;
+ }
+
+ // complex arithmetic
+ pair J(pair p)
+ {
+ return p *= pair(0,1);
+ }
+
+ pair operator* (pair u, const pair& v)
+ {
+ return u *= v;
+ }
+
+ pair operator/ (pair u, const pair& v)
+ {
+ return u /= v;
+ }
+
+ // dot product
+ double operator| (const pair& u, const pair& v)
+ {
+ return u.x1()*v.x1() + u.x2()*v.x2();
+ }
+
+ double norm (const pair& u)
+ {
+ return sqrt(u|u);
+ }
+
+ // componentwise product (a,b)&(x,y)=(ax,by)
+ pair operator& (const pair& u, const pair& v)
+ {
+ return pair(u.x1()*v.x1(), u.x2()*v.x2());
+ }
+
+} // end of namespace
diff --git a/graphics/epix/pairs.h b/graphics/epix/pairs.h
new file mode 100644
index 0000000000..cfbfd27c1a
--- /dev/null
+++ b/graphics/epix/pairs.h
@@ -0,0 +1,88 @@
+/*
+ * pairs.h -- ePiX pair:: class and mathematical operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PAIRS
+#define EPIX_PAIRS
+
+namespace ePiX {
+
+ class P;
+
+ class pair {
+ public:
+ pair(double arg1=0, double arg2=0)
+ : m_x1(arg1), m_x2(arg2) { }
+
+ pair(const P& arg); // take first two coordinates
+
+ double x1() const { return m_x1; }
+ double x2() const { return m_x2; }
+
+ // unary increment operators
+ pair& operator += (const pair& arg);
+ pair& operator -= (const pair& arg);
+ pair& operator *= (double c);
+
+ // complex multiplication and division
+ pair& operator *= (const pair& arg);
+ pair& operator /= (const pair& arg);
+ bool operator== (const pair& u) const;
+ bool operator!= (const pair& u) const;
+
+ private:
+ double m_x1;
+ double m_x2;
+
+ }; // end of class pair
+
+ pair operator- (pair u);
+ pair operator+ (pair u, const pair& v);
+ pair operator- (pair u, const pair& v);
+ pair operator* (double c, pair u);
+
+ // complex arithmetic
+ pair J(pair p);
+ pair operator* (pair u, const pair& v);
+ pair operator/ (pair u, const pair& v);
+
+ // dot product
+ double operator| (const pair& u, const pair& v);
+ double norm (const pair& u);
+
+ // componentwise product (a,b)&(x,y)=(ax,by)
+ pair operator& (const pair& u, const pair& v);
+
+} // end of namespace
+
+#endif /* EPIX_PAIRS */
diff --git a/graphics/epix/path.cc b/graphics/epix/path.cc
new file mode 100644
index 0000000000..c786485670
--- /dev/null
+++ b/graphics/epix/path.cc
@@ -0,0 +1,329 @@
+/*
+ * path.cc -- ePiX user class for polygons and paths
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 25, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <vector>
+#include <cmath>
+
+#include "errors.h"
+#include "triples.h"
+#include "constants.h"
+
+#include "functions.h"
+
+#include "Color.h"
+#include "pen_data.h"
+#include "state.h"
+
+#include "camera.h"
+#include "active_screen.h"
+
+#include "spline_data.h"
+#include "path_data.h"
+
+#include "path.h"
+
+namespace ePiX {
+
+ class screen;
+ class Sphere;
+
+ path::path(const path& C)
+ : m_segments(C.m_segments->clone()) { }
+
+ path& path::operator= (const path& C)
+ {
+ if (this != &C)
+ {
+ path_data* tmp_segs(C.m_segments->clone());
+
+ delete m_segments;
+
+ m_segments=tmp_segs;
+ }
+
+ return *this;
+ }
+
+ path::~path()
+ {
+ delete m_segments;
+ }
+
+
+ path::path()
+ : m_segments(new path_data()) { }
+
+ path::path(const std::vector<P>& data, bool closed, bool filled)
+ : m_segments(new path_data(data, closed, filled)) { }
+
+
+ // path constructors *do not* close/fill; this must be done by client code
+
+ // lines, without and with specified number of points
+ path::path(const P& tail, const P& head, double expand)
+ : m_segments(new path_data())
+ {
+ double c(expm1(M_LN2*expand/100.0)); // 2^{expand/100} - 1
+ P dir(head - tail);
+
+ m_segments->pt(tail - (0.5*c)*dir);
+ m_segments->pt(head + (0.5*c)*dir);
+ } // end of line constructor
+
+
+ path::path(const P& tail, const P& head,
+ double expand, unsigned int num_pts)
+ : m_segments(new path_data())
+ {
+ if (num_pts < 1)
+ num_pts=1;
+
+ double c(expm1(M_LN2*expand/100.0)); // 2^{expand/100} - 1
+
+ // direction and starting location
+ P dir(head - tail);
+ P start(tail - (0.5*c)*dir);
+
+ dir *= ((1+c)/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ m_segments->pt(start+i*dir);
+
+ } // end of line constructor
+
+
+ // ellipse drawn with N edges
+ path::path(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max,
+ unsigned int N)
+ : m_segments(new path_data())
+ {
+ double T_MAX(t_max);
+ if (full_turn() < fabs(t_max-t_min))
+ {
+ epix_warning("Angle bounds in ellipse span more than one turn");
+ T_MAX = t_min + full_turn();
+ }
+
+ const unsigned int num_pts(1 < N ? N : 1);
+ const double dt((T_MAX - t_min)/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ {
+ double t(t_min + i*dt);
+ m_segments->pt(center + ((Cos(t)*axis1)+(Sin(t)*axis2)));
+ }
+ } // end of ellipse constructor
+
+ // ellipse with default number of points
+ path::path(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max)
+ : m_segments(new path_data())
+ {
+ double frac(min(fabs(t_max-t_min)/full_turn(), 1));
+ unsigned int num_pts((unsigned int) max(2, ceil(frac*EPIX_NUM_PTS)));
+
+ const double dt((t_max - t_min)/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ {
+ double t(t_min + i*dt);
+ m_segments->pt(center + ((Cos(t)*axis1)+(Sin(t)*axis2)));
+ }
+ } // end of ellipse EPIX_NUM_PTS constructor
+
+
+ // Splines
+ path::path(const P& p1, const P& p2, const P& p3, unsigned int num_pts)
+ : m_segments(new path_data())
+ {
+ if (num_pts < 2)
+ num_pts=2; // draw at least V
+
+ const double dt(1.0/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ m_segments->pt(spl_pt(p1, p2, p3, i*dt));
+ }
+
+
+ path::path(const P& p1, const P& p2, const P& p3)
+ : m_segments(new path_data())
+ {
+ const double dt(1.0/EPIX_NUM_PTS);
+
+ for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i)
+ m_segments->pt(spl_pt(p1, p2, p3, i*dt));
+ }
+
+
+ path::path(const P& p1, const P& p2, const P& p3, const P& p4,
+ unsigned int num_pts)
+ : m_segments(new path_data())
+ {
+ if (num_pts < 3)
+ num_pts=3; // draw at least N
+
+ const double dt(1.0/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ m_segments->pt(spl_pt(p1, p2, p3, p4, i*dt));
+ }
+
+
+ path::path(const P& p1, const P& p2, const P& p3, const P& p4)
+ : m_segments(new path_data())
+ {
+ const double dt(1.0/EPIX_NUM_PTS);
+
+ for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i)
+ m_segments->pt(spl_pt(p1, p2, p3, p4, i*dt));
+ }
+
+
+ // parametrized path
+ path::path(P f(double), double t_min, double t_max, unsigned int num_pts)
+ : m_segments(new path_data())
+ {
+ if (num_pts < 2)
+ num_pts = 2;
+
+ const double dt((t_max - t_min)/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ m_segments->pt(f(t_min + i*dt));
+ }
+
+ // with default number of points
+ path::path(P f(double), double t_min, double t_max)
+ : m_segments(new path_data())
+ {
+ const double dt((t_max - t_min)/EPIX_NUM_PTS);
+
+ for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i)
+ m_segments->pt(f(t_min + i*dt));
+ }
+
+
+ // graphs
+ path::path(double f(double), double t_min, double t_max,
+ unsigned int num_pts)
+ : m_segments(new path_data())
+ {
+ if (num_pts < 2)
+ num_pts = 2;
+
+ const double dt((t_max - t_min)/num_pts);
+
+ for (unsigned int i=0; i <= num_pts; ++i)
+ {
+ double t(t_min + i*dt);
+ m_segments->pt(P(t, f(t)));
+ }
+ }
+
+ path::path(double f(double), double t_min, double t_max)
+ : m_segments(new path_data())
+ {
+ const double dt((t_max - t_min)/EPIX_NUM_PTS);
+
+ for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i)
+ {
+ double t(t_min + i*dt);
+ m_segments->pt(P(t, f(t)));
+ }
+ }
+
+
+ // append a point
+ path& path::pt(double x, double y, double z)
+ {
+ m_segments->pt(P(x, y, z));
+ return *this;
+ }
+
+ path& path::pt(const P& loc)
+ {
+ m_segments->pt(loc);
+ return *this;
+ }
+
+
+ // concatenate
+ path& path::operator+= (const path& data)
+ {
+ *m_segments += *(data.m_segments);
+
+ return *this;
+ }
+
+ path& path::operator-= (const path& data)
+ {
+ *m_segments -= *(data.m_segments);
+
+ return *this;
+ }
+
+ path& path::close()
+ {
+ m_segments->close();
+ return *this;
+ }
+ path& path::fill(const bool arg)
+ {
+ m_segments->fill(arg);
+ return *this;
+ }
+
+
+ void path::clip()
+ {
+ m_segments->clip();
+ }
+
+ void path::clip_to(const Sphere& S, const P& viewpt, bool back)
+ {
+ m_segments->clip_to(S, viewpt, back);
+ }
+
+ void path::draw() const
+ {
+ m_segments->draw();
+ }
+
+ void path::draw(const Color& col, const pen_data& pen) const
+ {
+ m_segments->photo(*active_screen(), cam(), col, pen, Xfine());
+ }
+} // end of namespace
diff --git a/graphics/epix/path.h b/graphics/epix/path.h
new file mode 100644
index 0000000000..9816eed383
--- /dev/null
+++ b/graphics/epix/path.h
@@ -0,0 +1,135 @@
+/*
+ * path.h -- ePiX user class for polygons and paths
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.3
+ * Last Change: March 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_PATHS
+#define EPIX_PATHS
+
+#include <vector>
+
+namespace ePiX {
+
+ class Camera;
+ class Color;
+ class P;
+ class path_data;
+ class pen_data;
+ class screen;
+ class Sphere;
+
+ class path {
+ friend class facet;
+ public:
+
+ // path was visible to users, but is now implemented as a p_impl.
+ path(const path&);
+ path& operator= (const path&);
+ ~path();
+
+ // Interface dictated by backward compatibility
+ path(const std::vector<P>& data, bool closed, bool filled);
+ path();
+
+ // line constructors
+ path(const P& tail, const P& head, double expand=0);
+ path(const P&, const P&, double expand, unsigned int num_pts);
+
+
+ // Constructors that specify the number of points have two prototypes
+ // rather than accepting a default argument. This hides the global
+ // (but user-inaccessible) default number of points (see constants.h).
+
+ // ellipse
+ path(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max,
+ unsigned int num_pts);
+
+ path(const P& center, const P& axis1, const P& axis2,
+ double t_min, double t_max);
+
+
+ // spline
+ path(const P& p1, const P& p2, const P& p3, unsigned int n);
+ path(const P& p1, const P& p2, const P& p3);
+
+ path(const P& p1, const P& p2, const P& p3, const P& p4, unsigned int n);
+ path(const P& p1, const P& p2, const P& p3, const P& p4);
+
+
+ // parametric path
+ path(P f(double), double t_min, double t_max, unsigned int num_pts);
+ path(P f(double), double t_min, double t_max);
+
+ // function graph
+ path(double f(double), double t_min, double t_max, unsigned int num_pts);
+ path(double f(double), double t_min, double t_max);
+
+ // append a point
+ path& pt(double, double, double=0);
+ path& pt(const P&);
+
+ // concatenate path segments
+ path& operator+= (const path&);
+ // concatenate, reversing second sequence
+ path& operator-= (const path&);
+
+ bool is_closed() const;
+ bool is_filled() const;
+
+ // set attributes
+ path& close();
+ path& fill(const bool arg=true);
+
+
+ void clip();
+
+ // assumes path lies on sphere
+ void clip_to(const Sphere&, const P& viewpt, bool back=false);
+
+ void draw() const;
+ void draw(const Color&, const pen_data&) const;
+
+ private:
+ path_data* m_segments;
+
+ }; // end of class path
+
+ /*
+ Slated for removal
+ // polygon/polyline with variable number of vertices
+ path polygon(unsigned int num_pts ...);
+ path polyline(unsigned int num_pts ...);
+ */
+
+} // end of namespace
+
+#endif /* EPIX_PATHS */
diff --git a/graphics/epix/path_data.cc b/graphics/epix/path_data.cc
new file mode 100644
index 0000000000..e4359ee030
--- /dev/null
+++ b/graphics/epix/path_data.cc
@@ -0,0 +1,280 @@
+/*
+ * path_data.cc -- ePiX implementation classes for polygons and paths
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.21
+ * Last Change: September 22, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <list>
+#include <algorithm>
+
+#include "errors.h"
+#include "constants.h"
+
+#include "triples.h"
+#include "camera.h"
+#include "sphere.h"
+
+#include "edge_data.h"
+#include "active_screen.h"
+#include "clipping.h"
+
+#include "paint_style.h"
+
+#include "halfspace.h"
+#include "pen_line.h"
+#include "pen_fill.h"
+
+#include "screen_data.h"
+#include "screen.h"
+
+#include "path_data.h"
+
+namespace ePiX {
+
+ path_data::path_data() : m_closed(false), m_filled(false) { }
+
+ path_data::path_data(const std::vector<P>& pv, bool closed, bool filled)
+ : m_closed(closed), m_filled(closed && filled)
+ {
+ if (pv.size() == 1)
+ m_data.push_back(edge3d(pv.at(0), pv.at(0), true)); // will delete later
+
+ else
+ for (unsigned int i=0; i<pv.size()-1; ++i)
+ m_data.push_back(edge3d(pv.at(i), pv.at(i+1), true));
+ }
+
+ path_data::path_data(const std::list<edge3d>& data, bool closed, bool filled)
+ : m_closed(closed), m_filled(closed && filled), m_data(data) { }
+
+
+ path_data* path_data::clone() const
+ {
+ return new path_data(*this);
+ }
+
+
+ // join to arg; no effect if we're closed
+ path_data& path_data::pt(const P& arg)
+ {
+ if (0 < m_data.size())
+ {
+ const P hd((--m_data.end())->head()); // terminal point
+ m_data.push_back(edge3d(hd, arg, true));
+ }
+
+ else
+ m_data.push_back(edge3d(arg, arg, true));
+
+ return *this;
+ }
+
+
+ // concatenate path_data segments
+ path_data& path_data::operator+= (path_data pd)
+ {
+ if (!m_closed)
+ m_data.splice(m_data.end(), pd.m_data);
+
+ return *this;
+ }
+
+ // concatenate, reversing second sequence
+ path_data& path_data::operator-= (path_data pd)
+ {
+ if (!m_closed)
+ {
+ for (std::list<edge3d>::iterator ep=pd.m_data.begin();
+ ep != pd.m_data.end(); ++ep)
+ (*ep).reverse(); // swap tails and heads
+
+ pd.m_data.reverse(); // reverse list order
+ m_data.splice(m_data.end(), pd.m_data);
+ }
+
+ return *this;
+ }
+
+ bool path_data::is_closed() const
+ {
+ return m_closed;
+ }
+
+ bool path_data::is_filled() const
+ {
+ return m_filled;
+ }
+
+
+ // set flag and close up if necessary
+ path_data& path_data::close()
+ {
+ if (0 < m_data.size())
+ {
+ m_closed=true;
+
+ const P tail_pt((m_data.begin())->tail());
+ const P head_pt((--m_data.end())->head());
+
+ if (tail_pt != head_pt)
+ m_data.push_back(edge3d(head_pt, tail_pt, true));
+ }
+
+ return *this;
+ }
+
+ // no action unless we're closed
+ path_data& path_data::fill(const bool arg)
+ {
+ if (m_closed)
+ m_filled=arg;
+ return *this;
+ }
+
+
+ path_data& path_data::clip()
+ {
+ if (m_closed)
+ the_clip_box().clip_loop(m_data);
+
+ else
+ the_clip_box().clip_path(m_data);
+
+ return *this;
+ }
+
+ path_data& path_data::clip_to(const halfspace& knife)
+ {
+ if (m_closed)
+ knife.clip_loop(m_data);
+ else
+ knife.clip_path(m_data);
+ return *this;
+ }
+
+
+ path_data& path_data::clip_to(const Sphere& S, const P& viewpt,
+ bool back)
+ {
+ const double rad(S.radius());
+
+ P dir(S.center() - viewpt);
+ const double dist(norm(dir));
+
+ if (rad < dist) // viewpt is outside
+ {
+ dir *= 1/dist; // unit vector from center to viewpt
+ double x(rad*rad/dist);
+
+ halfspace knife(S.center() - x*dir, dir);
+
+ if (back)
+ knife.reverse();
+
+ clip_to(knife);
+ }
+
+ else
+ epix_warning("Can't clip path to sphere from interior viewpoint");
+
+ return *this;
+ }
+
+
+ void path_data::photo(screen& scr, const Camera& mycam, const Color& fill,
+ const pen_data& line, const pen_data& base) const
+ {
+ path_data tmp_data(*this);
+
+ tmp_data.clip(); // clip_box
+ if (mycam.needs_clip())
+ tmp_data.clip_to(mycam.clip_plane());
+
+ std::list<edge2d> edges;
+ unsigned int edge_ct(0); // don't print filled unless >= 3 non-null edges
+
+ for (std::list<edge3d>::const_iterator p=tmp_data.m_data.begin();
+ p != tmp_data.m_data.end(); ++p)
+ {
+ edge2d tmp(mycam((*p).tail()), mycam((*p).head()), (*p).is_seen());
+
+ if (!tmp.is_null()) // endpoints not equal
+ {
+ ++edge_ct;
+ edges.push_back(tmp);
+ }
+ }
+
+ // draw fill bordered by base, then re-draw border with line/base pens
+ if (m_filled && 3 <= edge_ct)
+ {
+ scr.m_screen->add_tile(pen_fill(mycam(fill),
+ line.seen_through(mycam), edges));
+ if (line.width() < base.width())
+ scr.m_screen->add_tile(pen_line(line.seen_through(mycam),
+ base.seen_through(mycam), edges));
+ }
+
+ else if (1 <= edge_ct)
+ {
+ // print edges in groups
+ std::list<edge2d>::iterator p(edges.begin());
+ std::list<edge2d> path_buf;
+
+ int count(0);
+ while (p != edges.end())
+ {
+ path_buf.push_back(*p);
+ p = edges.erase(p);
+
+ if (++count == 250 || p == edges.end()) // Magic number
+ {
+ scr.m_screen->add_tile(pen_line(line.seen_through(mycam),
+ base.seen_through(mycam),
+ path_buf));
+ path_buf.clear();
+ count = 0;
+ }
+ }
+ }
+ }
+
+ void path_data::draw() const
+ {
+ photo(*active_screen(), cam(), the_paint_style().fill_color(),
+ the_paint_style().line_pen(), the_paint_style().base_pen());
+ }
+
+ void path_data::draw(const Color& col, const pen_data& pen) const
+ {
+ photo(*active_screen(), cam(), col, pen, Xfine());
+ }
+} // end of namespace
diff --git a/graphics/epix/path_data.h b/graphics/epix/path_data.h
new file mode 100644
index 0000000000..fa7803f976
--- /dev/null
+++ b/graphics/epix/path_data.h
@@ -0,0 +1,101 @@
+/*
+ * path_data.h -- ePiX implementation classes for polygons and paths
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_PATH_DATA
+#define EPIX_PATH_DATA
+
+#include <list>
+#include <vector>
+
+#include "triples.h"
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class Camera;
+ class Color;
+ class halfspace;
+ class pen_data;
+ class screen;
+ class Sphere;
+
+ // sequence of vertices
+ class path_data {
+ public:
+ path_data();
+ path_data(const std::vector<P>&, bool closed=false, bool filled=false);
+ path_data(const std::list<edge3d>&, bool closed=false, bool filled=false);
+
+ path_data* clone() const;
+
+ // add points
+ path_data& pt(const P&);
+
+ // concatenate path_data segments
+ path_data& operator+= (path_data);
+
+ // concatenate, reversing second sequence
+ path_data& operator-= (path_data);
+
+ bool is_closed() const;
+ bool is_filled() const;
+
+ // make loop and prevent subsequent additions of points
+ path_data& close();
+
+ // (un)set fill flag if closed
+ path_data& fill(const bool arg=true);
+
+ path_data& clip();
+ path_data& clip_to(const halfspace&);
+
+ // assumes path already lies on sphere
+ path_data& clip_to(const Sphere&, const P& viewpt, bool back=false);
+
+ void photo(screen&, const Camera&, const Color& fill,
+ const pen_data& line, const pen_data& base) const;
+
+ void draw() const;
+ void draw(const Color&, const pen_data&) const;
+
+ private:
+ bool m_closed;
+ bool m_filled;
+
+ std::list<edge3d> m_data;
+
+ }; // end of class path_data
+
+} // end of namespace
+
+#endif /* EPIX_PATH_DATA */
diff --git a/graphics/epix/path_style.cc b/graphics/epix/path_style.cc
new file mode 100644
index 0000000000..43b93681a4
--- /dev/null
+++ b/graphics/epix/path_style.cc
@@ -0,0 +1,160 @@
+/*
+ * path_style.cc -- ePiX's class for path styles.
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include "constants.h"
+
+#include "functions.h" // for snip_to
+#include "utils.h" // for get_chars
+#include "path_style.h"
+
+namespace ePiX {
+
+ // true if arg is a string of ch
+ static bool __epix_all_one_char(const std::string& arg, const char ch)
+ {
+ return arg.find_first_not_of(ch) == std::string::npos;
+ }
+
+ // convert string of dashes, spaces, and periods to a vector of breakpoints
+ static std::vector<double> __epix_get_breakpts(const std::string& pattern)
+ {
+ std::vector<double> value;
+
+ // Assume solid on anomalous input
+ if (pattern.size() == 0
+ || __epix_all_one_char(pattern, '-')
+ || __epix_all_one_char(pattern, ' '))
+ {
+ value.push_back(0);
+ value.push_back(1);
+
+ return value;
+ }
+
+ // else
+ const unsigned int sz(pattern.size()); // not zero
+ const double dt(1.0/sz);
+
+ for (unsigned int i=0; i<sz; ++i)
+ {
+ if (pattern.at(i) == '-')
+ {
+ // previous element was a dash; extend instead of adding breaks
+ if (0 < value.size()
+ && fabs(value.at(value.size()-1) - i*dt) < 0.25*dt)
+ value.at(value.size()-1) = (i+1)*dt;
+
+ else
+ {
+ value.push_back(i*dt);
+ value.push_back((i+1)*dt);
+ }
+ }
+
+ else if (pattern.at(i) == '.')
+ {
+ value.push_back((i+0.5)*dt);
+ value.push_back((i+0.5)*dt); // same value twice
+ }
+ // spaces have no breakpoints, just increment i
+ }
+
+ return value;
+ } // end of __epix_get_breakpts
+
+
+ path_state::path_state()
+ : m_separation(AVG_SEP), m_natural_length(1), m_solid(true)
+ {
+ m_breakpoints.push_back(0);
+ m_breakpoints.push_back(1);
+ }
+
+ path_state::path_state(std::string arg)
+ : m_separation(AVG_SEP), m_solid(false)
+ {
+ // strip out everything but dash, space, period.
+ const std::string pattern(get_chars(arg, "- ."));
+ m_breakpoints = __epix_get_breakpts(pattern); // ok even if pattern=""
+
+ m_natural_length = pattern.size();
+
+ if (m_breakpoints.at(0) == 0 && m_breakpoints.at(1) == 1)
+ {
+ m_solid = true;
+ m_natural_length = 1;
+ }
+ }
+
+ path_state& path_state::separation(double len)
+ {
+ if (0 < len)
+ m_separation = snip_to(len, MIN_SEP, MAX_SEP);
+
+ else
+ m_separation = AVG_SEP;
+
+ return *this;
+ }
+
+ double path_state::separation() const
+ {
+ return m_separation;
+ }
+
+ unsigned int path_state::natural_length() const
+ {
+ return m_natural_length;
+ }
+
+ std::vector<double> path_state::breakpts() const
+ {
+ return m_breakpoints;
+ }
+
+ bool path_state::is_solid() const
+ {
+ return m_solid;
+ }
+
+
+ path_state& the_path_style()
+ {
+ static path_state* the_path_state(new path_state());
+ return *the_path_state;
+ }
+} // end of namespace
diff --git a/graphics/epix/path_style.h b/graphics/epix/path_style.h
new file mode 100644
index 0000000000..988847660e
--- /dev/null
+++ b/graphics/epix/path_style.h
@@ -0,0 +1,83 @@
+/*
+ * path_style.h -- ePiX's class for solid/dashed/dotted paths
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file implements ePiX's styles for dashed and dotted paths. The
+ * data are a string containing dashes (-), spaces ( ), and dots (.),
+ * each of which represents a fixed portion of a path segment, e.g.
+ *
+ * Solid: "-"
+ * Dashed: "- -"
+ * Dotted: " . "
+ * Custom: "- . -- . -", etc.
+ *
+ * The class in this file implements backend for user-level global
+ * functions defined in state.h.
+ *
+ * This header is not part of epix.h.
+ */
+#ifndef EPIX_PATH_STYLE
+#define EPIX_PATH_STYLE
+
+#include <string>
+#include <vector>
+
+namespace ePiX {
+
+ class path_state {
+ public:
+ path_state();
+ path_state(std::string);
+
+ path_state& separation(double len); // dist in pt between adjacent elements
+
+ double separation() const;
+ unsigned int natural_length() const;
+ std::vector<double> breakpts() const;
+
+ bool is_solid() const;
+
+ private:
+ double m_separation; // true length of pattern
+ std::vector<double> m_breakpoints; // subdivision of [0,1]
+
+ unsigned int m_natural_length; // number of chars in defining string
+ bool m_solid;
+ }; // end of class path_state
+
+ path_state& the_path_style();
+
+} // end of namespace
+
+#endif /* EPIX_PATH_STYLE */
diff --git a/graphics/epix/pen_arrow.cc b/graphics/epix/pen_arrow.cc
new file mode 100644
index 0000000000..e39dbd906c
--- /dev/null
+++ b/graphics/epix/pen_arrow.cc
@@ -0,0 +1,190 @@
+/*
+ * pen_arrow.cc -- ePiX::pen_arrow class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+#include <list> // for arrow shaft cropping
+
+#include "pairs.h"
+#include "affine.h"
+#include "screen_mask.h"
+
+#include "length.h"
+
+#include "edge_data.h"
+
+#include "Color.h"
+#include "arrow_style.h"
+#include "label_style.h"
+#include "marker_style.h" // for bbox marker
+
+#include "format.h"
+#include "picture_data.h"
+#include "picture.h"
+
+#include "tile.h"
+#include "pen_arrow.h"
+
+namespace ePiX {
+ pen_arrow::pen_arrow(const pair& tail, const pair& head,
+ const pen_data& line, const pen_data& base,
+ double scale, double sin_th, bool head_seen)
+ : m_shaft(tail, head, true), m_line(line), m_base(base),
+ m_scale(scale), m_shorten(sin_th), m_head_seen(head_seen),
+ m_style(the_arrowhead_style()) { }
+
+ pen_arrow* pen_arrow::clone() const
+ {
+ return new pen_arrow(*this);
+ }
+
+ pen_arrow& pen_arrow::map_by(const affine& f)
+ {
+ m_shaft = edge2d(f(m_shaft.tail()), f(m_shaft.head()), m_shaft.is_seen());
+
+ return *this;
+ }
+
+
+ pen_arrow& pen_arrow::crop_to(const screen_mask& M)
+ {
+ // update head visibility; never re-mark as visible
+ if (M.crops(m_shaft.head()))
+ m_head_seen = false;
+
+ // screen masks are convex, so we're cropped iff an end is cropped
+ if (M.crops(m_shaft.head()) || M.crops(m_shaft.tail()))
+ {
+ std::list<edge2d> shaft;
+ shaft.push_back(m_shaft);
+ M.crop_path(shaft);
+
+ // search for visible segment; will find no more than one
+ bool still_seen(false);
+
+ for (std::list<edge2d>::const_iterator ep = shaft.begin();
+ ep != shaft.end(); ++ep)
+ if ((*ep).is_seen())
+ {
+ still_seen = true;
+ m_shaft = *ep;
+ }
+
+ if (!still_seen)
+ {
+ m_head_seen = false;
+ m_shaft.seen(false);
+ }
+ }
+
+ return *this;
+ }
+
+ bool pen_arrow::is_empty() const
+ {
+ return !(m_head_seen && m_shaft.is_seen()) || m_line.color().is_unset();
+ }
+
+
+ /*
+ *
+ * 1: base, 2: foot, 3: tip, 4: ear_right, 5: ear_left
+ *
+ 5
+ ...
+ ......... .....
+ .........1 2.....3
+ ......... .....
+ ...
+ 4
+ * <-height->
+ *
+ * <--> inset (fraction of height)
+ *
+ */
+ std::string pen_arrow::print_to(const format& fmt,
+ const std::string& len) const
+ {
+ if (is_empty())
+ return "";
+
+ // else
+ std::stringstream obuf;
+
+ if (m_shaft.tail() == m_shaft.head()) // draw a ddot
+ {
+ label_state my_state(the_label_style());
+ my_state.text_color(m_line.color());
+
+ obuf << fmt.print_mark(m_shaft.tail(), pair(0,0),
+ DDOT, the_mark_size(), my_state, len);
+ }
+
+ else
+ {
+ const pair head(m_shaft.head());
+ const double stretch(length("1pt").to(len).magnitude());
+
+ pair dir(head - m_shaft.tail());
+ double dist(norm(dir));
+
+ const pair unit_dir((stretch/dist)*dir);
+ const pair unit_perp(J(unit_dir));
+
+ const double wd(m_scale*m_style.width());
+ const double ht(m_style.ratio()*wd*m_shorten);
+
+ const pair base(head - ht*unit_dir);
+ const pair foot(head - (1-m_style.inset())*ht*unit_dir);
+
+ const pair ear_left(base + wd*unit_perp);
+ const pair ear_right(base - wd*unit_perp);
+
+ std::list<edge2d> bd;
+ bd.push_back(edge2d(foot, ear_right, true));
+ bd.push_back(edge2d(ear_right, head, true));
+ bd.push_back(edge2d(head, ear_left, true));
+ bd.push_back(edge2d(ear_left, foot, true));
+
+ obuf << fmt.print_fill(bd, pair(0,0), m_line.color(), m_line, len);
+ }
+
+ return obuf.str();
+ }
+
+ void pen_arrow::add_to_pallet() const
+ {
+ if (!is_empty())
+ the_picture().add_to_pallet(m_line.color())
+ .add_to_pallet(m_base.color());
+ }
+} // end of namespace
diff --git a/graphics/epix/pen_arrow.h b/graphics/epix/pen_arrow.h
new file mode 100644
index 0000000000..09f65e8a42
--- /dev/null
+++ b/graphics/epix/pen_arrow.h
@@ -0,0 +1,83 @@
+/*
+ * pen_arrow.cc -- ePiX::pen_arrow class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 19, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PEN_ARROW
+#define EPIX_PEN_ARROW
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+#include "pen_data.h"
+#include "tile.h"
+
+namespace ePiX {
+
+ class affine;
+ class screen_mask;
+
+ // arrowhead tile class
+ class pen_arrow : public tile {
+ public:
+ pen_arrow(const pair& tail, const pair& head,
+ const pen_data& line, const pen_data& base,
+ double scale, double sin_th, bool head_seen);
+
+ pen_arrow* clone() const;
+
+ pen_arrow& map_by(const affine&);
+ pen_arrow& crop_to(const screen_mask&);
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ private:
+ edge2d m_shaft;
+
+ pen_data m_line;
+ pen_data m_base;
+
+ double m_scale; // overall scale of head
+ double m_shorten; // foreshortening factor
+
+ bool m_head_seen;
+
+ arrowhead_state m_style;
+ }; // end of class pen_arrow
+
+} // end of namespace
+
+#endif /* EPIX_PEN_ARROW */
diff --git a/graphics/epix/pen_data.cc b/graphics/epix/pen_data.cc
new file mode 100644
index 0000000000..95bcef0ec2
--- /dev/null
+++ b/graphics/epix/pen_data.cc
@@ -0,0 +1,88 @@
+/*
+ * pen_data.cc -- ePiX's pen class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.20
+ * Last Change: September 19, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+
+#include "camera.h"
+#include "pen_data.h"
+
+namespace ePiX {
+
+ pen_data::pen_data(const Color& col, const length& wid)
+ : m_color(col), m_width(wid) { }
+
+ pen_data::pen_data(const Color& col)
+ : m_color(col), m_width(PLAIN_WIDTH) { }
+
+ // set
+ void pen_data::color(const Color& col) { m_color = col; }
+ void pen_data::width(const length& len) { m_width = len; }
+
+ // get
+ Color pen_data::color() const { return m_color; }
+ length pen_data::width() const { return m_width; }
+
+ bool pen_data::operator== (const pen_data& pen) const
+ {
+ return ((m_color == pen.m_color) && (m_width == pen.m_width));
+ }
+
+ bool pen_data::operator!= (const pen_data& pen) const
+ {
+ return !(*this == pen);
+ }
+
+ pen_data pen_data::seen_through(const Camera& mycam) const
+ {
+ Color col(m_color);
+ if (!col.is_unset())
+ col = mycam(col);
+
+ return pen_data(col, m_width);
+ }
+
+ bool pen_data::is_unset() const
+ {
+ return m_color.is_unset() || (m_width < length(EPIX_EPSILON));
+ }
+
+ // undrawn
+ const pen_data& Xfine()
+ {
+ static const pen_data*
+ const xfine_pen(new pen_data(Neutral(), length(0)));
+
+ return *xfine_pen;
+ }
+} // end of namespace
diff --git a/graphics/epix/pen_data.h b/graphics/epix/pen_data.h
new file mode 100644
index 0000000000..643e7161fe
--- /dev/null
+++ b/graphics/epix/pen_data.h
@@ -0,0 +1,82 @@
+/*
+ * pen_data.h -- Color and width
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.20
+ * Last Change: September 19, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines ePiX's concept of a pen (Color and length)
+ *
+ * This header is not part of epix.h.
+ */
+#ifndef EPIX_PEN_DATA
+#define EPIX_PEN_DATA
+
+#include "Color.h"
+#include "length.h"
+
+namespace ePiX {
+
+ class Camera;
+
+ class pen_data {
+ public:
+ // plain black
+ pen_data(const Color& col, const length& wid);
+ pen_data(const Color& col=Black());
+
+ // set
+ void color(const Color& col);
+ void width(const length& len);
+
+ // get
+ Color color() const;
+ length width() const;
+
+ bool operator== (const pen_data& pen) const;
+ bool operator!= (const pen_data& pen) const;
+
+ pen_data seen_through(const Camera& cam) const;
+
+ bool is_unset() const;
+
+ private:
+ Color m_color;
+ length m_width;
+ }; // end of class pen_data
+
+
+ // undrawn
+ const pen_data& Xfine();
+
+} // end of namespace
+
+#endif /* EPIX_PEN_DATA */
diff --git a/graphics/epix/pen_fill.cc b/graphics/epix/pen_fill.cc
new file mode 100644
index 0000000000..5da5de647b
--- /dev/null
+++ b/graphics/epix/pen_fill.cc
@@ -0,0 +1,149 @@
+/*
+ * pen_fill.cc -- ePiX::pen_fill class, for filled screen elements
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.20
+ * Last Change: September 19, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <string>
+
+#include "functions.h"
+
+#include "pairs.h"
+#include "affine.h"
+#include "screen_mask.h"
+
+#include "length.h"
+
+#include "pen_data.h"
+#include "path_style.h"
+
+#include "format.h"
+#include "picture_data.h"
+#include "picture.h"
+
+#include "edge_data.h"
+
+#include "tile.h"
+#include "pen_fill.h"
+
+namespace ePiX {
+
+ typedef std::list<edge2d>::const_iterator ep2;
+
+ pen_fill::pen_fill()
+ : m_tint(Neutral()), m_line(Xfine()), m_style(the_path_style()) { }
+
+ pen_fill::pen_fill(const Color& fill, const pen_data& line,
+ const std::list<edge2d>& data)
+ : m_tint(fill), m_line(line),
+ m_style(the_path_style()), m_border(data), m_edges(data) { }
+
+ pen_fill::pen_fill(const Color& fill, const pen_data& line, double th,
+ const std::list<edge2d>& data)
+ : m_tint(fill), m_line(line),
+ m_style(the_path_style()), m_border(data), m_edges(data) { }
+
+
+ pen_fill* pen_fill::clone() const
+ {
+ return new pen_fill(*this);
+ }
+
+
+ pen_fill& pen_fill::map_by(const affine& f)
+ {
+ if (m_border.size() == 0)
+ return *this;
+
+ // else map border
+ std::list<edge2d> bord;
+
+ for (ep2 p=m_border.begin(); p!=m_border.end(); ++p)
+ bord.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen()));
+
+ swap(m_border, bord);
+
+ // and edges
+ std::list<edge2d> edges;
+
+ for (ep2 p=m_edges.begin(); p!=m_edges.end(); ++p)
+ edges.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen()));
+
+ swap(m_edges, edges);
+ return *this;
+ }
+
+
+ pen_fill& pen_fill::crop_to(const screen_mask& M)
+ {
+ m_border = M.crop_loop(m_border);
+ m_edges = M.crop_path(m_edges);
+ return *this;
+ }
+
+ bool pen_fill::is_empty() const
+ {
+ return (m_border.size() == 0
+ || (m_tint.is_unset() && m_line.is_unset()));
+ }
+
+
+ std::string pen_fill::print_to(const format& fmt,
+ const std::string& len) const
+ {
+ if (is_empty())
+ return "";
+
+ // else at least one is true
+ bool filled(!m_tint.is_unset());
+ bool edged(!m_line.is_unset());
+
+ // if solid bd, try to draw/fill in one step
+ if (m_style.is_solid() && filled && edged)
+ return fmt.print_fill(m_border, pair(0,0), m_tint, m_line, len);
+
+ // else draw fill, border separately
+ std::string val;
+
+ if (filled)
+ val += fmt.print_fill(m_border, pair(0,0), m_tint,
+ pen_data(m_tint, m_line.width()), len);
+
+ if (edged)
+ val += fmt.print_line(m_edges, pair(0,0), m_line, Xfine(),
+ m_style, len);
+
+ return val;
+ }
+
+ void pen_fill::add_to_pallet() const
+ {
+ the_picture().add_to_pallet(m_tint).add_to_pallet(m_line.color());
+ }
+} // end of namespace
diff --git a/graphics/epix/pen_fill.h b/graphics/epix/pen_fill.h
new file mode 100644
index 0000000000..12abe4707e
--- /dev/null
+++ b/graphics/epix/pen_fill.h
@@ -0,0 +1,83 @@
+/*
+ * pen_fill.cc -- ePiX::pen_fill class, for filled screen elements
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.11
+ * Last Change: August 12, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PEN_FILL
+#define EPIX_PEN_FILL
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+
+#include "Color.h"
+#include "path_style.h"
+#include "tile.h"
+
+namespace ePiX {
+
+ class length;
+ class screen_mask;
+
+ class pen_fill : public tile {
+ public:
+ pen_fill();
+
+ pen_fill(const Color&, const pen_data&, const std::list<edge2d>&);
+
+ pen_fill(const Color&, const pen_data&, double theta,
+ const std::list<edge2d>&);
+
+ pen_fill* clone() const;
+
+ pen_fill& map_by(const affine&);
+ pen_fill& crop_to(const screen_mask&);
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ private:
+ Color m_tint;
+ pen_data m_line;
+
+ path_state m_style;
+
+ std::list<edge2d> m_border; // filled boundary (loop)
+ std::list<edge2d> m_edges; // visible boundary (path)
+ }; // end of class pen_fill
+
+} // end of namespace
+
+#endif /* EPIX_PEN_FILL */
diff --git a/graphics/epix/pen_line.cc b/graphics/epix/pen_line.cc
new file mode 100644
index 0000000000..9ce7621a4d
--- /dev/null
+++ b/graphics/epix/pen_line.cc
@@ -0,0 +1,125 @@
+/*
+ * pen_line.cc -- ePiX::pen_line class, for line-like objects
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.20
+ * Last Change: September 19, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "functions.h"
+
+#include "pairs.h"
+#include "affine.h"
+#include "screen_mask.h"
+
+#include "length.h"
+
+#include "pen_data.h"
+#include "paint_style.h"
+
+#include "format.h"
+#include "picture_data.h" // for add_to_pallet()
+#include "picture.h" // for the_picture()
+
+#include "edge_data.h"
+
+#include "tile.h"
+#include "pen_line.h"
+
+namespace ePiX {
+
+ typedef std::list<edge2d>::const_iterator ep2;
+
+ pen_line::pen_line()
+ : m_line(the_paint_style().line_pen()),
+ m_base(the_paint_style().base_pen()), m_style(the_path_style()) { }
+
+ pen_line::pen_line(const pen_data& line, const pen_data& base,
+ const std::list<edge2d>& data)
+ : m_line(line), m_base(base), m_style(the_path_style()), m_border(data) { }
+
+
+ pen_line* pen_line::clone() const
+ {
+ return new pen_line(*this);
+ }
+
+
+ pen_line& pen_line::map_by(const affine& f)
+ {
+ if (m_border.size() == 0)
+ return *this;
+
+ std::list<edge2d> bord;
+
+ for (ep2 p=m_border.begin(); p!=m_border.end(); ++p)
+ bord.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen()));
+
+ swap(m_border, bord);
+ return *this;
+ }
+
+
+ pen_line& pen_line::crop_to(const screen_mask& M)
+ {
+ m_border = M.crop_path(m_border);
+ return *this;
+ }
+
+
+ bool pen_line::is_empty() const
+ {
+ // N.B. line trumps base, even if base is otherwise visible
+ return (m_border.size() == 0 ||
+ m_line.color().is_unset() ||
+ m_line.width() == length(0));
+ }
+
+
+ std::string pen_line::print_to(const format& fmt,
+ const std::string& len) const
+ {
+ if (is_empty())
+ return "";
+
+ // else
+ return fmt.print_line(m_border, pair(0,0), m_line, m_base, m_style, len);
+ }
+
+ void pen_line::add_to_pallet() const
+ {
+ // add_to_pallet checks for unset
+ the_picture().add_to_pallet(m_line.color())
+ .add_to_pallet(m_base.color());
+ }
+
+ void pen_line::add(const edge2d& E)
+ {
+ m_border.push_back(E);
+ }
+} // end of namespace
+
diff --git a/graphics/epix/pen_line.h b/graphics/epix/pen_line.h
new file mode 100644
index 0000000000..6713b5de74
--- /dev/null
+++ b/graphics/epix/pen_line.h
@@ -0,0 +1,79 @@
+/*
+ * pen_line.h -- ePiX::pen_line class, for line-like objects
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.3
+ * Last Change: March 04, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PEN_LINE
+#define EPIX_PEN_LINE
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+#include "pen_data.h"
+#include "path_style.h"
+#include "tile.h"
+
+namespace ePiX {
+
+ class length;
+ class affine;
+ class screen_mask;
+
+ class pen_line : public tile {
+ public:
+ pen_line();
+ pen_line(const pen_data&, const pen_data&, const std::list<edge2d>&);
+
+ pen_line* clone() const;
+
+ pen_line& map_by(const affine&);
+ pen_line& crop_to(const screen_mask&);
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ void add(const edge2d&);
+
+ private:
+ pen_data m_line;
+ pen_data m_base;
+
+ path_state m_style;
+
+ std::list<edge2d> m_border;
+
+ }; // end of class pen_line
+
+} // end of namespace
+
+#endif /* EPIX_PEN_LINE */
diff --git a/graphics/epix/picture.cc b/graphics/epix/picture.cc
new file mode 100644
index 0000000000..d194edf5f4
--- /dev/null
+++ b/graphics/epix/picture.cc
@@ -0,0 +1,429 @@
+/*
+ * picture.cc -- ePiX::epix_picture class, and global functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+
+#include "triples.h"
+#include "errors.h"
+
+#include "functions.h"
+#include "length.h"
+
+#include "verbatim.h"
+#include "screen_data.h"
+
+#include "screen_mask.h"
+
+#include "screen.h"
+#include "active_screen.h"
+
+#include "eepic.h"
+#include "pst.h"
+#include "tikz.h"
+
+#include "picture_data.h"
+#include "picture.h"
+
+namespace ePiX {
+
+ // static objects
+ picture_data& the_picture()
+ {
+ static picture_data* the_root_picture(new picture_data());
+ return *the_root_picture;
+ }
+
+ double& xmin()
+ {
+ static double* the_x_min(new double);
+ return *the_x_min;
+ }
+
+ double& xmax()
+ {
+ static double* the_x_max(new double);
+ return *the_x_max;
+ }
+
+ double& xsize()
+ {
+ static double* the_x_size(new double);
+ return *the_x_size;
+ }
+
+ double& ymin()
+ {
+ static double* the_y_min(new double);
+ return *the_y_min;
+ }
+
+ double& ymax()
+ {
+ static double* the_y_max(new double);
+ return *the_y_max;
+ }
+
+ double& ysize()
+ {
+ static double* the_y_size(new double);
+ return *the_y_size;
+ }
+
+
+ double & tix()
+ {
+ static double* the_tix(new double);
+ return *the_tix;
+ }
+
+
+ void bounding_box(const P& arg1, const P& arg2)
+ {
+ xmin()=min(arg1.x1(), arg2.x1());
+ xmax()=max(arg1.x1(), arg2.x1());
+
+ ymin()=min(arg1.x2(), arg2.x2());
+ ymax()=max(arg1.x2(), arg2.x2());
+
+ xsize() = xmax() - xmin();
+ if (xsize() == 0)
+ epix_error("Bounding box has width zero!");
+
+ ysize() = ymax() - ymin();
+ if (ysize() == 0)
+ epix_error("Bounding box has height zero!");
+
+ // else
+ the_picture().the_canvas
+ = screen(P(xmin(), ymin()), P(xmax(), ymax()));
+ }
+
+
+ // one-line initializer
+ void picture(const P& arg1, const P& arg2, std::string sz)
+ {
+ // bounding_box()
+ the_picture().the_canvas
+ = screen(P(arg1.x1(), arg1.x2()), P(arg2.x1(), arg2.x2()));
+
+ xmin() = the_picture().the_canvas.h_min();
+ xmax() = the_picture().the_canvas.h_max();
+ xsize() = the_picture().the_canvas.h_size();
+
+ ymin() = the_picture().the_canvas.v_min();
+ ymax() = the_picture().the_canvas.v_max();
+ ysize() = the_picture().the_canvas.v_size();
+
+
+ // parse size string
+ length pic_hsize, pic_vsize;
+ get_lengths(sz, pic_hsize, pic_vsize);
+
+ // width units take precedence
+ std::string u(pic_hsize.units());
+ pic_vsize.to(u);
+ the_picture().the_hoffset.to(u);
+ the_picture().the_voffset.to(u);
+
+ // unitlength()
+ the_picture().the_unitlength = length("1"+u);
+
+ // offset()
+ the_picture().the_hoffset = length("0"+u);
+ the_picture().the_voffset = length("0"+u);
+
+ // picture()
+ the_picture().the_page
+ = screen(P(0,0), P(pic_hsize.magnitude(), pic_vsize.magnitude()));
+
+ if (xsize() == 0 || pic_hsize.magnitude() == 0)
+ epix_error("Picture has width zero!");
+
+ if (ysize() == 0 || pic_vsize.magnitude() == 0)
+ epix_error("Picture has height zero!");
+ }
+
+ // old initializers
+ void picture(double horiz, double vert)
+ {
+ if (horiz == 0)
+ epix_error("Picture has width zero!");
+
+ if (vert == 0)
+ epix_error("Picture has height zero!");
+
+ the_picture().the_page = screen(P(0,0), P(horiz, vert));
+ }
+
+ void picture(const P& arg)
+ {
+ picture(arg.x1(), arg.x2());
+ }
+
+ // same syntax as for picture dimensions
+ void offset(std::string sz)
+ {
+ length hoff, voff;
+ std::string units(the_picture().the_unitlength.units());
+
+ get_lengths(sz, hoff, voff);
+
+ the_picture().the_hoffset=hoff.to(units);
+ the_picture().the_voffset=voff.to(units);
+ }
+
+ void offset(double hoff, double voff)
+ {
+ std::string u(the_picture().the_unitlength.units());
+
+ std::stringstream hbuf, vbuf;
+ hbuf << hoff << u;
+ vbuf << voff << u;
+
+ the_picture().the_hoffset = length(hbuf.str());
+ the_picture().the_voffset = length(vbuf.str());
+ }
+
+ void offset(const P& arg)
+ {
+ offset(arg.x1(), arg.x2());
+ }
+
+ void unitlength(const std::string& units)
+ {
+ the_picture().the_unitlength = length(units);
+ }
+
+
+ void begin()
+ {
+ const double mult(the_picture().the_unitlength.magnitude());
+ if (mult != 1) // someone called unitlength(); must adjust size, offsets
+ {
+ const P TR(the_picture().the_page.tr());
+ the_picture().the_page = screen(P(0,0), mult*TR);
+
+ the_picture().the_hoffset *= mult;
+ the_picture().the_voffset *= mult;
+ }
+
+ // If we've seen bounding_box or equivalent, this properly initializes.
+ // Otherwise we'll segfault momentarily... :(
+ active_screen();
+ }
+
+ void end_picture()
+ {
+ the_picture().print();
+ }
+
+ screen& canvas()
+ {
+ return the_picture().the_canvas;
+ }
+
+ void activate(screen& scr)
+ {
+ the_screen_stack().push(scr);
+ }
+
+ void deactivate(screen& scr)
+ {
+ const screen* active(the_screen_stack().pop());
+
+ if (active != &scr)
+ epix_warning("Deactivation requested for non-active screen");
+ }
+
+ // page layout
+ void import()
+ {
+ if (&(the_picture().the_canvas) != active_screen())
+ the_picture().the_canvas.paste(*active_screen());
+ }
+
+ void inset(const P& sw, const P& ne)
+ {
+ if (&(the_picture().the_canvas) != active_screen())
+ the_picture().the_canvas.paste(*active_screen(), sw, ne);
+ }
+
+
+ void import(const screen& child)
+ {
+ the_picture().the_canvas.paste(child);
+ }
+
+ void inset(const screen& child, const P& sw, const P& ne)
+ {
+ the_picture().the_canvas.paste(child, sw, ne);
+ }
+
+ void inset(const screen& child)
+ {
+ the_picture().the_canvas.paste(child, child.bl(), child.tr());
+ }
+
+ void inlay(const screen& child, const P& loc)
+ {
+ const std::string units(the_picture().the_unitlength.units());
+ const double scale(length("1pt").to(units).magnitude());
+ double H(active_screen()->h_size()/the_picture().the_page.h_size());
+ double V(active_screen()->v_size()/the_picture().the_page.v_size());
+
+ active_screen()->paste(child,
+ loc + H*scale*child.bl(),
+ loc + V*scale*child.tr());
+ }
+
+ // interpret stated coord as true pt, the other as Cartesian
+ void inlay_vertical(const screen& child, const P& loc)
+ {
+ const std::string units(the_picture().the_unitlength.units());
+ const double scale(length("1pt").to(units).magnitude());
+ double V(active_screen()->v_size()/the_picture().the_page.v_size());
+
+ active_screen()->paste(child,
+ loc + child.l() + V*scale*child.b(),
+ loc + child.r() + V*scale*child.t());
+ }
+
+ void inlay_horizontal(const screen& child, const P& loc)
+ {
+ const std::string units(the_picture().the_unitlength.units());
+ const double scale(length("1pt").to(units).magnitude());
+ double H(active_screen()->h_size()/the_picture().the_page.h_size());
+
+ active_screen()->paste(child,
+ loc + child.b() + H*scale*child.l(),
+ loc + child.t() + H*scale*child.r());
+ }
+
+ void backing(const Color& col)
+ {
+ active_screen()->backing(col);
+ }
+
+ void border(const Color& col, double len)
+ {
+ active_screen()->border(col, len);
+ }
+
+ void border(const Color& col, const std::string& len)
+ {
+ active_screen()->border(col, len);
+ }
+
+ void backing()
+ {
+ active_screen()->backing();
+ }
+
+ void border()
+ {
+ active_screen()->border();
+ }
+
+ void write(const std::string& text)
+ {
+ active_screen()->m_screen->add_tile(verbatim(text));
+ }
+
+ void pre_write(const std::string& text)
+ {
+ the_picture().pre_write(text);
+ }
+
+ void post_write(const std::string& text)
+ {
+ the_picture().post_write(text);
+ }
+
+ void eepic_format()
+ {
+ the_picture().set_format(eepic());
+ }
+
+ void tikz_format()
+ {
+ the_picture().set_format(tikz());
+ }
+
+ void pst_format()
+ {
+ the_picture().set_format(pst());
+ }
+
+
+ // write in specified format to named output file
+ void print_eepic(const std::string& filename)
+ {
+ the_picture().print_to(filename, eepic());
+ }
+
+ void print_tikz(const std::string& filename)
+ {
+ the_picture().print_to(filename, tikz());
+ }
+
+ void print_pst(const std::string& filename)
+ {
+ the_picture().print_to(filename, pst());
+ }
+
+
+ double pic_units_per_pt()
+ {
+ return length("1pt").to(the_picture().the_unitlength.units()).magnitude();
+ }
+
+ // approximate, but correct at true aspect ratio
+ double units_per_pic_unit()
+ {
+ const double H(active_screen()->h_size()/the_picture().the_page.h_size());
+ const double V(active_screen()->v_size()/the_picture().the_page.v_size());
+
+ return 0.5*(H+V);
+ }
+
+ double pt_to_screen(double arg)
+ {
+ return arg*units_per_pic_unit()*pic_units_per_pt();
+ }
+
+ // initialize deprecated globals
+ double x_min(xmin()), x_max(xmax()), x_size(xsize());
+ double y_min(ymin()), y_max(ymax()), y_size(ysize());
+
+} // end of namespace
diff --git a/graphics/epix/picture.h b/graphics/epix/picture.h
new file mode 100644
index 0000000000..38258fc02c
--- /dev/null
+++ b/graphics/epix/picture.h
@@ -0,0 +1,170 @@
+/*
+ * picture.h -- ePiX globals functions for picture interface
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.16
+ * Last Change: September 11, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PICTURE
+#define EPIX_PICTURE
+
+#include <string>
+
+namespace ePiX {
+
+ class Color;
+ class P;
+ class picture_data;
+ class screen;
+
+ // "global" references
+ picture_data& the_picture();
+
+ double& xmin();
+ double& xmax();
+ double& xsize();
+
+ double& ymin();
+ double& ymax();
+ double& ysize();
+
+ double& tix();
+
+ // preferred initialization functions
+ // corners and dimensions, e.g. "4in x 15cm" or "4 x 6in"
+ // (width units take precedence, dimension string must be passed by value)
+ void picture(const P& arg1, const P& arg2, std::string);
+
+ // same syntax as for picture dimensions
+ void offset(std::string);
+
+ //// Old global functions for manipulating the page markup region ////
+ void bounding_box(const P&, const P&);
+
+ void picture(double, double);
+ void picture(const P&);
+
+ void offset(double hoff, double voff);
+ void offset(const P& arg);
+
+ void unitlength(const std::string& units);
+
+ // activate default screen
+ void begin();
+ // write the output file
+ void end_picture();
+
+ //// New global functions ////
+ // the_picture().the_canvas
+ screen& canvas();
+
+ // specify active screen; pass non-const ref only to assign/compare pointer
+ void activate(screen&);
+ void deactivate(screen&);
+
+ // add active or specified screen to the_picture
+ void import();
+ void inset(const P& sw, const P& ne);
+
+ void import(const screen& child);
+ void inset(const screen& child, const P& sw, const P& ne);
+
+ void inset(const screen& child); // use child's corners
+
+ // interpret child's coordinates as true pt on the page,
+ // place origin at P
+ void inlay(const screen& child, const P& loc);
+
+ // interpret stated coord as true pt, the other as Cartesian
+ void inlay_vertical(const screen& child, const P& loc);
+ void inlay_horizontal(const screen& child, const P& loc);
+
+ // set decorations on active screen
+ void backing(const Color&);
+ void border(const Color&, double); // width in pt
+ void border(const Color&, const std::string&);
+
+ void backing(); // use current fill style
+ void border(); // use current line pen
+
+ // write verbatim string to output file
+ void write(const std::string&);
+
+ void pre_write(const std::string&); // before picture header
+ void post_write(const std::string&); // after picture footer
+
+ // set output format
+ void eepic_format();
+ // void mp_format();
+ void tikz_format();
+ void pst_format();
+
+ // write in specified format to named output file
+ void print_eepic(const std::string& filename);
+ // void print_mp(const std::string& filename);
+ void print_tikz(const std::string& filename);
+ void print_pst(const std::string& filename);
+
+ // allow user to override in-file format request on the command line
+ inline void end()
+ {
+#ifdef EPIX_FMT_PSTRICKS
+ pst_format();
+#else
+#ifdef EPIX_FMT_TIKZ
+ tikz_format();
+#else
+#ifdef EPIX_FMT_EEPIC
+ eepic_format();
+#endif /* EPIX_FMT_EEPIC */
+#endif /* EPIX_FMT_TIKZ */
+#endif /* EPIX_FMT_PSTRICKS */
+ end_picture();
+ }
+
+ // for implementors of true-size elements
+ double pic_units_per_pt(); // exact
+ double units_per_pic_unit(); // approximate, exact at true aspect ratio
+ double pt_to_screen(double); // true length to screen length
+
+ ////////////////////////////////////////////////////////////////
+ //// ////
+ //// DEPRECATED global variables required for backward ////
+ //// compatibility. Will be removed in a future release. ////
+ //// Use reference functions xmin() et. al. ////
+ //// ////
+ ////////////////////////////////////////////////////////////////
+
+ // bounding_box corners and dimensions
+ extern double x_min, x_max, x_size, y_min, y_max, y_size;
+
+} // end of namespace
+
+#endif /* EPIX_PICTURE */
diff --git a/graphics/epix/picture_data.cc b/graphics/epix/picture_data.cc
new file mode 100644
index 0000000000..a16c0552b8
--- /dev/null
+++ b/graphics/epix/picture_data.cc
@@ -0,0 +1,193 @@
+/*
+ * picture_data.cc -- ePiX::picture implementation class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "errors.h"
+#include "utils.h"
+#include "Color.h"
+
+#include "verbatim.h"
+
+#include "format.h"
+#include "eepic.h" // default format
+#include "picture.h"
+
+#include "screen_data.h"
+#include "picture_data.h"
+
+namespace ePiX {
+
+ picture_data::picture_data()
+ : m_format(new eepic()), m_pallet() { }
+
+
+ picture_data::picture_data(const picture_data& pd)
+ : the_unitlength(pd.the_unitlength),
+ the_hoffset(pd.the_hoffset), the_voffset(pd.the_voffset),
+ the_canvas(pd.the_canvas), the_page(pd.the_page),
+ m_format(pd.m_format->clone()), m_pallet(pd.m_pallet),
+ m_pre_writes(pd.m_pre_writes), m_post_writes(pd.m_post_writes) { }
+
+
+ picture_data& picture_data::operator= (const picture_data& pd)
+ {
+ if (this != &pd)
+ {
+ format* tmp_fmt(pd.m_format->clone());
+
+ // okay, safe to muck with our data
+ the_unitlength = pd.the_unitlength;
+ the_hoffset = pd.the_hoffset;
+ the_voffset = pd.the_voffset;
+
+ the_canvas = pd.the_canvas;
+ the_page = pd.the_page;
+
+ delete m_format;
+ m_format = tmp_fmt;
+
+ m_pallet = pd.m_pallet;
+
+ m_pre_writes = pd.m_pre_writes;
+ m_post_writes = pd.m_post_writes;
+ }
+
+ return *this;
+ } // end of copy assignment
+
+ picture_data::~picture_data()
+ {
+ delete m_format;
+ }
+
+
+ picture_data& picture_data::add_to_pallet(const Color& col)
+ {
+ if (!col.is_unset())
+ m_pallet.insert(col);
+ return *this;
+ }
+
+ void picture_data::set_format(const format& fmt)
+ {
+ m_format = fmt.clone();
+ }
+
+ void picture_data::print()
+ {
+ print_to(*m_format);
+ }
+
+ void picture_data::print_to(const format& fmt)
+ {
+ the_page.clear();
+ the_page.paste(the_canvas);
+
+ const pair offset(the_hoffset.magnitude(), the_voffset.magnitude());
+
+ std::cout << fmt.file_comments(the_unitlength.units(),
+ the_hoffset, the_voffset,
+ xmin(), xmax(), ymin(), ymax(),
+ the_page.h_size(), the_page.v_size());
+
+ for (std::list<verbatim>::const_iterator p = m_pre_writes.begin();
+ p != m_pre_writes.end(); ++p)
+ std::cout << (*p).print_to(fmt, the_unitlength.units());
+
+ // the_page.br() = (0,0), so tr() is size
+ std::cout << fmt.pic_header(the_page.tr(), offset,
+ m_pallet, the_unitlength.units())
+
+ << the_page.m_screen->print_to(fmt, the_unitlength)
+
+ << fmt.pic_footer();
+
+ for (std::list<verbatim>::const_iterator p = m_post_writes.begin();
+ p != m_post_writes.end(); ++p)
+ std::cout << (*p).print_to(fmt, the_unitlength.units());
+ }
+
+ void picture_data::print_to(const std::string& filename, const format& fmt)
+ {
+ const char* fn(filename.c_str());
+
+ std::ofstream output(fn);
+ if (!output)
+ {
+ epix_warning("Cannot open file " + filename);
+ return;
+ }
+
+ // else
+ the_page.clear();
+ the_page.paste(the_canvas);
+
+ const pair offset(the_hoffset.magnitude(), the_voffset.magnitude());
+
+ output << fmt.file_comments(the_unitlength.units(),
+ the_hoffset, the_voffset,
+ xmin(), xmax(), ymin(), ymax(),
+ the_page.h_size(), the_page.v_size());
+
+ for (std::list<verbatim>::const_iterator p = m_pre_writes.begin();
+ p != m_pre_writes.end(); ++p)
+ output << (*p).print_to(fmt, the_unitlength.units());
+
+ // the_page.br() = (0,0), so tr() is size
+ output << fmt.pic_header(the_page.tr(), offset,
+ m_pallet, the_unitlength.units())
+
+ << the_page.m_screen->print_to(fmt, the_unitlength)
+
+ << fmt.pic_footer();
+
+ for (std::list<verbatim>::const_iterator p = m_post_writes.begin();
+ p != m_post_writes.end(); ++p)
+ output << (*p).print_to(fmt, the_unitlength.units());
+
+ output.close();
+ }
+
+ void picture_data::pre_write(const std::string& text)
+ {
+ m_pre_writes.push_back(verbatim(text));
+ }
+
+ void picture_data::post_write(const std::string& text)
+ {
+ m_post_writes.push_back(verbatim(text));
+ }
+} // end of namespace
diff --git a/graphics/epix/picture_data.h b/graphics/epix/picture_data.h
new file mode 100644
index 0000000000..518dbb966b
--- /dev/null
+++ b/graphics/epix/picture_data.h
@@ -0,0 +1,113 @@
+/*
+ * picture_data.h -- ePiX::picture implementation class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * The picture_data class was designed with three primary goals:
+ *
+ * (i) Encapsulate state data formerly scattered (and inconsistently
+ * structured) through multiple files,
+ *
+ * (ii) Provide some of the flexibility of building a scene in memory
+ * instead of writing data immediately to the output,
+ *
+ * (iii) Ensure compatibility with existing syntax.
+ *
+ * A picture_data comprises two screens (canvas -- the bounding_box, and
+ * page -- the picture box), unitlength and offsets, state data
+ * (clip_box; angle units; styles for labels, painting, and arrowheads),
+ * and a set of colors so that color dclarations in the output file can
+ * be made using named colors.
+ *
+ * Dozens of global and member functions need to access and modify
+ * the_picture(). Instead of making these functions friends, our data
+ * (except for the color pallet) are public. Under the circumstances,
+ * this seemed the Path of Least Evil.
+ */
+#ifndef EPIX_PICTURE_DATA
+#define EPIX_PICTURE_DATA
+
+#include <string>
+#include <list>
+#include <set>
+
+#include "verbatim.h"
+
+#include "length.h"
+#include "Color.h"
+#include "screen.h"
+
+namespace ePiX {
+
+ class format;
+
+ class picture_data {
+ public:
+ // rely on members' default constructors
+ picture_data();
+
+ picture_data(const picture_data&);
+ picture_data& operator= (const picture_data&);
+ ~picture_data();
+
+ picture_data& add_to_pallet(const Color&);
+
+ void set_format(const format&);
+
+ // output requires knowledge of unitlength; all other ops handled by data
+ void print();
+ void print_to(const format&);
+ void print_to(const std::string& filename, const format&);
+
+ void pre_write(const std::string&);
+ void post_write(const std::string&);
+
+ //// public data (true size, offsets, and screens) ////
+ length the_unitlength;
+ length the_hoffset, the_voffset;
+
+ screen the_canvas;
+ screen the_page;
+
+
+ private:
+ format* m_format;
+ std::set<Color> m_pallet;
+ // user-specified strings to be written before/after start of picture
+ std::list<verbatim> m_pre_writes;
+ std::list<verbatim> m_post_writes;
+ }; // end of class picture_data
+
+} // end of namespace
+
+#endif /* EPIX_PICTURE_DATA */
diff --git a/graphics/epix/plane.cc b/graphics/epix/plane.cc
new file mode 100644
index 0000000000..148e81a7e0
--- /dev/null
+++ b/graphics/epix/plane.cc
@@ -0,0 +1,143 @@
+/*
+ * plane.cc -- ePiX::Plane class and mathematical operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+#include "errors.h"
+
+#include "curves.h" // for draw()
+
+#include "plane.h"
+
+namespace ePiX {
+
+ const double INF(2*EPIX_INFTY);
+
+ Plane::Plane(const P& pt, const P& perp)
+ : m_pt(pt), m_perp(perp), m_malformed(false)
+ {
+ double temp(norm(perp));
+
+ if (temp < EPIX_EPSILON)
+ {
+ epix_warning("Degenerate plane normal, using (0,0,1)");
+ m_perp=E_3;
+ }
+
+ else
+ m_perp *= 1.0/temp;
+ }
+
+ Plane::Plane(const P& p1, const P& p2, const P& p3)
+ : m_pt(p1), m_malformed(false)
+ {
+ P perp((p3-p1)*(p2-p1));
+ double norm_perp(norm(perp));
+
+ if (norm_perp < EPIX_EPSILON)
+ {
+ epix_warning("Collinear points in Plane constructor");
+ m_malformed = true;
+ }
+
+ else
+ m_perp = (1/norm_perp)*perp;
+ }
+
+
+ P Plane::pt() const
+ {
+ return m_pt;
+ }
+
+ P Plane::perp() const
+ {
+ return m_perp;
+ }
+
+ bool Plane::malformed() const
+ {
+ return m_malformed;
+ }
+
+ // translate
+ Plane& Plane::shift(const P& arg)
+ {
+ if (!m_malformed)
+ m_pt += arg;
+ return *this;
+ }
+
+ Plane& Plane::move_to(const P& arg)
+ {
+ if (!m_malformed)
+ m_pt = arg;
+ return *this;
+ }
+
+ void Plane::draw() const
+ {
+ if (m_malformed)
+ return;
+
+ // else
+ const P ctr((m_pt|m_perp)*m_perp); // closest point to origin
+
+ // construct an orthonormal basis
+ P e1(m_perp*E_1);
+
+ if (norm(e1) < 0.7) // ~sqrt(0.5)
+ e1 = m_perp*E_2;
+
+ e1 *= 1.0/norm(e1);
+ P e2(m_perp*e1);
+
+ // very large rectangle
+ quad(ctr + INF*( e1 + e2), ctr + INF*(-e1 + e2),
+ ctr + INF*(-e1 - e2), ctr + INF*( e1 - e2));
+ }
+
+
+ //// global functions ////
+ void plane(const P& point, const P& normal)
+ {
+ Plane pl(point, normal);
+ pl.draw();
+ }
+
+ void plane(const P& p1, const P& p2, const P& p3)
+ {
+ Plane pl(p1, p2, p3);
+ pl.draw();
+ }
+} // end of namespace
diff --git a/graphics/epix/plane.h b/graphics/epix/plane.h
new file mode 100644
index 0000000000..637e3e8240
--- /dev/null
+++ b/graphics/epix/plane.h
@@ -0,0 +1,74 @@
+/*
+ * plane.h -- ePiX::Plane class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.17
+ * Last Change: September 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_PLANE
+#define EPIX_PLANE
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class Circle;
+ class Plane;
+ class Segment;
+ class Sphere;
+
+ class Plane {
+ public:
+ Plane(const P& pt=P(0,0,0), const P& perp=E_3);
+ Plane(const P&, const P&, const P&);
+
+ P pt() const;
+ P perp() const;
+ bool malformed() const;
+
+ // affine operations
+ Plane& shift(const P&);
+ Plane& move_to(const P&);
+
+ void draw() const;
+
+ private:
+ P m_pt;
+ P m_perp; // unit normal
+
+ bool m_malformed;
+ }; // end of Plane class
+
+ void plane(const P& pt=P(0,0,0), const P& perp=E_3);
+ void plane(const P&, const P&, const P&);
+
+} // end of namespace
+
+#endif /* EPIX_PLANE */
diff --git a/graphics/epix/plot_algorithms.h b/graphics/epix/plot_algorithms.h
new file mode 100644
index 0000000000..3566915f09
--- /dev/null
+++ b/graphics/epix/plot_algorithms.h
@@ -0,0 +1,245 @@
+/*
+ * plot_algorithms.h -- plot function templates, for build use only
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ *
+ * Version 1.1.9
+ * Last Change: August 01, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides plotting templates, with T a class
+ *
+ * void plot_map_dom(const T&, const domain&)
+ * void plot_map_domlist(const T&, const domain_list&)
+ * void plot_function(const T&, double, double, int)
+ * void euler_plot(const T&, const P&, double, double, int)
+ * P euler_flow(const T&, P start, double, int)
+ */
+
+#ifndef EPIX_PLOT_ALGO
+#define EPIX_PLOT_ALGO
+
+#include <cmath>
+#include <list>
+
+#include "constants.h"
+
+#include "triples.h"
+#include "functions.h"
+
+#include "edge_data.h"
+
+#include "paint_style.h"
+
+#include "domain.h"
+#include "path_data.h"
+
+namespace ePiX {
+
+ typedef std::list<domain>::const_iterator dolci;
+
+ const double INF(EPIX_INFTY);
+
+ // Are args endpoints of a plottable edge?
+ static bool is_valid(const P& tail, const P& head)
+ {
+ return tail.is_valid() && head.is_valid();
+ }
+
+ template<class T> void plot_map_dom(const T& map, const domain& R)
+ {
+ // only attempt to fill if plotting a curve
+ const bool is_curve(R.dim() == 1);
+ const bool filling(is_curve && the_paint_style().fill_flag());
+
+ // max summation indices
+ unsigned int i_max((R.dx1() > 0) ? R.coarse_n1() : 0);
+ unsigned int j_max((R.dx2() > 0) ? R.coarse_n2() : 0);
+ unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0);
+
+ if (R.dx1() > 0) // there's something to draw
+ {
+ // number of intervals in subdivision
+ unsigned int count1(R.fine_n1());
+
+ const double st1(R.dx1());
+ const double st2(R.step2());
+ const double st3(R.step3());
+
+ for (unsigned int j=0; j <= j_max; ++j)
+ for (unsigned int k=0; k <= k_max; ++k)
+ {
+ std::list<edge3d> data1;
+ const P init(R.corner1() + (j*st2)*E_2 + (k*st3)*E_3);
+
+ for (unsigned int i=0; i < count1; ++i)
+ {
+ P curr(map(init + P(i*st1,0,0)));
+ P next(map(init + P((i+1)*st1,0,0)));
+ data1.push_back(edge3d(curr, next, is_valid(curr, next)));
+ }
+
+ // close path if initial and terminal points coincide
+ bool closed(is_curve &&
+ map(init) == map(init + P(count1*st1,0,0)));
+
+ path_data path1(data1, closed && filling, filling);
+ path1.draw();
+ }
+ }
+
+ if (R.dx2() > 0)
+ {
+ unsigned int count2(R.fine_n2());
+
+ const double st1(R.step1());
+ const double st2(R.dx2());
+ const double st3(R.step3());
+
+ for (unsigned int i=0; i <= i_max; ++i)
+ for (unsigned int k=0; k <= k_max; ++k)
+ {
+ std::list<edge3d> data2;
+ const P init(R.corner1() + (i*st1)*E_1 + (k*st3)*E_3);
+
+ for (unsigned int j=0; j < count2; ++j)
+ {
+ P curr(map(init + P(0,j*st2,0)));
+ P next(map(init + P(0,(j+1)*st2,0)));
+ data2.push_back(edge3d(curr, next, is_valid(curr, next)));
+ }
+
+ // close path if initial and terminal points coincide
+ bool closed(is_curve &&
+ map(init) == map(init + P(0,count2*st2,0)));
+
+ path_data path2(data2, closed && filling, filling);
+ path2.draw();
+ }
+ }
+
+ if (R.dx3() > 0)
+ {
+ unsigned int count3(R.fine_n3());
+
+ const double st1(R.step1());
+ const double st2(R.step2());
+ const double st3(R.dx3());
+
+ for (unsigned int i=0; i <= i_max; ++i)
+ for (unsigned int j=0; j <= j_max; ++j)
+ {
+ std::list<edge3d> data3;
+ const P init(R.corner1() + (i*st1)*E_1 + (j*st2)*E_2);
+
+ for (unsigned int k=0; k < count3; ++k)
+ {
+ P curr(map(init + P(0,0,k*st3)));
+ P next(map(init + P(0,0,(k+1)*st3)));
+ data3.push_back(edge3d(curr, next, is_valid(curr, next)));
+ }
+
+ // close path if initial and terminal points coincide
+ bool closed(is_curve &&
+ map(init) == map(init + P(0,0,count3*st3)));
+
+ path_data path3(data3, closed && filling, filling);
+ path3.draw();
+ }
+ }
+ }; // end of plot_map_dom
+
+ // plot over a list of domains
+ template<class T> void plot_map_domlist(const T& map, const domain_list& R)
+ {
+ for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p)
+ plot_map_dom(map, *p);
+ }
+
+ // paths
+ template<class T>void plot_function(const T& f, double t1, double t2,
+ unsigned int n)
+ {
+ plot_map_dom(f, domain(t1, t2, n));
+ }
+
+
+ // Solutions of ODE systems
+ template<class VF> void euler_plot(const VF& field, P curr,
+ double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ std::list<edge3d> data;
+
+ const double dt(t_max/(num_pts*EPIX_ITERATIONS));
+ const double dseek(t_min/(num_pts*EPIX_ITERATIONS));
+
+ if (fabs(t_min/num_pts) > EPIX_EPSILON) // seek beginning of path
+ for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i)
+ curr += dseek*field(curr);
+
+ // curr = "start, flowed by t_min"
+ P next(curr);
+
+ for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i)
+ {
+ next += dt*field(next); // Euler's method
+
+ if (i%EPIX_ITERATIONS == 0)
+ {
+ data.push_back(edge3d(curr, next, is_valid(curr, next)));
+ curr = next;
+ }
+ }
+
+ path_data temp(data, false, false);
+
+ temp.draw();
+ } // end of euler_plot
+
+
+ // flow x0 under field for specified time; pass x0 by value
+ template<class VF> P euler_flow(const VF& field, P x0,
+ double t_max, unsigned int num_pts=0)
+ {
+ if (num_pts == 0) // use "sensible" default; hardwired constant 4
+ num_pts = 4*(1 + (unsigned int)ceil(fabs(t_max)));
+
+ const double dt(t_max/(num_pts*EPIX_ITERATIONS));
+
+ for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i)
+ x0 += dt*field(x0);
+
+ return x0;
+ }
+} // end of namespace
+
+#endif /* EPIX_PLOT_ALGO */
diff --git a/graphics/epix/plots.cc b/graphics/epix/plots.cc
new file mode 100644
index 0000000000..5f619dbe40
--- /dev/null
+++ b/graphics/epix/plots.cc
@@ -0,0 +1,613 @@
+/*
+ * plots.cc: Plotting functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.0-2
+ * Last Change: September 26, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+#include "errors.h"
+
+#include "triples.h"
+#include "functions.h"
+
+#include "camera.h"
+#include "map.h"
+#include "domain.h"
+
+#include "path.h"
+
+#include "markers.h"
+#include "curves.h"
+
+#include "deriv.h"
+#include "plot_algorithms.h"
+#include "plots.h"
+
+namespace ePiX {
+
+ typedef std::list<domain>::const_iterator dolci;
+
+ // f:R -> R^3
+ void plot(P f(double), double t_min, double t_max, unsigned int num_pts)
+ {
+ plot_map_dom(path_map(f), domain(t_min, t_max, num_pts));
+ }
+
+ // f:R -> R x R x R
+ void plot(double f1(double), double f2(double), double f3(double),
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ plot_map_dom(column_1var(f1,f2,f3), domain(t_min, t_max, num_pts));
+ }
+
+ // f:R -> R
+ void plot(double f(double), double t_min, double t_max, unsigned int num_pts)
+ {
+ plot(id, f, zero, t_min, t_max, num_pts);
+ }
+
+ void plot(const Deriv& f, double t_min, double t_max, unsigned int num_pts)
+ {
+ plot_map_dom(f, domain(t_min, t_max, num_pts));
+ }
+
+ void plot(const Integral& f, double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ plot_map_dom(f, domain(t_min, t_max, num_pts));
+ }
+
+ // f: R -> R x R
+ void plot(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ plot(f1, f2, zero, t_min, t_max, num_pts);
+ }
+
+ void polarplot (double f(double), double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ plot_map_dom(column_1var(f, id, zero, cylindrical),
+ domain(t_min, t_max, num_pts));
+ }
+
+ // surfaces
+ // f:R^2 -> R x R x R
+ void plot(double f1(double u1, double u2),
+ double f2(double u1, double u2),
+ double f3(double u1, double u2),
+ const P& min, const P& max, const mesh& coarse, const mesh& fine)
+ {
+ plot_map_dom(column_2var(f1,f2,f3), domain(min, max, coarse, fine));
+ }
+
+ void plot(double f1(double u1, double u2),
+ double f2(double u1, double u2),
+ double f3(double u1, double u2),
+ const domain& R)
+ {
+ plot_map_dom(column_2var(f1,f2,f3), R);
+ }
+
+ // f:R^2 -> R
+ void plot(double f(double u1, double u2),
+ const P& p1, const P& p2, const mesh& coarse, const mesh& fine)
+ {
+ plot(proj1, proj2, f, p1, p2, coarse, fine);
+ }
+
+ // f:R^2 -> R^3
+ void plot(P f(double u1, double u2), const domain& R)
+ {
+ plot_map_dom(surface_map(f), R);
+ }
+
+ void plot(P f(double u1, double u2), const domain_list& R)
+ {
+ surface_map phi(f);
+
+ for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p)
+ plot_map_dom(phi, *p);
+ }
+
+
+ // f:R^3 -> R^3
+ void plot(P f(double, double, double), const domain& R)
+ {
+ plot_map_dom(space_map(f), R);
+ }
+
+ void plot(P f(double, double, double), const domain_list& R)
+ {
+ space_map phi(f);
+
+ for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p)
+ plot_map_dom(phi, *p);
+ }
+
+
+ // Derivatives and integrals
+ void plot_deriv(double f(double t), double a, double b,
+ unsigned int num_pts)
+ {
+ plot_function(Deriv(f), a, b, num_pts);
+ }
+
+ void plot_int(double f(double), double a, double b,
+ unsigned int num_pts)
+ {
+ plot_function(Integral(f, a), a, b, num_pts);
+ }
+
+ void plot_int(double f(double), double x0, double a, double b,
+ unsigned int num_pts)
+ {
+ plot_function(Integral(f, x0), a, b, num_pts);
+ }
+
+ // tuples of real-valued plot arguments
+ void tan_line(double f1(double t), double f2(double t), double t0)
+ {
+ Line(P(f1(t0), f2(t0)),
+ P(f1(t0), f2(t0)) + P(deriv(f1, t0), deriv(f2, t0)));
+ }
+
+ void tan_line(double f(double t), double t0)
+ {
+ Line(P(t0, f(t0)), P(t0, f(t0)) + P(1, deriv(f, t0)));
+ }
+
+ void envelope(double f1(double t), double f2(double t),
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ const double step((t_max - t_min)/num_pts);
+ double t(t_min);
+
+ for (unsigned int i=0; i <= num_pts; ++i, t += step)
+ Line(P(f1(t), f2(t)),
+ P(f1(t), f2(t)) + P(deriv(f1, t), deriv(f2, t)));
+ }
+
+ void envelope(double f(double t), double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ const double step((t_max - t_min)/num_pts);
+ double t(t_min);
+
+ for (unsigned int i=0; i <= num_pts; ++i, t += step)
+ Line(P(t, f(t)), P(t, f(t)) + P(1, deriv(f, t)));
+ }
+
+ // P-valued plot argument
+ void tan_line(P f(double t), double t0)
+ {
+ Line(f(t0), f(t0) + deriv(f, t0));
+ }
+
+ void envelope(P f(double t), double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ const double step((t_max - t_min)/num_pts);
+ double t(t_min);
+
+ for (unsigned int i=0; i <= num_pts; ++i, t += step)
+ Line(f(t), f(t) + deriv(f, t));
+ }
+
+ // Tangent field along parametrized path
+ void tan_field(double f1(double), double f2(double), double t_min,
+ double t_max, unsigned int num_pts)
+ {
+ const double step((t_max - t_min)/num_pts);
+ double t(t_min);
+
+ for (unsigned int i=0; i <= num_pts; ++i, t += step)
+ arrow(P(f1(t), f2(t)), P(f1(t), f2(t)) +
+ step*P(deriv(f1, t), deriv(f2, t)));
+ }
+
+ // P-valued plot argument
+ void tan_field(P f(double), double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ const double step((t_max - t_min)/num_pts);
+ double t(t_min);
+
+ for (unsigned int i=0; i <= num_pts; ++i, t += step)
+ arrow(f(t), f(t) + step*deriv(f, t));
+ }
+
+ // Slope, dart, and vector fields
+
+ // utility functions
+ // vector, dart, and slope fields
+ void field_element(const P& tail, const P& head, epix_field_type TYPE,
+ double head_scale=1.0)
+ {
+ switch(TYPE) {
+
+ case VECTOR:
+ arrow(tail, head, head_scale);
+ break;
+
+ case DART:
+ dart(tail, head);
+ break;
+
+ case SLOPE:
+ line(tail, head, 0, 1);
+ break;
+
+ default:
+ ; // do nothing
+ } // end of switch(TYPE)
+ } // end of field_element
+
+
+ void draw_field(P F(double, double, double), P p, P q,
+ unsigned int n1, unsigned int n2,
+ epix_field_type TYPE, double scale)
+ {
+ P diagonal(q-p);
+ int perp_count(0);
+ P jump1, jump2;
+
+ if (fabs(diagonal|E_1) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_2&diagonal;
+ jump2 = E_3&diagonal;
+
+ }
+ if (fabs(diagonal|E_2) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_3&diagonal;
+ jump2 = E_1&diagonal;
+ }
+ if (fabs(diagonal|E_3) < EPIX_EPSILON)
+ {
+ ++perp_count;
+ jump1 = E_1&diagonal;
+ jump2 = E_2&diagonal;
+ }
+
+ if (perp_count == 0)
+ {
+ epix_warning("Projecting corners of vector field plot");
+ jump1 = E_1&diagonal;
+ jump2 = E_2&diagonal;
+ p %= E_3; // project corners to (x1, x2)-plane
+ q %= E_3;
+ }
+
+ // grid line spacing
+ jump1 *= 1.0/n1;
+ jump2 *= 1.0/n2;
+
+ const double d1(norm(jump1));
+ const double d2(norm(jump2));
+
+ for (unsigned int i=0; i <= n1; ++i)
+ for (unsigned int j=0; j <= n2; ++j)
+ {
+ P base(p + (i*jump1 + j*jump2));
+ P vect(F(base.x1(), base.x2(), base.x3()));
+
+ if (norm(camera(base+vect) - camera(base)) < EPIX_EPSILON)
+ marker(base, BBOX);
+
+ else if (TYPE == VECTOR)
+ field_element(base, base + vect, VECTOR, scale);
+
+ else
+ {
+ // N.B. May not work if page export bolloxes aspect ratio
+ double object_len(norm(camera(base+vect)-camera(base)));
+ pair dX(pair(d1, d2));
+
+ // Hardwired constant 0.4: Segment 80% of shorter grid length
+ double minimum((dX.x1() > dX.x2()) ? 0.4*dX.x2() : 0.4*dX.x1());
+
+ if ( object_len > EPIX_EPSILON) // not projected to zero
+ vect *= minimum/object_len;
+
+ // scale affects length of element, not head size
+ field_element(base - scale*vect, base + scale*vect, TYPE);
+ }
+ }
+ } // end of draw_field F(x, y, z)
+
+
+ void draw_field(P F(double, double), P p, P q,
+ unsigned int n1, unsigned int n2,
+ epix_field_type TYPE, double scale)
+ {
+ P diagonal(q-p);
+ P jump1(E_1&diagonal);
+ P jump2(E_2&diagonal);
+ p %= E_3; // project corners to (x1, x2)-plane
+ q %= E_3;
+
+ // grid line spacing
+ jump1 *= 1.0/n1;
+ jump2 *= 1.0/n2;
+
+ const double d1(norm(jump1));
+ const double d2(norm(jump2));
+
+ for (unsigned int i=0; i <= n1; ++i)
+ for (unsigned int j=0; j <= n2; ++j)
+ {
+ P base(p + (i*jump1 + j*jump2));
+ P vect(F(base.x1(), base.x2()));
+
+ if (norm(camera(base+vect) - camera(base)) < EPIX_EPSILON)
+ marker(base, BBOX);
+
+ // scale affects head size
+ else if (TYPE == VECTOR)
+ field_element(base, base + vect, VECTOR, scale);
+
+ else
+ {
+ // see caution above
+ double object_len(norm(camera(base+vect)-camera(base)));
+ pair dX(pair(d1, d2));
+ // Hardwired constant 0.4: Segment 80% of shorter grid length
+ double minimum((dX.x1() > dX.x2()) ? 0.4*dX.x2() : 0.4*dX.x1());
+ if ( object_len > EPIX_EPSILON) // not projected to zero
+ vect *= minimum/object_len;
+
+ // scale affects length of element, not head size
+ field_element(base - scale*vect, base + scale*vect, TYPE);
+ }
+ }
+ } // end of draw_field F(x, y)
+
+
+ // planar fields
+ void slope_field(P F(double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, SLOPE, scale);
+ }
+
+ void dart_field(P F(double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, DART, scale);
+ }
+
+ void vector_field(P F(double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, VECTOR, scale);
+ }
+
+ void slope_field(P F(double, double), const domain& R, double scale)
+ {
+ draw_field(F, R.corner1(), R.corner2(),
+ R.coarse_n1(), R.coarse_n2(),
+ SLOPE, scale);
+ }
+
+ void dart_field(P F(double, double), const domain& R, double scale)
+ {
+ draw_field(F, R.corner1(), R.corner2(),
+ R.coarse_n1(), R.coarse_n2(),
+ DART, scale);
+ }
+
+ void vector_field(P F(double, double), const domain& R, double scale)
+ {
+ draw_field(F, R.corner1(), R.corner2(),
+ R.coarse_n1(), R.coarse_n2(),
+ VECTOR, scale);
+ }
+
+ // spatial fields
+ void slope_field(P F(double, double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, SLOPE, scale);
+ }
+
+ void dart_field(P F(double, double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, DART, scale);
+ }
+
+ void vector_field(P F(double, double, double), const P& p, const P& q,
+ unsigned int n1, unsigned int n2, double scale)
+ {
+ draw_field(F, p, q, n1, n2, VECTOR, scale);
+ }
+
+ // spatial fields over a domain
+ void slope_field(P F(double, double, double), const domain& R,
+ double scale)
+ {
+ P p(R.corner1()), q(R.corner2());
+ double height(q.x3() - p.x3());
+ q -= height*E_3; // p.x3() == q.x3()
+
+ // horizontal/vertical subdivisions
+ unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2());
+ unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0);
+ for (unsigned int k = 0; k <= k_max; ++k)
+ draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3,
+ i_max, j_max, SLOPE, scale);
+ }
+
+ void dart_field(P F(double, double, double), const domain& R,
+ double scale)
+ {
+ P p(R.corner1()), q(R.corner2());
+ double height(q.x3() - p.x3());
+ q -= height*E_3; // p.x3() == q.x3()
+
+ unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2());
+ unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0);
+
+ for (unsigned int k = 0; k <= k_max; ++k)
+ draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3,
+ i_max, j_max, DART, scale);
+ }
+
+ void vector_field(P F(double, double, double), const domain& R,
+ double scale)
+ {
+ P p(R.corner1()), q(R.corner2());
+ double height(q.x3() - p.x3());
+ q -= height*E_3; // p.x3() == q.x3()
+
+ unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2());
+ unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0);
+
+ for (unsigned int k = 0; k <= k_max; ++k)
+ draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3,
+ i_max, j_max, VECTOR, scale);
+ }
+
+ // Solutions of ODE systems
+ // start at time 0
+ void ode_plot (P F(double, double), const P& start,
+ double t_max, unsigned int n)
+ {
+ euler_plot(surface_map(F), start, 0, t_max, n);
+ }
+
+ void ode_plot (P F(double, double, double), const P& start,
+ double t_max, unsigned int num_pts)
+ {
+ euler_plot(space_map(F), start, 0, t_max, num_pts);
+ }
+
+ // arbitrary start time
+ void ode_plot (P F(double, double), const P& start,
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ euler_plot(surface_map(F), start, t_min, t_max, num_pts);
+ }
+
+ void ode_plot (P F(double, double, double), const P& start,
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ euler_plot(space_map(F), start, t_min, t_max, num_pts);
+ }
+
+
+ // flow x0 under field for specified time
+ P flow (P F(double, double), const P& start, double t_max,
+ unsigned int n)
+ {
+ return euler_flow(surface_map(F), start, t_max, n);
+ }
+
+ P flow (P F(double, double, double), const P& start, double t_max,
+ unsigned int n)
+ {
+ return euler_flow(space_map(F), start, t_max, n);
+ }
+
+
+ void riemann_sum(double f(double), double a, double b,
+ unsigned int n, epix_integral_type TYPE)
+ {
+ const double dx((b-a)/n);
+
+ for (unsigned int i=0; i < n; ++i)
+ {
+ double x(a + i*dx);
+
+ switch (TYPE) {
+
+ case LEFT:
+ rect(P(x, f(x)), P(x+dx,0));
+ break;
+
+ case RIGHT:
+ rect(P(x, 0), P(x+dx, f(x+dx)));
+ break;
+
+ case UPPER:
+ rect(P(x, 0), P(x+dx, sup(f, x, x+dx)));
+ break;
+
+ case LOWER:
+ rect(P(x, 0), P(x+dx, inf(f, x, x+dx)));
+ break;
+
+ case TRAP:
+ quad(P(x, 0), P(x+dx, 0), P(x+dx, f(x+dx)), P(x, f(x)));
+ break;
+
+ case MIDPT:
+ rect(P(x, 0), P(x+dx, f(x+0.5*dx)));
+ break;
+
+ default:
+ ;
+
+ } // end of switch(TYPE)
+ }
+ } // end of riemann_sum()
+
+
+ // Jay Belanger's shaded plotting functions -- December 1, 2002
+ // Re-implemented using paths, July 16, 2004
+ // " for Version 1.2, June 2007
+ void shadeplot(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int num_pts)
+ {
+ // build contour
+ path boundary(f1, t_min, t_max, num_pts);
+ path graph2(f2, t_min, t_max, num_pts);
+
+ path right_edge(P(t_max, f1(t_max)), P(t_max, f2(t_max)));
+ path left_edge(P(t_min, f2(t_min)), P(t_min, f1(t_min)));
+
+ boundary += right_edge;
+ boundary -= graph2;
+ boundary += left_edge;
+
+ boundary.close().fill();
+ boundary.draw();
+ } // end of shadeplot
+
+ void shadeplot(double f(double), double t_min, double t_max,
+ unsigned int num_pts)
+ {
+ shadeplot(f, zero, t_min, t_max, num_pts);
+ }
+} // end of namespace
diff --git a/graphics/epix/plots.h b/graphics/epix/plots.h
new file mode 100644
index 0000000000..05069c838b
--- /dev/null
+++ b/graphics/epix/plots.h
@@ -0,0 +1,206 @@
+/*
+ * plots.h -- parametrized plotting algorithms
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ *
+ * Version 1.0.23
+ * Last Change: January 13, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_PLOTS
+#define EPIX_PLOTS
+
+#include "enums.h"
+
+namespace ePiX {
+
+ class domain;
+ class domain_list;
+ class Deriv;
+ class Integral;
+ class P;
+
+ //// paths ////
+ // f:R -> R^3
+ void plot (P f(double), double t_min, double t_max, unsigned int n);
+
+ // f:R -> R x R x R
+ void plot (double f1(double), double f2(double), double f3(double),
+ double t_min, double t_max, unsigned int n);
+
+ // f:R -> R
+ void plot (double f(double), double t_min, double t_max, unsigned int n);
+ void plot (const Deriv&, double t_min, double t_max, unsigned int n);
+ void plot (const Integral&, double t_min, double t_max, unsigned int n);
+
+ // f: R -> R x R
+ void plot (double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int n);
+
+ void polarplot (double f(double), double t_min, double t_max, unsigned int);
+
+ //// surfaces ////
+ // f:R^2 -> R x R x R
+ void plot(double f1(double u1, double u2),
+ double f2(double u1, double u2),
+ double f3(double u1, double u2),
+ const P& min, const P& max, const mesh& coarse, const mesh& fine);
+
+ void plot(double f1(double u1, double u2),
+ double f2(double u1, double u2),
+ double f3(double u1, double u2),
+ const domain& R);
+
+ // f:R^2 -> R
+ void plot(double f(double u1, double u2),
+ const P& p1, const P& p2, const mesh& coarse, const mesh& fine);
+
+ // f:R^2 -> R^3
+ void plot(P f(double, double), const domain&);
+ void plot(P f(double, double), const domain_list&);
+
+ // f:R^3 -> R^3
+ void plot(P f(double, double, double), const domain&);
+ void plot(P f(double, double, double), const domain_list&);
+
+
+ // Derivatives and integrals
+ void plot_deriv(double f(double), double a, double b, unsigned int n);
+
+ void plot_int(double f(double), double a, double b, unsigned int n);
+
+ void plot_int(double f(double), double x0, double a, double b, unsigned int);
+
+ void tan_line(double f1(double), double f2(double), double t0);
+ void tan_line(double f(double), double t0);
+ void tan_line(P f(double), double t0);
+
+ void envelope(double f1(double), double f2(double),
+ double, double, unsigned int);
+ void envelope(double f(double), double, double, unsigned int);
+ void envelope(P f(double), double, double, unsigned int);
+
+ void tan_field(double f1(double), double f2(double), double, double,
+ unsigned int);
+ void tan_field(P f(double), double, double, unsigned int);
+
+
+ // Slope, dart, and vector fields
+ // For slope and dart fields, the optional scale argument affects the
+ // (constant) drawn length of field elements. For vector fields, elements
+ // are drawn at true length, and "scale" affects the arrowhead size.
+
+ // planar fields
+ void slope_field(P F(double, double), const P& p, const P& q,
+ unsigned int, unsigned int, double scale=1.0);
+ void dart_field(P F(double, double), const P& p, const P& q,
+ unsigned int, unsigned int, double scale=1.0);
+ void vector_field(P F(double, double), const P& p, const P& q,
+ unsigned int, unsigned int, double scale=1.0);
+
+ void slope_field(P F(double, double), const domain& R,
+ double scale=1.0);
+ void dart_field(P F(double, double), const domain& R,
+ double scale=1.0);
+ void vector_field(P F(double, double), const domain& R,
+ double scale=1.0);
+
+ // spatial fields
+ void slope_field(P F(double, double, double), const P&, const P&,
+ unsigned int, unsigned int, double scale=1.0);
+ void dart_field(P F(double, double, double), const P&, const P&,
+ unsigned int, unsigned int, double scale=1.0);
+ void vector_field(P F(double, double, double), const P&, const P&,
+ unsigned int, unsigned int, double scale=1.0);
+
+ // spatial fields over a (3-D) domain
+ void slope_field(P F(double, double, double), const domain&,
+ double scale=1.0);
+ void dart_field(P F(double, double, double), const domain&,
+ double scale=1.0);
+ void vector_field(P F(double, double, double), const domain&,
+ double scale=1.0);
+
+
+ // Solutions of ODE systems
+
+ // start at time 0
+ void ode_plot (P F(double, double),
+ const P& start, double t_max, unsigned int);
+
+ void ode_plot (P F(double, double, double),
+ const P& start, double t_max, unsigned int);
+
+ // arbitrary start time
+ void ode_plot (P F(double, double),
+ const P& start, double t_min, double t_max, unsigned int);
+
+ void ode_plot (P F(double, double, double),
+ const P& start, double t_min, double t_max, unsigned int);
+
+ // flow x0 under field for specified time
+ P flow (P F(double, double), const P& start, double t_max, unsigned int n=0);
+ P flow (P F(double, double, double),
+ const P& start, double t_max, unsigned int n = 0);
+
+ void riemann_sum(double f(double), double a, double b,
+ unsigned int n, epix_integral_type TYPE);
+
+
+ // Jay Belanger's shaded plot functions -- December 1, 2002
+ void shadeplot(double f1(double), double f2(double), double, double,
+ unsigned int);
+ void shadeplot(double f(double), double t_min, double t_max, unsigned int);
+
+ void blackplot(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int);
+
+ void blackplot(double f(double), double t_min, double t_max, unsigned int);
+
+ void whiteplot(double f1(double), double f2(double),
+ double t_min, double t_max, unsigned int);
+
+ void whiteplot(double f(double), double t_min, double t_max, unsigned int);
+
+
+ // wiremesh surface plotting
+ void plot(P Phi(double, double),
+ const P&, const P&, const mesh& N, const mesh& num_pts);
+
+ /*
+ void clipplot(P Phi(double, double),
+ const P&, const P&, const mesh& N, const mesh& num_pts);
+
+ void cropplot(P Phi(double, double),
+ const P&, const P&, const mesh& N, const mesh& num_pts);
+ */
+
+} // end of namespace
+
+#endif /* EPIX_PLOTS */
diff --git a/graphics/epix/pst.cc b/graphics/epix/pst.cc
new file mode 100644
index 0000000000..c10c6ec08b
--- /dev/null
+++ b/graphics/epix/pst.cc
@@ -0,0 +1,359 @@
+/*
+ * pst.cc -- ePiX's pstricks output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.20
+ * Last Change: September 19, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+
+#include <string>
+#include <sstream>
+
+#include <set>
+
+#include "constants.h"
+
+#include "functions.h"
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "Color.h"
+
+#include "path_style.h"
+#include "pen_data.h"
+
+#include "format.h"
+#include "pst.h"
+
+namespace ePiX {
+
+ pst::pst()
+ : m_fill(Neutral()), m_line(Black()), m_base(Neutral()),
+ m_lwidth(PLAIN_WIDTH), m_bwidth("0pt") { }
+
+ pst* pst::clone() const
+ {
+ return new pst(*this);
+ }
+
+ std::string pst::print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fc,
+ const pen_data& line,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ // compute attribute string
+ std::string attribs("[fillstyle=");
+
+ if (fc.is_unset())
+ attribs += "none";
+ else
+ attribs += "solid";
+
+ attribs += "]";
+
+ obuf << set_fill_state(fc) << set_pen_state(line); // side effects
+ obuf << print_paths(edges, offset, attribs, len);
+
+ return obuf.str();
+ }
+
+
+ std::string pst::print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line,
+ const pen_data& base,
+ const path_state& style,
+ const std::string& len) const
+ {
+ std::stringstream value, obuf;
+
+ obuf << set_pen_state(line);
+
+ // update base
+ m_base = base.color();
+ m_bwidth = base.width();
+
+ std::string attribs;
+
+ // Generate string to pass as third argument to print_paths if need border
+ if (m_lwidth < m_bwidth && !m_base.is_unset())
+ {
+ length tmp_b(m_bwidth), tmp_l(m_lwidth);
+ tmp_b += (tmp_l *= -1);
+ tmp_b *= 0.5;
+
+ std::stringstream bordbuf;
+ bordbuf << "[border=" << print(tmp_b)
+ << ",bordercolor=" << m_base.name() << "]";
+
+ attribs = bordbuf.str();
+ }
+
+ if (style.is_solid())
+ obuf << print_paths(edges, offset, attribs, len);
+
+ else // not solid
+ {
+ // Use base to draw solid underlayer, line to draw top layer.
+ // Attempt to adjust PST pen alignment; m_bwidth too large.
+ if (m_lwidth < m_bwidth && !base.color().is_unset())
+ obuf << set_pen_state(pen_data(base.color(),
+ 0.5*(m_bwidth + m_lwidth)))
+ << print_paths(edges, offset, attribs, len);
+
+ obuf << format::print_line(edges, offset, line, style, "", len);
+ }
+
+ return obuf.str();
+ }
+
+
+ std::string pst::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3) const
+ {
+ // PSTricks declaration
+ std::stringstream obuf;
+ obuf << "\\new" << model;
+ if (model == "cmy")
+ obuf << "k";
+
+ obuf << "color{" << name << "}";
+
+ if (model == "cmy")
+ {
+ double bk(min(min(d1,d2),d3));
+
+ obuf << "{"
+ << d1-bk << " " << d2-bk << " " << d3-bk << " " << bk
+ << "}%" << std::endl;
+ }
+
+ else
+ obuf << "{"
+ << d1 << " " << d2 << " " << d3
+ << "}%" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string pst::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3, double d4) const
+ {
+ // model presumably "cmyk"
+ std::stringstream obuf;
+ obuf << "\\newcmykcolor{" << name << "}{"
+ << d1 << " " << d2 << " " << d3 << " " << d4 << "}%"
+ << std::endl;
+
+ return obuf.str();
+ }
+
+
+ std::string pst::print_comment(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << "%% " << msg << std::endl;
+
+ return obuf.str();
+ }
+
+ // verbatim text, %-protected newline
+ std::string pst::print_verbatim(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << msg << "%" << std::endl;
+
+ return obuf.str();
+ }
+
+ void pst::reset_state() const
+ {
+ m_fill = Neutral();
+ m_line = Neutral();
+ m_base = Neutral();
+
+ m_lwidth = length(0);
+ m_bwidth = length(0);
+ }
+
+
+ //// private member functions ////
+ std::string pst::start_picture(const pair& sz, const pair& offset) const
+ {
+ std::stringstream obuf;
+ obuf << "\\begin{pspicture}"
+ << format::print(sz) << format::print(-offset) << "%" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string pst::end_picture() const
+ {
+ std::stringstream obuf;
+ obuf << "\\end{pspicture}%" << std::endl;
+ return obuf.str();
+ }
+
+ std::string pst::set_unitlength(const std::string& len) const
+ {
+ std::stringstream obuf;
+
+ obuf << "\\psset{unit=1" << len
+ << ",linewidth=" << print(length(PLAIN_WIDTH)) << "}%"
+ << std::endl;
+
+ return obuf.str();
+ }
+
+
+ std::string pst::usepackages() const
+ {
+ return "usepackages pstricks";
+ }
+
+ std::string pst::start_open_path(const std::string& attribs) const
+ {
+ return "\\psline" + attribs;
+ }
+
+ std::string pst::end_open_path(const std::string& attribs) const
+ {
+ std::stringstream obuf;
+ obuf << std::endl;
+ return obuf.str();
+ }
+
+ std::string pst::start_closed_path(const std::string& attribs) const
+ {
+ return "\\pspolygon" + attribs;
+ }
+
+ std::string pst::end_closed_path(const std::string& attribs) const
+ {
+ std::stringstream obuf;
+ obuf << std::endl;
+ return obuf.str();
+ }
+
+ std::string pst::set_fill_state(const Color& col) const
+ {
+ if (m_fill == col)
+ return "";
+
+ // else
+ m_fill = col;
+
+ std::stringstream obuf;
+ obuf << "\\psset{";
+
+ // filled paths set fillstyle
+ if (m_fill.is_unset())
+ obuf << "fillstyle=none";
+
+ else
+ obuf << "fillcolor=" << m_fill.name();
+
+ obuf << "}%" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string pst::set_pen_state(const pen_data& pen) const
+ {
+ std::stringstream obuf;
+
+ if (pen.color().is_unset())
+ {
+ m_lwidth=length(0);
+ return "\\psset{linewidth=0pt}";
+ }
+
+ // else
+ bool change_width(m_lwidth != pen.width());
+ bool change_color(m_line != pen.color());
+
+ if (change_width || change_color)
+ {
+ obuf << "\\psset{";
+
+ if (change_width)
+ {
+ m_lwidth = pen.width();
+ obuf << "linewidth=" << m_lwidth.name();
+
+ if (change_color) // both true, need separator
+ obuf << ",";
+ }
+
+ if (change_color)
+ {
+ m_line = pen.color();
+ obuf << "linecolor=" << m_line.name();
+ }
+
+ obuf << "}%" << std::endl;
+ }
+
+ return obuf.str();
+ }
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string pst::put_box(const pair& loc, const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << "\\rput" << print(loc) << "{" << msg << "}" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string pst::print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+ obuf << "\\pscircle";
+
+ if (fill)
+ obuf << "*";
+
+ obuf << "[linecolor=" << print(color) << "]" << print(here)
+ << "{" << 0.5*diam << "}%" << std::endl;
+
+ return obuf.str();
+ }
+} // end of namespace
diff --git a/graphics/epix/pst.h b/graphics/epix/pst.h
new file mode 100644
index 0000000000..342bce9573
--- /dev/null
+++ b/graphics/epix/pst.h
@@ -0,0 +1,124 @@
+/*
+ * pst.h -- ePiX's pstricks output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 07, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_PST
+#define EPIX_PST
+
+#include <string>
+#include <list>
+#include <set>
+
+#include "Color.h"
+#include "length.h"
+
+#include "edge_data.h"
+#include "format.h"
+
+namespace ePiX {
+
+ class path_state;
+ class pen_data;
+
+ class pst : public format {
+ public:
+ pst();
+
+ pst* clone() const;
+
+ std::string print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const;
+
+ std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line,
+ const pen_data& base,
+ const path_state& style,
+ const std::string& len) const;
+
+
+ // model, name, densities
+ std::string print_color(const std::string&, const std::string&,
+ double, double,
+ double) const;
+
+ std::string print_color(const std::string&, const std::string&,
+ double, double,
+ double, double) const;
+
+
+ // output file comment
+ std::string print_comment(const std::string&) const;
+
+ std::string print_verbatim(const std::string&) const;
+
+ void reset_state() const;
+
+ private:
+ mutable Color m_fill;
+ mutable Color m_line;
+ mutable Color m_base;
+
+ mutable length m_lwidth;
+ mutable length m_bwidth;
+
+ // start, end pspicture, set unit and default linewidth
+ std::string start_picture(const pair&, const pair&) const;
+ std::string end_picture() const;
+
+ std::string set_unitlength(const std::string& len) const;
+
+ std::string usepackages() const;
+
+ // string argument for passing attributes local to this path/loop
+ std::string start_open_path(const std::string&) const;
+ std::string end_open_path(const std::string&) const;
+
+ std::string start_closed_path(const std::string&) const;
+ std::string end_closed_path(const std::string&) const;
+
+ // print declarations to set state of output format
+ std::string set_fill_state(const Color&) const;
+ std::string set_pen_state(const pen_data&) const;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string put_box(const pair&, const std::string&) const;
+
+ std::string print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const;
+ }; // end of class pst
+} // end of namespace
+
+#endif /* EPIX_PST */
diff --git a/graphics/epix/samples/Makefile.am b/graphics/epix/samples/Makefile.am
new file mode 100644
index 0000000000..46aea1a065
--- /dev/null
+++ b/graphics/epix/samples/Makefile.am
@@ -0,0 +1,20 @@
+# Makefile.am for ePiX v1.x "samples" directory
+#
+
+XPS := $(wildcard *.xp)
+FLX := $(wildcard *.flx)
+
+CLEANFILES = *~ *.eepic *.eps sample_src.tar sample_src.tar.gz sample-stamp
+
+## Targets ##
+doc_DATA = sample_src.tar.gz
+
+
+# tar up tex, xp, and eepic files
+sample-stamp: $(XPS) $(FLX)
+ touch sample-stamp
+
+sample_src.tar.gz: sample-stamp
+ tar -cf sample_src.tar $(XPS) $(FLX) \
+ README binom.cc lighting.h std_F.cc std_F.h
+ gzip -9 sample_src.tar
diff --git a/graphics/epix/samples/Makefile.in b/graphics/epix/samples/Makefile.in
new file mode 100644
index 0000000000..759cd4259f
--- /dev/null
+++ b/graphics/epix/samples/Makefile.in
@@ -0,0 +1,340 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for ePiX v1.x "samples" directory
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = samples
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(docdir)"
+docDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASH_PATH = @BASH_PATH@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@
+ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RUNTIME_COMPILER = @RUNTIME_COMPILER@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+XPS := $(wildcard *.xp)
+FLX := $(wildcard *.flx)
+CLEANFILES = *~ *.eepic *.eps sample_src.tar sample_src.tar.gz sample-stamp
+doc_DATA = sample_src.tar.gz
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu samples/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu samples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+uninstall-info-am:
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(docdir)" || $(mkdir_p) "$(DESTDIR)$(docdir)"
+ @list='$(doc_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
+ $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(doc_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(docdir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(docdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-docDATA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-docDATA uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-docDATA install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-docDATA \
+ uninstall-info-am
+
+
+# tar up tex, xp, and eepic files
+sample-stamp: $(XPS) $(FLX)
+ touch sample-stamp
+
+sample_src.tar.gz: sample-stamp
+ tar -cf sample_src.tar $(XPS) $(FLX) \
+ README binom.cc lighting.h std_F.cc std_F.h
+ gzip -9 sample_src.tar
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/graphics/epix/samples/README b/graphics/epix/samples/README
new file mode 100644
index 0000000000..b51bd10d3c
--- /dev/null
+++ b/graphics/epix/samples/README
@@ -0,0 +1,258 @@
+ePiX -- samples/README
+
+Last Change: September 22, 2007
+
+This directory contains sample files. Files with extension ".flx" may
+be compiled like xp files with epix or elaps, or converted to gif or
+mng animations with flix.
+
+
+artifacts.xp
+ Interaction between coarse and fine meshes in shade surface plotting.
+
+binom.cc:
+ Generates pseudo-random data for histogram.xp
+
+bowl.xp:
+ Quasi-realistic colored surface shading.
+
+butterfly.xp:
+ A Thom catastrophe graph.
+
+calculus.xp:
+ Plotting derivatives and definite integrals.
+
+clipping.xp:
+ Clipping, shaded surfaces, and fake transparency.
+
+color_sep.xp:
+ Color separation.
+
+conic.xp:
+ Envelopes and tangent lines; projective equivalence of a parabola
+ with a circle.
+
+contour.xp:
+ Building a path from sub-paths.
+
+coord_tricks.xp:
+ Using page layout to achieve broken axes.
+
+cropplot.xp
+ Graphing functions with singularities.
+
+cube.flx:
+ Stereoscopic (3-D glasses) movie of a rotating cube.
+
+dataplot.xp:
+ Scatter plots, histograms, and page layout.
+
+decorate.xp:
+ Decorated shaded surface (see file for compiling).
+
+demoivre.xp:
+ Loops; a geometric proof of deMoivre's formula.
+
+densityplot.xp:
+ A gray-shaded interference pattern.
+
+dipole.xp:
+ Plotting flow lines and isobars.
+
+denom.xp:
+ Loops and gcd; Thomae's function with discontinuity set Q.
+
+extract.xp:
+ A magnified inset using screen::extract; an unexpected tangent line.
+
+geomsum.xp:
+ Loops and color filling.
+
+golden_rect.xp:
+ Simple use of variables; constructing a golden rectangle.
+
+helicoid.flx:
+ Isometric deformation of a catenoid to a helicoid.
+
+hello.xp:
+ My First Figure, from the manual.
+
+histogram.xp:
+ Histograms of simulated coin tosses (data from binom.cc).
+
+house.flx:
+ Color semantics; sun setting on a simple house.
+
+hyperboloid.xp:
+ Clipping, shaded surfaces; two families of rulings on a hyperboloid.
+
+inverse.xp:
+ Screen affine operations; inverse functions.
+
+koch.xp:
+ The von Koch snowflake fractal.
+
+label_debug.xp:
+ Format debugging tests for labels, draws 32 attribute combinations.
+
+layout2.xp:
+ Page layout; flow lines of a planar vector field.
+
+layout.xp:
+ Page layout; six views of the square root Riemann surface.
+
+legend.xp:
+ Axes and legends; Taylor polynomials of sin x.
+
+levelset.xp:
+ Clipping and plotting; manual level curves on a saddle.
+
+levelset2.xp:
+ "Advanced" clipping; level bands on a monkey saddle.
+
+levelset3.xp:
+ Clipping and legends; flat-shaded level bands wth matching legend.
+
+lissajous.xp:
+ A Lissajous figure with arrows.
+
+lighting.h: Classes for lighting effects and color-shaded surfaces.
+ (lighting.flx illustrates use.)
+
+line_debug.xp:
+ Format debugging tests for paths, draws 32 attribute combinations.
+
+log.xp:
+ Object hiding with paths and surfaces; the Riemann surface of log.
+
+lorenz.xp:
+ Page layout, ode_plot; the Lorenz attractor and its 3-D vector field.
+
+medians.xp:
+ Euclidean geometry; medians and altitudes of a triangle.
+
+minkowski.xp:
+ A longitudinal slice of Minkowski space R^{2,1}.
+
+mirrorball.flx:
+ The circle class and intersections; 3-D stereographic movie.
+
+newton.xp:
+ Loops; root location by Newton's method.
+
+objects.xp:
+ Simple geometric objects; 2-D landscape.
+
+oscillator.xp:
+ Graphing, user-defined elements, and page layout.
+
+parabola.xp:
+ A basic plot.
+
+pascal.xp:
+ Intersection operators; Pascal's theorem in projective geometry.
+
+pendulum.flx:
+ Phase diagram of an undamped pendulum.
+
+planes.xp:
+ Manipulating objects, clipping; a stack of plane sections of a cube.
+
+plotting2.xp:
+ Surface plotting in PSTricks; from the manual.
+
+plotting3.xp:
+ Loops and color control; from the manual.
+
+plotting.xp:
+ A basic plot; from the manual.
+
+polar.xp:
+ Polar plotting.
+
+pole.xp:
+ Clipping a plot; the real part of a first-order pole.
+
+polyhedra.xp:
+ Spherical regular polyhedra. Compilation controlled with
+ pre-processor flags, e.g., "epix -DCOLOR -DDODECA polyhedra.xp".
+
+R_demo.xp:
+ Gaussians from the R demo.
+
+riemann.flx:
+ Rotating the Riemann surface of sqrt(z) in R^4.
+
+S2_harmonics.xp:
+ Domain-dependent surface shading (color function depends on two
+ variables), page layout; the spherical harmonic Y_3^0. (Compile with
+ "epix -DY20 S2_harmonics.xp" for Y_2^0.)
+
+saddle.xp:
+ A quadratic saddle using "surface" capabilities.
+
+semicirc.xp:
+ A simple figure using variables and a function for organization.
+
+shadeplot.xp:
+ Shading regions enclosed by graphs; the fundamental theorem of calculus.
+
+slopefield.xp:
+ A slope field and flow lines.
+
+sphere.xp:
+ Plotting curves and latitudes/longitudes; loxodromes.
+
+spherical.xp:
+ Scenery (multiple shaded surfaces); spherical coordinates.
+
+sqrt.xp:
+ Domains and selective plotting; the Riemann surface of sqrt(z).
+
+sqrt2.xp:
+ Domains, selective plotting, and change of style in a single plot.
+
+std_F.cc, std_F.h:
+ Extensively-commented library code for depicting 2-D affine maps.
+
+std_F.xp:
+ Sample file illustrating the use of external libraries. Contains
+ instructions on building a library from std_F.cc.
+
+steiner.flx:
+ Steiner's Roman surface, rotating.
+
+steiner2.flx:
+ Steiner's Roman surface sliced, with slice direction rotating.
+
+surface_shade.xp:
+ Position-dependent surface shading. (Color function depends on three
+ variables.)
+
+symmetries.xp:
+ Affine maps and layout; the symmetry group S_3 acting on a regular
+ hexagon.
+
+tori.xp:
+ Clipping and cropping, page layout.
+
+torus.xp:
+ Domains and selective plotting.
+
+trig.flx:
+ Trigonometric functions.
+
+twisted_cubic.xp:
+ Page layout; a crossed-eyes stereogram of the twisted cubic.
+
+uppersum.xp:
+ Riemann sums.
+
+vfield.xp:
+ 3-D vector field plotting.
+
+weierstrass.xp:
+ Loops; a Weierstrass nowhere-differentiable function.
+
+wheel.xp:
+ Page layout; a cycloid at successive times.
diff --git a/graphics/epix/samples/R_demo.xp b/graphics/epix/samples/R_demo.xp
new file mode 100644
index 0000000000..183f74b988
--- /dev/null
+++ b/graphics/epix/samples/R_demo.xp
@@ -0,0 +1,69 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double mult(1.0/sqrt(M_PI));
+
+double f(double x)
+{
+ return 0.4*exp(-mult*x*x);
+}
+
+double g(double x)
+{
+ return f(x-3);
+}
+
+double PAD_X(0.4), PAD_Y(0.01);
+
+int main() {
+ picture(P(-3-PAD_X, -PAD_Y), P(8+PAD_X, 0.4+PAD_Y), "5 x 3.5in");
+
+ begin();
+ border();
+
+ legend L;
+ L.border(0);
+
+ fill(Black(0.2));
+ shadeplot(g, 1.96, xmax(), 120);
+ L.fill_item("$P(|Z|>1.96, H_1) = 0.85$");
+
+ fill(Black(0.8));
+ shadeplot(f, xmin(), -1.96, 20);
+ shadeplot(f, 1.96, 4, 40);
+ L.fill_item("$P(|Z|>1.96, H_0) = 0.05$");
+
+ plot(f, xmin(), xmax(), 240);
+ plot(g, xmin(), xmax(), 240);
+
+ font_size("scriptsize");
+ L.draw(P(4,0.35), P(0,0), tr);
+
+ label(P(0, 0.15), P(0,2), "$H_0$: $\\mu_1=\\mu_2$", t);
+ label(P(2, 0.15), P(2,2), "$H_1$: $\\mu_1=\\mu_2+\\delta$", tr);
+
+ font_size("footnotesize");
+ axis Ax(P(-2, ymin()), P(8, ymin()), 5, P(0,-8), b);
+ Ax.align(b).draw();
+
+ label(P(2, ymin()), P(0,-18),
+ "$Z=\\displaystyle\\frac{\\mu_1-\\mu_2}{\\sigma/\\sqrt{\\pi}}$", b);
+
+ degrees();
+ label_angle(90);
+
+#ifdef OLD_GCC
+ axis Ay(P(-3.4, 0), P(xmin(), 0.4), 4, P(-8,0), l);
+#else
+ // may not compile under gcc <= 3.3
+ axis Ay(P(xmin(), 0), P(xmin(), 0.4), 4, P(-8,0), l);
+#endif
+
+ Ay.align(l).draw();
+
+ label(P(xmin(), 0.2), P(-18,0), "Density", l);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/S2_harmonics.xp b/graphics/epix/samples/S2_harmonics.xp
new file mode 100644
index 0000000000..d1ed709165
--- /dev/null
+++ b/graphics/epix/samples/S2_harmonics.xp
@@ -0,0 +1,104 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double P_n(double z)
+{
+#ifdef Y20
+ return 0.5*(3*z*z - 1);
+#else
+ // Y_3^0
+ return 0.5*z*(5*z*z - 3);
+#endif
+}
+
+double rho(double th, double phi)
+{
+ return P_n(Sin(phi));
+}
+
+P color(double x, double y)
+{
+ return P(rho(x,y), 0, -rho(x,y));
+}
+
+P orbital(double u, double v)
+{
+ return sph(fabs(rho(u,v)), u, v);
+}
+
+int main()
+{
+ picture(P(-1,-1), P(1,1.5), "4x5in");
+
+ begin();
+
+ backing(Black());
+
+ set_crop();
+ revolutions();
+ fill();
+
+ // back 3/4
+ domain Bk(P(0.25, -0.25), P(1, 0.25), mesh(24,96), mesh(48,96));
+
+ plain(RGB(1, 0.8, 0.2) *= 0.8);
+
+ camera.at(sph(10, 0.06, 0.05));
+
+ // color-shaded surface
+ surface(orbital, Bk, color);
+
+ // draw boundary with "tube-like" green pen
+ nofill();
+ plain(Green(1.6));
+ base(Green(0.6), "2pt");
+ plot(orbital, Bk.slice1(0.25));
+ plot(orbital, Bk.slice1(1));
+
+ // set color for axes and labels
+ rgb(0.9,0.7,1);
+ base(RGB(0.8, 0, 1), "1pt");
+
+ arrow(P(0,0,0), P(1,0,0));
+ arrow(P(0,0,0), P(0,0.75,0));
+ arrow(P(0,0,0), P(0,0,1.25));
+
+ label(P(1,0,0), P(-2,-2), "$x$", bl);
+ label(P(0,0.75,0), P(4,-2), "$y$", r);
+ label(P(0,0,1.25), P(0,4), "$z$", t);
+
+ // "unset" base pen
+ base(Neutral());
+
+ // inset graph of Legendre polynomial
+ screen graph(P(-1,-1), P(1,1));
+ activate(graph);
+
+ camera.at(P(0,0,10000));
+ plain(Green(0.6));
+ grid(P(-1,-1), P(1,1), 8, 8);
+ bold(Yellow());
+ h_axis(8);
+ v_axis(8);
+
+ bold(Green());
+ plot(P_n, -1, 1, 60);
+
+ font_size("footnotesize");
+ label_color(Green(0.6));
+ label_mask(RGB(1, 0.8,0.2));
+
+#ifdef Y20
+ label(P(0,-1), P(0,-4), "$P(z)=\\frac{1}{2}(3z^2-1)$", b);
+#else
+ // Y30
+ label(P(0,-1), P(0,-4), "$P(z)=\\frac{1}{2}(5z^2-3)$", b);
+#endif
+
+ inset(P(-1,0.875), P(-0.375,1.5));
+ deactivate(graph); // a good habit, but not strictly necessary
+
+ tikz_format();
+ end();
+}
diff --git a/graphics/epix/samples/artifacts.xp b/graphics/epix/samples/artifacts.xp
new file mode 100644
index 0000000000..bd20166717
--- /dev/null
+++ b/graphics/epix/samples/artifacts.xp
@@ -0,0 +1,51 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double MAX(1);
+
+P F(double u, double v)
+{
+ return sph(1, u, v);
+}
+
+int main()
+{
+ picture(P(0,0),P(5,1), "5 x 1in");
+
+ begin();
+
+ pst_format();
+ domain coarse(P(0,0), P(0.5, 1), mesh(6,12), mesh(60,60));
+ domain fine(P(0,0), P(0.5, 1), mesh(15,30), mesh(60,60));
+
+ revolutions();
+ camera.at(P(5, 4, 3));
+
+ fill(White());
+
+ nofill(); // fill color set -> flat shading
+ screen scr1(P(-1,-1), P(1,1));
+ activate(scr1);
+ surface(F, coarse);
+
+ screen scr2(P(-1,-1), P(1,1));
+ activate(scr2);
+ surface(F, fine);
+
+ fill();
+ screen scr3(P(-1,-1), P(1,1));
+ activate(scr3);
+ surface(F, coarse);
+
+ screen scr4(P(-1,-1), P(1,1));
+ activate(scr4);
+ surface(F, fine);
+
+ inset(scr1, P(0,0), P(1,1));
+ inset(scr2, P(1.25,0), P(2.25,1));
+ inset(scr3, P(2.5,0), P(3.5,1));
+ inset(scr4, P(3.75,0), P(4.75,1));
+
+ end();
+}
diff --git a/graphics/epix/samples/binom.cc b/graphics/epix/samples/binom.cc
new file mode 100644
index 0000000000..1dc068fcd6
--- /dev/null
+++ b/graphics/epix/samples/binom.cc
@@ -0,0 +1,37 @@
+#include <iostream>
+#include <cmath>
+// Generate pseudo-random outcomes of tossing a biased coin 100 times.
+// Compile with, e.g.
+//
+// g++ -o binom binom.cc && ./binom > binom.dat
+
+const int trials=100000; // amount of data to collect
+
+int flip(double wt=0.5) // 0 < wt < 1
+{
+ if (rand() < (1-wt)*RAND_MAX)
+ return 0;
+ else
+ return 1;
+}
+
+void toss(unsigned int tosses, double wt=0.5)
+{
+ int count=0;
+ for (int i=0; i < tosses; ++i)
+ count += flip(wt);
+
+ std::cout << count << "\t";
+}
+
+int main()
+{
+ for (int j=0; j < trials; ++j)
+ {
+ toss(100, 0.05);
+ toss(100, 0.1);
+ toss(100, 0.3);
+ toss(100);
+ std::cout << "\n";
+ }
+}
diff --git a/graphics/epix/samples/bowl.xp b/graphics/epix/samples/bowl.xp
new file mode 100644
index 0000000000..fe3921b6db
--- /dev/null
+++ b/graphics/epix/samples/bowl.xp
@@ -0,0 +1,55 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P f(double u, double v)
+{
+ return u*P(Cos(v), Sin(v), u);
+}
+
+int main()
+{
+ picture(P(-2,-1),P(2,2), "6x4.5in");
+
+ begin();
+
+ backing(Black());
+
+ white();
+ label(P(0, ymax()), P(0,-2), "\\LARGE$z=x^2+y^2$", b);
+
+ revolutions();
+ camera.at(P(3,2,2.5));
+
+ red();
+ polar_grid(1, 8, 36);
+
+ arrow(P(0,0,0), P(1.25,0,0));
+ arrow(P(0,0,0), P(0,1.25,0));
+ label(P(1.25,0,0), P(-2,-2), "$x$", bl);
+ label(P(0,1.25,0), P(2,-1), "$y$", br);
+
+ fill();
+ rgb(1,0.8,0.2);
+ domain R(P(0,0), P(1,1), mesh(12,180), mesh(12,180));
+
+ scenery my(f, R);
+
+ my.draw(1); // cull front-pointing facets
+
+ red();
+ arrow(P(0,0,0), P(0,0,1));
+
+ pen(Blue(1.6), "0.5pt");
+ fill(Blue(1.4));
+ scenery my2(f, R);
+ my2.draw(-1); // cull back-pointing facets
+
+ nofill();
+ bold(Green());
+ base(Green(0.6), "1.5pt");
+ plot(f, R.slice1(1));
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/butterfly.xp b/graphics/epix/samples/butterfly.xp
new file mode 100644
index 0000000000..2ec303d780
--- /dev/null
+++ b/graphics/epix/samples/butterfly.xp
@@ -0,0 +1,136 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const P VIEWPT(20, 0, 8);
+
+const double tmin(2/sqrt(3));
+
+const Color light(Blue(1.6));
+const Color dark(Red(0.8));
+const Color lt_gray(Black(0.2));
+const Color net_color(Yellow(0.1));
+
+void label_tag(P loc, P head, std::string txt, epix_label_posn align)
+{
+ dart(loc, head);
+ masklabel(loc, P(0,0), txt, align);
+}
+
+domain R(P(-2,-2), P(2,2), mesh(20, 20), mesh(40,40));
+domain edge(P(-2,-2), P(2,2), mesh(1,1), mesh(40,40));
+
+// surface
+P Phi(double u, double v)
+{
+ return P(4*v, 0.75*(u*u-2*v)*u, 2*u);
+}
+
+P cubic(double t) { return Phi(t, 1.5*t*t); }
+
+// cubic projections to background planes
+P Phi12(double t)
+{
+ P temp(cubic(t));
+ return P(temp.x1(), temp.x2(), -8);
+}
+
+P Phi13(double t)
+{
+ P temp(cubic(t));
+ return P(temp.x1(), -8, temp.x3());
+}
+
+P Phi23(double t)
+{
+ P temp(cubic(t));
+ return P(-8, temp.x2(), temp.x3());
+}
+
+
+int main() {
+ picture(P(-14,-15), P(10,9), "6x6in");
+
+ begin();
+ set_crop();
+ camera.at(VIEWPT);
+
+ // background grids
+ pen(lt_gray);
+ grid(P(-8, -8, -8), P(8, 8, -8), 8,8);
+ grid(P(-8, -8, -8), P(8, -8, 6), 7,8); // n.b. (z,x) divisions
+ grid(P(-8, -8, -8), P(-8, 8, 6), 8,7);
+
+ // background coordinate axes
+ pen(Black());
+ line(P(0, -8, -8), P(0, 8, -8));
+ line(P(-8, 0, -8), P(8, 0, -8));
+
+ line(P(0, -8, -8), P(0, -8, 6));
+ line(P(-8, -8, 0), P(8, -8, 0));
+
+ line(P(-8, 0, -8), P(-8, 0, 6));
+ line(P(-8, -8, 0), P(-8, 8, 0));
+
+ // projections of cubic
+ bold(dark);
+ plot(Phi12, -tmin, tmin, 80);
+ plot(Phi13, -tmin, tmin, 80);
+ plot(Phi23, -tmin, tmin, 80);
+
+ // surface
+ plain(net_color);
+ fill(lt_gray);
+ surface(Phi, R.resize1(-2,0)); // bottom half
+
+ // and cubic curve
+ bold(dark);
+ plot(cubic, -tmin, 0, 80);
+
+ plain(net_color);
+ surface(Phi, R.resize1(0,2)); // top half
+
+ bold(dark);
+ plot(cubic, 0, tmin, 80);
+
+ // surface boundary
+ bold(Yellow());
+ plot(Phi, edge);
+
+ // guide lines to cusp projection
+ plain(light);
+ dashed();
+ line(cubic( tmin), Phi12( tmin));
+ line(cubic(-tmin), Phi12(-tmin));
+
+ /*
+ // guide lines to other projections
+ line(cubic( tmin), Phi13( tmin));
+ line(cubic(-tmin), Phi13(-tmin));
+
+ line(cubic( tmin), Phi23( tmin));
+ line(cubic(-tmin), Phi23(-tmin));
+ */
+
+ // fake transparency
+ plain(dark);
+ plot(Phi12, -tmin, tmin, 20); // cusp
+ // plot(Phi13, -tmin, tmin, 20);
+ // plot(Phi23, -tmin, tmin, 20);
+
+ label_color(Black());
+ label(P(8,0,-8), P(0,-4), "$x$", b);
+ label(P(0,8,-8), P(4,0), "$y$", r);
+
+ pen(light);
+ label_border(light, "0.4pt");
+ solid();
+ label_tag(Phi(-2,-2)+P(0,2,6), Phi(-1.75,-1.75),
+ "$y=\\frac{3}{32}(z^3-2xz)$", t);
+
+ label_tag(cubic(-1)+P(0,2,3), cubic(-1),
+ "$(x,y,z)=(6t^2, -\\frac{3}{2}t^3, 2t)$", t);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/calculus.xp b/graphics/epix/samples/calculus.xp
new file mode 100644
index 0000000000..c5aa0efe0b
--- /dev/null
+++ b/graphics/epix/samples/calculus.xp
@@ -0,0 +1,43 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double MAX(2*M_PI);
+double f(double t)
+{
+ return t*Sin(t);
+}
+
+int main()
+{
+ picture(P(-MAX,-MAX), P(MAX,MAX), "240x240pt");
+
+ begin();
+
+ // Coordinate axes and labels
+ pen(Black(0.3));
+ grid(8,8);
+
+ font_size("scriptsize");
+ // trigonometric axis labels
+ bottom_axis(4, P(0,-4)).trig().draw_labels();
+ left_axis(4, P(-4,0)).trig().draw_labels();
+
+ legend L;
+ L.item_border(0).border(Red(), 0.4);
+
+ bold(Black());
+ plot(f, xmin(), xmax(), 90);
+ L.path_item("$y=x\\sin x$");
+
+ pen(Green());
+ plot(Deriv(f), xmin(), xmax(), 90);
+ L.path_item("$y=\\frac{d}{dx}(x\\sin x)$");
+
+ pen(Blue());
+ plot(Integral(f, 0), xmin(), xmax(), 90); // definite integral from 0
+ L.path_item("$y=\\int_0^x t\\sin t\\,dt$");
+
+ L.draw(P(0,2*M_PI), P(2,-2), br);
+ end();
+}
diff --git a/graphics/epix/samples/clipping.xp b/graphics/epix/samples/clipping.xp
new file mode 100644
index 0000000000..0df86eb85b
--- /dev/null
+++ b/graphics/epix/samples/clipping.xp
@@ -0,0 +1,233 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+/*
+ * This file, a monkey saddle sliced by two vertical planes showing
+ * the definition and geometric meaning of partial derivatives,
+ * contains a high degree of manual object ordering. Coordinate grids
+ * in the back come first. The surface itself is broken into pieces
+ * interspersed with axes and cutting planes. Figure parameters
+ * (color, the size and fineness of the domain, locations of cutting
+ * planes, and camera location) are defined in the preamble. The
+ * figure's appearance can then be adjusted visually at leisure to
+ * obtain the desired effect.
+ *
+ * Compile with
+ *
+ * epix -DDISSECT clipping.xp
+ *
+ * to create frames showing stages of the construction.
+ */
+
+// Style parameters
+// camera location (in spherical coordinates); must be in first orthant
+const P VIEWPT(sph(4, M_PI/6, M_PI/6));
+
+// colors
+void color_coord()
+{
+ // fill(RGB(1, 0.9, 0.5));
+ // plain(RGB(1, 0.5, 0.2));
+ plain(RGB(1, 0.9, 0.7));
+}
+
+void color_axis()
+{
+ rgb(0.8, 0.2, 0.9);
+}
+
+// graph and mesh
+void color_surf()
+{
+ plain(RGB(1, 0.5, 0));
+ fill(RGB(1, 0.8, 0.2));
+}
+
+// slicing plane and border
+void color_xslice()
+{
+ red();
+}
+
+void fill_xslice()
+{
+ // black(0.1);
+ rgb(0.8, 0.5, 0.1);
+}
+
+void color_yslice()
+{
+ blue();
+}
+
+void fill_yslice()
+{
+ // black(0.3);
+ rgb(0.6, 0.3,0);
+}
+
+const int MESH(12); // number of coordinate grid squares
+
+// location of tangency point
+const double x_0(7.0/MESH);
+const double y_0(6.0/MESH);
+const double z_0(0.25); // height of top of slicing planes
+
+const int MAX(1); // maximum coordinate
+
+const double sqrt3(sqrt(3));
+
+// function to be graphed
+P f(double x, double y)
+{
+ return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x));
+}
+
+int main()
+{
+ picture(P(-2,-2), P(2,1.5), "6 x 5.25in");
+
+ begin();
+
+ // "legend"
+ masklabel(P(xmax(), ymax()), P(-2,-2),
+ "$z=\\displaystyle\\frac{1}{2}(y^3-3x^2y)$", bl);
+
+ font_size("scriptsize");
+ camera.at(VIEWPT);
+ border(Green(0.6), "1pt");
+
+ domain R(P(-MAX,-MAX), P(MAX,MAX),
+ mesh(4*MESH, 4*MESH), mesh(8*MESH, 8*MESH));
+
+ // coordinate grids
+ color_coord();
+ grid(P(-MAX,-MAX,-MAX), P(-MAX, MAX, MAX), MESH, MESH);
+ grid(P(-MAX,-MAX,-MAX), P( MAX,-MAX, MAX), MESH, MESH);
+ grid(P(-MAX,-MAX,-MAX), P( MAX, MAX,-MAX), MESH, MESH);
+
+#ifdef DISSECT
+ print_pst("clipping01.eepic");
+#endif
+
+ clip_box(P(-2, -2, -1), P(2, 2, 1));
+
+ // back half and front left quarter
+ color_surf();
+ surface(f, R.resize1(-MAX,0));
+#ifdef DISSECT
+ print_pst("clipping02.eepic");
+#endif
+
+ surface(f, R.resize1(0,MAX).resize2(-MAX,0));
+#ifdef DISSECT
+ print_pst("clipping03.eepic");
+#endif
+
+ // coordinate axes
+ color_axis();
+ bold();
+
+ clip_box(P(-2, -2, -1), P(2, 2, 2));
+
+ dart(P(-MAX,0,0), P(0.25+MAX,0,0));
+ dart(P(0,-MAX,0), P(0,0.25+MAX,0));
+ dart(P(0,0,0), P(0,0,0.25+MAX));
+
+ label(P(0.25+MAX,0,0), P(-2,-2), "$x$", bl);
+ label(P(0,0.25+MAX,0), P( 4,-2), "$y$", r);
+ label(P(0,0,0.25+MAX), P( 0, 4), "$z$", t);
+
+#ifdef DISSECT
+ print_pst("clipping04.eepic");
+#endif
+
+ // front quarter of surface; chop into four pieces
+ color_surf();
+ surface(f, R.resize1(0, x_0).resize2(0,y_0)); // behind both planes
+
+#ifdef DISSECT
+ print_pst("clipping05.eepic");
+#endif
+
+ fill_xslice();
+ rect(P(x_0, 0, -MAX), P(x_0, y_0, z_0)); // left part of plane x = x_0
+
+#ifdef DISSECT
+ print_pst("clipping06.eepic");
+#endif
+
+ pen(3);
+ color_xslice();
+ plot(f, R.slice1(x_0).resize2(0, y_0));
+
+#ifdef DISSECT
+ print_pst("clipping07.eepic");
+#endif
+
+ color_surf();
+ surface(f, R.resize1(x_0, MAX).resize2(0,y_0)); // back right piece
+
+#ifdef DISSECT
+ print_pst("clipping08.eepic");
+#endif
+
+ fill_yslice();
+ rect(P(0, y_0, -MAX), P(MAX, y_0, z_0)); // plane y = y_0
+
+#ifdef DISSECT
+ print_pst("clipping09.eepic");
+#endif
+
+ pen(3);
+ color_yslice();
+ plot(f, R.slice2(y_0).resize1(0, MAX));
+
+#ifdef DISSECT
+ print_pst("clipping11.eepic");
+#endif
+
+ color_surf();
+ surface(f, R.resize1(0, x_0).resize2(y_0, MAX)); // front left piece
+
+#ifdef DISSECT
+ print_pst("clipping12.eepic");
+#endif
+
+ fill_xslice();
+ rect(P(x_0, y_0, -MAX), P(x_0, MAX, z_0)); // right part of plane x = x_0
+
+#ifdef DISSECT
+ print_pst("clipping13.eepic");
+#endif
+
+ pen(3);
+ color_xslice();
+ plot(f, R.slice1(x_0).resize2(y_0, MAX));
+
+#ifdef DISSECT
+ print_pst("clipping14.eepic");
+#endif
+
+ color_surf();
+ surface(f, R.resize1(x_0, MAX).resize2(y_0, MAX)); // front right piece
+
+ clip_box(P(-MAX,-MAX,-2), P(MAX,MAX,2));
+
+ // labels and graph slices
+ color_yslice();
+ label(f(MAX, y_0), P(-4,0),
+ "$\\displaystyle\\frac{\\partial f}{\\partial x}$: $y$ constant", l);
+
+ color_xslice();
+ label(f(x_0, MAX), P(4,0),
+ "$\\displaystyle\\frac{\\partial f}{\\partial y}$: $x$ constant", br);
+
+#ifdef DISSECT
+ print_pst("clipping15.eepic");
+#endif
+
+ pst_format();
+ end();
+}
+
diff --git a/graphics/epix/samples/color_sep.xp b/graphics/epix/samples/color_sep.xp
new file mode 100644
index 0000000000..5ba4df4fc9
--- /dev/null
+++ b/graphics/epix/samples/color_sep.xp
@@ -0,0 +1,76 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// re cos(u+iv)
+P f(double u, double v)
+{
+ return P(u, v, 2*cosh(u)*Cos(v));
+}
+
+domain R(P(-1,-1), P(1,1), mesh(16,16));
+
+// RGB densities
+P color(double x, double y, double z)
+{
+ return P(Sin(x), -Sin(y), -Sin(x));
+}
+
+int main()
+{
+ picture(P(0,0), P(5,1), "5x1in");
+
+ begin();
+
+ camera.filter(CMYK_Neutral()); // convert colors to CMYK in output
+ grid(5,1);
+ camera.at(4,3,1);
+
+ plain(Red(1.6));
+
+ // Original
+ screen all(P(-1.5,0.5), P(1.5,3.5));
+ activate(all);
+ set_crop();
+
+ surface(f, R, color);
+ inset(all, P(0,0), P(1,1));
+
+ // Cyan
+ screen cyn(P(-1.5,0.5), P(1.5,3.5));
+ activate(cyn);
+ set_crop();
+ camera.filter(C_Process()); // get cyan layer
+
+ surface(f, R, color);
+ inset(cyn, P(1,0), P(2,1));
+
+ // Magenta
+ screen mgn(P(-1.5,0.5), P(1.5,3.5));
+ activate(mgn);
+ set_crop();
+ camera.filter(M_Process());
+
+ surface(f, R, color);
+ inset(mgn, P(2,0), P(3,1));
+
+ // Yellow
+ screen ylw(P(-1.5,0.5), P(1.5,3.5));
+ activate(ylw);
+ set_crop();
+ camera.filter(Y_Process());
+
+ surface(f, R, color);
+ inset(ylw, P(3,0), P(4,1));
+
+ // Black
+ screen blk(P(-1.5,0.5), P(1.5,3.5));
+ activate(blk);
+ set_crop();
+ camera.filter(K_Process());
+
+ surface(f, R, color);
+ inset(blk, P(4,0), P(5,1));
+
+ end();
+}
diff --git a/graphics/epix/samples/conic.xp b/graphics/epix/samples/conic.xp
new file mode 100644
index 0000000000..394a326394
--- /dev/null
+++ b/graphics/epix/samples/conic.xp
@@ -0,0 +1,55 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int MAX(24);
+const double x0(4);
+const double ht(3); // camera height
+const double INFTY(100000);
+
+P f(double t)
+{
+ return P(t, t*t, 0);
+}
+
+int main()
+{
+ picture(P(-3,-3),P(3,3), "4x4in");
+
+ begin();
+
+ border();
+ set_crop();
+
+ viewpoint(0,-ht*ht, ht);
+ camera.look_at(P(0,0,1));
+
+ pen(Black(0.3), "0.1pt");
+ grid(P(-MAX,0), P(MAX, MAX*MAX), MAX, MAX*MAX/8);
+ grid(P(-MAX, 0, 2*ht), P(MAX, MAX*MAX, 2*ht), MAX, MAX*MAX/8);
+
+ pen(Blue(1.4));
+ envelope(f, -MAX/2, MAX/2, 20); // envelope of tangent lines
+
+
+ bbold(Blue());
+ Line(P(-100, INFTY, 0), P(100, INFTY, 0));
+
+ masklabel(P(0,0), P(0,2), "$(0,0)$", t);
+ label(P(0,INFTY), P(0,-2), "$(0,\\infty)$", b);
+ label(P(-0.25*INFTY,INFTY), P(0, 2), "Horizon", t);
+
+ masklabel(P(x0, x0*x0), P(-4,0), "$y=x^2$", l);
+
+ box(P(0,0));
+ box(P(0,INFTY));
+
+ pen(1);
+ plot(f, -MAX, MAX, 240);
+
+ camera.at(0,0,1000);
+ masklabel(P(0, ymin()), P(0,0),
+ "Projective equivalence of a parabola and a circle", t);
+
+ end();
+}
diff --git a/graphics/epix/samples/contour.xp b/graphics/epix/samples/contour.xp
new file mode 100644
index 0000000000..2a0b093b5b
--- /dev/null
+++ b/graphics/epix/samples/contour.xp
@@ -0,0 +1,56 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// arc arrow extent
+const double theta(60);
+
+// arc radii
+const double rad(0.25);
+const double Rad(4.5);
+
+// half-width of slit
+const double ht(0.0625);
+
+int main()
+{
+ // old-style size declarations
+ bounding_box(P(-5, -5), P(5,5));
+ picture(160, 160);
+ unitlength("0.35mm");
+
+ begin();
+ degrees();
+ tikz_format();
+
+ // "start" angles of arcs; must come after degrees()
+ const double theta1(Asin(ht/rad));
+ const double theta2(Asin(ht/Rad));
+
+ fill(Black(0.1)); // light gray
+
+ // build keyhole in pieces; += concatenates
+ path contour(P(0,0), Rad*E_1, Rad*E_2, theta2, 360-theta2); // outer arc
+ contour += path(polar(Rad,-theta2), polar(rad,-theta1)); // lower slit
+ contour += path(P(0,0), rad*E_1, rad*E_2, 360-theta1, theta1); // inner arc
+ contour += path(polar(rad, theta1), polar(Rad, theta2)); // upper slit
+
+ contour.close().fill().draw();
+
+ dot(P(0,0)); // the origin
+
+ // plain(Black());
+ arrow_width(2);
+ arrow_inset(0.25);
+
+ arrow(P(Rad/4, 0.1*Rad), P(3*Rad/4, 0.1*Rad)); // arrow ends in terms of Rad
+ arrow(P(3*Rad/4, -0.1*Rad), P(Rad/4, -0.1*Rad));
+
+ arc_arrow(P(0,0), 0.9*Rad, 180-theta, 180+theta);
+
+ label(P(Rad,ht), P(2,4), "$R\\to\\infty$", tr);
+ label(P(0,rad), P(0,4), "$\\delta\\to0$", tl);
+ label(polar(Rad, 45), P(0,0), "$\\gamma$", tr);
+
+ end();
+}
diff --git a/graphics/epix/samples/coord_tricks.xp b/graphics/epix/samples/coord_tricks.xp
new file mode 100644
index 0000000000..06cf009037
--- /dev/null
+++ b/graphics/epix/samples/coord_tricks.xp
@@ -0,0 +1,66 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double gap(0.15); // distance between graph portions
+
+Color GRAY(Black(0.5));
+
+int main()
+{
+ picture(P(0,0),P(2+gap,2+gap), "4x4in");
+
+ begin();
+
+ plain(GRAY);
+ // draw in global coordinates
+ axis_break(P(1,0), P(1+gap,0));
+ axis_break(P(0,1), P(0,1+gap));
+
+ // portion adjacent to origin
+ screen scr1(P(0,0), P(4,4));
+ activate(scr1);
+
+ set_crop();
+ grid(8,8);
+
+ h_axis_labels(4, P(0,-4), b);
+ v_axis_labels(4, P(-4,0), l);
+
+ bold(Red());
+ plot(recip, 0, 4, 120);
+
+ inset(P(0,0), P(1,1));
+
+ // right portion
+ screen scr2(P(10,0), P(14,4));
+ activate(scr2);
+
+ set_crop();
+ plain(GRAY);
+ grid(8,8);
+
+ h_axis_labels(4, P(0,-4), b);
+
+ bold(Red());
+ plot(recip, 10, 14, 20);
+
+ inset(P(1+gap,0), P(2+gap,1));
+
+ // top portion
+ screen scr3(P(0,10), P(4,14));
+ activate(scr3);
+
+ set_crop();
+ plain(GRAY);
+ grid(8,8);
+
+ v_axis_labels(4, P(-4,0), l);
+
+ bold(Red());
+ plot(recip, 0.05, 0.1, 10);
+
+ inset(P(0,1+gap), P(1,2+gap));
+
+ end();
+}
diff --git a/graphics/epix/samples/cropplot.xp b/graphics/epix/samples/cropplot.xp
new file mode 100644
index 0000000000..b470d90497
--- /dev/null
+++ b/graphics/epix/samples/cropplot.xp
@@ -0,0 +1,35 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double t) { return 2*t*(1-t)*(1-t); }
+double g(double t) { return 1/(1-t*t); }
+
+int main()
+{
+ picture(P(-2,-4), P(2,4), "200x200pt");
+
+ begin();
+
+ set_crop();
+ // Vertical asymptotes
+ dashed();
+ line(P(-1, ymin()), P(-1, ymax()));
+ line(P( 1, ymin()), P( 1, ymax()));
+ solid();
+
+ // Axes
+ h_axis(8);
+ v_axis(8);
+
+ h_axis_labels(4, P(-1, 2), tl); // align top-left
+ v_axis_labels(4, P(-1, 2), tl);
+
+ // Graphs
+ plot(f, xmin(), xmax(), 80);
+
+ bold();
+ plot(g, xmin(), xmax(), 80); // N.B. poles are sample points
+
+ end();
+}
diff --git a/graphics/epix/samples/cube.flx b/graphics/epix/samples/cube.flx
new file mode 100644
index 0000000000..c2d1df2505
--- /dev/null
+++ b/graphics/epix/samples/cube.flx
@@ -0,0 +1,44 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ picture(P(-4,-4), P(4,4), "5 x 5in");
+
+ begin();
+ revolutions();
+
+ grid(1,1);
+
+ P ctr(3.25,-3.25); // "clock" center
+ bold();
+ ellipse(ctr, P(0.5,0.5)); // clock face
+
+ line(ctr, ctr+polar(0.4,tix())); // hands
+ label_angle(tix()-0.25);
+ label(ctr+polar(0.6,tix()), "$\\theta$");
+
+ // a cube :)
+ domain R(P(-2,-2,-2), P(2,2,2), mesh(1,1,1));
+
+ camera.at(sph(10,tix(),-0.05));
+ plain(Cyan());
+ plot(xyz, R); // draw cube; xyz = Cartesian pt constructor
+
+ camera.at(sph(10,0.01 + tix(),-0.05)); // 3.6 degrees away
+ red(1.4); // slightly lightened red
+ plot(xyz, R);
+
+ end();
+}
diff --git a/graphics/epix/samples/dataplot.xp b/graphics/epix/samples/dataplot.xp
new file mode 100644
index 0000000000..221c33a73c
--- /dev/null
+++ b/graphics/epix/samples/dataplot.xp
@@ -0,0 +1,55 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double x, double y)
+{
+ return P((x-y)*(x+y), 2*x*y);
+}
+
+int main()
+{
+ picture(P(-1,0),P(1,20), "6x6in");
+
+ begin();
+
+ // create a 2-column data file with 121 rows
+ data_file DF(Cos, Sin, 0, M_PI, 120);
+
+ legend L;
+ plain(Black());
+ fill(Blue(1.8));
+
+ // act on first two columns; result doubles angles
+ DF.transform(F);
+
+ data_bins db(-1.05, 1.05, 21); // bins centered on -1, -0.9, ..., 0.9, 1
+ db.read(DF.column(1)); // read col1
+ db.bar_chart(db.pop()); // and plot, scaling to population
+
+ L.fill_item("Population count"); // add a filled legend item
+
+ label_color(Blue(1.2));
+ v_axis_labels(P(xmin(), ymin()), P(xmin(), ymax()), 0.5*ysize(), P(-4,0), l);
+ // superimpose plot of raw data
+ screen raw(P(-1,-1), P(1,1));
+ activate(raw);
+ label_color(Red());
+ DF.plot(DDOT); // scatter plot
+ L.mark_item(DDOT, "Data points");
+
+ nofill();
+ plain(Black(0.3));
+ grid(1,10);
+
+ v_axis_labels(P(1,-1), P(1,1), 4, P(4,0), r);
+
+ // DF.write("circle.dat"); // write to a disk file
+ inset(P(-1,0), P(1,20));
+ deactivate(raw); // polite but unnecessary
+
+ L.draw(canvas().c(), P(0,0), c);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/decorate.xp b/graphics/epix/samples/decorate.xp
new file mode 100644
index 0000000000..5b6d9cf32c
--- /dev/null
+++ b/graphics/epix/samples/decorate.xp
@@ -0,0 +1,120 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+/*
+ * Compile with, e.g. elaps -DNORMAL --huge decorate.xp
+ */
+
+#define LINEFIELD
+// #define NORMAL
+
+const int N1(24); // latitudes
+const int N2(48); // longitudes
+
+const double du(1.0/N1);
+const double dv(1.0/N2);
+
+const P VIEWPT(6, 3, 4);
+
+const double r_0(0.95); // minor radius
+const double R_0(2); // major radius
+double g(double u)
+{
+ return R_0 + r_0*Cos(u);
+}
+
+P F(double u, double v)
+{
+ return polar(g(u), v) + P(0,0,r_0*Sin(u));
+}
+
+namespace ePiX {
+ // a facet-like class that can be drawn with extra decorations, e.g.,
+ // normal vectors, diagonals, orientation-dependent colors...
+ class mesh_quad {
+ private:
+ P pt1, pt2, pt3, pt4, center;
+ double distance;
+
+ public:
+ mesh_quad(P f(double u, double v), double u0, double v0)
+ : pt1(f(u0,v0)), pt2(f(u0+du,v0)), pt3(f(u0+du,v0+dv)), pt4(f(u0,v0+dv)),
+ center(0.25*(pt1 + pt2 + pt3 + pt4)),
+ distance(norm(center-camera.viewpt())) { }
+
+ double how_far() const { return distance; }
+
+ void draw() const
+ {
+ P direction(center-camera.viewpt());
+ P normal((pt2 - pt1)*(pt4 - pt1));
+ normal *= 1/norm(normal);
+
+ blue(0.75*(normal|(recip(distance)*direction)));
+
+#ifdef NORMAL
+ if ((normal|direction) < 0)
+ {
+ plain(Green(0.6));
+ arrow(center, center-0.5*normal, 0.5);
+ }
+#endif
+ fill();
+ ePiX::quad(pt1, pt2, pt3, pt4);
+ fill(false);
+
+#ifdef LINEFIELD
+ if ((normal|direction) > 0)
+ bbold(Blue(1.8));
+ else
+ bold(Red());
+
+ line(pt1, 0.5*(pt3+pt4));
+ line(0.5*(pt1+pt2), pt3);
+#endif
+
+#ifdef NORMAL
+ if ((normal|direction) > 0)
+ {
+ plain(Green(0.6));
+ arrow(center, center-0.5*normal, 0.5);
+ }
+#endif
+ }
+ };
+
+ class by_distance {
+ public:
+ bool operator() (const mesh_quad& arg1, const mesh_quad& arg2)
+ { return arg1.how_far() > arg2.how_far(); }
+ };
+} // end of namespace
+
+int main() {
+ picture(P(-3,-3),P(3,3), "4x4in");
+
+ begin();
+ revolutions();
+
+ viewpoint(VIEWPT);
+ camera.range(10);
+
+ // chop off the front
+ clip_face(P(R_0, 0, r_0), P(-0.25,-0.25,-1));
+
+ // build and draw a torus
+ std::vector<mesh_quad> mesh;
+
+ for (int i=0; i<N1; ++i)
+ for (int j=0; j<N2; ++j)
+ mesh.push_back(mesh_quad(F, i*du, j*dv));
+
+ sort(mesh.begin(), mesh.end(), by_distance());
+
+ // arrow_fill(1);
+ for (unsigned int i=0; i<mesh.size(); ++i)
+ mesh.at(i).draw();
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/demoivre.xp b/graphics/epix/samples/demoivre.xp
new file mode 100644
index 0000000000..1225906a12
--- /dev/null
+++ b/graphics/epix/samples/demoivre.xp
@@ -0,0 +1,42 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(24);
+const double theta(0.875*M_PI);
+const pair alpha(1, theta/N);
+
+// pairs implement complex arithmetic, but need P to draw
+P pair2P(pair arg)
+{
+ return P(arg.x1(), arg.x2());
+}
+
+int main()
+{
+ picture(P(-1.5,0), P(1,1.25), "200 x 100pt");
+
+ begin();
+
+ pair power(1,0);
+
+ for(int i=0; i<N; ++i)
+ {
+ line(P(0,0), pair2P(alpha*power)); // draw two sides
+ line(pair2P(power), pair2P(alpha*power)); // of triangle
+ power *= alpha; // and increment power
+ }
+
+ label(pair2P(alpha), P(2,0), "$\\alpha=1+\\frac{i\\theta}{n}$", r);
+ label_angle(theta-M_PI);
+ ddot(pair2P(power), P(2,4), "$\\alpha^n\\approx e^{i\\theta}$", b);
+
+ plain(Black(0.3));
+ arc(P(0,0), 1, 0, theta);
+ ddot(cis(theta), P(0,-4), "$$", b);
+
+ bold(Red());
+ triangle(P(0, 0), P(1, 0), pair2P(alpha));
+
+ end();
+}
diff --git a/graphics/epix/samples/denom.xp b/graphics/epix/samples/denom.xp
new file mode 100644
index 0000000000..015f29bb4a
--- /dev/null
+++ b/graphics/epix/samples/denom.xp
@@ -0,0 +1,39 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int N(30); // maximum denominator plotted
+
+int main()
+{
+ picture(P(-2,0), P(2,1), "4x1in");
+
+ begin();
+ tikz_format();
+
+ axis Ax(P(-2,0), P(2,0), 8, P(0,-6), b);
+ Ax.subdivide(6).frac().draw();
+
+ v_axis(2);
+
+ dot_size(2);
+ for (int i=1; i< N; ++i)
+ for (int j=i*xmin(); j <= i*xmax(); ++j)
+ if (gcd(i, j) == 1)
+ ddot(P(j*1.0/i, 1.0/i));
+
+ font_size("scriptsize");
+
+ // The long label text can be written in one string, but using a
+ // stringstream allows the input to be formatted more readably.
+ std::stringstream buf;
+ buf << "$f(x)=\\begin{cases}%" << std::endl
+ << " \\frac{1}{q} & "
+ << "\\text{ $x=\\frac{p}{q}$ in lowest terms} \\\\" << std::endl
+ << " 0 & \\text{ $x$ irrational}%" << std::endl
+ << "\\end{cases}$";
+
+ label(P(0,0.75), P(2,0), buf.str(), r);
+ end();
+}
+
diff --git a/graphics/epix/samples/densityplot.xp b/graphics/epix/samples/densityplot.xp
new file mode 100644
index 0000000000..51ef671cc6
--- /dev/null
+++ b/graphics/epix/samples/densityplot.xp
@@ -0,0 +1,44 @@
+/* -*-ePiX-*- */
+#include <epix.h>
+using namespace ePiX;
+
+const int MAX(18);
+
+// basic circular wave
+double ripple(double u, double v)
+{
+ return pow(Cos(0.5*sqrt(u*u+v*v)),2);
+}
+
+// superposition
+double f(double u, double v)
+{
+ return 0.25*(1+ripple(u, v-10) + ripple(u, v+10));
+}
+
+// f as a parametric surface
+P F(double u, double v)
+{
+ return P(u, v, f(u,v));
+}
+
+// height-dependent coloring
+P color(double u, double v, double w)
+{
+ return P(0.2+0.8*w, 0.3, 0.8 - 0.6*w);
+}
+
+domain R(P(-MAX,-MAX), P(MAX,MAX), mesh(2*MAX, 2*MAX));
+
+int main()
+{
+ picture(P(-MAX,-MAX), P(MAX,MAX), "3x3in");
+
+ begin();
+
+ pen(Magenta(1.4), 0.2);
+ surface(F, R, color);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/dipole.xp b/graphics/epix/samples/dipole.xp
new file mode 100644
index 0000000000..da17229481
--- /dev/null
+++ b/graphics/epix/samples/dipole.xp
@@ -0,0 +1,86 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// number of field lines per charge
+const int N(13);
+
+// charge magnitudes and locations
+const int charge1(1);
+const int charge2(1);
+
+const P Q1( 1,0);
+const P Q2(-1,0);
+
+// inverse-square electric field from a point charge at the origin
+P unit_charge(const P& arg)
+{
+ return recip(arg|arg)*arg;
+}
+
+// electric field simulated by superimposing individual fields, then
+// re-scaling so that field -> 0 near the charge location (improves
+// plot quality:)
+P E(double x, double y)
+{
+ P temp(x,y);
+ // superposition of charge fields
+ P E_temp(charge1*unit_charge(temp-Q1) + charge2*unit_charge(temp-Q2));
+
+ // re-scale
+ return (1.0/(E_temp|E_temp))*E_temp;
+}
+
+P potential(double x, double y)
+{
+ // J rotates a vector by 1/4 turn; parallel to equipotentials
+ return J(E(x,y));
+}
+
+const double MAX(3);
+
+int main()
+{
+ picture(P(-MAX,-MAX), P(MAX,MAX), "4x4in");
+
+ begin();
+ set_crop();
+ degrees(); // change angle mode
+
+ // plot field lines
+ blue();
+ for (int i=0; i < N; ++i)
+ {
+ // initial points trace a small circle about Q1 or Q2,
+ ode_plot(E, Q1+polar(0.05, i*360.0/N), 10, 120);
+ ode_plot(E, Q2-polar(0.05, i*360.0/N), 10, 120);
+
+ // location of arrowhead
+ P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3, 12));
+ }
+
+ green();
+ for (int i=-10; i < 10; ++i)
+ {
+ ode_plot(potential, Q1+polar(0.25*pow(0.8, i), 0), 2*M_PI, 120);
+ ode_plot(potential, Q2-polar(0.25*pow(0.8, i), 0), 2*M_PI, 120);
+ }
+
+ dot_size(6);
+ circ(Q1);
+ circ(Q2);
+
+ magenta();
+ label(Q1, "$+$");
+ label(Q2, "$+$");
+
+ blue();
+ for (int i=0; i < N; ++i)
+ {
+ P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3.5, 12));
+ arrow(pt, pt+0.01*E(pt.x1(), pt.x2()));
+ arrow(-pt, -pt+0.01*E(-pt.x1(), -pt.x2()));
+ }
+
+ end();
+}
diff --git a/graphics/epix/samples/extract.xp b/graphics/epix/samples/extract.xp
new file mode 100644
index 0000000000..b061df18db
--- /dev/null
+++ b/graphics/epix/samples/extract.xp
@@ -0,0 +1,109 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// a benign function
+double phi(double x)
+{
+ return x*x;
+}
+
+// and its derivative
+Deriv dphi(phi);
+
+// parameters defining an arbitrary line ell
+const double slope(-2);
+const double beta(0.5);
+
+const double ht(phi(beta));
+const double alpha(slope-dphi.eval(beta));
+
+const double eps(0.02); // size of extraction
+
+// a small perturbation to adjust the derivative
+double f(double x)
+{
+ return x/(1+16384*x*x);
+}
+
+double gn(double x)
+{
+ return f(alpha*(x-beta));
+}
+
+// phi's Evil Twin
+double psi(double x)
+{
+ return phi(x) + gn(x);
+}
+
+// inset parameters
+const P mag_ctr(P(0.75, 0.2));
+const double mag_sz(0.125);
+
+int main()
+{
+ picture(P(0,0), P(1,0.75), "4x3in");
+
+ begin();
+ set_crop();
+
+ // two nearly-equal graphs, and the tangent to one of them
+ plain(Blue());
+ plot(psi, xmin(), beta-eps, 60);
+ plot(psi, beta+eps, xmax(), 60);
+ plot(psi, beta-eps, beta+eps, 60);
+
+ pen(Green(0.6));
+ Line(P(beta,phi(beta)), slope);
+
+ bold(Red());
+ plot(phi, xmin(), xmax(), 60);
+ plain();
+
+ // cut out a small neighborhood and magnify it
+ screen mag(canvas().extract_ellipse(P(beta-eps, psi(beta)-eps),
+ P(beta+eps, psi(beta)+eps)));
+ mag.backing(Yellow(0.05));
+ mag.border(Black(), "0.4pt");
+
+ inset(mag, mag_ctr - mag_sz*P(1,1), mag_ctr + mag_sz*P(1,1));
+
+ pen(Black());
+ // axes
+ line(P(xmin(),0), P(xmax(),0));
+ line(P(0,ymin()), P(0,ymax()));
+
+ // indicators
+ line(P(beta,0), P(beta,phi(beta)), -20); // shorten slightly
+ line(P(0,phi(beta)), P(beta,phi(beta)), -10);
+
+ // zoom lines
+ line(P(beta, phi(beta)), mag_ctr + polar(mag_sz, 2*M_PI/3), -20);
+ line(P(beta, phi(beta)), mag_ctr + polar(mag_sz, 5*M_PI_4), -20);
+
+ font_size("footnotesize");
+ label(P(beta,0), P(0,-4), "$\\beta$", b);
+ label(P(0,phi(beta)), P(-4,0), "$b$", l);
+
+ // use mag_ctr to place inset labels
+ red();
+ label(P(beta+0.1,phi(beta+0.1)), P(-2,2), "$\\varphi$",tl);
+ label(mag_ctr, P(0,6), "$\\varphi$",tr);
+
+ blue();
+ label(P(beta+0.1,psi(beta+0.1)), P(2,-2), "$\\psi$",br);
+ label(mag_ctr, P(8,-2), "$\\psi$",br);
+
+ green(0.6);
+ label(P(beta-0.1,ht-0.1*slope), P(2,2), "$\\ell$",tr);
+ label(mag_ctr, P(-12,20), "$\\ell$", bl);
+
+ black();
+ // a large label
+ label_border(Blue(), "0.2pt");
+ masklabel(P(0.5*(xmin()+xmax()), ymax()), P(0,0),
+ "\\begin{minipage}{2.25in}A graph with unexpected tangent line\\end{minipage}", b);
+
+ end();
+}
diff --git a/graphics/epix/samples/geomsum.xp b/graphics/epix/samples/geomsum.xp
new file mode 100644
index 0000000000..665b1568e8
--- /dev/null
+++ b/graphics/epix/samples/geomsum.xp
@@ -0,0 +1,37 @@
+/* -*-ePiX-*- */
+/* geomsum.c -- July 16, 2001 */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(8);
+
+int main()
+{
+ picture(P(0,0), P(1,1), "2.5x2.5in");
+ begin();
+
+ pen(White(), "0.8pt");
+ fill(White(0.9));
+ rect(P(0,0), P(1,1));
+
+ black();
+ label(P(1.0/4, 1.0/2), "$\\frac{1}{2}$");
+ label(P(5.0/8, 3.0/4), "$\\frac{1}{8}$");
+ label(P(13.0/16, 7.0/8), "$\\frac{1}{32}$");
+
+ white();
+ fill(Blue());
+ double t(0.5);
+
+ for(int i=0; i<N; ++i, t *= 0.5)
+ {
+ rect(P(1-t, 1-2*t), P(1, 1-t));
+ line(P(1-t, 1-2*t), P(1-t, 1));
+ }
+
+ label(P(3.0/4, 1.0/4), "$\\mathbf{\\frac{1}{4}}$");
+ label(P(7.0/8, 5.0/8), "$\\mathbf{\\frac{1}{16}}$");
+ label(P(15.0/16, 13.0/16), "$\\mathbf{\\frac{1}{64}}$");
+
+ end();
+}
diff --git a/graphics/epix/samples/golden_rect.xp b/graphics/epix/samples/golden_rect.xp
new file mode 100644
index 0000000000..f6fc6d54a1
--- /dev/null
+++ b/graphics/epix/samples/golden_rect.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double tau((1+sqrt(5))/2);
+
+int main()
+{
+ bounding_box(P(0,0), P(tau,1));
+ picture(100*(1+tau), 100*tau);
+ unitlength("0.0125in");
+
+ begin();
+
+ dashed();
+ line(P(0.5,0), P(0.5,1));
+
+ solid();
+ line(P(1,0), P(1,1));
+ line(P(0.5,0), P(1,1));
+
+ arc(P(0.5,0), tau-0.5, 0, Atan(2.0));
+
+ bold();
+ rect(P(0,0), P(tau, 1));
+
+ end();
+}
+
diff --git a/graphics/epix/samples/helicoid.flx b/graphics/epix/samples/helicoid.flx
new file mode 100644
index 0000000000..fdf68fc7ad
--- /dev/null
+++ b/graphics/epix/samples/helicoid.flx
@@ -0,0 +1,133 @@
+/* -*-flix-*- */
+/*
+ * Animation depicting the local isometric deformation of a
+ * catenoid to a helicoid through minimal immersions
+ */
+#include "epix.h"
+using namespace ePiX;
+
+// number of meridians and latitudes
+int N1(72);
+int N2(24);
+
+P VIEWPT(4, 3, 4);
+
+// locations of "lights"; see mesh::draw() below for implementation
+P LIGHT_R(10,0,10);
+P LIGHT_G(0,10,10);
+P LIGHT_B(0,-10,10);
+
+// internal constants
+double r_0(1.0);
+double EPS(0.0); // fact shrink factor
+double du(2.0/N1), dv(4.0/N2);
+
+// parametrized surfaces
+P helicoid(double u, double v)
+{
+ return P(sinh(v)*Cos(M_PI*u), sinh(v)*Sin(M_PI*u), 2*M_PI*u);
+}
+
+P catenoid(double u, double v)
+{
+ return P(cosh(v)*Sin(M_PI*u), -cosh(v)*Cos(M_PI*u), -v);
+}
+
+P morph(double u, double v)
+{
+ return Cos(2*M_PI*tix())*helicoid(u,v) + Sin(2*M_PI*tix())*catenoid(u,v);
+}
+
+// facet-like class with spot reflection
+class element
+{
+private:
+ P pt1;
+ P pt2;
+ P pt3;
+ P pt4;
+
+ double distance;
+
+public:
+ element(P f(double u, double v), double u0, double v0)
+ : pt1(f(u0+EPS,v0+EPS)), pt2(f(u0+du-EPS,v0+EPS)),
+ pt3(f(u0+du-EPS,v0+dv-EPS)), pt4(f(u0+EPS,v0+dv-EPS))
+ {
+ P center(0.25*(pt1 + (pt2 + (pt3 + pt4))));
+ P temp(camera.viewpt());
+
+ distance = norm(center-temp);
+ }
+
+ double how_far() const { return distance; }
+
+ void draw()
+ {
+ P normal((pt2 - pt1)*(pt4 - pt1));
+ normal *= 1/norm(normal);
+
+ double dens_r(0.75*(pow(normal|LIGHT_R, 2)/(LIGHT_R|LIGHT_R)));
+ double dens_g(0.75*(pow(normal|LIGHT_G, 2)/(LIGHT_G|LIGHT_G)));
+ double dens_b(0.75*(pow(normal|LIGHT_B, 2)/(LIGHT_B|LIGHT_B)));
+
+ fill(RGB(dens_r, dens_g, dens_b));
+ ePiX::quad(pt1, pt2, pt3, pt4);
+ }
+
+};
+
+class By_distance {
+public:
+ bool operator() (const element& arg1, const element& arg2)
+ {
+ return arg1.how_far() > arg2.how_far();
+ }
+};
+
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ double MAX(8);
+ picture(P(-MAX,-MAX),P(MAX,MAX), "5x5in");
+
+ begin();
+ pen(Neutral(), 0); // no grid lines
+
+ // draw bounding square for uniform frame size
+ backing(Black());
+ viewpoint(VIEWPT);
+
+ /* rotating lights
+ LIGHT_R=cis(2*M_PI*tix());
+ LIGHT_G=cis(2*M_PI*(tix()+0.25));
+ LIGHT_B=P(-2,-2,6);
+ */
+
+ camera.range(20);
+
+ // build surface
+ std::vector<element> mesh;
+
+ for (int i=0; i<N1; ++i)
+ for (int j=0; j<N2; ++j)
+ mesh.push_back(element(morph, -1+du*i, -2+dv*j));
+
+ sort(mesh.begin(), mesh.end(), By_distance());
+
+ for (unsigned int i=0; i<mesh.size(); ++i)
+ mesh.at(i).draw();
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/hello.xp b/graphics/epix/samples/hello.xp
new file mode 100644
index 0000000000..812529f654
--- /dev/null
+++ b/graphics/epix/samples/hello.xp
@@ -0,0 +1,20 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "2x1in");
+
+ begin();
+
+ // uncomment and permute these lines
+ // crop_ellipse();
+ // backing(Cyan());
+ border(Black(), "1pt");
+
+ font_size("Huge");
+ label(P(0,0), "Hello, world!");
+
+ end();
+}
diff --git a/graphics/epix/samples/histogram.xp b/graphics/epix/samples/histogram.xp
new file mode 100644
index 0000000000..47e704fba2
--- /dev/null
+++ b/graphics/epix/samples/histogram.xp
@@ -0,0 +1,83 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// See binom.cc for instructions on creating data file binom.dat
+
+double erf(double x)
+{
+ return 100*exp(-0.02*(x-50)*(x-50))/sqrt(50*M_PI);
+}
+
+int main()
+{
+ picture(P(0,0),P(100,20), "6 x 6in");
+
+ begin();
+
+ grid(1,10);
+
+ // read disk file
+ data_file binom("binom.dat");
+
+ // create "bins" for bar chart
+ data_bins db05(-0.5, 100.5, 101); // 5% biased coin
+ data_bins db10(-0.5, 100.5, 101); // 10%
+ data_bins db30(-0.5, 100.5, 101); // 30%
+ data_bins db50(-0.5, 100.5, 101); // 50%
+
+ db05.read(binom.column(1));
+ db10.read(binom.column(2));
+ db30.read(binom.column(3));
+ db50.read(binom.column(4));
+
+ legend L;
+
+ fill();
+ gray(0.6);
+ db05.bar_chart(100);
+ L.fill_item("5\\%");
+
+ gray(0.4);
+ db10.bar_chart(100);
+ L.fill_item("10\\%");
+
+ gray(0.2);
+ db30.bar_chart(100);
+ L.fill_item("30\\%");
+
+ gray(0);
+ db50.bar_chart(100);
+ L.fill_item("50\\%");
+
+ nofill();
+
+ font_size("footnotesize");
+ tick_size(1);
+ bottom_axis(10, P(0,-4), b).draw();
+
+ left_axis(10, P(-4,0), l).subdivide(2).draw();
+
+ bold(Red());
+ plot(erf, xmin(), xmax(), 240);
+ L.path_item("Normal");
+
+ font_size("LARGE");
+ L.key_size(18);
+ L.draw(P(50, 12.5), P(2,2), tr);
+
+ font_face("sc");
+ label(P(0.5*(xmin()+xmax()), ymax()), P(0,12),
+ "Tossing a Biased Coin, 100,000 Trials", t);
+
+ font_size(); // reset to default
+ label(P(0.5*(xmin()+xmax()), ymin()), P(0,-18),
+ "Number of Heads (100 Tosses per Trial)", b);
+
+ degrees();
+ label_angle(90);
+ label(P(xmin(), 0.5*(ymin()+ymax())), P(-18,0), "Percentage of Trials", l);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/house.flx b/graphics/epix/samples/house.flx
new file mode 100644
index 0000000000..7f4d683849
--- /dev/null
+++ b/graphics/epix/samples/house.flx
@@ -0,0 +1,88 @@
+/* -*-flix-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double DY(0.1);
+const int N(200);
+const double dN(1.0/N);
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ picture(P(0,0), P(5,3), "5 x 3in");
+
+ begin();
+ set_crop();
+ // sky
+ bbold();
+ for (int i=0; i<2*N; ++i)
+ {
+ // fade blue gradient to black
+ rgb((1-0.6*tix())*(0.5-0.25*dN*i),
+ (1-0.6*tix())*(0.5-0.25*dN*i),
+ (1-0.6*tix())*(1-0.2*dN*i));
+
+ line(P(0,1+i*dN), P(5,1+i*dN));
+ }
+
+ // sun
+ pen(4);
+ revolutions();
+ for (int i=1; i<=10; ++i)
+ {
+ // redden as tix() -> 1
+ rgb((1-0.25*tix())*(1-0.01*i), (1-tix())*(1-0.015*i), 0);
+ circle(P(3+0.5*tix(), 2.5 - 2*tix()), 0.025*i);
+ }
+
+ // roof
+ red(0.6*(1-0.6*tix()));
+ line(P(0.9,1.5), P(1.5,1.8));
+ line(P(2.1,1.5), P(1.5,1.8));
+
+ // lawn
+ bbold();
+ for (int i=0; i<N; ++i)
+ {
+ // fade green gradient to black
+ green((1-0.6*tix())*0.4*(1+i*dN));
+
+ line(P(0,i*dN), P(5,i*dN));
+ }
+
+ plain();
+ fill();
+ gray(0.2+0.8*tix());
+
+ path house;
+ house.pt(P(1,1-DY)).pt(P(2,1-DY)).pt(P(2, 1.5)).pt(P(1.5,1.75)).pt(P(1,1.5));
+ house.close().fill();
+ house.draw();
+
+ gray(0.1+0.4*tix());
+
+ rect(P(1.2,1.1), P(1.4, 1.3)); // window
+
+ pen(2);
+ dot_size(1);
+ rgb(0.8*(1-tix()), 0.8*(1-tix()), 0);
+ ring(P(1.65, 1.15)); // doorknob
+
+ fill(false);
+ plain(Black());
+ rect(P(1.6, 1-DY), P(1.85, 1.4)); // door frame
+
+ bold(RGB((1-tix())*(0.6),(1-tix())*(0.4),(1-tix())*(0.2)));
+ grid(P(1.2,1.1), P(1.4, 1.3), 2, 2); // panes
+
+ end();
+}
diff --git a/graphics/epix/samples/hyperboloid.xp b/graphics/epix/samples/hyperboloid.xp
new file mode 100644
index 0000000000..6ea45c9192
--- /dev/null
+++ b/graphics/epix/samples/hyperboloid.xp
@@ -0,0 +1,63 @@
+/* -*-ePiX-*- */
+// A circular hyperboloid of one sheet and its two families of rulings
+#include "epix.h"
+using namespace ePiX;
+
+const int NUM_LINES(64);
+const double dt(1.0/NUM_LINES);
+
+int main()
+{
+ picture(P(-3, -3), P(3, 3), "6x6in");
+
+ begin();
+ revolutions();
+
+ cam().at(20, 0, 5);
+
+ clip_box(P(4, 4, 2));
+
+ fill(Black(0.8));
+
+ // hyperboloid
+ surface_rev(sinh, cosh, domain(P(-2,0), P(2,1), mesh(24,36)),
+ frame(E_3, E_2, E_1));
+
+ // clip to {x>0}
+ clip_box(P(0, -4, -2), P(4, 4, 2));
+
+ // rulings
+ for (int i=-0.5*NUM_LINES; i <= 0.5*NUM_LINES; ++i)
+ {
+ const double t(i*dt);
+ rgb(0,0.5,1);
+ Line(P(Cos(t), Sin(t), 0), P(Cos(t) + Sin(t), Sin(t) - Cos(t), 1));
+
+ red();
+ Line(P(Cos(t), Sin(t), 0), P(Cos(t) - Sin(t), Sin(t) + Cos(t), 1));
+ }
+
+ // emphatic rulings
+ bbold(RGB(0.1,0.6,0.9));
+ Line(P(1,0,0), P(1,-1,1));
+
+ pen(Red(1.2));
+ Line(P(1,0,0), P(1,1,1));
+ Line(P(0,1,0), P(-1,1,1));
+
+ clip_box();
+ // font_size("footnotesize");
+ black();
+ label(P(1,0,0)-P(0,-2,2), P(2,-2), "$\\ell_0^-$", br);
+ label(P(1,0,0)+P(0, 2,2), P(18,2), "$\\ell_0^+$", t);
+ label(P(0,1,0)-P(-2,0,2), P(0,-4), "$\\ell_{\\pi/2}^+$",b);
+
+ label(P(0,0,-3), P(0,-24),
+ "$\\ell_\\theta^-(t)=(\\cos\\theta, \\sin\\theta, 0) + t(\\sin\\theta, -\\cos\\theta, 1)$", b);
+
+ label(P(0,0,-3), P(0,-12),
+ "$\\ell_\\theta^+(t)=(\\cos\\theta, \\sin\\theta, 0) + t(-\\sin\\theta, \\cos\\theta, 1)$", b);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/inverse.xp b/graphics/epix/samples/inverse.xp
new file mode 100644
index 0000000000..d336b67b31
--- /dev/null
+++ b/graphics/epix/samples/inverse.xp
@@ -0,0 +1,74 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// parameters and an odd cubic
+const double x0(0.4); // critical point
+const double sqrt3(sqrt(3));
+
+double f(double x)
+{
+ return 2*x*(x-sqrt3*x0)*(x+sqrt3*x0);
+}
+
+int main()
+{
+ picture(P(-2,-1), P(2,1), "6 x 3in");
+
+ begin();
+
+ degrees();
+
+ // draw "ordinary" graph
+ screen tmp(P(-1,-1), P(1,1));
+ activate(tmp);
+
+ // diagonal
+ pen(Black(0.1));
+ line(P(-1,-1), P(1,1));
+
+ // two-headed arrow
+ pen(Black(0.3));
+ aarrow(P(0.4,0.6), P(0.6,0.4), 0.5);
+
+ // axes and labels
+ pen(Black());
+ font_size("footnotesize");
+
+ h_axis(8);
+ v_axis(8);
+
+ masklabel(P(1,0), "$x$");
+ masklabel(P(0,1), "$y$");
+
+ label(P(0.5,-0.5), "$y=f(x)$");
+
+ label_angle(-90);
+ label(P(-0.5,0.5), "$x=f^{-1}(y)$");
+
+ // crop remaining elements
+ tmp.set_crop();
+
+ // a horizontal tangent line
+ plain(Blue(1.4));
+ tan_line(f, x0);
+
+ // graphs that will be inverse branches
+ plain(Red(1.4));
+ plot(f, -1, -x0, 20);
+
+ bold(Red());
+ plot(f, -x0, x0, 20);
+
+ plain(Red(1.4));
+ plot(f, x0, 1, 20);
+
+ inset(tmp, P(-2,-1), P(0,1));
+
+ // flip plane over diagonal
+ affine af;
+ af.reflect(45).shift(P(0.25,0)); // compose affine maps
+ inset(tmp.apply(af), P(0,-1), P(2,1));
+
+ end();
+}
diff --git a/graphics/epix/samples/koch.xp b/graphics/epix/samples/koch.xp
new file mode 100644
index 0000000000..8a9683715c
--- /dev/null
+++ b/graphics/epix/samples/koch.xp
@@ -0,0 +1,38 @@
+/* -*-ePiX-*- */
+/* koch.c -- May 29, 2002 */
+#include "epix.h"
+using namespace ePiX;
+
+const int koch_seed[] = {6, 4, 0, 1, -1, 0};
+
+int main()
+{
+ picture(P(0,0), P(4, 1), "6 x 1.5in");
+
+ begin();
+ degrees();
+
+ for (int i=1; i <= 4; ++i)
+ {
+ // draw von Koch curve at "depth" i
+ screen tmp(P(-1,-1), P(1,1));
+ activate(tmp);
+
+ if (i==1)
+ {
+ bold(Red());
+ fractal(cis(150), cis(30), i, koch_seed);
+ plain(Black());
+ }
+ else
+ fractal(cis(150), cis( 30), i, koch_seed);
+
+ fractal(cis( 30), cis(-90), i, koch_seed);
+ fractal(cis(-90), cis(150), i, koch_seed);
+
+ inset(tmp, P(i-1,0), P(i,1));
+ deactivate(tmp);
+ }
+ end();
+}
+
diff --git a/graphics/epix/samples/label_debug.xp b/graphics/epix/samples/label_debug.xp
new file mode 100644
index 0000000000..0ca0462d74
--- /dev/null
+++ b/graphics/epix/samples/label_debug.xp
@@ -0,0 +1,132 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+/*
+ * Font tests; draws all 32 combinations of five attributes:
+ *
+ * label_color: (Neutral: cols 1, 3; Red, cols 2, 4)
+ * label_mask: (Neutral: cols 1, 2; Yellow: cols 3, 4)
+ *
+ * label_border color: (Neutral: odd rows, Blue otherwise)
+ * label_border width: (0pt: rows 1-2, 5-6, 1pt otherwise)
+ *
+ * pad: (0pt: rows 1-4, 1pt otherwise)
+ */
+
+// test objects
+void objs()
+{
+ label(P(-0.5,0), "The");
+ masklabel(P(0.5,0), "The");
+}
+
+// attribute-setting commands on bool flags
+void label_color(bool arg)
+{
+ if (arg)
+ label_color(Red());
+
+ else
+ label_color(Neutral());
+}
+
+void label_mask(bool arg)
+{
+ if (arg)
+ label_mask(Yellow(0.3));
+ else
+ label_mask(Neutral());
+}
+
+void set_border(bool col, std::string len)
+{
+ if (col)
+ label_border(Blue(1.2), len);
+
+ else
+ label_border(Neutral(), len);
+}
+
+void label_border(bool col, bool wid)
+{
+ if (wid)
+ set_border(col, "1pt");
+
+ else
+ set_border(col, "0pt");
+}
+
+void pad(bool arg)
+{
+ if (arg)
+ label_pad("6pt");
+
+ else
+ label_pad("0pt");
+}
+
+// we'll use 0, 1 as loop indices; convert to bool
+bool tf(int i)
+{
+ return i == 0 ? false : true;
+}
+
+// where to position the result of a test
+P loc(int i0, int i1, int i2, int i3, int i4)
+{
+ double horiz(0), vert(7);
+ if (tf(i0))
+ horiz += 1;
+
+ if (tf(i1))
+ horiz += 2;
+
+ if (tf(i2))
+ vert -= 1;
+
+ if(tf(i3))
+ vert -= 2;
+
+ if (tf(i4))
+ vert -= 4;
+
+ return P(horiz, vert);
+}
+
+int main()
+{
+ picture(P(0,0), P(4,8), "6 x 9in");
+
+ begin();
+
+ // the tests proper
+ for (int i0=0; i0<2; ++i0)
+ for (int i1=0; i1<2; ++i1)
+ for (int i2=0; i2<2; ++i2)
+ for (int i3=0; i3<2; ++i3)
+ for (int i4=0; i4<2; ++i4)
+ {
+ screen scr(P(-1,-1), P(1,1));
+ activate(scr);
+
+ solid(); // may need to reset line style
+ border(Green(0.6), "0.1pt");
+
+ backing(Black(0.1));
+ pen(Black(0.3));
+ grid(8,8);
+
+ label_color(tf(i0));
+ label_mask(tf(i1));
+ label_border(tf(i2),tf(i3));
+ pad(tf(i4));
+
+ objs();
+
+ scr.scale(0.9);
+ inset(loc(i0,i1,i2,i3,i4), loc(i0,i1,i2,i3,i4) + P(1,1));
+ deactivate(scr);
+ }
+ end();
+}
diff --git a/graphics/epix/samples/layout.xp b/graphics/epix/samples/layout.xp
new file mode 100644
index 0000000000..0967af53e2
--- /dev/null
+++ b/graphics/epix/samples/layout.xp
@@ -0,0 +1,36 @@
+/* -*-ePiX-*- */
+/* layout.xp -- June 27, 2007 */
+#include "epix.h"
+using namespace ePiX;
+
+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");
+ 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);
+ inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j));
+ deactivate(my);
+ }
+
+ end();
+}
+
diff --git a/graphics/epix/samples/layout2.xp b/graphics/epix/samples/layout2.xp
new file mode 100644
index 0000000000..f2203a2a84
--- /dev/null
+++ b/graphics/epix/samples/layout2.xp
@@ -0,0 +1,42 @@
+/* -*-ePiX-*- */
+/* layout.xp -- June 27, 2007 */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double s, double t)
+{
+ return P(0.1*s, 0.025*t) + (1/(0.01+s*s+t*t))*P(-t, s);
+}
+
+int main()
+{
+ picture(P(0,0), P(2,3), "5x7in");
+
+ begin();
+
+ for (int k=0; k<3; ++k)
+ for (int j=0; j<2; ++j)
+ {
+ screen my(P(-4, -3), P(2,2));
+ activate(my);
+
+ border(Red(0.6), "1pt");
+ set_crop();
+ plain(Blue(1.8));
+ dart_field(F, P(-4, -3), P(2, 2), 12, 10);
+
+ bold();
+ for (int i=0; i<7; ++i)
+ {
+ pen(RGB(0.05*(7-i), 1 - 0.1*i, 0.15*i));
+ ode_plot(F, P(-0.9-0.025*i,0), 4*(3*j+k+0.5), 30*(3*j+k+0.5));
+ }
+
+ inset(P(j+0.05,1.05-k), P(j+0.95,1.95-k));
+
+ deactivate(my);
+ }
+
+ end();
+}
+
diff --git a/graphics/epix/samples/legend.xp b/graphics/epix/samples/legend.xp
new file mode 100644
index 0000000000..a6be848bc9
--- /dev/null
+++ b/graphics/epix/samples/legend.xp
@@ -0,0 +1,72 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P sin_n(double x, double n) // Taylor polynomial of sin x
+{
+ const int N((int) floor(n)); // convert y to an index bound
+ const double sqx(-pow(x, 2)); // store -x^2 for efficiency
+ double val(x), summand(x); // places to store results of evaluation
+
+ // step through odd numbers from 1 to 2N+1
+ 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,-2.5),P(6*M_PI, 1), "5x3.5in");
+
+ begin();
+
+ camera.filter(CMY_Neutral());
+ set_crop();
+ plain(Black(0.5));
+ grid(12, 7);
+
+ // coordinate axis
+ axis Ax(P(0,0), P(6*M_PI,0), 12, P(0,-4), b);
+ Ax.trig().subdivide(4);
+
+ axis Ay(P(0,ymin()), P(0,ymax()), 7, P(-4,0), l);
+ Ay.frac().draw_labels();
+
+ // define a legend and set global attributes
+ legend L;
+ L.backing(Yellow(0.1)).border(Blue(), 1).item_border(0);
+
+ bbold(Green());
+ plot(Sin, 0, xmax(), 120);
+
+ // add a legend item
+ L.path_item("$y=\\sin x$");
+
+ domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(240, 40));
+
+ // print in descending degree so paths overlap better
+ for (int i=3; 0 <= i; --i)
+ {
+ pen(RGB(0.25*i, 0, 1-0.25*i));
+ plot(sin_n, R.slice2(5*i+1));
+
+ // add a legend item; key set automatically
+ std::stringstream buf;
+ buf << "$y=p_{" << 10*i+5 << "}(x)$";
+ L.path_item(buf.str());
+ }
+
+ plain(Black());
+ label_mask(White());
+ Ax.draw();
+
+ // place at bottom left
+ L.draw(canvas().bl(), P(2,2), tr);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/levelset.xp b/graphics/epix/samples/levelset.xp
new file mode 100644
index 0000000000..c802f5dc52
--- /dev/null
+++ b/graphics/epix/samples/levelset.xp
@@ -0,0 +1,60 @@
+/* -*-ePiX-*- */
+/* levelset.xp -- level sets */
+#include "epix.h"
+using namespace ePiX;
+
+const int MAX(3);
+const double k(0.25);
+
+P Fp(double u, double v)
+{
+ double r(sqrt(fabs(v)));
+ if (v>=0)
+ return P(r*cosh(u), r*sinh(u), k*v);
+
+ else
+ return P(-r*sinh(u), -r*cosh(u), k*v);
+
+}
+
+P Fm(double u, double v)
+{
+ double r(sqrt(fabs(v)));
+ if (v>=0)
+ return P(-r*cosh(u), r*sinh(u), k*v);
+
+ else
+ return P(-r*sinh(u), r*cosh(u), k*v);
+
+}
+
+double f(double x, double y)
+{
+ return k*(x-y)*(x+y);
+}
+
+int main()
+{
+ picture(P(-MAX,-MAX), P(MAX, MAX), "2x2in");
+
+ begin();
+
+ camera.at(P(1,-3,5));
+ camera.range(40);
+
+ clip_box(P(MAX,MAX,2*MAX));
+ clip();
+
+ red();
+ plot(f, P(-MAX,-MAX), P(MAX, MAX), mesh(4,4), mesh(40,40));
+
+ domain R(P(-4,-9), P(4,9), mesh(1,12), mesh(90,1));
+
+ bold(); rgb(0.5,0.5,1);
+ line(P(MAX,-MAX,0), P(-MAX, MAX,0));
+ line(P(MAX, MAX,0), P(-MAX,-MAX,0));
+ plot(Fp, R.slices2());
+ plot(Fm, R.slices2());
+
+ end();
+}
diff --git a/graphics/epix/samples/levelset2.xp b/graphics/epix/samples/levelset2.xp
new file mode 100644
index 0000000000..ab1a605069
--- /dev/null
+++ b/graphics/epix/samples/levelset2.xp
@@ -0,0 +1,72 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// Style parameters
+const int MAX(1); // maximum coordinate
+
+domain R(P(-MAX,-MAX), P(MAX, MAX), (24, 24), mesh(72,72));
+
+const double sqrt3(sqrt(3));
+
+// function to be graphed
+P f(double x, double y)
+{
+ return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x));
+}
+
+P color(double u, double v, double w)
+{
+ return P(-0.5*w, 0.25*w, 0.95*w);
+}
+
+int main()
+{
+ picture(P(-2*MAX,-2*MAX), P(2*MAX,2*MAX), "6 x 6in");
+
+ begin();
+
+ border(Green(0.6), "1pt");
+ backing(Black());
+
+ camera.at(sph(4*MAX, M_PI/6, M_PI/6));
+
+ // positioned for viewpt in first orthant
+ yellow();
+ grid(P(-MAX,-MAX,-MAX), P(MAX,MAX,-MAX), 4, 4);
+ grid(P(-MAX,-MAX,-MAX), P(MAX,-MAX,MAX), 4, 4);
+ grid(P(-MAX,-MAX,-MAX), P(-MAX,MAX,MAX), 4, 4);
+
+ axis Ax(P(-MAX,-MAX,MAX), P(MAX,-MAX,MAX), 4, P(0,6), t);
+ axis Ay(P(MAX,-MAX,-MAX), P(MAX,MAX,-MAX), 4, P(-2,-2), bl);
+ axis Az(P(MAX,-MAX,-MAX), P(MAX,-MAX,MAX), 4, P(-2,-2), bl);
+
+ Ax.frac().draw();
+ Ay.frac().draw();
+ Az.frac().draw();
+
+ clip_box(P(MAX,MAX,MAX));
+
+ // wire mesh surface
+ plain(Green());
+ plot(f, R);
+
+ // level bands
+ plain(Red());
+
+ for (int i=-5; i <=5; ++i)
+ {
+ clip_slice(P(0,0,0.2*i), P(0,0,1), 0.1);
+#ifdef FLATFILL
+ fill(RGB(0.25+0.1*i, 0, -0.1*i)); // index-dependent coloring
+ surface(f, R);
+#else
+ surface(f, R, color); // domain- or position-dependent coloring
+#endif
+ clip_restore(); // remove temporary slicing planes, keep clip box
+ }
+
+ pst_format();
+ end();
+}
+
diff --git a/graphics/epix/samples/levelset3.xp b/graphics/epix/samples/levelset3.xp
new file mode 100644
index 0000000000..aab13bec4f
--- /dev/null
+++ b/graphics/epix/samples/levelset3.xp
@@ -0,0 +1,89 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// Style parameters
+const int MESH(12); // number of coordinate grid squares
+const int MAX(3); // maximum coordinate
+
+// camera location (in spherical coordinates); must be in first orthant
+const P VIEWPT(sph(4*MAX, M_PI/6, M_PI/6));
+
+const double sqrt3(sqrt(3));
+
+// function to be graphed
+P f(double x, double y)
+{
+ // return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x));
+ return P(x,y, 0.9*MAX*exp(-0.5*(x*x+y*y))*x*y);
+ // return P(x, y, 0.25*(x-y*y)*(x-3*y*y));
+}
+
+P color(double u, double v, double w)
+{
+ return P(-0.5*w, 0.25*w, 0.5*w);
+}
+
+Color Bk(Green(0.7));
+
+int main()
+{
+ // picture(P(-2*MAX,-2*MAX), P(2*MAX,2*MAX), "6 x 6in");
+ picture(P(-MAX,-MAX), P(MAX,MAX), "6 x 6in");
+
+ begin();
+ backing(Bk);
+
+ camera.at(0,-10,4);
+
+ border(Green(0.6), "1pt");
+
+ clip_box(P(MAX,MAX,MAX));
+
+ domain R(P(-MAX,-MAX), P(MAX, MAX), (6*MESH, 6*MESH), mesh(6*MESH, 6*MESH));
+
+ legend L1, L2, L3;
+ L1.backing(Bk);
+ L2.backing(Bk);
+ L3.backing(Bk);
+
+ // pen(RGB(1, 0.8, 0.2), 0.1);
+ for (int i=-10; i <=10; ++i)
+ {
+ clip_slice(P(0,0,0.1*i), P(0,0,1), 0.1);
+ // fill(RGB(0.25+0.1*i, 0, -0.1*i));
+ rgb(0.25+0.1*i, 0, -0.1*i);
+
+ std::stringstream buf;
+ buf << "$" << 0.1*i - 0.05
+ << "\\leq z \\leq " << 0.1*i + 0.05 << "$";
+
+ if (i <-3)
+ L1.fill_item(buf.str());
+
+ else if(i<4)
+ L2.fill_item(buf.str());
+
+ else
+ L3.fill_item(buf.str());
+
+ nofill();
+ surface(f, R);
+ clip_restore();
+ }
+
+ camera.at(0,0,1000);
+ font_size("scriptsize");
+ label_color(Black());
+ L1.border(0);
+ L2.border(0);
+ L3.border(0);
+
+ L1.draw(canvas().bl(), P(2,2), tr);
+ L2.draw(canvas().bl()+P(2,0), P(2,2), tr);
+ L3.draw(canvas().bl()+P(4,0), P(2,2), tr);
+
+ pst_format();
+ end();
+}
+
diff --git a/graphics/epix/samples/lighting.flx b/graphics/epix/samples/lighting.flx
new file mode 100644
index 0000000000..80997bebeb
--- /dev/null
+++ b/graphics/epix/samples/lighting.flx
@@ -0,0 +1,132 @@
+/* -*-flix-*- */
+// compile with flix -I. [-DAXES] lighting.flx
+// in a directory containing lighting.h
+#include "epix.h"
+#include "lighting.h"
+using namespace ePiX;
+
+// mesh intervals for torus
+int N1(36), N2(12);
+
+// torus
+P F(double x, double y)
+{
+ double R(5-2*Sin(M_PI*y/N2));
+ return P(R*Cos(2*M_PI*x/N1), R*Sin(2*M_PI*x/N1), 2*Cos(M_PI*y/N2));
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+ picture(P(-10,-10),P(10,10), "4x4in");
+
+ begin();
+ set_crop();
+
+ backing(Black());
+
+ domain R(P(0,N2), P(N1,2*N2), mesh(N1,N2), mesh(2*N1,2*N2));
+
+ // manual layering below may require adjustment if the camera is moved
+ camera.at(P(4,6,4));
+ camera.range(16);
+
+#ifdef AXES
+ yellow();
+ label(P(8,0,0), P(-2,-2), "$\\mathbf{x}$", bl);
+ label(P(0,8,0), P( 2,-2), "$\\mathbf{y}$", br);
+ label(P(0,0,8), P( 0, 4), "$\\mathbf{z}$", t);
+#endif
+
+ // draw grid only
+ pen(Green(), 0.15);
+ plot(F, R);
+
+ // axes (with solid arrowheads) and shaded surface
+#ifdef AXES
+ arrow(P(0,0,0), P(8,0,0));
+ arrow(P(0,0,0), P(0,8,0));
+ arrow(P(0,0,0), P(0,0,8));
+#endif
+
+ rgb(0.8, 0.4, 0);
+ fill();
+ Color chip_color(White()); // true color of torus
+ Color ambient(RGB(1,0.75,0)); // ambient light
+
+ Fog fog(White(), 0.0125);
+
+ // spot light location
+ P spot_at(sph(10, M_PI_4, 2*M_PI*tix())); // traverses a longitude
+
+ // P spot_b=P(5,0,0)+cyl(10, 2*M_PI*tix(), 5); // or latitude
+ // P spot_b(5,-5,10); // or stays put
+ Spot spot(Blue(), spot_at);
+
+ std::vector<Chip> surf_mesh;
+ // torus, surface reflectivity .75
+ for (int i=0; i<N1; ++i)
+ for (int j=0; j<N2; ++j)
+ surf_mesh.push_back(Chip(F(i,j), F(i+1,j), F(i+1,j+1), F(i,j+1),
+ 0.75, chip_color));
+
+ sort(surf_mesh.begin(), surf_mesh.end(), chip_distance());
+
+#ifdef SHOW_SPOT
+ // mark spot light's location
+ if (spot_at.x2() <= 0)
+ {
+ blue();
+ box(spot.m_loc);
+ }
+#endif
+
+ // draw shaded surface mesh
+ for (unsigned int i=0; i<surf_mesh.size(); ++i)
+ surf_mesh.at(i).draw(fog, spot, ambient);
+
+#ifdef SHOW_SPOT
+ if (spot_at.x2() > 0)
+ {
+ blue();
+ box(spot.m_loc);
+ }
+#endif
+
+#ifdef AXES
+ // re-draw hidden portions
+ green();
+ line(P(3,0,0), P(8,0,0));
+ line(P(0,3,0), P(0,8,0));
+ line(P(0,0,0), P(0,0,8));
+#endif
+
+ fill(false);
+ // redraw front portion of mesh partially covered by solid surface
+ pen(Green(), 0.15);
+ plot(F, R.resize1(0, 0.25*N1));
+
+ // labels
+ base(White(), 1);
+ line(P(3,0,6), F(0,0.25*N2));
+ line(P(6,0,4), F(0,-0.25*N2));
+
+ label_border(Green(0.6), "0.5pt");
+ label_color(Black());
+ label_mask(RGB(1,0.8,0.2));
+
+ font_size("footnotesize");
+ masklabel(P(3,0,6), P(0,0), "Total curvature $-\\pi$", t);
+ masklabel(P(6,0,4), P(0,0), "Total curvature $\\pi$", t);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/lighting.h b/graphics/epix/samples/lighting.h
new file mode 100644
index 0000000000..6493332a95
--- /dev/null
+++ b/graphics/epix/samples/lighting.h
@@ -0,0 +1,114 @@
+double clip_0_1(double t)
+{
+ return (t<0) ? 0 : (t>1 ? 1 : t);
+}
+
+double trunc(double t)
+{
+ if (fabs(t) < 0.0001)
+ t=0;
+
+ return t;
+}
+
+namespace ePiX {
+
+ class Spot {
+ public:
+ Spot(const Color& col, const P& loc) : m_tint(col), m_loc(loc) { }
+
+ Color m_tint;
+ P m_loc;
+ };
+
+ class Fog {
+ public:
+ Fog(const Color& c, const double k) : m_tint(c), m_dens(k) { }
+
+ Color apply_to(const Color& col, const double dist) const
+ {
+ Color me(m_tint);
+ return me.blend(col, exp(-dist*m_dens));
+ }
+
+ private:
+ Color m_tint;
+ double m_dens;
+ };
+
+ // cf. facet class in facet.h
+ class Chip {
+ public:
+ Chip(const P& p1, const P& p2, const P& p3, const P& p4, const double s,
+ const Color& c)
+ : pt1(p1), pt2(p2), pt3(p3), pt4(p4), m_shine(s), m_tint(c)
+ {
+ m_ctr = 0.25*(p1+p2+p3+p4);
+ P n = (p2-p1)*(p4-p1);
+ n *= recip(norm(n));
+ m_perp=n;
+ }
+
+ double how_far() const { return norm(camera.viewpt()-m_ctr); }
+
+ void draw(const ePiX::Fog& fog,
+ const ePiX::Spot& spot,
+ const ePiX::Color& ambient) const
+ {
+ fill(appearance(camera.viewpt(), fog, spot, ambient));
+ ePiX::quad(pt1, pt2, pt3, pt4);
+ }
+
+ private:
+ P pt1, pt2, pt3, pt4; // vertices
+ double m_shine; // shininess
+ Color m_tint; // out color
+
+ P m_ctr; // our location
+ P m_perp; // unit normal
+
+ Color appearance(const P& viewer, const Fog& fog,
+ const Spot& spot, Color ambient) const
+ {
+ P spot_dir(spot.m_loc - m_ctr);
+ double spot_dist(norm(spot_dir));
+ spot_dir *= recip(spot_dist);
+
+ P view_dir(viewer - m_ctr);
+ double view_dist(norm(view_dir));
+ view_dir *= recip(view_dist);
+
+ // calculate relative intensities
+ //double I_ambt = pow((m_perp|view_dir), 2); // cos^2 of normal angle
+ double I_ambt(fabs(m_perp|view_dir)); // |cos| of normal angle
+
+ // crude but fairly effective
+ //double I_spot = 0.5*(1+((spot_dir*m_perp)|(m_perp*view_dir)));
+
+ // reflect spot_dir across m_perp in the plane they span,
+ // then take (cos(angle to viewer)^4)
+ P refl_dir(-spot_dir + 2*(spot_dir|m_perp)*m_perp);
+ double I_spot(pow((refl_dir|view_dir), 2));
+
+
+ // light from spot that reaches our location and is reflected to viewer
+ Color spot_refl(I_spot*(fog.apply_to(spot.m_tint, spot_dist)));
+
+ // not shiny -> reflect mostly ambient
+ Color refl(I_ambt*ambient.blend(spot_refl, m_shine));
+
+ // Color we reflect toward viewer
+ Color source(m_tint.filter(refl));
+ return fog.apply_to(source, view_dist);
+ }
+ };
+
+ class chip_distance {
+ public:
+ bool operator() (const Chip& arg1, const Chip& arg2)
+ {
+ return arg1.how_far() > arg2.how_far();
+ }
+ };
+} // end of namespace
+
diff --git a/graphics/epix/samples/line_debug.xp b/graphics/epix/samples/line_debug.xp
new file mode 100644
index 0000000000..13af932c78
--- /dev/null
+++ b/graphics/epix/samples/line_debug.xp
@@ -0,0 +1,126 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+/*
+ * Line and fill style test; draws all 32 combinations of five attributes:
+ *
+ * line color: (Neutral: cols 1, 3; Red, cols 2, 4)
+ * line style: (Solid: cols 1, 2; dashed: cols 3, 4)
+ *
+ * base color: (Neutral: odd rows, Blue otherwise)
+ * base width: (1pt: rows 1-2, 5-6, 4pt otherwise)
+ *
+ * fill color: (Neutral: rows 1-4, Yellow otherwise)
+ */
+
+// test objects
+void objs()
+{
+ rect(P(0,0), P(1,1));
+ line(P(-1,-1), P(1,-1));
+}
+
+// attribute-setting commands on bool flags
+void line_color(bool arg)
+{
+ if (arg)
+ pen(Red(), 2);
+
+ else
+ pen(Neutral(), 2);
+}
+
+void line_style(bool arg)
+{
+ if (arg)
+ dashed();
+}
+
+void base_color(bool col, double wid)
+{
+ if (col)
+ base(Blue(1.2), wid);
+
+ else
+ base(Neutral(), wid);
+}
+
+void base_pen(bool col, bool wid)
+{
+ if (wid)
+ base_color(col, 4);
+
+ else
+ base_color(col, 1);
+}
+
+void fill_color(bool arg)
+{
+ if (arg)
+ fill(Yellow());
+
+ else
+ fill(Neutral());
+}
+
+// we'll use 0, 1 as loop indices; convert to bool
+bool tf(int i)
+{
+ return i == 0 ? false : true;
+}
+
+// where to position the result of a test
+P loc(int i0, int i1, int i2, int i3, int i4)
+{
+ double horiz(0), vert(7);
+ if (tf(i0))
+ horiz += 1;
+
+ if (tf(i1))
+ horiz += 2;
+
+ if (tf(i2))
+ vert -= 1;
+
+ if(tf(i3))
+ vert -= 2;
+
+ if (tf(i4))
+ vert -= 4;
+
+ return P(horiz, vert);
+}
+
+int main()
+{
+ picture(P(0,0), P(4,8), "6 x 9in");
+
+ begin();
+
+ // the tests proper
+ for (int i0=0; i0<2; ++i0)
+ for (int i1=0; i1<2; ++i1)
+ for (int i2=0; i2<2; ++i2)
+ for (int i3=0; i3<2; ++i3)
+ for (int i4=0; i4<2; ++i4)
+ {
+ screen scr(P(-1,-1), P(1,1));
+ activate(scr);
+
+ solid(); // may need to reset line style
+ border(Green(0.6), "0.1pt");
+
+ line_color(tf(i0));
+ line_style(tf(i1));
+ base_pen(tf(i2),tf(i3));
+ fill_color(tf(i4));
+
+ objs();
+
+ scr.scale(0.9);
+ inset(loc(i0,i1,i2,i3,i4), loc(i0,i1,i2,i3,i4) + P(1,1));
+ deactivate(scr);
+ }
+ end();
+}
diff --git a/graphics/epix/samples/lissajous.xp b/graphics/epix/samples/lissajous.xp
new file mode 100644
index 0000000000..c713d760bb
--- /dev/null
+++ b/graphics/epix/samples/lissajous.xp
@@ -0,0 +1,28 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P f(double t)
+{
+ return P(Sin(3*t), Sin(4*t));
+}
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "2 x 2in");
+
+ begin();
+ revolutions();
+
+ bold(Red());
+ plot(f, 0, 1, 200);
+
+ arrow_inset(0.2);
+ arrow_width(1.5);
+
+ plain(Blue());
+ tan_field(f, 0, 1, 81);
+
+ end();
+}
+
diff --git a/graphics/epix/samples/log.xp b/graphics/epix/samples/log.xp
new file mode 100644
index 0000000000..4f16921cdf
--- /dev/null
+++ b/graphics/epix/samples/log.xp
@@ -0,0 +1,217 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// October 28, 2006
+//
+// This file depicts two sheets of the Riemann surface of log, together
+// with the log function over the unit circle. Surface and path elements
+// must be drawn together. However, path-like mesh elements must be drawn
+// after surface elements that lie at the same location in the scene,
+// since otherwise surface elements' edges occlude the path.
+//
+// A mesh_elt class stores the necessary P data as well as a flag marking
+// the element as a segment or a surface patch. Elements are stored in a
+// std::vector (global to the scene) and sorted by distance. To ensure that
+// surface patches are printed first, their true distance is increased by a
+// "fudge" amount (0.25), making the By_distance class see them as farther
+// than they really are.
+//
+// Path elements are drawn in green; surface patches are shaded gray
+// according to the angle between the incoming light (from a point source)
+// and the surface normal.
+//
+// Surface patches are drawn as octagons to make the mesh appear smoother
+// than a quadrilateral mesh. The vertices of a patch are the images of the
+// corners and midpoints of a coordinate quadrilateral, "retracted" inward
+// by a small "gap" EPS (possibly zero). A positive gap simulates surface
+// transparency.
+//
+// (u,v+dv) (u+0.5*du,v+dv) (u+du,v+dv)
+// +----------------------+-----------------------+
+// | *--------------------*---------------------* |
+// | | | |
+// | | | |
+// | | | |
+// + * (u+EPS,v+0.5*dv) * + (u+du,v+0.5*dv)
+// | | | |
+// | | | |
+// | | (u+EPS,v+EPS) | |
+// | *--------------------*---------------------* |
+// +----------------------+-----------------------+
+// (u,v) (u+0.5*du,v) (u+du,v)
+
+
+const P LIGHT(2, 2, 0); // location of light, for shading
+const P VIEWPT(15,-10,6);
+
+// surface and path mesh fineness
+const int N1(18);
+const int N2(80);
+
+const int N3(120);
+
+const double du(4.5/N1);
+const double dv(6.0/N2);
+
+const double dt(4.0/N3);
+
+// "gap size" between surface mesh elements
+const double EPS(0); // (0.002);
+
+// visual styles
+void path_color() { green(0.8); }
+void label_color() { yellow(0.5); }
+void dot_color() { red(); }
+void path_width() { pen(1.5); }
+
+// class can represent either a surface element or a path element
+class mesh_elt {
+private:
+ P pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, center;
+
+ double fudge; // artificial increment to distance
+ static bool last_was_seg;
+ bool is_segment;
+
+public:
+ double how_far() const
+ {
+ return fudge + norm(center - camera.viewpt());
+ }
+
+ mesh_elt(P f(double u, double v), double u0, double v0)
+ : pt1(f(u0+EPS,v0+EPS)), pt2(f(u0+0.5*du,v0+EPS)),
+ pt3(f(u0+du-EPS,v0+EPS)), pt4(f(u0+du-EPS,v0+0.5*dv)),
+ pt5(f(u0+du-EPS,v0+dv-EPS)), pt6(f(u0+0.5*du,v0+dv-EPS)),
+ pt7(f(u0+EPS,v0+dv-EPS)), pt8(f(u0+EPS,v0+0.5*dv)),
+ center(0.25*(pt1 + (pt3 + (pt5 + pt7)))),
+ fudge(0.25), is_segment(false) { }
+
+ mesh_elt(P f(double), double t0)
+ : pt1(f(t0)), pt2(f(t0+0.25*dt)), pt3(f(t0+0.5*dt)),
+ pt4(f(t0+0.75*dt)), pt5(f(t0+dt)), pt6(), pt7(), pt8(),
+ center(0.333*(pt1 + (pt3 + pt5))),
+ fudge(0), is_segment(true) { }
+
+ void draw() const
+ {
+ if (!is_segment) {
+ P normal((pt2 - pt1)*(pt4 - pt1));
+ normal *= 1/norm(normal);
+
+ double dens(0.5*(1-((normal|LIGHT)/norm(LIGHT))));
+
+ if (mesh_elt::last_was_seg)
+ {
+ mesh_elt::last_was_seg=false;
+ plain(); // reset pen width
+ }
+
+ black();
+ gray(dens);
+
+ std::vector<P> bd;
+ bd.push_back(pt1);
+ bd.push_back(pt2);
+ bd.push_back(pt3);
+ bd.push_back(pt4);
+ bd.push_back(pt5);
+ bd.push_back(pt6);
+ bd.push_back(pt7);
+ bd.push_back(pt8);
+
+ path temp(bd, true, true); // closed and filled
+ temp.draw();
+ }
+ else { // segment
+ if (!mesh_elt::last_was_seg)
+ {
+ mesh_elt::last_was_seg=true;
+ path_width();
+ path_color();
+ }
+
+ std::vector<P> bd;
+ bd.push_back(pt1);
+ bd.push_back(pt2);
+ bd.push_back(pt3);
+ bd.push_back(pt4);
+ bd.push_back(pt5);
+
+ path temp(bd, false, false);
+ temp.draw();
+ }
+
+ } // end of mesh_elt::draw()
+
+}; // end of class mesh_elt
+
+// initialize static data
+bool mesh_elt::last_was_seg = false;
+
+class By_distance {
+public:
+ bool operator() (const mesh_elt arg1, const mesh_elt arg2)
+ {
+ return (arg1.how_far()) > (arg2.how_far());
+ }
+};
+
+// the maps to be plotted
+P C_log(double u, double v)
+{
+ return polar(exp(u), M_PI*v) + P(0, 0, u+M_PI*v);
+}
+
+P C_log1(double t)
+{
+ return C_log(0,t);
+}
+
+int main() {
+ bounding_box(P(-6, -12),P(6,12));
+ unitlength("1in");
+ picture(P(4,8));
+
+ begin();
+ fill();
+
+ degrees();
+ // label_angle(90);
+ label(P(0, ymin()), P(0,4),
+ "$z=\\mathrm{Re}\\,\\log(x+iy) + \\mathrm{Im}\\,\\log(x+iy)$", t);
+ radians();
+ // label_angle(0);
+
+ viewpoint(VIEWPT);
+ camera.range(20);
+
+ std::vector<mesh_elt> mesh_data;
+
+ // surface elements
+ for (int i=0; i<N1; ++i)
+ for (int j=0; j<N2; ++j)
+ mesh_data.push_back(mesh_elt(C_log, -3+du*i, -3+dv*j));
+
+ // path elements
+ for (int i=0; i<N3; ++i)
+ mesh_data.push_back(mesh_elt(C_log1, -2+i*dt));
+
+ stable_sort(mesh_data.begin(), mesh_data.end(), By_distance());
+
+ for (int i=0; i<mesh_data.size(); ++i)
+ mesh_data.at(i).draw();
+
+ dot_color();
+ marker(C_log(0,-2), BOX);
+ marker(C_log(0, 0), BOX);
+ marker(C_log(0, 2), BOX);
+
+ label_color();
+ label(C_log(0,-2), P(6, 0), "$-2\\pi i$", r);
+ label(C_log(0, 0), P(6, 0), "$0$", r);
+ label(C_log(0, 2), P(-6, 0), "$2\\pi i$", l);
+
+ end();
+}
diff --git a/graphics/epix/samples/lorenz.xp b/graphics/epix/samples/lorenz.xp
new file mode 100644
index 0000000000..6b2afae3cf
--- /dev/null
+++ b/graphics/epix/samples/lorenz.xp
@@ -0,0 +1,70 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// ODE parameters
+const double A1(10);
+const double A2(28);
+const double A3(2.6666);
+
+// parameter box
+const double MAX(30);
+
+// bounding box (set in screens)
+const double XMAX(50);
+
+// flow time
+const double TMAX(2000);
+
+P F(double x, double y, double z)
+{
+ return 0.01*P(A1*(y-x), x*(A2-z)-y, x*y-A3*z);
+}
+
+domain R(P(-MAX,-MAX,0), P(MAX,MAX,2*MAX), mesh(6, 6, 6));
+
+void draw_frame()
+{
+ dart_field(F, R.resize1(0,MAX), 0.5);
+
+ bold(Red());
+ ode_plot(F, P(10,0,0), 0, TMAX, TMAX);
+
+ pen(Blue());
+ // nearby start points, but trajectories not close
+ ode_plot(F, P(10.5,0,0), 0, TMAX, TMAX);
+
+ plain(Black());
+ dart_field(F, R.resize1(-MAX,0), 0.5);
+}
+
+// initialize the camera
+void init_cam(const P& arg)
+{
+ camera.at(arg);
+ camera.look_at(P(0,0,MAX));
+ camera.range(500);
+}
+
+int main()
+{
+ picture(P(-1,0), P(1,1), "6x3in");
+
+ begin();
+
+ screen left_eye(P(-XMAX,-XMAX), P(XMAX,XMAX));
+ activate(left_eye);
+ init_cam(P(-100, 90, 63));
+ draw_frame();
+
+ screen right_eye(P(-XMAX,-XMAX), P(XMAX,XMAX));
+ activate(right_eye);
+ init_cam(P(-100, 80, 63));
+ draw_frame();
+
+ // page layout
+ inset(left_eye, P(0,0), P(1,1));
+ inset(right_eye, P(-1,0), P(0,1));
+
+ end();
+}
diff --git a/graphics/epix/samples/medians.xp b/graphics/epix/samples/medians.xp
new file mode 100644
index 0000000000..e1e8bf910a
--- /dev/null
+++ b/graphics/epix/samples/medians.xp
@@ -0,0 +1,134 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const P pt1(2,-1);
+const P pt2(1,2);
+const P pt3(-2,0);
+
+void altitude_color()
+{
+ blue(1.4);
+}
+
+#ifdef BISECTORS
+void bisector_color()
+{
+ green(1.4);
+}
+#endif
+
+// project arg to line through tail, head
+P drop_perp(const P& arg, const P& tail, const P& head)
+{
+ return arg - ((arg - tail)%(head - tail)); // % = orthogonalization
+}
+
+#ifdef BISECTORS
+P bisector(const P& arg, const P& tail, const P& head)
+{
+ P dir_tl(tail - arg);
+ dir_tl *= 1.0/norm(dir_tl);
+
+ P dir_hd(head - arg);
+ dir_hd *= 1.0/norm(dir_hd);
+
+ Segment bisect(arg, arg + 0.5*(dir_tl + dir_hd));
+
+ return Segment(tail, head)*bisect;
+}
+#endif
+
+void rangle(const P& arg, const P& tail, const P& head)
+{
+ const P dir(head - tail);
+ const P loc(arg - ((arg - tail)%dir));
+
+ right_angle(loc, dir, J(dir));
+}
+
+const P q1(drop_perp(pt1, pt2, pt3));
+const P q2(drop_perp(pt2, pt3, pt1));
+const P q3(drop_perp(pt3, pt1, pt2));
+
+#ifdef BISECTORS
+const P r1(bisector(pt1, pt2, pt3));
+const P r2(bisector(pt2, pt3, pt1));
+const P r3(bisector(pt3, pt1, pt2));
+#endif
+
+int main()
+{
+ picture(P(-3,-3), P(3,3), "4x4in");
+
+ begin();
+ set_crop();
+
+ // sides
+ Segment side1(pt2, pt3);
+ Segment side2(pt3, pt1);
+ Segment side3(pt1, pt2);
+
+ // medians
+ Segment med1(pt1, side1.midpoint());
+ Segment med2(pt2, side2.midpoint());
+ Segment med3(pt3, side3.midpoint());
+
+ // altitudes
+ Segment alt1(pt1, q1);
+ Segment alt2(pt2, q2);
+ Segment alt3(pt3, q3);
+
+#ifdef BISECTORS
+ // bisectors
+ Segment bis1(pt1, r1);
+ Segment bis2(pt2, r2);
+ Segment bis3(pt3, r3);
+#endif
+
+ med1.draw();
+ med2.draw();
+ med3.draw();
+
+ bold();
+ side1.draw();
+ side2.draw();
+ side3.draw();
+ plain();
+
+ altitude_color();
+ alt1.draw();
+ alt2.draw();
+ alt3.draw();
+
+ rangle(q1, pt2, pt3);
+ rangle(q2, pt3, pt1);
+ rangle(q3, pt1, pt2);
+
+ circle(q1, q2, q3);
+
+ label(q1, P(-2,4), "$a_1$", t);
+ label(q2, P(-2,-4), "$a_2$", b);
+ label(q3, P(4,0), "$a_3$", r);
+
+#ifdef BISECTORS
+ bisector_color();
+ bis1.draw();
+ bis2.draw();
+ bis3.draw();
+
+ // circle(r1, r2, r3);
+#endif
+
+ black();
+ font_size("footnotesize");
+ label(pt1, P(2,-2), "$p_1$", br);
+ label(pt2, P(2,2), "$p_2$", tr);
+ label(pt3, P(-4,-2), "$p_3$", l);
+
+ label(side1*med1, P(-4,2), "$m_1$", tl);
+ label(side2*med2, P(-2,-4), "$m_2$", b);
+ label(side3*med3, P(4,0), "$m_3$", r);
+
+ end();
+}
diff --git a/graphics/epix/samples/minkowski.xp b/graphics/epix/samples/minkowski.xp
new file mode 100644
index 0000000000..c9e841730b
--- /dev/null
+++ b/graphics/epix/samples/minkowski.xp
@@ -0,0 +1,103 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double MAX(3);
+
+// hyperboloid of one sheet/spacelike cone
+P Fp(double x, double y, double z)
+{
+ return P(z*cosh(x)*Cos(y), z*cosh(x)*Sin(y), z*sinh(x));
+}
+
+// hyperboloid of two sheets/timelike cone
+P Fm(double x, double y, double z)
+{
+ return P(z*sinh(x)*Cos(y), z*sinh(x)*Sin(y), z*cosh(x));
+}
+
+// light cone
+P Fz(double x, double y)
+{
+ return fabs(sinh(x))*P(Cos(y), Sin(y), sgn(x));
+}
+
+// hyperbolic lines
+P hl1(double t)
+{
+ return cosh(t)*P(-sqrt(1.25),0,1.5) + sinh(t)*E_2;
+}
+
+P hl2(double t)
+{
+ return cosh(t)*P(-1,0.5,1.5) + (sqrt(0.4)*sinh(t))*P(0.5, 1, 0);
+}
+
+int main()
+{
+ bounding_box(P(-MAX,-MAX),P(MAX,MAX));
+ unitlength("1in");
+ picture(6,6);
+
+ begin();
+ camera.at(10,-3,4);
+ // camera.range(40);
+
+ revolutions();
+
+ domain R(P(-1.5,0.25,-1), P(1.5,0.75,1), mesh(18, 12, 4), mesh(36, 48, 12));
+
+ fill(White());
+
+ // assemble surfaces as a single object
+ scenery hyp(Fp, R.slice3(1));
+ hyp.add(Fm, R.resize1(0,1.5).slice3(1));
+ hyp.add(Fm, R.resize1(-1.5,0).slice3(-1));
+ hyp.add(Fz, R.slice3(1));
+
+ hyp.draw();
+ nofill();
+
+ // Draw cuts of intersection with (y,z)-plane.
+ // Simulated 3-D/tube pen: light color drawn over darker shade
+ base(Red(0.6), "3pt");
+ bold(Red());
+
+ plot(Fp, R.slice2(0.25).slice3(1));
+ plot(Fp, R.slice2(0.25).slice3(-1));
+
+ plot(Fm, R.slice2(0.25).slice3(1));
+ plot(Fm, R.slice2(0.25).slice3(-1));
+
+ plot(Fz, R.slice2(0.25).slice3(1));
+ plot(Fz, R.slice2(0.75).slice3(-1));
+
+ // to clip lines
+ clip_box(P(-10,-10,-cosh(1.5)), P(10,10,cosh(1.5)));
+
+ base(Green(0.6), "3pt");
+ bold(Green());
+
+ plot(hl1, -1.5, 1.5, 120);
+ plot(hl2, -1.5, 1.5, 120);
+
+ // Labels with "overlay" arrows
+ font_size("scriptsize");
+
+ black();
+ camera.at(P(0,0,10000));
+ label(P(1.5,0), P(4,16), "Future timelike unit vectors", r);
+ label(P(1.5,0), P(4,0), "Unit spacelike vectors", r);
+ label(P(1.5,0), P(4,-16), "Lightlike vectors", r);
+ label(P(1.5,0), P(4,-32), "Past timelike unit vectors", r);
+
+ base(White(), "2pt");
+ bold(Black());
+ arrow(P(1.5,0), P(1,0), 0.5);
+ arrow(P(1.5, 0.25), P(1,1.35), 0.5);
+ arrow(P(1.5,-0.25), P(1,-0.75), 0.5);
+ arrow(P(1.5,-0.5), P(1,-1.05), 0.5);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/mirrorball.flx b/graphics/epix/samples/mirrorball.flx
new file mode 100644
index 0000000000..858ee4e904
--- /dev/null
+++ b/graphics/epix/samples/mirrorball.flx
@@ -0,0 +1,93 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double r_0(1); //0.75;
+const double golden(0.5*(1+sqrt(5)));
+
+Sphere S0(P(0,0,0), sqrt(3));
+
+Sphere S1(P( 1, golden, 0), r_0);
+Sphere S2(P(-1, golden, 0), r_0);
+Sphere S3(P( 1,-golden, 0), r_0);
+Sphere S4(P(-1,-golden, 0), r_0);
+
+Sphere S5(P( 0, 1, golden), r_0);
+Sphere S6(P( 0,-1, golden), r_0);
+Sphere S7(P( 0, 1,-golden), r_0);
+Sphere S8(P( 0,-1,-golden), r_0);
+
+Sphere S9(P( golden, 0, 1), r_0);
+Sphere Sa(P( golden, 0,-1), r_0);
+Sphere Sb(P(-golden, 0, 1), r_0);
+Sphere Sc(P(-golden, 0,-1), r_0);
+
+Circle C1(S0*S1);
+Circle C2(S0*S2);
+Circle C3(S0*S3);
+Circle C4(S0*S4);
+Circle C5(S0*S5);
+Circle C6(S0*S6);
+Circle C7(S0*S7);
+Circle C8(S0*S8);
+Circle C9(S0*S9);
+Circle Ca(S0*Sa);
+Circle Cb(S0*Sb);
+Circle Cc(S0*Sc);
+
+// bold circle if facing camera, otherwise plain
+void sphere_draw(const Circle& C)
+{
+ if ((C.center()|camera.viewpt()) >= 0)
+ bold();
+ else plain();
+
+ C.draw();
+}
+
+void icosa()
+{
+ // S0.draw();
+ sphere_draw(C1);
+ sphere_draw(C2);
+ sphere_draw(C3);
+ sphere_draw(C4);
+ sphere_draw(C5);
+ sphere_draw(C6);
+ sphere_draw(C7);
+ sphere_draw(C8);
+ sphere_draw(C9);
+ sphere_draw(Ca);
+ sphere_draw(Cb);
+ sphere_draw(Cc);
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ picture(P(-2,-2),P(2,2), "6x6in");
+
+ begin();
+ set_crop();
+ revolutions();
+
+ // draw frames
+ camera.at(sph(12, 0.5*tix(), 0.05));
+ red(-1.4); // nearly cyan
+ icosa();
+
+ camera.at(sph(12, 0.01+0.5*tix(), 0.05));
+ red(1.4);
+ icosa();
+
+ end();
+}
diff --git a/graphics/epix/samples/newton.xp b/graphics/epix/samples/newton.xp
new file mode 100644
index 0000000000..d9af0b087f
--- /dev/null
+++ b/graphics/epix/samples/newton.xp
@@ -0,0 +1,43 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double t)
+{
+ return 1 + t*(-3 + t*t);
+}
+
+double df(double t)
+{
+ return Deriv(f)(t).x2();
+}
+
+int main()
+{
+ picture(P(1.5,0), P(2,3), "2.5 x 2.5in");
+
+ begin();
+ h_axis(2);
+
+ double x0(2), x1(x0-f(x0)/df(x0));
+ label(P(x0,0), P(0,-4), "$x_i$", b);
+
+ for (int i=0; i < 3; ++i)
+ {
+ dashed();
+ line(P(x0,0), P(x0,f(x0)));
+ solid();
+ line(P(x0,f(x0)), P(x0-f(x0)/df(x0),0));
+
+ x0 -= f(x0)/df(x0); // Newton's method
+ }
+
+ bold();
+ plot(f, xmin(), xmax()+0.05, 60);
+
+ label(P(1.75, f(1.75)), P(-2,2), "$y=f(x)$", tl);
+ label(P(x1,0), P(0,-4), "$x_{i+1}$", b);
+ label(P(1.75, df(2)*(1.75-x1)), P(0,-4), "Slope $= f'(x_i)$", br);
+
+ end();
+}
diff --git a/graphics/epix/samples/objects.xp b/graphics/epix/samples/objects.xp
new file mode 100644
index 0000000000..ddf38cbee1
--- /dev/null
+++ b/graphics/epix/samples/objects.xp
@@ -0,0 +1,32 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(0,0), P(5,2), "3.75 x 1.5in");
+
+ begin();
+
+ // roof
+ triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices
+
+ // sun
+ circle(P(4,1.5), 0.25); // center and radius
+
+ // house
+ rect(P(1,0), P(3,1)); // opposite corners
+ // grid(P(1,0), P(3,1), 1, 10); // corners, numbers of subdivisions
+
+ // door
+ fill(Black(0.1));
+ rect(P(2.3,0), P(2.7,0.8)); // corners
+
+ fill(White());
+ // window
+ bold();
+ grid(P(1.4,0.2), P(2, 0.6), 2, 2);
+
+ line(P(xmin(),0), P(xmax(),0));
+ end();
+}
diff --git a/graphics/epix/samples/oscillator.xp b/graphics/epix/samples/oscillator.xp
new file mode 100644
index 0000000000..c174613cb0
--- /dev/null
+++ b/graphics/epix/samples/oscillator.xp
@@ -0,0 +1,89 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double t, double a) { return 2*exp(-0.5*t)*Sin(a*t); }
+
+// Completely fabricated data
+// "Predicted"
+double f1(double t)
+{
+ return f(t,2);
+}
+
+// "Observed"
+double f2(double t)
+{
+ return f1(t)+0.1*Cos(3*t);
+}
+
+//"error"
+double err(double t)
+{
+ return 0.125*(1+fabs(f1(t)));
+}
+
+// Number of error bars
+const int samples(8);
+
+// Half-size of bounding box
+const int N(2);
+
+int main()
+{
+ picture(P(0,-N),P(2*N,N), "2.5 x 2.5in");
+
+ begin();
+
+ // displacement for miscellaneous labels/objects
+ const double delta(0.0625*xsize());
+
+ // graph paper
+ pen(Black(0.25));
+ grid(5*N*(int)xsize(),5*N*ysize());
+
+ pen(Black());
+ grid(N*(int)xsize(), N*(int)ysize());
+
+ // axes, names, and labels
+ bold();
+ dart(P(xmin(),0), P(xmax()+delta,0));
+ dart(P(0,ymin()), P(0,ymax()+delta));
+
+ font_size("scriptsize");
+ h_axis_masklabels(P(xmin()+1,0), P(xmax(),0), xsize()-1, P(0,2), c);
+ v_axis_labels(P(0,ymin()), P(0,ymax()), ysize(), P(-2, 0), l);
+
+ font_size("footnotesize");
+ label(P(xmax()+delta,0), P(2,0), "Time (sec)", r);
+ label_angle(M_PI_2);
+ label(P(0,0), P(-8,0), "Displacement (cm)",l);
+ label_angle(0);
+
+ legend L;
+ L.item_border(0);
+
+ // "Predicted" curve
+ pen(RGB(0.2, 0.7, 0.8));
+ plot(f1, xmin(), xmax(), 120);
+ L.path_item("Predicted");
+
+ // "error bars"
+ red();
+ L.mark_item(CIRC, "Measured");
+
+ for (int i=1; i < samples; ++i)
+ {
+ double t(xmin() + i*xsize()/samples);
+ v_error_bar(P(t, f2(t)), err(t), CIRC, 4); // 4 pt wide
+ }
+
+ black();
+ L.draw(canvas().br(), P(-2,2), tl);
+
+ font_face("sc");
+ label(P(0.5*(xmin()+xmax()), ymax()), P(0,2),
+ "A damped harmonic oscillator", t);
+
+ end();
+}
diff --git a/graphics/epix/samples/parabola.xp b/graphics/epix/samples/parabola.xp
new file mode 100644
index 0000000000..474a89c132
--- /dev/null
+++ b/graphics/epix/samples/parabola.xp
@@ -0,0 +1,32 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// the function to be plotted
+double f(double x)
+{
+ return x*x;
+}
+
+int main()
+{
+ picture(P(-2,0), P(2,4), "2.5x2.5in");
+
+ begin();
+
+ pen(Black(0.3));
+ grid(8,8); // and coarse
+
+ pen(Black());
+ axis Ax(P(xmin(),0), P(xmax(),0), 4, P(0,-4), b);
+ axis Ay(P(0,ymin()), P(0,ymax()), 4, P(4, 0), r);
+
+ font_size("scriptsize");
+ Ax.draw();
+ Ay.unmark(0).draw();
+
+ bold(Red());
+ plot(f, xmin(), xmax(), 40);
+
+ end();
+}
diff --git a/graphics/epix/samples/pascal.xp b/graphics/epix/samples/pascal.xp
new file mode 100644
index 0000000000..7c597077a0
--- /dev/null
+++ b/graphics/epix/samples/pascal.xp
@@ -0,0 +1,53 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+int main()
+{
+ picture(P(-2,-2),P(2,2), "3 x 3in");
+
+ begin();
+ set_crop();
+
+ P V(2,-0.25), W(3,1);
+ P P1(-1.5,-1), P2(P1 + V), P3(P1 + 1.5*V); // points
+ P Q1(-1,1), Q2(Q1 + 0.5*W), Q3(Q1 + W);
+
+ Segment L12(P1, Q2), L13(P1, Q3);
+ Segment L21(P2, Q1), L23(P2, Q3);
+ Segment L31(P3, Q1), L32(P3, Q2);
+
+ // points of intersection
+ P R1(L12*L21), R2(L13*L31), R3(L32*L23);
+
+ dot(P1, P(0,-2), "$P_1$", b);
+ dot(P2, P(0,-2), "$P_2$", b);
+ dot(P3, P(0,-2), "$P_3$", b);
+
+ dot(Q1, P(0,2), "$Q_1$", t);
+ dot(Q2, P(0,2), "$Q_2$", t);
+ dot(Q3, P(0,2), "$Q_3$", t);
+
+ red();
+ L12.draw();
+ L21.draw();
+ L13.draw();
+
+ L31.draw();
+ L32.draw();
+ L23.draw();
+
+ green();
+ Line(P1,P3);
+ Line(Q1,Q3);
+
+ blue();
+ dot(R1, P(4,2), "$p_1$", r);
+ dot(R2, P(4,2), "$p_2$", r);
+ dot(R3, P(4,2), "$p_3$", r);
+
+ dashed();
+ Line(R1,R3);
+
+ end();
+}
diff --git a/graphics/epix/samples/pendulum.flx b/graphics/epix/samples/pendulum.flx
new file mode 100644
index 0000000000..ac0751d435
--- /dev/null
+++ b/graphics/epix/samples/pendulum.flx
@@ -0,0 +1,62 @@
+/* -*-flix-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double u, double v)
+{
+ return P(v, -Sin(u));
+}
+
+double theta0(-5*M_PI/6);
+double EPS(0.01); // to avoid singularity of f at theta0
+
+P posn0(theta0, 0);
+
+P pivot(0,5.5);
+double ell(3);
+
+double K(-Cos(theta0));
+
+double f(double t)
+{
+ return 1.0/sqrt(2*(K+Cos(t)));
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+ picture(P(-6.5,-2.5), P(6.5, 8.5), "6.5 x 5.5in");
+
+ begin();
+
+ // calculate period, avoiding singularity at theta0
+ double period(4*(sqrt(2*EPS/(-Sin(theta0)))+Integral(f).eval(-theta0-EPS)));
+
+ border(Black(0.1), "1pt");
+
+ P posn(flow(F, posn0, period*tix(), 120*tix())); // phase position
+ double x_t(-Sin(posn.x1()));
+ double y_t( Cos(posn.x1()));
+
+ slope_field(F, P(-2*M_PI,-2), P(2*M_PI,2), 48, 12);
+
+ bold();
+ line(pivot, pivot-ell*P(x_t, y_t));
+
+ red();
+ ode_plot(F, posn0, period, 120);
+
+ blue();
+ box(posn);
+ box(pivot-ell*P(x_t, y_t));
+
+ end();
+}
diff --git a/graphics/epix/samples/planes.xp b/graphics/epix/samples/planes.xp
new file mode 100644
index 0000000000..385a32194e
--- /dev/null
+++ b/graphics/epix/samples/planes.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(20);
+
+int main()
+{
+ picture(P(-2,-2), P(2,2), "6x6in");
+
+ begin();
+
+ border();
+ fill();
+
+ camera.at(P(10,-6,4));
+ clip_box(P(-1,-1,-1), P(1,1,1));
+
+ Plane C(P(-1,-1,-1), P(1,1,1));
+ for (int i=1; i<N; ++i)
+ {
+ rgb(i*1.0/N, 0.2, 1-i*1.0/N);
+ C.shift((2.0/N)*P(1,1,1));
+ C.draw();
+ }
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/plotting.xp b/graphics/epix/samples/plotting.xp
new file mode 100644
index 0000000000..ad310f7b02
--- /dev/null
+++ b/graphics/epix/samples/plotting.xp
@@ -0,0 +1,26 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double x)
+{
+ return 0.75*Sin(x) - 0.25*Sin(2*x);
+}
+
+int main()
+{
+ picture(P(-2,-1),P(2,1), "5x1in");
+
+ 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();
+}
diff --git a/graphics/epix/samples/plotting2.xp b/graphics/epix/samples/plotting2.xp
new file mode 100644
index 0000000000..41891142f5
--- /dev/null
+++ b/graphics/epix/samples/plotting2.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+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();
+
+ domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(16,120));
+
+ camera.at(3,1,2); // set the viewpoint
+
+ arrow(P(0,0,0), P(1.25,0,0));
+ arrow(P(0,0,0), P(0,1.25,0));
+
+ plain(Blue(1.2));
+ fill(Yellow()); // shade
+ surface(f, R);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/plotting3.xp b/graphics/epix/samples/plotting3.xp
new file mode 100644
index 0000000000..bd095e722c
--- /dev/null
+++ b/graphics/epix/samples/plotting3.xp
@@ -0,0 +1,43 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P sin_n(double x, double n) // Taylor polynomial of sin x
+{
+ const int N((int) floor(n)); // convert y to an index bound
+ const double sqx(-pow(x, 2)); // store -x^2 for efficiency
+ double val(x), summand(x); // places to store results of evaluation
+
+ // step through odd numbers from 1 to 2N+1
+ 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();
+
+ set_crop();
+ h_axis(4);
+ v_axis(1);
+
+ bold();
+ green();
+ 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)
+ {
+ pen(RGB(0.25*i, 0, 1-0.25*i));
+ plot(sin_n, R.slice2(5*i+1)); // plot with 2nd var = 5i+1
+ }
+
+ end();
+}
diff --git a/graphics/epix/samples/polar.xp b/graphics/epix/samples/polar.xp
new file mode 100644
index 0000000000..d2c1934552
--- /dev/null
+++ b/graphics/epix/samples/polar.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double f(double t)
+{
+ return 2*Cos(3*t);
+}
+
+int main()
+{
+ picture(P(-2,-2), P(2,2), "2x2in");
+
+ begin();
+ degrees();
+
+ black(0.3);
+ polar_grid(2, 4, 24); // radius, rings, sectors
+
+ black();
+ bottom_axis(4, P(0,-4)).subdivide(2).draw();
+ left_axis(4, P(-4,0)).subdivide(2).draw();
+
+ bold();
+ polarplot(f, 0, 180, 120); // plot over [0, 180] using 120 intervals
+
+ end();
+}
+
diff --git a/graphics/epix/samples/pole.xp b/graphics/epix/samples/pole.xp
new file mode 100644
index 0000000000..435c258a68
--- /dev/null
+++ b/graphics/epix/samples/pole.xp
@@ -0,0 +1,60 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int M(8);
+double MAX(1.5), Bd(2);
+
+P F(double x, double y) // fake pole
+{
+ return P(x, y, x/(0.01+x*x+y*y));
+}
+
+P pt1(-MAX,-MAX), pt2(MAX, MAX);
+domain R(pt1, pt2, mesh(2*M,2*M), mesh(6*M,6*M));
+
+int main()
+{
+ picture(P(-Bd,-Bd), P(Bd,Bd), "2.5x2.5in");
+
+ begin();
+
+ label(P(xmax(), 2.5), P(-2,-2),
+ "$z=\\mathrm{Re}\\,\\displaystyle\\frac{1}{x+iy}$", bl);
+
+ camera.at(P(6,8,5));
+
+ clip_box(P(-Bd,-Bd,-Bd), P(Bd,Bd,0));
+
+ plain(Magenta());
+ fill(White());
+ surface(F, R); // bottom half
+
+ grid(pt1, pt2, M, M); // axes
+
+ pen(White(0.75), "0.15pt");
+ plot(F,R); // simulate transparency
+
+ clip_box(P(-Bd,-Bd,-Bd), P(Bd,Bd,2*Bd));
+ plain(Magenta());
+
+ // axes and labels
+ arrow(P(-Bd,0,0), P(Bd,0,0));
+ label(P(Bd,0), P(-4,-2), "$x$", l);
+
+ arrow(P(0,-Bd,0), P(0,Bd,0));
+ label(P(0,Bd), P( 2,-2), "$y$", br);
+
+ arrow(P(0, 0, 0), P(0,0,2.5));
+ label(P(0,0,2.5), P(0,4), "$z$", t);
+
+ clip_box(P(-Bd,-Bd,0),P(Bd,Bd,Bd));
+
+ surface(F,R); // top half
+
+ bbold(Red());
+ plot(F, R.resize1(0.25,MAX).slice2(0));
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/polyhedra.xp b/graphics/epix/samples/polyhedra.xp
new file mode 100644
index 0000000000..c2a788986e
--- /dev/null
+++ b/graphics/epix/samples/polyhedra.xp
@@ -0,0 +1,129 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// compile with, e.g., elaps -DALL polyhedra.xp
+
+const double MAX(1.25);
+
+#define A5
+
+// draw everyone
+#ifdef ALL
+#define A4
+#define A5
+#endif /* ALL */
+
+// draw three polyhedra with A4 symmetry
+#ifdef A4
+#define COLOR
+#define TETRA
+#define CUBE
+#define OCTA
+#endif /* A4 */
+
+// draw two polyhedra with A5 symmetry
+#ifdef A5
+#ifndef COLOR
+#define COLOR
+#endif /* ndef COLOR */
+#define DODECA
+#define ICOSA
+#endif /* A5 */
+
+int main()
+{
+ picture(P(-MAX,-MAX),P(MAX,MAX), "6 x 6in");
+
+ begin();
+ const double gam(0.5*(1+sqrt(5)));
+
+ grid();
+ camera.at(P(8,3,2));
+ camera.range(20);
+
+ Sphere S;
+ frame f;
+ frame f2(E_2, E_1, E_3);
+
+#ifdef TETRA
+#ifdef COLOR
+ rgb(1,0.7,0.7);
+#endif /* COLOR */
+ back_tetra(S, f);
+ back_tetra(S, f2);
+#endif
+
+#ifdef CUBE
+#ifdef COLOR
+ rgb(0.7,0.7,1);
+#endif /* COLOR */
+ back_cube(S, f);
+#endif
+
+#ifdef OCTA
+#ifdef COLOR
+ rgb(0.7,1,0.7);
+#endif /* COLOR */
+ back_octa(S, f);
+#endif
+
+#ifdef DODECA
+#ifdef COLOR
+ rgb(0.7,1,1);
+#endif /* COLOR */
+ back_dodeca(S, f);
+#endif
+
+#ifdef ICOSA
+#ifdef COLOR
+ rgb(1,1,0.7);
+#endif /* COLOR */
+ back_icosa(S, f);
+#endif
+
+ bold();
+
+#ifdef TETRA
+#ifdef COLOR
+ red();
+#endif /* COLOR */
+ front_tetra(S, f);
+ front_tetra(S, f2);
+#endif
+
+#ifdef CUBE
+#ifdef COLOR
+ blue();
+#endif /* COLOR */
+ front_cube(S, f);
+#endif
+
+#ifdef OCTA
+#ifdef COLOR
+ green(0.6);
+#endif /* COLOR */
+ front_octa(S, f);
+#endif
+
+#ifdef DODECA
+#ifdef COLOR
+ rgb(0, 0.7, 0.7);
+#endif /* COLOR */
+ front_dodeca(S, f);
+#endif
+
+#ifdef ICOSA
+#ifdef COLOR
+ rgb(1, 0.9, 0);
+#endif /* COLOR */
+ front_icosa(S, f);
+#endif
+
+#ifdef COLOR
+ green(0.8);
+#endif
+ S.draw();
+
+ end();
+}
diff --git a/graphics/epix/samples/riemann.flx b/graphics/epix/samples/riemann.flx
new file mode 100644
index 0000000000..f7e4b47161
--- /dev/null
+++ b/graphics/epix/samples/riemann.flx
@@ -0,0 +1,68 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double t, double r, double theta)
+{
+ return P(r*r*Cos(2*theta),
+ r*r*Cos(t)*Sin(2*theta) + r*Sin(t)*Sin(theta),
+ r*Cos(theta));
+}
+
+domain R(P(0,0,0), P(1, 1.5, 1), mesh(24, 8, 32), mesh(24, 40, 80));
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ domain R1(R.slice1(tix()));
+
+ picture(P(-4,-4),P(4,4), "5x5in");
+
+ begin();
+ revolutions();
+
+ grid(1,1);
+
+ const P ctr(3.25,-3.25); // "clock" center
+ bold();
+ circle(ctr, 0.5); // clock face
+
+ line(ctr, ctr+polar(0.4, tix())); // hands
+ label(ctr+polar(0.6, tix()), "$y$");
+
+ line(ctr, ctr+polar(0.4, tix()+0.25));
+ label(ctr+polar(0.6, tix()+0.25), "$w$");
+
+ viewpoint(4,5,3);
+ camera.range(20);
+
+ line(P(0,0,0), P(3,0,0));
+ line(P(0,0,0), P(0,3,0));
+ line(P(0,0,0), P(0,0,2));
+
+ plain(Red());
+ plot(F, R1.resize3(0, 0.5));
+
+ blue();
+ plot(F, R1.resize3(0.5, 1));
+
+ bold(Magenta());
+ plot(F, R.slice3(0));
+ plot(F, R.slice3(0.5));
+
+ black();
+ masklabel(P(3,0,0), "$x$");
+ masklabel(P(0,3,0), "$y$");
+ masklabel(P(0,0,2), P(-4,0), "$z=\\textrm{Re}\\,\\sqrt{x+iy}$", tr);
+
+ end();
+}
diff --git a/graphics/epix/samples/saddle.xp b/graphics/epix/samples/saddle.xp
new file mode 100644
index 0000000000..b486cc4c9e
--- /dev/null
+++ b/graphics/epix/samples/saddle.xp
@@ -0,0 +1,70 @@
+/* -*-ePiX-*- */
+// fake 3D by layering
+#include "epix.h"
+using namespace ePiX;
+
+// function to plot
+P F(double u, double v)
+{
+ return P(u, v, 0.25*(u+v)*(u-v));
+}
+
+P TF(double u, double v)
+{
+ return P(u, v);
+}
+
+int main()
+{
+ picture(P(-3,-2),P(3,2), "6x4in");
+
+ begin();
+ backing(Black());
+
+ label_color(White());
+ label(P(0, ymax()), P(0,-4),
+ "\\textbf{A quadratic saddle cut by a tangent plane}", b);
+
+ camera.at(P(6,12,8));
+ camera.look_at(P(0,0,-0.25));
+
+ domain R(P(-2,-2), P(2,2), mesh(24,24), mesh(48,48));
+
+ // clip to lower half space
+ clip_face(P(0,0,0), -E_3); // 2nd arg is inward normal vector
+
+ // draw shaded saddle
+ fill();
+ surface(F, R);
+
+ // and re-draw the wiremesh in color
+ bold();
+ green(); // change label color as well
+ plot(F, R);
+ label(F(0,2), P(0,-4), "$\\mathbf{z<0}$", b);
+
+ // (x,y)-plane
+ red();
+ plot(TF, R);
+ label(P(2,0,0), P(-4,-2), "$\\mathbf{z=0}$", bl);
+
+ clip_restore(); // remove old restriction
+ clip_face(P(0,0,0), E_3); // and set new one
+
+ fill(Blue()); // set pen and fill colors
+ surface(F, R);
+
+ // fake transparency: re-draw (x,y)-plane lightly
+ pen(Red(), 0.2);
+ plot(TF, R);
+
+ // and plot top half of wiremesh in color
+ bold(Blue());
+ plot(F, R);
+
+ rgb(0.5,0.5,1);
+ label(F(-2,0), P(4,4), "$\\mathbf{z>0}$", tr);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/semicirc.xp b/graphics/epix/samples/semicirc.xp
new file mode 100644
index 0000000000..8cac63ae9d
--- /dev/null
+++ b/graphics/epix/samples/semicirc.xp
@@ -0,0 +1,28 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+double f(double x)
+{
+ return sqrt(1-x*x);
+}
+
+double width(0.6), height(f(width)), posn(0.5), y_posn(f(posn));
+
+int main()
+{
+ picture(P(-1, 0), P(1, 1), "2.5 x 1.25in");
+
+ begin();
+
+ h_axis(4);
+ v_axis(2);
+ h_axis_labels(xsize(), P(0, -4), b);
+
+ arc(P(0,0), 1, 0, M_PI);
+ bold();
+ rect(P(-width,0), P(width, height));
+
+ label(P(posn, y_posn), P(2,4), "$y=\\sqrt{1-x^2}$", tr);
+
+ end();
+}
diff --git a/graphics/epix/samples/shadeplot.xp b/graphics/epix/samples/shadeplot.xp
new file mode 100644
index 0000000000..7beb97e87f
--- /dev/null
+++ b/graphics/epix/samples/shadeplot.xp
@@ -0,0 +1,61 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+double k(4); // change width of hump
+double dx(0.05); // width of thin shaded region
+double x(1/sqrt(k)); // position of thin shaded region
+
+const double dy(0.5);
+
+double f(double t)
+{
+ return sqrt(fabs(k)/(2*M_PI))*exp(-k*t*t);
+}
+
+P pt1(x, f(x)+2*dy);
+P pt2(x+dx,f(x)+dy);
+P pt3(x+3*dx,f(x));
+
+Color shade1(Black(0.1));
+Color shade2(Black(0.4));
+Color shade3(Black(0.6));
+
+int main()
+{
+ picture(P(0,0), P(1,1), "150x150pt");
+
+ begin();
+ legend L;
+ L.backing(Neutral());
+
+ fill(shade1);
+ shadeplot(f, xmin(), x, 90);
+ L.fill_item("$=\\displaystyle\\int_a^x f(t)\\,dt$");
+
+ fill(shade2);
+ rect(P(x,0), P(x+dx, f(x)));
+ L.fill_item("= $f(x)\\,dx\\vphantom{\\Bigg|}$");
+
+ fill(shade3);
+ shadeplot(f, x, x+dx, 10);
+ L.fill_item("= $F(x+dx)-F(x)$");
+
+ bold();
+ plot(f, xmin(), xmax(), 120);
+
+ plain();
+ h_axis(4);
+ v_axis(4);
+
+ font_size("scriptsize");
+ L.draw(canvas().tr(), P(-2,-2), bl);
+
+ font_size("footnotesize");
+ label(P(xmin(),0), P(0,-5), "$a$", b);
+ label(P(x,0), P(0,-5), "$x$", b);
+ label(P(x+dx,0), P(0,-2), "$x+dx$", br);
+
+ pst_format();
+
+ end();
+}
diff --git a/graphics/epix/samples/slopefield.xp b/graphics/epix/samples/slopefield.xp
new file mode 100644
index 0000000000..5ecfd597c1
--- /dev/null
+++ b/graphics/epix/samples/slopefield.xp
@@ -0,0 +1,29 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double s, double t)
+{
+ return P(0.1*s, 0.025*t) + (1/(0.01+s*s+t*t))*P(-t, s);
+}
+
+int main()
+{
+ picture(P(-4, -3), P(2,2), "3x2.5in");
+
+ begin();
+
+ blue(1.8);
+ dart_field(F, P(xmin(), ymin()), P(xmax(), ymax()), 4*xsize(), 4*ysize());
+ set_crop();
+
+ bold();
+ for (int i=0; i<7; ++i)
+ {
+ rgb(0.05*(7-i), 1 - 0.1*i, 0.15*i);
+ ode_plot(F, P(-0.9-0.025*i,0), 20, 200);
+ }
+
+ end();
+}
+
diff --git a/graphics/epix/samples/sphere.xp b/graphics/epix/samples/sphere.xp
new file mode 100644
index 0000000000..dfff26e1e4
--- /dev/null
+++ b/graphics/epix/samples/sphere.xp
@@ -0,0 +1,46 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double k(2*M_PI/(360*sqrt(3))); // assume "degrees" mode
+
+double exp_cos(double t) { return exp(k*t)*Cos(t); }
+double exp_sin(double t) { return exp(k*t)*Sin(t); }
+double minus_exp_cos(double t) { return -exp_cos(t); }
+double minus_exp_sin(double t) { return -exp_sin(t); }
+
+int main()
+{
+ picture(P(-1,-1), P(1,1), "2.5 x 2.5in");
+
+ begin();
+ degrees(); // set angle units
+ camera.at(P(1, 2.5, 3));
+
+ sphere(); // draw unit sphere's horizon
+
+ pen(Blue(1.6)); // hidden portions of loxodromes
+ backplot_N(exp_cos, exp_sin, -540, 540, 180);
+ backplot_N(minus_exp_cos, minus_exp_sin, -540, 540, 180);
+
+ pen(Red(1.6));
+ backplot_N(exp_sin, minus_exp_cos, -540, 540, 180);
+ backplot_N(minus_exp_sin, exp_cos, -540, 540, 180);
+
+ pen(Black(0.3)); // coordinate grid
+
+ for (int i=0; i<=12; ++i) {
+ latitude(90-15*i, 0, 360);
+ longitude(30*i, 0, 360);
+ }
+
+ bold(Blue()); // visible portions of loxodromes
+ frontplot_N(exp_cos, exp_sin, -540, 540, 360);
+ frontplot_N(minus_exp_cos, minus_exp_sin, -540, 540, 360);
+
+ pen(Red());
+ frontplot_N(exp_sin, minus_exp_cos, -540, 540, 360);
+ frontplot_N(minus_exp_sin, exp_cos, -540, 540, 360);
+
+ end();
+}
diff --git a/graphics/epix/samples/spherical.xp b/graphics/epix/samples/spherical.xp
new file mode 100644
index 0000000000..c40b897e8f
--- /dev/null
+++ b/graphics/epix/samples/spherical.xp
@@ -0,0 +1,76 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double MAX(3);
+
+int main()
+{
+ picture(P(-MAX,-MAX),P(MAX,MAX), "6x6in");
+
+ begin();
+ camera.at(30,5,20);
+
+#ifdef GRAY
+ camera.filter(Gray_Neutral());
+#endif
+ revolutions();
+
+ domain R(P(0,0,-0.25), P(3,1,0.25), mesh(12, 48, 24), mesh(12, 96, 120));
+
+ std::list<domain> cuts;
+
+ double Phi(7.0/48), Theta(7.0/48);
+
+ cuts.push_back(R.slice1(2));
+ cuts.push_back(R.slice2(0));
+ cuts.push_back(R.slice2(Theta));
+ cuts.push_back(R.slice3(0));
+ cuts.push_back(R.slice3(Phi));
+
+ plain(Black(0.5));
+ fill(Red(1.9));
+ scenery coords(sph, R.slice1(2)); // rho = 2
+
+ fill(Yellow(0.35));
+ coords.add(sph, R.slice2(0)).add(sph, R.slice2(Theta)); // theta = 0, Theta
+
+ fill(Blue(1.9));
+ coords.add(sph, R.slice3(0)).add(sph, R.slice3(Phi)); // phi = 0, Phi
+
+ coords.draw();
+ // surface(sph, cuts);
+ fill(false);
+
+ pen(Black());
+ base(White(), "1.2pt");
+ arrow_fill(1);
+ arrow(P(3,0,0), P(3.5,0,0));
+ label(P(3.5,0,0), P(-2,-2), "$x$", bl);
+
+ arrow(P(0,3,0), P(0,3.5,0));
+ label(P(0,3.5,0), P(2,-2), "$y$", br);
+
+ arrow(P(0,0,3), P(0,0,3.5));
+ label(P(0,0,3.5), P(0,4), "$z$", t);
+
+ bold();
+ arc_arrow(P(0,0,0), 2, 0.5*Theta, Theta);
+ arc_arrow(P(0,0,0), 2, 0.5*Theta, 0);
+
+ aarrow(P(0,0,0), sph(2, Theta, Phi));
+
+ label(sph(2, 0.5*Theta, 0), P(2,2), "$\\theta$", t);
+ label(sph(2, Theta, 0.5*Phi), P(-2,0), "$\\phi$", l);
+ label(sph(1, Theta, Phi), P(2,-2), "$\\rho$", br);
+
+ base(Neutral(), 0);
+ dashed();
+ plain();
+ line(P(0,0,0), P(2,0,0));
+ line(P(0,0,0), sph(2, Theta, 0));
+ line(P(0,0,0), sph(2, Theta, Phi));
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/sqrt.xp b/graphics/epix/samples/sqrt.xp
new file mode 100644
index 0000000000..ffc5335c99
--- /dev/null
+++ b/graphics/epix/samples/sqrt.xp
@@ -0,0 +1,51 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P f(double x, double y)
+{
+ pair z(x,y);
+ pair temp(z*z);
+ return P(temp.x1(), temp.x2(), x);
+}
+
+P F(double r, double t)
+{
+ return f(r*Cos(t), r*Sin(t));
+}
+
+P g(double t)
+{
+ return t*P(t,0,1);
+}
+
+domain R(P(0,0), P(1.25,0.5), mesh(6,24), mesh(12,60));
+
+int main()
+{
+ picture(P(-1.5, -1.5), P(1.5, 1.5), "2.5x2.5in");
+
+ begin();
+ revolutions();
+ camera.at(P(4,-2,3));
+
+ pen(Blue(1.7));
+ plot(F, R);
+
+ pen(Blue());
+ plot(F, R.resize2(0.5,1));
+
+ pen(Black());
+ arrow(P(0,0,0), 2*E_1);
+ arrow(P(0,0,0), 2*E_2);
+ arrow(P(0,0,0), 1.5*E_3);
+
+ masklabel(2*E_1, P(0,0), "$\\mathrm{Re}\\,z$", r);
+ label(2*E_2, P(0,0), "$\\mathrm{Im}\\,z$", r);
+ label(1.5*E_3, P(2,0), "$\\mathrm{Re}\\,\\sqrt{z}$", r);
+
+ bold(Red());
+ plot(g, -1.25, 1.25, 40);
+
+ end();
+}
diff --git a/graphics/epix/samples/sqrt2.xp b/graphics/epix/samples/sqrt2.xp
new file mode 100644
index 0000000000..8bfcfcfab4
--- /dev/null
+++ b/graphics/epix/samples/sqrt2.xp
@@ -0,0 +1,64 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// MAX^2 = radius of plot
+const double MAX(1.5);
+
+// complex square root in polar coordinates
+P f(double u, double v)
+{
+ return P(u*u*Cos(v), u*u*Sin(v), u*Cos(0.5*v));
+}
+
+// restrictions of sqrt to real axis, unit circle
+P sqrt_re(double t) { return f(t,0); }
+P sqrt_im(double t) { return f(1,t); }
+
+int main() {
+ picture(P(-4, -4), P(4, 2), "4x3in");
+
+ begin();
+
+ camera.filter(RGB_Neutral());
+
+ backing(Magenta(0.1));
+ set_crop();
+
+ revolutions();
+ label(P(xmin(), ymax()), P(2,-2), "Branches of $\\sqrt{z}$", br);
+
+ camera.at(6, -2, 2);
+ camera.range(4);
+ domain R(P(0,0), P(MAX,2), mesh(16, 80), mesh(16, 160));
+
+ // transparent branch
+ pen(Green(0.7), "0.15pt");
+ scenery surf(f, R.resize2(1,2));
+
+ fill(White(0.7));
+ pen(Black());
+ // opaque branch
+ surf.add(f, R.resize2(0,1));
+
+ surf.draw();
+ nofill();
+ // boundary curve, unit circle, axes, grid, labels
+ bbold(Red());
+
+ plot(sqrt_re, -MAX, 0, 30);
+
+ bold(Blue());
+ arrow(P(0,0,0), P(2,0,0));
+ arrow(P(0,0,0), P(0,2,0));
+
+ label_color(Blue());
+ label(P(2,0,0), P(0,-4), "$\\mathrm{Re}\\,z$", b);
+ label(P(0,2,0), P(4, 0), "$\\mathrm{Im}\\,z$", r);
+
+ bbold(Yellow());
+ plot(sqrt_re, 0, MAX, 30);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/std_F.cc b/graphics/epix/samples/std_F.cc
new file mode 100644
index 0000000000..9ccd7b90c6
--- /dev/null
+++ b/graphics/epix/samples/std_F.cc
@@ -0,0 +1,124 @@
+/*
+ * std_F.cc -- The std_F class definitions
+ *
+ * Last Change: September 23, 2007
+ */
+// Include only the headers we need; burdensome, but generally more
+// efficient for larger projects with many dependencies.
+#ifdef MINIMAL
+#include "epix/affine.h"
+#include "epix/Color.h"
+#include "epix/curves.h"
+#include "epix/pairs.h"
+#include "epix/path.h"
+#include "epix/state.h"
+#include "epix/triples.h"
+
+#else
+#include "epix.h"
+#endif
+
+#include "epix/paint_style.h"
+#include "std_F.h"
+
+namespace ePiX {
+
+ // The constructor initializes the class data, ensuring objects are
+ // well-formed. For efficiency, we use "initialization" instead of
+ // assignment (the "=" operator); this way, data members get their
+ // actual values immediately. The constructor body is empty, since
+ // this class requires no further initialization.
+
+ // All class member function definitions must be qualified with the
+ // class name, here "std_F::"
+ std_F::std_F()
+ : m_loc(0,0), m_e1(1,0), m_e2(0,1),
+ m_fore(Black()), m_back(White()),
+ m_edge(Black()), m_edge_width(0.4) { }
+
+ // Apply the affine map af; return a reference to this object so
+ // calls can be daisy-chained. Note the efficiency of storing only
+ // the bare minimum data to specify an affine map rather than
+ // holding and manipulating the shape of an F.
+ std_F& std_F::map_by(const affine& af)
+ {
+ m_loc = af(m_loc); // affines map locations, so this works
+ m_e1 = af(m_e1);
+ m_e2 = af(m_e2);
+
+ return *this;
+ }
+
+ // Set the background and foreground colors. Arguments' names chosen
+ // to indicate their purpose.
+ std_F& std_F::backing(const Color& back)
+ {
+ m_back = back;
+ return *this;
+ }
+
+ std_F& std_F::fill(const Color& fore)
+ {
+ m_fore = fore;
+ return *this;
+ }
+
+ // Set outline parameters.
+ std_F& std_F::border(const Color& edge, double wid)
+ {
+ m_edge = edge;
+ m_edge_width = wid;
+ return *this;
+ }
+
+ // Draw in the active screen. Most of the "real work" is done here.
+ void std_F::draw() const
+ {
+ // Get global drawing state, so we can restore before returning.
+ // Not particularly elegant, but it's what we have to work with.
+ Color old_fill(the_paint_style().fill_color());
+ bool old_flag(the_paint_style().fill_flag());
+
+ Color old_line(the_paint_style().line_color());
+ length old_line_width(the_paint_style().line_width());
+
+ // now we can draw
+ const double r(1.0/6.0);
+
+ path F;
+
+ // pr converts coords in [0,1] x [0,1] to our coords
+ F .pt(pr(r, 0.75*r)).pt(pr(2*r, 0.75*r)).pt(pr(2*r, 2.25*r))
+ .pt(pr(4*r, 2.25*r)).pt(pr(4*r, 3.25*r)).pt(pr(2*r, 3.25*r))
+ .pt(pr(2*r, 4.25*r)).pt(pr(5*r, 4.25*r)).pt(pr(5*r, 5.25*r))
+ .pt(pr( r, 5.25*r));
+
+ F.close().fill();
+
+ // Set global drawing state. We have a member function named fill,
+ // so the call must be explicitly qualified with "ePiX::".
+ ePiX::fill(m_back);
+ ePiX::pen(m_edge, m_edge_width);
+
+ // Bounding parallelogram
+ ePiX::quad(pr(0,0), pr(1,0), pr(1,1), pr(0,1));
+
+ ePiX::fill(m_fore);
+ F.draw();
+ // Restore global fill state.
+ the_paint_style().fill_color(old_fill);
+ the_paint_style().fill_flag(old_flag);
+
+ the_paint_style().line_color(old_line);
+ the_paint_style().line_width(old_line_width);
+ }
+
+ // private; convert (x,y) to a location usable in path construction
+ // "Privacy" is enforced by the compiler from reading the header;
+ // the definition requires no special syntax.
+ P std_F::pr(double x, double y) const
+ {
+ pair loc((1 - x -y)*m_loc + x*m_e1 + y*m_e2);
+ return P(loc.x1(), loc.x2());
+ }
+} // end of namespace
diff --git a/graphics/epix/samples/std_F.h b/graphics/epix/samples/std_F.h
new file mode 100644
index 0000000000..961fc984e4
--- /dev/null
+++ b/graphics/epix/samples/std_F.h
@@ -0,0 +1,83 @@
+/*
+ * std_F.h -- A class to draw the action of an affine transformation.
+ *
+ * This file is a C++ class tutorial (illustrating basic features), as
+ * well as sample code for a small library, and style guide to writing
+ * external modules for ePiX.
+ *
+ * Last Change: September 23, 2007
+ */
+
+/*
+ * This file provides the "std_F" class, which draws the image of an "F"
+ * (the first roman letter having no symmetries) under an affine map.
+ *
+ * std_F(); // An F in the unit square [0,1] x [0,1].
+ * map_by(af); // Apply the affine map af
+ *
+ * // Set the background, foreground, border style
+ * backing(color);
+ * fill(folor);
+ * border(color, width);
+ *
+ * draw(); // Draw in the active screen
+ *
+ * The file affine.xp illustrates use.
+ */
+// "MINIMAL" compilation works, and entails fewer dependencies,
+// but places a larger burdern on the programer
+#ifdef MINIMAL
+#include "epix/pairs.h"
+#include "epix/Color.h"
+#else
+
+#include "epix.h"
+#endif
+
+namespace ePiX {
+
+ // forward declarations if we don't include epix.h
+#ifdef MINIMAL
+ class affine;
+ class P;
+#endif
+
+ // declare a new class "std_F"
+ class std_F {
+ // The "public" part of a class declaration specifies the interface:
+ public:
+ // A "constructor"; creates the standard F in the unit square
+ std_F();
+
+ // apply the affine map af; return a reference to this object so
+ // calls can be daisy-chained
+ std_F& map_by(const affine& af);
+
+ // set the background and foreground colors
+ std_F& backing(const Color&);
+ std_F& fill(const Color&);
+
+ // set outline pen
+ std_F& border(const Color&, double);
+
+ void draw() const; // draw in the active screen
+
+ // The private section contains implementation data, etc. The
+ // shape of the F is not stored in the class data, but generated
+ // at runtime by draw().
+ private:
+ pair m_loc; // lower left corner
+ pair m_e1; // lower right corner
+ pair m_e2; // upper left corner
+
+ Color m_fore;
+ Color m_back;
+ Color m_edge;
+
+ double m_edge_width;
+
+ // for internal use; convert (x,y) in [0,1] x [0,1] to a location
+ P pr(double x, double y) const;
+ }; // end of std_F; class declarations must end with a semicolon
+
+} // end of namespace
diff --git a/graphics/epix/samples/std_F.xp b/graphics/epix/samples/std_F.xp
new file mode 100644
index 0000000000..e2ae794d5d
--- /dev/null
+++ b/graphics/epix/samples/std_F.xp
@@ -0,0 +1,88 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+#include "std_F.h" // include the custom header
+using namespace ePiX;
+
+// September 23, 2007
+//
+// The instructions below assume you've copied this file and the
+// sample files std_F.cc and std_F.h into a directory where you
+// have write permission.
+//
+// To build std_F.cc, you'll need to run commands similar to
+//
+// g++ -I. -c std_F.cc
+// ar -ru libaff.a std_F.o
+// ranlib libaff.a
+//
+// Respectively, these compile std_F.cc into an object file, std_F.o;
+// create a static library named libaff.a containing the object code;
+// and create an index in libaff.a for the linker, so the library can
+// be used in external programs, such as the one built from this
+// source file. (On Mac OSX, you may need to run ranlib *after* moving
+// the library file to its permanent home.)
+//
+// You may give the library a different name, but it MUST begin "lib"
+// and have the extension ".a": "libblug.a" and "libaff-1.0.a" are all
+// right, but "mylib.a" or "libaff.test" are not. You refer to the
+// library by its name with "lib" and ".a" removed, as in "blug" or
+// "aff-1.0".
+//
+// To compile this source file (the one you're reading now), build
+// libaff.a as described above, then run the command
+//
+// epix -I. -L. -laff std_F.xp
+//
+// Files (such as this one) that use an external library cannot be
+// compiled from emacs, since there is no way to pass the required
+// options; they must be compiled at a shell prompt.
+//
+// Please consult the gcc documentation ("g++ --help") for information on
+// what each option does.
+
+
+// About this file:
+//
+// "F" is the first letter of the Roman alphabet that has no non-trivial
+// symmetries.
+//
+// std_F is a class for representing plane affine maps; please consult
+// the manual for general information of ePiX's plane affine map class.
+//
+
+int main()
+{
+ picture(P(0,0), P(6,6), "4x4in");
+
+ begin();
+ degrees();
+
+ grid(6,6);
+
+ std_F F1; // the standard F
+ affine af1; // the identity map
+
+ F1.draw();
+
+ // stretch along the main diagonal
+ af1.rotate(45).v_scale(3).h_scale(0.75).rotate(-45);
+
+ // flip over the main diagonal and translate
+ af1.reflect(45).shift(pair(3,2));
+
+ // apply af, set style, and draw
+ F1.map_by(af1).fill(Black(0.6)).backing(Blue(1.8)).draw();
+
+ std_F F2;
+ affine af2;
+ af2.rotate(60).scale(1.5).shift(pair(5,0));
+ F2.map_by(af2).backing(RGB(1,0.8,0.2)).fill(Green(0.6)).draw();
+
+ std_F F3;
+ // define af3 by images of e1, e2, origin
+ affine af3(pair(2-sqrt(3), 6), pair(2,3), pair(2,5));
+ F3.map_by(af3).backing(Black(0.4)).fill(White()).draw();
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/steiner.flx b/graphics/epix/samples/steiner.flx
new file mode 100644
index 0000000000..a7d4953097
--- /dev/null
+++ b/graphics/epix/samples/steiner.flx
@@ -0,0 +1,50 @@
+/* -*-flix-*- */
+// Steiner's Roman surface, using "surface" plots
+// May 19, 2006
+#include "epix.h"
+
+using namespace ePiX;
+
+double MAX(2.5), rad(0.8*MAX);
+
+P F(double u, double v)
+{
+ double x(rad*Cos(u)*Cos(v)), y(rad*Cos(u)*Sin(v)), z(rad*Sin(u));
+ return P(y*z, x*z, x*y);
+}
+
+P color(double x, double y)
+{
+#ifdef COLORSHADE
+ return P(0.5*Sin(x), -0.5*Sin(x), Cos(y));
+#else
+ return P(1,1,1); // white
+#endif
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+ picture(P(-MAX,-MAX),P(MAX,MAX), "4x4in");
+
+ begin();
+
+ backing(RGB(0.7, 0.9, 1));
+
+ fill();
+ revolutions();
+ camera.at(cyl(10, 0.5*tix(), 2)); // exploit 2-fold symmetry
+
+ surface(F, domain(P(-0.25, 0), P(0.25, 0.5), mesh(32,32), mesh(64,64)), color);
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/steiner2.flx b/graphics/epix/samples/steiner2.flx
new file mode 100644
index 0000000000..37a8199825
--- /dev/null
+++ b/graphics/epix/samples/steiner2.flx
@@ -0,0 +1,70 @@
+/* -*-flix-*- */
+#include "epix.h"
+using namespace ePiX;
+
+double MAX(2.5), rad(0.8*MAX);
+
+int N(6); // slices
+
+P F(double u, double v)
+{
+ double x(rad*Cos(u)*Cos(v)), y(rad*Cos(u)*Sin(v)), z(rad*Sin(u));
+ return P(y*z, x*z, x*y);
+}
+
+/*
+P color(double x, double y)
+{
+#ifdef COLORSHADE
+ return P(0.5*Sin(x), -0.5*Sin(x), Cos(y));
+#else
+ return P(1,1,1); // white
+#endif
+}
+*/
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg));
+
+ tix()=temp1/temp2;
+ }
+
+ picture(P(-MAX,-MAX),P(MAX,MAX), "4x4in");
+
+ begin();
+
+ backing(RGB(0.7, 0.9, 1));
+
+ fill();
+ revolutions();
+ camera.at(cyl(10, 0.25, 4));
+
+ P perp(sph(1, 0.125, tix()));
+
+ domain R(P(-0.25, 0), P(0.25, 0.5), mesh(32,32), mesh(64,64));
+#ifdef SHOWGRID
+ plain(Red());
+ plot(F, R);
+#endif
+
+ int mult(1);
+ // reverse slice order if necessary
+ if ((perp | camera.eye()) < 0)
+ mult=-1;
+
+ for (int i=-mult*N; i != mult*N; i += mult)
+ {
+ clip_slice((MAX*i*1.0/N)*perp, perp, 0.1);
+ rgb(0.25+0.1*i, 0, -0.1*i);
+
+ surface(F, R);
+ clip_restore();
+ }
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/surface_shade.xp b/graphics/epix/samples/surface_shade.xp
new file mode 100644
index 0000000000..d2676190c8
--- /dev/null
+++ b/graphics/epix/samples/surface_shade.xp
@@ -0,0 +1,46 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// surface to plot (a dog saddle)
+P f(double u, double v)
+{
+ return P(u, v, 0.5*u*v*(u-v)*(u+v));
+}
+
+// position-dependent color function
+P color(double x, double y, double z)
+{
+#ifdef LAUREL_BURCH
+ return P(-Sin(0.25*x), 0.2, -Cos(0.25*x)); // Laurel Burch colors
+#else
+ return P(-tanh(z), 0, tanh(z)); // Quasi-geographic 70s colors
+#endif
+}
+
+int main()
+{
+ picture(P(-3,-3), P(3,3), "6x6in");
+
+ begin();
+
+ // Set creation attributes,
+ revolutions();
+ set_crop();
+ fill();
+
+ // style attributes,
+ backing(Black());
+ plain(Yellow());
+
+ // and viewpoint.
+ camera.at(P(8, -8, 4));
+
+ // Add scenery
+ domain R(P(-2,-2), P(2, 2), mesh(36, 36), mesh(72, 72));
+ surface(f, R, color);
+
+ // and print
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/symmetries.xp b/graphics/epix/samples/symmetries.xp
new file mode 100644
index 0000000000..bda649bdbf
--- /dev/null
+++ b/graphics/epix/samples/symmetries.xp
@@ -0,0 +1,87 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// draw a regular n-gon with labeled vertices
+void polygon(int n, double th_0 = 0)
+{
+ const double d_th(full_turn()/n);
+ path poly;
+ for (int i=0; i<n; ++i)
+ {
+ // i-th vertex
+ double th(th_0 + i*d_th);
+ const P vtx(cis(th));
+ poly.pt(vtx);
+
+ // set label angle
+ label_angle(th + 0.25*full_turn());
+
+ // draw label
+ std::stringstream buf;
+ buf << "$" << i << "$";
+ dot(vtx, -8*vtx, buf.str());
+ }
+
+ poly.close().draw();
+}
+
+int main()
+{
+ picture(P(0,0), P(2,3), "4 x 6in");
+
+ begin();
+
+ border();
+
+ // draw one hexagon in a screen
+ screen scr(P(-1,-1), P(1,1));
+ activate(scr);
+
+ polygon(6);
+
+ // marks to distinguish a vertex and orientation
+ spot(P(1,0));
+ black(0.3);
+ line(P(-0.75,0), P(0.75,0));
+
+ black();
+ arc_arrow(P(0,0), 0.75, 0, M_PI/3);
+ arc_arrow(P(0,0), 0.75, 2*M_PI/3, M_PI);
+ arc_arrow(P(0,0), 0.75, 4*M_PI/3, 5*M_PI/3);
+ scr.scale(0.9);
+
+ // use layout and affine maps to draw symmetries
+ inset(P(0,2), P(1,3));
+
+ scr.rotate(2*M_PI/3);
+ inset(P(0,1), P(1,2));
+
+ scr.rotate(2*M_PI/3);
+ inset(P(0,0), P(1,1));
+
+ scr.rotate(2*M_PI/3).reflect(0);
+ inset(P(1,2), P(2,3));
+
+ scr.rotate(2*M_PI/3);
+ inset(P(1,1), P(2,2));
+
+ scr.rotate(2*M_PI/3);
+ inset(P(1,0), P(2,1));
+
+ deactivate(scr);
+
+ // label insets
+ font_size("LARGE");
+ label_angle(0);
+ masklabel(P(0.5, 2.5), "$e$");
+ masklabel(P(0.5, 1.5), "$\\alpha$");
+ masklabel(P(0.5, 0.5), "$\\alpha^2$");
+
+ masklabel(P(1.5, 2.5), "$\\beta$");
+ masklabel(P(1.5, 1.5), "$\\beta\\alpha^2$");
+ masklabel(P(1.5, 0.5), "$\\beta\\alpha$");
+
+ pst_format();
+ end();
+}
diff --git a/graphics/epix/samples/tori.xp b/graphics/epix/samples/tori.xp
new file mode 100644
index 0000000000..aa925845d6
--- /dev/null
+++ b/graphics/epix/samples/tori.xp
@@ -0,0 +1,63 @@
+/* -*-ePiX-*- */
+/* tori.xp -- May 09, 2005 */
+// compile tutorial torus meshes at once
+#include "epix.h"
+using namespace ePiX;
+
+// torus
+P F(double u, double v)
+{
+ return polar(2.25+Cos(u), v) + P(0,0,Sin(u));
+}
+
+int main()
+{
+ picture(P(0,0), P(4,1), "6 x 1.5in");
+
+ begin();
+
+ domain R(P(0,0), P(1,1), mesh(12,30), mesh(24, 60));
+
+ revolutions();
+ camera.at(10,7,5);
+
+ // unclipped/cropped
+ screen scr1(P(-3,-3), P(3,3));
+ activate(scr1);
+ fill(White());
+ surface(F, R);
+ inset(P(0,0), P(1,1));
+ deactivate(scr1);
+
+ // cropped
+ screen scr2(P(-3,-3), P(3,3));
+ activate(scr2);
+ set_crop();
+ border();
+ surface(F, R);
+ inset(P(1.5,0), P(2.5,1));
+ deactivate(scr2);
+
+ // clipped
+ screen scr3(P(-3,-3), P(3,3));
+ activate(scr3);
+ clip_box(P(3.5, 2, 1.5));
+
+ // box, sides layered manually
+ nofill();
+ rect(P(-3.5, -2, -1.5), P(-3.5, 2, 1.5));
+ rect(P(-3.5, -2, -1.5), P( 3.5, -2, 1.5));
+
+ fill();
+ surface(F, R);
+ nofill();
+ rect(P( 3.5, -2, -1.5), P( 3.5, 2, 1.5));
+ rect(P(-3.5, 2, -1.5), P( 3.5, 2, 1.5));
+
+ inset(P(3,0), P(4,1));
+ deactivate(scr3);
+
+ pst_format();
+ end();
+}
+
diff --git a/graphics/epix/samples/torus.xp b/graphics/epix/samples/torus.xp
new file mode 100644
index 0000000000..dbcfe31906
--- /dev/null
+++ b/graphics/epix/samples/torus.xp
@@ -0,0 +1,39 @@
+/* -*-ePiX-*- */
+/* torus.xp -- July 6, 2004 */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(8);
+
+P F(double t1, double t2)
+{
+ return polar(2+Sin(t2), t1) + Cos(t2)*E_3;
+}
+
+domain R(P(0,0), P(1,1), mesh(4*N, 2*N), mesh(12*N, 6*N));
+
+int main()
+{
+ picture(P(-3,-3), P(3,3), "2x2in");
+
+ begin();
+ revolutions();
+ camera.at(1.7,-1, 0.75);
+ camera.range(8);
+
+ rgb(0.2, 0.5, 0.7);
+
+ plot(F, R.resize1(0,0.875));
+
+ bold();
+ rgb(0.5, 0.3, 0.9);
+ plot(F, R.resize2(-0.375,0).resize1(0,0.125));
+
+ red();
+ dashed();
+ plot(F, R.slice1(0));
+ plot(F, R.slice2(0));
+
+ end();
+}
+
diff --git a/graphics/epix/samples/trig.flx b/graphics/epix/samples/trig.flx
new file mode 100644
index 0000000000..f07763f4d4
--- /dev/null
+++ b/graphics/epix/samples/trig.flx
@@ -0,0 +1,74 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P f(double x, double t)
+{
+ return P(x, Sin(x+t));
+}
+
+domain R(P(0,0), P(1,1), mesh(60,24), mesh(120, 72));
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ char* arg;
+ double temp1, temp2;
+ temp1=strtod(argv[1], &arg);
+ temp2=strtod(argv[2], &arg);
+
+ tix()=temp1/temp2;
+ }
+
+ picture(P(0,0), P(5,2), "5x2in");
+
+ begin();
+ revolutions();
+
+ border();
+ set_crop();
+
+ screen rolling(P(-1,-1), P(1,1));
+ screen waving(P(0,-1), P(1,1));
+
+ activate(rolling);
+
+ P ctr(polar(0.5, tix()));
+ P rim(polar(0.5, tix()) + polar(0.5, -tix()));
+ P rim2(polar(0.5, tix()) + polar(0.5, 0.5-tix()));
+
+ circle(ctr, 0.5); // small wheel
+
+ bold();
+ circle(P(0,0), 1); // big wheel
+
+ green();
+ line(P(1,0), P(-1,0));
+
+ blue();
+ line(P(0,1), P(0,-1));
+
+ red();
+ line(ctr, rim);
+ line(ctr, rim2);
+
+ ddot(rim);
+ ddot(rim2);
+ deactivate(rolling);
+
+ activate(waving);
+ set_crop();
+ blue();
+ plot(f, R.slice2(tix()));
+ deactivate(waving);
+
+ inset(rolling, P(0,0), P(2,2));
+ inset(waving, P(3,0), P(5,2));
+
+ dashed();
+ pen(Blue(1.6), 0.15);
+ line(P(1,1+Sin(tix())), P(3,1) + f(0, tix()));
+
+ end();
+}
diff --git a/graphics/epix/samples/twisted_cubic.xp b/graphics/epix/samples/twisted_cubic.xp
new file mode 100644
index 0000000000..8e9ec5d4b7
--- /dev/null
+++ b/graphics/epix/samples/twisted_cubic.xp
@@ -0,0 +1,106 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const double MAX(2.5);
+
+const double XMIN(-2);
+
+// twisted cubic
+P cubic(double t)
+{
+ return t*P(1, t, t*t);
+}
+
+// projections to coordinate planes
+P cubic12(double t)
+{
+ const P arg(cubic(t));
+ return P(arg.x1(), arg.x2(), XMIN);
+}
+
+P cubic13(double t)
+{
+ const P arg(cubic(t));
+ return P(arg.x1(), XMIN, arg.x3());
+}
+
+P cubic23(double t)
+{
+ const P arg(cubic(t));
+ return P(XMIN, arg.x2(), arg.x3());
+}
+
+// draw lines from one path to another
+void bars(P f1(double), P f2(double))
+{
+ for (int i=0; i<=20; ++i)
+ line(f1(-1+0.1*i), f2(-1+0.1*i));
+}
+
+// code to draw entire figure
+void draw_frame()
+{
+ // (x,z)-plane
+ blue();
+ bbold();
+ plot(cubic13, -1, 1, 60);
+ plain();
+ bars(cubic13, cubic);
+ label(cubic13(1), P(0,2), "$x$-$z$", t);
+
+ // (y,z)-plane
+ green(0.6);
+ bbold();
+ plot(cubic23, -1, 1, 60);
+ plain();
+ bars(cubic23, cubic);
+ label(cubic23(1), P(0,2), "$y$-$z$", t);
+
+ // (x,y)-plane
+ magenta();
+ bbold();
+ plot(cubic12, -1, 1, 60);
+ plain();
+ bars(cubic12, cubic);
+ label(cubic12(1), P(2,0), "$x$-$y$",r);
+
+ // the cubic
+ bold(Red(1.6));
+ base(Red(0.6), "2pt");
+ plot(cubic, -1, 1, 60);
+}
+
+int main()
+{
+ picture(P(-1,0), P(1.25,1), "4.5 x 2in");
+
+ begin();
+
+ screen scr_left(P(-MAX,-MAX), P(MAX,MAX));
+ activate(scr_left);
+
+ border(Black(), "1pt");
+
+ camera.at(sph(10, 0.8, 0.5));
+ camera.look_at(P(0,0,-0.25));
+
+ draw_frame();
+ base(Neutral());
+
+ screen scr_right(P(-MAX,-MAX), P(MAX,MAX));
+ activate(scr_right);
+
+ border(Black(), "1pt");
+
+ camera.at(sph(10, 0.9, 0.5));
+ camera.look_at(P(0,0,-0.25));
+
+ draw_frame();
+
+ inset(scr_left, P(0.25,0), P(1.25,1));
+ inset(scr_right, P(-1,0), P(0,1));
+
+ end();
+}
+
diff --git a/graphics/epix/samples/uppersum.xp b/graphics/epix/samples/uppersum.xp
new file mode 100644
index 0000000000..d1ff6ac2b0
--- /dev/null
+++ b/graphics/epix/samples/uppersum.xp
@@ -0,0 +1,37 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(12); // Number of rectangles
+
+// gather references to integrand
+double f(double t)
+{
+ return Sin(t);
+}
+
+int main()
+{
+ picture(P(0,0), P(3,1), "3x1in");
+
+ begin();
+
+ const double dx(xsize()/N);
+
+ riemann_sum(f, xmin(), xmax(), N, UPPER);
+
+ fill(Black(0.1));
+ riemann_sum(f, xmin(), xmax(), N, LOWER);
+ nofill();
+
+ h_axis(xsize());
+ v_axis(2*ysize());
+
+ h_axis_labels(xsize(), P(0,-4), b);
+ label(P(2, f(2)), P(4,2), "$y=\\sin x$", tr);
+
+ bold(Blue());
+ plot(f, xmin(), xmax(), 40);
+
+ end();
+}
diff --git a/graphics/epix/samples/vfield.xp b/graphics/epix/samples/vfield.xp
new file mode 100644
index 0000000000..ba6e1fd8ba
--- /dev/null
+++ b/graphics/epix/samples/vfield.xp
@@ -0,0 +1,71 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+// A spatial vector field depending on three variables
+P F(double x, double y, double z)
+{
+ return -0.25*P(0.5*x+y, 0.5*y-x, 1+z);
+}
+
+domain R(P(-1,-1,-1), P(1,1,1), mesh(6,6,4), mesh());
+
+int main()
+{
+ picture(P(-2,-2),P(2,2), "4x4in");
+
+ begin();
+ border();
+
+ label(P(0, ymax()), P(0,-4), "$F(x,y,z)=-(x+2y, y-2x, 1+z)$",b);
+
+ camera.at(P(11,8,5));
+
+ // coordinate grids
+ const int GRIDS(6);
+ plain(Black(0.3));
+ grid(P(-1, -1,-1), P(-1, 1, 1), GRIDS, GRIDS);
+ grid(P(-1, -1,-1), P( 1,-1, 1), GRIDS, GRIDS);
+ grid(P(-1, -1,-1), P(1, 1, -1), GRIDS, GRIDS);
+
+ // flow lines
+ bold();
+ for (int i=0; i<12; ++i)
+ {
+ double t(M_PI_2+i*M_PI/6);
+ pen(RGB(0.25*(3+Sin(t)), 0.25, 0.25*(3+Cos(t))));
+ ode_plot(F, cyl(1.4, t, 1), 0, 10, 60);
+ }
+
+ // draw arrows in plain black borderd by a white edge;
+ // vectors will appear to hide vectors behind them
+ plain(Black());
+ base(White(), "2pt");
+
+ // the field is drawn in successive slices x_3 = const
+#ifdef VECT
+ vector_field(F, R, 0.75); // draw arrowheads at 75% of default size
+#else
+ dart_field(F, R, 0.5); // draw darts at 50% of default length
+#endif
+
+ const double DX(0.125); // label padding
+ font_size("scriptsize");
+ degrees();
+
+ label_angle(30); // adjusted visually; could calculate from camera position
+ label(P(1+DX, -1, -1), P(-4,-2), "$y=-1$", bl);
+ label(P(1+DX, 0, -1), P(-4,-2), "$y=0$", bl);
+ label(P(1+DX, 1, -1), P(-4,-2), "$y=1$", bl);
+
+ label_angle(-15);
+ label(P(-1, 1+DX, -1), P(4,0), "$x=-1$", br);
+ label(P( 0, 1+DX, -1), P(4,0), "$x=0$", br);
+ label(P( 1, 1+DX, -1), P(4,0), "$x=1$", br);
+
+ label(P( 1, -1-DX, -1), P(-4,0), "$z=-1$", tl);
+ label(P( 1, -1-DX, 0), P(-4,0), "$z=0$", tl);
+ label(P( 1, -1-DX, 1), P(-4,0), "$z=1$", tl);
+
+ end();
+}
diff --git a/graphics/epix/samples/weierstrass.xp b/graphics/epix/samples/weierstrass.xp
new file mode 100644
index 0000000000..2822b0737a
--- /dev/null
+++ b/graphics/epix/samples/weierstrass.xp
@@ -0,0 +1,36 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+const int N(8); // Number of summands
+
+double weierstrass(double t)
+{
+ double y(0);
+ for(int i=0; i < N; ++i)
+ y += pow(2,-i)*cb(pow(2,i)*t);
+
+ return y;
+}
+
+int main()
+{
+ picture(P(-2, 0), P(2, 1.5), "3.2 x 1.2in");
+
+ begin();
+
+ h_axis(2*xsize());
+ v_axis(2*ysize());
+ h_axis_labels(xsize(), P(-4,-8));
+
+ blue();
+ plot(cb, xmin() - 0.25, xmax()+0.25, 4*xsize() + 2);
+
+ bold(Black());
+ plot(weierstrass, xmin(), xmax(), pow(2,N));
+
+ pen(Red());
+ plot(weierstrass, 0.5, 1.5, pow(2,N-2));
+
+ end();
+}
diff --git a/graphics/epix/samples/wheel.xp b/graphics/epix/samples/wheel.xp
new file mode 100644
index 0000000000..e8056f8658
--- /dev/null
+++ b/graphics/epix/samples/wheel.xp
@@ -0,0 +1,50 @@
+/* -*-ePiX-*- */
+#include "epix.h"
+using namespace ePiX;
+
+P F(double t, double r)
+{
+ return P(t-r*Sin(t), 1-r*Cos(t)); // a cycloid
+}
+
+int main()
+{
+ picture(P(0,0), P(15,27), "4 x 7.2in");
+
+ begin();
+
+ const double dt(5*M_PI/11);
+ double t(dt);
+
+ for(int i=0; i < 9; ++i, t += dt)
+ {
+ screen scr(P(-1,0), P(15,2)); // drawing area
+ activate(scr);
+
+ plain(Black());
+ line(P(-1, 0), P(15, 0)); // the ground
+
+ circle(P(t,1), 1); // the wheel
+
+ // [0,t] x [0,1]
+ domain R(P(0,0), P(t, 1), mesh(10*i,5), mesh((int) ceil(1+4*t), 5));
+
+ // the paths
+ bold();
+ for (int j=0; j < 6; ++j)
+ {
+ pen(RGB(1-0.125*j, 0.125*j, 0.5+0.125*j));
+ plot(F, R.slice2(0.2*j));
+ }
+
+ // the spoke
+ bold(Green());
+ line(P(t,1), F(t,1));
+
+ inset(P(0, 25-3*i), P(15, 27-3*i)); // page layout
+ deactivate(scr);
+ }
+
+ end();
+}
+
diff --git a/graphics/epix/screen.cc b/graphics/epix/screen.cc
new file mode 100644
index 0000000000..2c23a26d68
--- /dev/null
+++ b/graphics/epix/screen.cc
@@ -0,0 +1,390 @@
+/*
+ * screen.cc -- ePiX::screen_data class wrapper (for user interface)
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 16, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <string>
+#include <sstream>
+
+#include "triples.h"
+#include "pairs.h"
+#include "affine.h"
+
+#include "Color.h"
+
+#include "mask_ellipse.h"
+#include "mask_rectangle.h"
+#include "mask_diamond.h"
+
+#include "screen_data.h"
+#include "screen.h"
+
+namespace ePiX {
+
+ // N.B. Our interface handles only P, not pair.
+ // Our implementation works only with pair, not P.
+
+ P __epix_pair2P(const pair& arg)
+ {
+ return P(arg.x1(), arg.x2(), 0);
+ }
+
+ screen::screen() { }
+
+ screen::screen(const P& arg1, const P& arg2)
+ : m_screen(new screen_data(pair(arg1.x1(), arg1.x2()),
+ pair(arg2.x1(), arg2.x2()))) { }
+
+
+ screen::screen(const screen& sc)
+ : m_screen(sc.m_screen->clone()) { }
+
+ screen& screen::operator= (const screen& sc)
+ {
+ if (this != &sc)
+ {
+ screen_data* tmp(sc.m_screen->clone());
+
+ delete m_screen;
+ m_screen = tmp;
+ }
+
+ return *this;
+ }
+
+ screen::~screen()
+ {
+ delete m_screen;
+ }
+
+
+ // Set mask; one named function for each type of screen_mask
+ screen& screen::crop_mask_rectangle(const P& sw, const P& ne)
+ {
+ const pair BL(sw.x1(), sw.x2());
+ const pair TR(ne.x1(), ne.x2());
+
+ m_screen->set_mask(mask_rectangle(BL, TR));
+ return *this;
+ }
+
+ screen& screen::crop_mask_ellipse(const P& sw, const P& ne)
+ {
+ const pair BL(sw.x1(), sw.x2());
+ const pair TR(ne.x1(), ne.x2());
+
+ m_screen->set_mask(mask_ellipse(BL, TR));
+ return *this;
+ }
+
+ screen& screen::crop_mask_diamond(const P& sw, const P& ne)
+ {
+ const pair BL(sw.x1(), sw.x2());
+ const pair TR(ne.x1(), ne.x2());
+
+ m_screen->set_mask(mask_diamond(BL, TR));
+ return *this;
+ }
+
+ // masks' cardinal points lie on circumrectangle, corners may not
+ screen& screen::crop_mask_rectangle()
+ {
+ const pair BL((m_screen->l()).x1(), (m_screen->b()).x2());
+ const pair TR((m_screen->r()).x1(), (m_screen->t()).x2());
+
+ m_screen->set_mask(mask_rectangle(BL, TR));
+ return *this;
+ }
+
+ screen& screen::crop_mask_ellipse()
+ {
+ const pair BL((m_screen->l()).x1(), (m_screen->b()).x2());
+ const pair TR((m_screen->r()).x1(), (m_screen->t()).x2());
+
+ m_screen->set_mask(mask_ellipse(BL, TR));
+ return *this;
+ }
+
+ screen& screen::crop_mask_diamond()
+ {
+ const pair BL((m_screen->l()).x1(), (m_screen->b()).x2());
+ const pair TR((m_screen->r()).x1(), (m_screen->t()).x2());
+
+ m_screen->set_mask(mask_diamond(BL, TR));
+ return *this;
+ }
+
+
+ screen screen::extract(const P& arg1, const P& arg2) const
+ {
+ screen value(arg1, arg2);
+
+ value.m_screen
+ = new screen_data(m_screen->extract(pair(arg1.x1(), arg1.x2()),
+ pair(arg2.x1(), arg2.x2())));
+ return value;
+ }
+
+ screen screen::extract_diamond(const P& arg1, const P& arg2) const
+ {
+ screen value(arg1, arg2);
+
+ value.m_screen
+ = new screen_data(m_screen->extract_diamond(pair(arg1.x1(), arg1.x2()),
+ pair(arg2.x1(), arg2.x2())));
+ return value;
+ }
+
+ screen screen::extract_ellipse(const P& arg1, const P& arg2) const
+ {
+ screen value(arg1, arg2);
+
+ value.m_screen
+ = new screen_data(m_screen->extract_ellipse(pair(arg1.x1(), arg1.x2()),
+ pair(arg2.x1(), arg2.x2())));
+ return value;
+ }
+
+
+ screen& screen::set_crop(bool arg)
+ {
+ m_screen->set_crop(arg);
+ return *this;
+ }
+
+ // crop contents to current mask
+ screen& screen::crop()
+ {
+ m_screen->crop();
+ return *this;
+ }
+
+
+ // inset and import
+ screen& screen::paste(const screen& child, const P& sw, const P& ne)
+ {
+ m_screen->paste(*(child.m_screen), mask_rectangle(pair(sw.x1(), sw.x2()),
+ pair(ne.x1(), ne.x2())));
+ return *this;
+ }
+
+ screen& screen::paste(const screen& child)
+ {
+ m_screen->paste(*(child.m_screen));
+ return *this;
+ }
+
+ screen& screen::clear()
+ {
+ m_screen->clear();
+ return *this;
+ }
+
+ screen& screen::border(const Color& col, double len)
+ {
+ std::stringstream buf;
+ buf << len << "pt";
+ m_screen->border(col, buf.str());
+ return *this;
+ }
+
+ screen& screen::border(const Color& col, const std::string& len)
+ {
+ m_screen->border(col, len);
+ return *this;
+ }
+
+ screen& screen::backing(const Color& col)
+ {
+ m_screen->backing(col);
+ return *this;
+ }
+
+
+ screen& screen::border()
+ {
+ m_screen->border();
+ return *this;
+ }
+
+ screen& screen::backing()
+ {
+ m_screen->backing();
+ return *this;
+ }
+
+ // affine operations on contents (not border, backing)
+ screen& screen::apply(const affine& af)
+ {
+ m_screen->apply(af);
+ return *this;
+ }
+
+ screen& screen::shift(const P& arg)
+ {
+ m_screen->shift(pair(arg.x1(), arg.x2()));
+ return *this;
+ }
+
+ // rotate by theta about ctr
+ screen& screen::rotate(double theta, const P& ctr)
+ {
+ m_screen->rotate(theta, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ // reflect in angle-theta line through ctr
+ screen& screen::reflect(double theta, const P& ctr)
+ {
+ m_screen->reflect(theta, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ // scale coord direction(s) fixing ctr
+ screen& screen::h_scale(double sc, const P& ctr)
+ {
+ m_screen->h_scale(sc, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ screen& screen::v_scale(double sc, const P& ctr)
+ {
+ m_screen->v_scale(sc, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ screen& screen::scale(double sc, const P& ctr)
+ {
+ m_screen->scale(sc, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y)
+ screen& screen::h_shear(double sc, const P& ctr)
+ {
+ m_screen->h_shear(sc, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ screen& screen::v_shear(double sc, const P& ctr)
+ {
+ m_screen->v_shear(sc, pair(ctr.x1(), ctr.x2()));
+ return *this;
+ }
+
+ P screen::tr() const
+ {
+ return __epix_pair2P(m_screen->tr());
+ }
+
+ P screen::tl() const
+ {
+ return __epix_pair2P(m_screen->tl());
+ }
+
+ P screen::bl() const
+ {
+ return __epix_pair2P(m_screen->bl());
+ }
+
+ P screen::br() const
+ {
+ return __epix_pair2P(m_screen->br());
+ }
+
+
+ P screen::t() const
+ {
+ return __epix_pair2P(m_screen->t());
+ }
+
+ P screen::b() const
+ {
+ return __epix_pair2P(m_screen->b());
+ }
+
+ P screen::l() const
+ {
+ return __epix_pair2P(m_screen->l());
+ }
+
+ P screen::r() const
+ {
+ return __epix_pair2P(m_screen->r());
+ }
+
+ P screen::c() const
+ {
+ return __epix_pair2P(m_screen->c());
+ }
+
+
+ double screen::h_min() const
+ {
+ return m_screen->h_min();
+ }
+
+ double screen::h_max() const
+ {
+ return m_screen->h_max();
+ }
+
+ double screen::h_size() const
+ {
+ return m_screen->h_size();
+ }
+
+ double screen::h_avg() const
+ {
+ return m_screen->h_avg();
+ }
+
+
+ double screen::v_min() const
+ {
+ return m_screen->v_min();
+ }
+
+ double screen::v_max() const
+ {
+ return m_screen->v_max();
+ }
+
+ double screen::v_size() const
+ {
+ return m_screen->v_size();
+ }
+
+ double screen::v_avg() const
+ {
+ return m_screen->v_avg();
+ }
+} // end of namespace
diff --git a/graphics/epix/screen.h b/graphics/epix/screen.h
new file mode 100644
index 0000000000..023d34b4be
--- /dev/null
+++ b/graphics/epix/screen.h
@@ -0,0 +1,175 @@
+/*
+ * screen.h -- ePiX::screen class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file defines the screen class interface, a Cartesian rectangle
+ * into which objects are drawn. Object-creating commands add to the
+ * the "global" screen the_picture(). Users may create and activate
+ * additional screens, then import their content to the_picture().
+ *
+ * Constructor:
+ * screen(P(a,c), P(b,d)); // corners of bounding box
+ *
+ * Markup functions:
+ * crop(); // remove elements outside bounding box
+ * crop_to(mask); // or specified mask
+ * paste(screen); // overlay contents of screen
+ * paste(screen, P(a,c), P(b,d)); // or inset into specified rectangle
+ *
+ * Decorations:
+ * border(Color, "1pt"); // set border color/width
+ * backing(Color); // and backing color
+ *
+ * This file wraps the implementation, which is hidden from the user.
+ */
+#ifndef EPIX_SCREEN
+#define EPIX_SCREEN
+
+#include <string>
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class Color;
+ class affine;
+ class screen_data;
+ class P;
+
+ // global function
+ void write(const std::string&);
+
+ class screen {
+ // There's no user-visible form for screen contents, so
+ // we give these classes access to our implementation.
+ friend class arrow_data;
+ friend class label_data;
+ friend class legend;
+ friend class path_data;
+ friend class picture_data;
+ friend void write(const std::string&);
+
+ public:
+ screen();
+ screen(const P&, const P&);
+
+ screen(const screen&);
+ screen& operator= (const screen&);
+ ~screen();
+
+ // Set mask; one named function for each type of screen_mask
+ screen& crop_mask_rectangle(const P&, const P&);
+ screen& crop_mask_ellipse(const P&, const P&);
+ screen& crop_mask_diamond(const P&, const P&);
+
+ screen& crop_mask_rectangle();
+ screen& crop_mask_ellipse();
+ screen& crop_mask_diamond();
+
+ // return selected region
+ screen extract(const P&, const P&) const;
+ screen extract_diamond(const P&, const P&) const;
+ screen extract_ellipse(const P&, const P&) const;
+
+ // set flag only
+ screen& set_crop(bool arg=true);
+
+ // crop contents to current mask
+ screen& crop();
+
+ // inset and import
+ screen& paste(const screen& child, const P& inset_sw, const P& inset_ne);
+ screen& paste(const screen& child);
+
+ screen& clear();
+
+ // border(Color, length)?
+ screen& border(const Color&, double);
+ screen& border(const Color&, const std::string&);
+ screen& backing(const Color&);
+
+ screen& border();
+ screen& backing();
+
+ //// pass-through functions ////
+ // affine operations on contents (not border, backing)
+ screen& apply(const affine& f);
+
+ // convenience operators for single affine ops
+ screen& shift(const P& arg);
+
+ // rotate by theta about ctr
+ screen& rotate(double theta, const P& ctr = P(0,0));
+
+ // reflect in angle-theta line through ctr
+ screen& reflect(double theta, const P& ctr = P(0,0));
+
+ // scale coord direction(s) fixing ctr
+ screen& h_scale(double, const P& ctr=P(0,0));
+ screen& v_scale(double, const P& ctr=P(0,0));
+ screen& scale(double, const P& ctr=P(0,0));
+
+ // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y)
+ screen& h_shear(double sc, const P& ctr=P(0,0));
+ screen& v_shear(double sc, const P& ctr=P(0,0));
+
+ P tr() const;
+ P tl() const;
+ P bl() const;
+ P br() const;
+
+ P t() const;
+ P b() const;
+ P l() const;
+ P r() const;
+ P c() const;
+
+ double h_min() const;
+ double h_max() const;
+ double h_size() const;
+ double h_avg() const;
+
+ double v_min() const;
+ double v_max() const;
+ double v_size() const;
+ double v_avg() const;
+
+ private:
+ screen_data* m_screen;
+
+ }; // end of class screen
+
+} // end of namespace
+
+#endif /* EPIX_SCREEN */
diff --git a/graphics/epix/screen_crop.cc b/graphics/epix/screen_crop.cc
new file mode 100644
index 0000000000..1eb6860266
--- /dev/null
+++ b/graphics/epix/screen_crop.cc
@@ -0,0 +1,70 @@
+/*
+ * screen_crop.cc -- ePiX functions for cropping 2D paths and loops
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 17, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include "functions.h"
+#include "pairs.h"
+
+#include "edge_data.h"
+#include "screen_crop.h"
+#include "crop_algorithms.h"
+
+namespace ePiX {
+
+ typedef std::list<edge2d>::const_iterator CLI;
+
+ static pair unit_perp(const edge2d& E)
+ {
+ pair N(J(E.head() - E.tail()));
+ return N *= recip(norm(N));
+ }
+
+ // O(n^2) algorithm seems necessary since edge_list needn't be convex
+ std::list<edge2d>& crop_path_2nd(const std::list<edge2d>& bord,
+ std::list<edge2d>& edge_list)
+ {
+ for (CLI ep=bord.begin(); ep != bord.end(); ++ep)
+ chop_path<pair>(unit_perp(*ep), (*ep).tail(), edge_list);
+
+ return cull<pair>(edge_list);
+ }
+
+ std::list<edge2d>& crop_loop_2nd(const std::list<edge2d>& bord,
+ std::list<edge2d>& edge_list)
+ {
+ for (CLI ep=bord.begin(); ep != bord.end(); ++ep)
+ {
+ chop_path<pair>(unit_perp(*ep), (*ep).tail(), edge_list);
+ loopify<pair>(edge_list);
+ }
+
+ return cull<pair>(edge_list);
+ }
+} // end of namespace
diff --git a/graphics/epix/screen_crop.h b/graphics/epix/screen_crop.h
new file mode 100644
index 0000000000..910114528a
--- /dev/null
+++ b/graphics/epix/screen_crop.h
@@ -0,0 +1,49 @@
+/*
+ * screen_crop.h -- ePiX functions for cropping 2D paths and loops
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 17, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_SCREEN_CROP
+#define EPIX_SCREEN_CROP
+
+#include <list>
+
+#include "edge_data.h"
+
+namespace ePiX {
+
+ // return reference to second argument
+ std::list<edge2d>& crop_path_2nd(const std::list<edge2d>&,
+ std::list<edge2d>&);
+
+ std::list<edge2d>& crop_loop_2nd(const std::list<edge2d>&,
+ std::list<edge2d>&);
+} // end of namespace
+
+#endif /* EPIX_SCREEN_CROP */
diff --git a/graphics/epix/screen_data.cc b/graphics/epix/screen_data.cc
new file mode 100644
index 0000000000..02eac318b5
--- /dev/null
+++ b/graphics/epix/screen_data.cc
@@ -0,0 +1,572 @@
+/*
+ * screen_data.cc -- ePiX::screen class implementation
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.2.1
+ * Last Change: September 28, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+#include <algorithm>
+#include <sstream>
+
+#include "camera.h"
+
+#include "pairs.h"
+
+#include "functions.h"
+
+#include "Color.h"
+
+#include "utils.h"
+
+#include "tile.h"
+
+#include "pen_line.h"
+#include "pen_fill.h"
+
+#include "affine.h"
+#include "mask_ellipse.h"
+#include "mask_rectangle.h"
+#include "mask_diamond.h"
+
+#include "format.h"
+
+// #include "screen_mask.h"
+#include "screen_data.h"
+
+namespace ePiX {
+
+ typedef std::list<tile*>::const_iterator Tp;
+
+ // constructor
+ screen_data::screen_data(const pair& arg1, const pair& arg2)
+ : m_bl(pair(min(arg1.x1(), arg2.x1()), min(arg1.x2(), arg2.x2()))),
+ m_tr(pair(max(arg1.x1(), arg2.x1()), max(arg1.x2(), arg2.x2()))),
+ m_mask(new mask_rectangle(m_bl, m_tr)),
+ m_border(new pen_line()),
+ m_backing(new pen_fill()),
+ m_crop(false) { }
+
+ // copy constructor
+ screen_data::screen_data(const screen_data& scr)
+ : m_bl(scr.m_bl),
+ m_tr(scr.m_tr),
+ m_mask(scr.m_mask->clone()),
+ m_border(scr.m_border->clone()),
+ m_backing(scr.m_backing->clone()),
+ m_crop(scr.m_crop)
+ {
+ for(Tp p=scr.m_tiles.begin(); p!= scr.m_tiles.end(); ++p)
+ add_tile(*p);
+ }
+
+ // copy assignment
+ screen_data& screen_data::operator= (const screen_data& scr)
+ {
+ if (this != &scr)
+ {
+ // copy scr's tiles before freeing ours
+ std::list<tile*> tmp;
+ for(Tp p=scr.m_tiles.begin(); p!= scr.m_tiles.end(); ++p)
+ add_tile(*p);
+
+ screen_mask* tmp_mask(scr.m_mask->clone());
+
+ pen_line* tmp_border(scr.m_border->clone());
+ pen_fill* tmp_backing(scr.m_backing->clone());
+
+ // okay, safe to muck with our data
+ m_bl = scr.m_bl;
+ m_tr = scr.m_tr;
+
+ delete m_mask;
+ m_mask = tmp_mask;
+
+ delete m_border;
+ m_border = tmp_border;
+
+ delete m_backing;
+ m_backing = tmp_backing;
+
+ for (Tp p=m_tiles.begin(); p!=m_tiles.end(); ++p)
+ delete *p;
+
+ swap(m_tiles, tmp);
+
+ m_crop = scr.m_crop;
+ }
+ return *this;
+ } // end of copy assignment
+
+
+ screen_data::~screen_data()
+ {
+ delete m_mask;
+ delete m_border;
+ delete m_backing;
+
+ for(Tp p=m_tiles.begin(); p!= m_tiles.end(); ++p)
+ delete *p;
+ }
+
+ screen_data* screen_data::clone() const
+ {
+ return new screen_data(*this);
+ }
+
+
+ // superimpose a layer by affine scaling
+ // map child to inset (inset defaults to m_mask)
+ screen_data& screen_data::paste(const screen_data& child,
+ const screen_mask& inset)
+ {
+ if (this != &child)
+ {
+ const double h_sc(inset.h_size()/child.h_size());
+ const double v_sc(inset.v_size()/child.v_size());
+
+ const pair tmp00(inset.bl() - (child.bl() & pair(h_sc, v_sc)));
+
+ affine af(tmp00 + pair(h_sc, 0), tmp00 + pair(0, v_sc), tmp00);
+
+ // backing
+ if (!child.m_backing->is_empty())
+ {
+ // child is const, so must copy tile
+ pen_fill* temp(child.m_backing->clone());
+ add_tile(temp->map_by(af));
+ }
+
+ // tiles
+ for(Tp p=child.m_tiles.begin(); p!= child.m_tiles.end(); ++p)
+ {
+ tile* temp((*p)->clone());
+ add_tile(temp->map_by(af));
+ }
+
+ // border
+ if (!child.m_border->is_empty())
+ {
+ pen_line* temp(child.m_border->clone());
+ add_tile(temp->map_by(af));
+ }
+ }
+
+ return *this;
+ } // end of paste(child, inset)
+
+
+ screen_data& screen_data::paste(const screen_data& child)
+ {
+ if (this != &child)
+ {
+ const double h_sc(h_size()/child.h_size());
+ const double v_sc(v_size()/child.v_size());
+
+ const pair tmp00(bl() - (child.bl() & pair(h_sc, v_sc)));
+
+ affine af(tmp00 + pair(h_sc, 0), tmp00 + pair(0, v_sc), tmp00);
+
+ // backing
+ if (!child.m_backing->is_empty())
+ {
+ // child is const, so must copy tile
+ pen_fill* temp(child.m_backing->clone());
+
+ add_tile(temp->map_by(af));
+ }
+
+ // tiles
+ for(Tp p=child.m_tiles.begin(); p!= child.m_tiles.end(); ++p)
+ {
+ tile* temp((*p)->clone());
+ add_tile(temp->map_by(af));
+ }
+
+ // border
+ if (!child.m_border->is_empty())
+ {
+ pen_line* temp(child.m_border->clone());
+ add_tile(temp->map_by(af));
+ }
+ }
+
+ return *this;
+ }
+
+ screen_data& screen_data::clear()
+ {
+ delete m_border;
+ m_border = new pen_line();
+
+ m_tiles.clear();
+
+ delete m_backing;
+ m_backing = new pen_fill();
+
+ m_crop = false;
+ return *this;
+ }
+
+ screen_data& screen_data::crop_to(const screen_mask& mask)
+ {
+ std::list<tile*> visibles;
+
+ if (!m_border->is_empty())
+ m_border->crop_to(mask);
+
+ if (!m_backing->is_empty())
+ m_backing->crop_to(mask);
+
+ for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr)
+ {
+ (*curr)->crop_to(mask);
+
+ if (!(*curr)->is_empty())
+ visibles.push_back(*curr);
+ }
+
+ swap(m_tiles, visibles);
+ return *this;
+ }
+
+ screen_data& screen_data::crop()
+ {
+ return crop_to(*m_mask);
+ }
+
+
+ screen_data& screen_data::set_mask(const screen_mask& mask)
+ {
+ delete m_mask;
+ m_mask = mask.clone();
+
+ return *this;
+ }
+
+ screen_data& screen_data::set_crop(bool arg)
+ {
+ m_crop = arg;
+ return *this;
+ }
+
+ screen_data screen_data::extract(const pair& arg1, const pair& arg2) const
+ {
+ screen_data value(arg1, arg2);
+ value.set_crop(true);
+
+ for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr)
+ value.add_tile(*curr);
+
+ return value;
+ }
+
+ screen_data screen_data::extract_diamond(const pair& arg1,
+ const pair& arg2) const
+ {
+ screen_data value(arg1, arg2);
+
+ value.set_mask(mask_diamond(arg1, arg2)).set_crop(true);
+
+ for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr)
+ value.add_tile(*curr);
+
+ return value;
+ }
+
+ screen_data screen_data::extract_ellipse(const pair& arg1,
+ const pair& arg2) const
+ {
+ screen_data value(arg1, arg2);
+
+ value.set_mask(mask_ellipse(arg1, arg2)).set_crop(true);
+
+ for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr)
+ value.add_tile(*curr);
+
+ return value;
+ }
+
+
+ screen_data& screen_data::border(const Color& col, const std::string& len)
+ {
+ delete m_border;
+ m_border = new pen_line(m_mask->border(cam()(col), len));
+ m_crop = true;
+
+ return *this;
+ }
+
+
+ screen_data& screen_data::backing(const Color& col)
+ {
+ delete m_backing;
+ m_backing = new pen_fill(m_mask->backing(cam()(col)));
+ m_crop = true;
+
+ return *this;
+ }
+
+
+ screen_data& screen_data::border()
+ {
+ delete m_border;
+ m_border = new pen_line(m_mask->border());
+ m_crop = true;
+
+ return *this;
+ }
+
+
+ screen_data& screen_data::backing()
+ {
+ delete m_backing;
+ m_backing = new pen_fill(m_mask->backing());
+ m_crop = true;
+
+ return *this;
+ }
+
+ // screen cropping done in these two functions
+ void screen_data::add_tile(const tile& T)
+ {
+ tile* tmp(T.clone());
+ if (m_crop)
+ tmp->crop_to(*m_mask);
+
+ if (!tmp->is_empty())
+ m_tiles.push_back(tmp);
+ }
+
+ void screen_data::add_tile(tile* Tp)
+ {
+ tile* tmp(Tp->clone());
+ if (m_crop)
+ tmp->crop_to(*m_mask);
+
+ if (!tmp->is_empty())
+ m_tiles.push_back(tmp);
+ }
+
+
+ // affine operations on contents (not border, backing)
+ void screen_data::apply(const affine& af)
+ {
+ for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr)
+ (*curr)->map_by(af);
+ }
+
+ void screen_data::shift(const pair& arg)
+ {
+ affine af;
+ af.shift(arg);
+ apply(af);
+ }
+
+ // rotate by theta about ctr
+ void screen_data::rotate(double theta, const pair& ctr)
+ {
+ affine af;
+ af.rotate(theta, ctr);
+ apply(af);
+ }
+
+ // reflect in angle-theta line through ctr
+ void screen_data::reflect(double theta, const pair& ctr)
+ {
+ affine af;
+ af.reflect(theta, ctr);
+ apply(af);
+ }
+
+ // scale coord direction(s) fixing ctr
+ void screen_data::h_scale(double sc, const pair& ctr)
+ {
+ affine af;
+ af.h_scale(sc, ctr);
+ apply(af);
+ }
+
+ void screen_data::v_scale(double sc, const pair& ctr)
+ {
+ affine af;
+ af.v_scale(sc, ctr);
+ apply(af);
+ }
+
+ void screen_data::scale(double sc, const pair& ctr)
+ {
+ affine af;
+ af.scale(sc, ctr);
+ apply(af);
+ }
+
+ // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y)
+ void screen_data::h_shear(double sc, const pair& ctr)
+ {
+ affine af;
+ af.h_shear(sc, ctr);
+ apply(af);
+ }
+
+ void screen_data::v_shear(double sc, const pair& ctr)
+ {
+ affine af;
+ af.v_shear(sc, ctr);
+ apply(af);
+ }
+
+
+ pair screen_data::tr() const
+ {
+ return m_tr;
+ }
+
+ pair screen_data::tl() const
+ {
+ return pair(m_bl.x1(), m_tr.x2());
+ }
+
+ pair screen_data::bl() const
+ {
+ return m_bl;
+ }
+
+ pair screen_data::br() const
+ {
+ return pair(m_tr.x1(), m_bl.x2());
+ }
+
+
+ pair screen_data::t() const
+ {
+ return pair(0.5*(m_bl.x1() + m_tr.x1()), m_tr.x2());
+ }
+
+ pair screen_data::b() const
+ {
+ return pair(0.5*(m_bl.x1() + m_tr.x1()), m_bl.x2());
+ }
+
+ pair screen_data::l() const
+ {
+ return pair(m_bl.x1(), 0.5*(m_bl.x2() + m_tr.x2()));
+ }
+
+ pair screen_data::r() const
+ {
+ return pair(m_tr.x1(), 0.5*(m_bl.x2() + m_tr.x2()));
+ }
+
+ pair screen_data::c() const
+ {
+ return pair(0.5*(m_bl.x1() + m_tr.x1()), 0.5*(m_bl.x2() + m_tr.x2()));
+ }
+
+
+ double screen_data::h_min() const
+ {
+ return m_bl.x1();
+ }
+
+ double screen_data::h_max() const
+ {
+ return m_tr.x1();
+ }
+
+ double screen_data::h_size() const
+ {
+ return m_tr.x1() - m_bl.x1();
+ }
+
+ double screen_data::h_avg() const
+ {
+ return 0.5*(m_bl.x1() + m_tr.x1());
+ }
+
+
+ double screen_data::v_min() const
+ {
+ return m_bl.x2();
+ }
+
+ double screen_data::v_max() const
+ {
+ return m_tr.x2();
+ }
+
+ double screen_data::v_size() const
+ {
+ return m_tr.x2() - m_bl.x2();
+ }
+
+ double screen_data::v_avg() const
+ {
+ return 0.5*(m_bl.x2() + m_tr.x2());
+ }
+
+ std::string screen_data::print_to(const format& fmt, const length& len,
+ bool wrap) const
+ {
+ std::ostringstream obuf;
+
+ if (wrap)
+ {
+ obuf << fmt.start_picture(tr()-bl(), bl());
+ fmt.reset_state(); // ensures drawing attribs set properly below
+ }
+
+ if (!m_backing->is_empty())
+ {
+ m_backing->add_to_pallet();
+
+ obuf << m_backing->print_to(fmt, len.units());
+ }
+
+ for (Tp curr = m_tiles.begin(); curr != m_tiles.end(); ++curr)
+ {
+ (*curr)->add_to_pallet();
+
+ obuf << (*curr)->print_to(fmt, len.units());
+ }
+
+ if (!m_border->is_empty())
+ {
+ m_border->add_to_pallet();
+
+ obuf << m_border->print_to(fmt, len.units());
+ }
+
+ if (wrap)
+ obuf << fmt.end_picture();
+
+ return obuf.str();
+ } // end of print_to()
+
+} // end of namespace
diff --git a/graphics/epix/screen_data.h b/graphics/epix/screen_data.h
new file mode 100644
index 0000000000..582ec1d555
--- /dev/null
+++ b/graphics/epix/screen_data.h
@@ -0,0 +1,153 @@
+/*
+ * screen_data.h -- ePiX::screen class implementation
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 16, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file implements the screen class, a Cartesian rectangle into
+ * which objects are drawn. This file is not part of epix.h.
+ */
+#ifndef EPIX_SCREEN_DATA
+#define EPIX_SCREEN_DATA
+
+#include <string>
+#include <list>
+
+#include "pairs.h"
+
+namespace ePiX {
+
+ class affine;
+ class Color;
+ class format;
+ class length;
+ class pen_fill;
+ class pen_line;
+ class screen_mask;
+ class tile;
+
+ class screen_data {
+ public:
+ screen_data(const pair&, const pair&);
+
+ screen_data(const screen_data&);
+ screen_data& operator= (const screen_data&);
+ ~screen_data();
+
+ screen_data* clone() const;
+
+ screen_data& crop_to(const screen_mask&);
+ screen_data& crop();
+
+
+ screen_data& set_mask(const screen_mask&);
+ screen_data& set_crop(bool);
+
+ // cut out and return a region
+ screen_data extract(const pair&, const pair&) const;
+ screen_data extract_diamond(const pair&, const pair&) const;
+ screen_data extract_ellipse(const pair&, const pair&) const;
+
+ // inset and import
+ screen_data& paste(const screen_data& child, const screen_mask& inset);
+ screen_data& paste(const screen_data& child);
+
+ screen_data& clear();
+
+ screen_data& border(const Color&, const std::string&);
+ screen_data& backing(const Color&);
+
+ screen_data& border();
+ screen_data& backing();
+
+ void add_tile(const tile&);
+ void add_tile(tile*);
+
+ // wrap=true -> encapsulate in a picture, for legends
+ std::string print_to(const format&, const length&, bool wrap=false) const;
+
+ // affine operations on contents (not border, backing)
+ void apply(const affine& af);
+ void shift(const pair& arg);
+
+ // rotate by theta about ctr
+ void rotate(double theta, const pair& ctr = pair(0,0));
+
+ // reflect in angle-theta line through ctr
+ void reflect(double theta, const pair& ctr = pair(0,0));
+
+ // scale coord direction(s) fixing ctr
+ void h_scale(double, const pair& ctr=pair(0,0));
+ void v_scale(double, const pair& ctr=pair(0,0));
+ void scale(double, const pair& ctr=pair(0,0));
+
+ // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y)
+ void h_shear(double sc, const pair& ctr=pair(0,0));
+ void v_shear(double sc, const pair& ctr=pair(0,0));
+
+ pair tr() const;
+ pair tl() const;
+ pair bl() const;
+ pair br() const;
+
+ pair t() const;
+ pair b() const;
+ pair l() const;
+ pair r() const;
+ pair c() const;
+
+ double h_min() const;
+ double h_max() const;
+ double h_size() const;
+ double h_avg() const;
+
+ double v_min() const;
+ double v_max() const;
+ double v_size() const;
+ double v_avg() const;
+
+ private:
+ pair m_bl;
+ pair m_tr;
+
+ screen_mask* m_mask;
+ pen_line* m_border;
+ pen_fill* m_backing;
+
+ bool m_crop;
+
+ std::list<tile*> m_tiles;
+ }; // end of class screen_data
+
+} // end of namespace
+
+#endif /* EPIX_SCREEN_DATA */
diff --git a/graphics/epix/screen_mask.cc b/graphics/epix/screen_mask.cc
new file mode 100644
index 0000000000..e652685e4e
--- /dev/null
+++ b/graphics/epix/screen_mask.cc
@@ -0,0 +1,55 @@
+/*
+ * screen_mask.cc -- ePiX::screen_mask interface
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.4
+ * Last Change: June 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+
+#include "pairs.h"
+
+#include "screen_mask.h"
+
+namespace ePiX {
+
+ //// screen_mask::alignment points ////
+ pair screen_mask::tr() const { return pair(h_max(), v_max()); }
+ pair screen_mask::tl() const { return pair(h_min(), v_max()); }
+ pair screen_mask::bl() const { return pair(h_min(), v_min()); }
+ pair screen_mask::br() const { return pair(h_max(), v_min()); }
+
+ pair screen_mask::t() const { return pair(h_avg(), v_max()); }
+ pair screen_mask::b() const { return pair(h_avg(), v_min()); }
+ pair screen_mask::l() const { return pair(h_min(), v_avg()); }
+ pair screen_mask::r() const { return pair(h_max(), v_avg()); }
+ pair screen_mask::c() const { return pair(h_avg(), v_avg()); }
+
+} // end of ePiX namespace
diff --git a/graphics/epix/screen_mask.h b/graphics/epix/screen_mask.h
new file mode 100644
index 0000000000..0ec475f3db
--- /dev/null
+++ b/graphics/epix/screen_mask.h
@@ -0,0 +1,97 @@
+/*
+ * screen_mask.h -- ePiX::screen_mask interface, for screen cropping
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.8
+ * Last Change: July 17, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_SCREEN_MASK
+#define EPIX_SCREEN_MASK
+
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class pair;
+
+ class Color;
+
+ class length;
+ class pen_fill;
+ class pen_line;
+
+ class screen_mask {
+ public:
+ virtual ~screen_mask() { }
+
+ virtual screen_mask* clone() const = 0;
+
+ // alignment points
+ pair tr() const;
+ pair tl() const;
+ pair bl() const;
+ pair br() const;
+
+ pair t() const;
+ pair b() const;
+ pair l() const;
+ pair r() const;
+ pair c() const;
+
+ // cropping facilities (for tiles: glyph, pen_line, pen_fill resp.)
+ virtual bool crops(const pair& arg) const = 0; // false if arg visible
+ virtual std::list<edge2d>& crop_path(std::list<edge2d>&) const = 0;
+ virtual std::list<edge2d>& crop_loop(std::list<edge2d>&) const = 0;
+
+ // extreme and average coordinates, dimensions
+ virtual double h_min() const = 0;
+ virtual double h_max() const = 0;
+ virtual double h_size() const = 0;
+ virtual double h_avg() const = 0;
+
+ virtual double v_min() const = 0;
+ virtual double v_max() const = 0;
+ virtual double v_size() const = 0;
+ virtual double v_avg() const = 0;
+
+ // convert us to screen border or backing
+ virtual pen_line border(const Color&, const length&) const = 0;
+ virtual pen_fill backing(const Color&) const = 0;
+
+ virtual pen_line border() const = 0;
+ virtual pen_fill backing() const = 0;
+ }; // end of class screen_mask
+
+} // end of namespace
+
+#endif /* EPIX_SCREEN_MASK */
diff --git a/graphics/epix/segment.cc b/graphics/epix/segment.cc
new file mode 100644
index 0000000000..3ea5eb3760
--- /dev/null
+++ b/graphics/epix/segment.cc
@@ -0,0 +1,111 @@
+/*
+ * segment.cc -- ePiX::Segment class and mathematical operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "triples.h"
+
+#include "path.h"
+#include "segment.h"
+
+namespace ePiX {
+
+ Segment::Segment(const P& p1, const P& p2)
+ : m_endpt1(p1), m_endpt2(p2), m_malformed(false) { }
+
+ Segment::Segment(bool tag) : m_malformed(true) { }
+
+ P Segment::end1() const
+ {
+ return m_endpt1;
+ }
+
+ P Segment::end2() const
+ {
+ return m_endpt2;
+ }
+
+ bool Segment::malformed() const
+ {
+ return m_malformed;
+ }
+
+ // translate
+ Segment& Segment::shift(const P& arg)
+ {
+ if (!m_malformed)
+ {
+ m_endpt1 += arg;
+ m_endpt2 += arg;
+ }
+ return *this;
+ }
+
+ Segment& Segment::move_to(const P& arg)
+ {
+ if (!m_malformed)
+ {
+ const P dX(arg - 0.5*(m_endpt1 + m_endpt2));
+ m_endpt1 += dX;
+ m_endpt2 += dX;
+ }
+ return *this;
+ }
+
+ Segment& Segment::scale(double c)
+ {
+ if (!m_malformed)
+ {
+ const P ctr(0.5*(m_endpt1 + m_endpt2));
+
+ m_endpt1 = ctr + c*(m_endpt1 - ctr);
+ m_endpt2 = ctr + c*(m_endpt2 - ctr);
+ }
+ return *this;
+ }
+
+ P Segment::midpoint() const
+ {
+ return 0.5*(m_endpt1 + m_endpt2);
+ }
+
+ void Segment::draw() const
+ {
+ if (m_malformed)
+ return;
+
+ // else
+ path temp(m_endpt1, m_endpt2);
+
+ temp.draw();
+ }
+} // end of namespace
diff --git a/graphics/epix/segment.h b/graphics/epix/segment.h
new file mode 100644
index 0000000000..5a19b1dd6a
--- /dev/null
+++ b/graphics/epix/segment.h
@@ -0,0 +1,84 @@
+/*
+ * segment.h -- ePiX::Segment class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides:
+ *
+ * The Segment class (unordered pair of points), and operators:
+ * - end1(), end2() (no guaranteed order)
+ * - Translation operators shift(P), move_to(P)
+ * - Stretch about midpoint: scale(double)
+ * - draw() (ePiX line)
+ * - midpoint();
+ */
+
+#ifndef EPIX_SEGMENT
+#define EPIX_SEGMENT
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class Segment {
+ public:
+ Segment(const P&, const P&); // endpoints
+
+ Segment(bool); // malformed Segment for intersection operators
+
+ // Segment ends are not distinguished geometrically,
+ // so these functions should normally be used in tandem.
+ P end1() const;
+ P end2() const;
+
+ bool malformed() const;
+
+ // translate
+ Segment& shift(const P&);
+ Segment& move_to(const P&);
+
+ Segment& scale(double);
+
+ P midpoint() const;
+
+ void draw() const;
+
+ private:
+ P m_endpt1;
+ P m_endpt2;
+
+ bool m_malformed;
+ }; // end of Segment class
+
+} // end of namespace
+#endif /* EPIX_SEGMENT */
diff --git a/graphics/epix/sphere.cc b/graphics/epix/sphere.cc
new file mode 100644
index 0000000000..5f172e0fb0
--- /dev/null
+++ b/graphics/epix/sphere.cc
@@ -0,0 +1,131 @@
+/*
+ * sphere.cc -- ePiX::Sphere class and mathematical operators
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+
+#include "errors.h"
+
+#include "triples.h"
+
+#include "functions.h"
+
+#include "camera.h"
+#include "circle.h"
+
+#include "sphere.h"
+
+namespace ePiX {
+
+ Sphere::Sphere(const P& ctr, double rad)
+ : m_ctr(ctr), m_rad(rad), m_malformed(false) { }
+
+ Sphere::Sphere(const P& ctr, const P& pt)
+ : m_ctr(ctr), m_rad(norm(pt-ctr)), m_malformed(false) { }
+
+ P Sphere::center() const
+ {
+ return m_ctr;
+ }
+
+ double Sphere::radius() const
+ {
+ return m_rad;
+ }
+
+ bool Sphere::malformed() const
+ {
+ return m_malformed;
+ }
+
+ // translation
+ Sphere& Sphere::shift(const P& arg)
+ {
+ if (!m_malformed)
+ m_ctr += arg;
+ return *this;
+ }
+
+ Sphere& Sphere::move_to(const P& arg)
+ {
+ if (!m_malformed)
+ m_ctr = arg;
+ return *this;
+ }
+
+ Sphere& Sphere::scale(double& arg)
+ {
+ if (!m_malformed)
+ m_rad *= arg;
+ return *this;
+ }
+
+
+ void Sphere::draw() const
+ {
+ if (m_malformed)
+ return;
+
+ // else
+ P location(cam().viewpt());
+
+ P dir(m_ctr - location);
+ double dist(norm(dir));
+
+ if (dist <= m_rad)
+ epix_warning("Cannot draw sphere enclosing camera");
+
+ else
+ {
+ dir *= 1/dist;
+ double x(m_rad*m_rad/dist);
+
+ Circle temp(m_ctr - x*dir, sqrt((m_rad-x)*(m_rad+x)), dir);
+ temp.draw();
+ }
+ } // end of Sphere::photo()
+
+
+ //// global functions ////
+ void sphere(const P& ctr, double rad)
+ {
+ Sphere S(ctr, rad);
+ S.draw();
+ }
+
+ void sphere(const P& ctr, const P& pt)
+ {
+ Sphere S(ctr, pt);
+ S.draw();
+ }
+} // end of namespace
diff --git a/graphics/epix/sphere.h b/graphics/epix/sphere.h
new file mode 100644
index 0000000000..fa043ca382
--- /dev/null
+++ b/graphics/epix/sphere.h
@@ -0,0 +1,87 @@
+/*
+ * sphere.h -- ePiX::Sphere class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: July 30, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides:
+ *
+ * The Sphere class (center, radius), and operators:
+ * - Sphere += P (translate by <P>)
+ * - Sphere *= double (scale about center)
+ * - draw() (ePiX line)
+ * - center();
+ * - radius();
+ *
+ * Hiding test, latitude and longitudes on a sphere.
+ */
+#ifndef EPIX_SPHERE
+#define EPIX_SPHERE
+
+#include "triples.h"
+
+namespace ePiX {
+
+ class Sphere {
+ public:
+ Sphere(const P& ctr=P(0,0,0), double rad=1);
+ Sphere(const P& ctr, const P& pt);
+
+ P center() const;
+ double radius() const;
+
+ bool malformed() const; // always returns false, currently
+
+ // translation
+ Sphere& shift(const P&);
+ Sphere& move_to(const P&);
+
+ // scale radius
+ Sphere& scale(double&);
+
+ void draw() const;
+
+ private:
+ P m_ctr;
+ double m_rad;
+
+ bool m_malformed;
+ }; // end of Sphere class
+
+
+ // global horizon-drawing functions
+ void sphere(const P& ctr=P(0,0,0), double rad=1);
+ void sphere(const P& ctr, const P& pt);
+
+} // end of namespace
+
+#endif /* EPIX_SPHERE */
diff --git a/graphics/epix/spline.cc b/graphics/epix/spline.cc
new file mode 100644
index 0000000000..286d63d57a
--- /dev/null
+++ b/graphics/epix/spline.cc
@@ -0,0 +1,145 @@
+/*
+ * spline.cc -- ePiX n_spline class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: August 02, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "path.h"
+#include "spline.h"
+
+namespace ePiX {
+ // natural spline constructor
+ n_spline::n_spline(const std::vector<P>& data, bool loop)
+ : m_vertices(data)
+ {
+ if (loop)
+ m_vertices.push_back(m_vertices.at(0));
+
+ const unsigned int N(m_vertices.size()-1);
+
+ // notation and algorithm from John H. Matthews and Kurtis K. Fink
+ std::vector<double> tmp_h(N+1); // h_k = x_{k+1} - x_k
+ std::vector<double> tmp_d(N+1); // d_k = (y_{k+1} - y_k)/h_k
+ std::vector<double> tmp_u(N+1); // u_k = 6*(d_{k+1} - d_k)
+ std::vector<double> tmp_y(N+1); // y_k
+
+ // entries of tridiagonal coefficient matrix
+ std::vector<double> tmp_A(N+1); // subdiagonal of coefficient matrix
+ std::vector<double> tmp_C(N+1); // superdiagonal
+ std::vector<double> tmp_D(N+1); // diagonal
+
+ std::vector<double> tmp_m(N+1); // m_k = S"(x_k), 1 <= k <= N-1
+
+ // initialize...
+ for (unsigned int i = 0; i <= N; ++i)
+ {
+ P curr(m_vertices.at(i));
+
+ tmp_y.at(i) = curr.x2();
+
+ if (i <= N-1)
+ {
+ P next(m_vertices.at(i+1));
+
+ tmp_h.at(i) = (next.x1() - curr.x1());
+ tmp_d.at(i) = (next.x2() - curr.x2())/tmp_h.at(i);
+
+ if (0 < i)
+ {
+ tmp_u.at(i) = 6*(tmp_d.at(i) - tmp_d.at(i-1));
+ tmp_D.at(i) = 2*(tmp_h.at(i) + tmp_h.at(i-1));
+
+ if (i <= N-2)
+ {
+ tmp_A.at(i) = tmp_h.at(i);
+ tmp_C.at(i) = tmp_h.at(i);
+ }
+ }
+ }
+ }
+
+ for (unsigned int i=2; i <= N; ++i)
+ {
+ const double ratio(tmp_A.at(i-1)/tmp_D.at(i-1));
+
+ tmp_D.at(i) -= ratio*tmp_C.at(i-1);
+ tmp_u.at(i) -= ratio*tmp_u.at(i-1);
+ }
+
+ tmp_m.at(N) = tmp_u.at(N-1)/tmp_D.at(N-1);
+
+ for (unsigned int i=N-1; 0 < i; --i)
+ tmp_m.at(i) = (tmp_u.at(i) - tmp_C.at(i)*tmp_m.at(i+1))/tmp_D.at(i);
+
+ std::vector<double> tmp_k0(N);
+ std::vector<double> tmp_k1(N);
+ std::vector<double> tmp_k2(N);
+ std::vector<double> tmp_k3(N);
+
+ for (unsigned int i=0; i < N; ++i)
+ {
+ tmp_k0.at(i) = tmp_y.at(i);
+ tmp_k1.at(i)
+ = tmp_d.at(i) - (tmp_h.at(i)/6)*(2*tmp_m.at(i) + tmp_m.at(i+1));
+
+ tmp_k2.at(i) = 0.5*tmp_m.at(i);
+ tmp_k3.at(i) = (tmp_m.at(i+1) - tmp_m.at(i))/(6*tmp_h.at(i));
+ }
+
+ swap(tmp_k0, m_k0);
+ swap(tmp_k1, m_k1);
+ swap(tmp_k2, m_k2);
+ swap(tmp_k3, m_k3);
+ }
+
+ path n_spline::data(const unsigned int num_pts) const
+ {
+ path value;
+ for (unsigned int i=0; i < m_vertices.size()-1; ++i)
+ {
+ const double Xmin(m_vertices.at(i).x1());
+ const double dx((m_vertices.at(i+1).x1() - Xmin)/num_pts);
+
+ for (unsigned int j=0; j<=num_pts; ++j)
+ {
+ const double w(j*dx);
+ const double x(Xmin + w);
+
+ // Horner's form
+ double y((((m_k3.at(i)*w) + m_k2.at(i))*w + m_k1.at(i))*w + m_k0.at(i));
+
+ value.pt(P(x, y));
+ }
+ }
+ return value;
+ }
+
+} // end of namespace
diff --git a/graphics/epix/spline.h b/graphics/epix/spline.h
new file mode 100644
index 0000000000..bf8630a39f
--- /dev/null
+++ b/graphics/epix/spline.h
@@ -0,0 +1,63 @@
+/*
+ * spline.h -- ePiX spline class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.3
+ * Last Change: March 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_SPLINE
+#define EPIX_SPLINE
+
+#include <vector>
+#include "triples.h"
+
+namespace ePiX {
+
+ class path;
+
+ class n_spline {
+ public:
+
+ n_spline(const std::vector<P>& data, bool loop=false);
+
+ path data(const unsigned int) const;
+
+ private:
+ std::vector<P> m_vertices;
+
+ // coefficient sequences
+ std::vector<double> m_k0;
+ std::vector<double> m_k1;
+ std::vector<double> m_k2;
+ std::vector<double> m_k3;
+ }; // end of class n_spline
+
+} // end of namespace
+
+#endif /* EPIX_SPLINE */
diff --git a/graphics/epix/spline_data.h b/graphics/epix/spline_data.h
new file mode 100644
index 0000000000..ea47eeb982
--- /dev/null
+++ b/graphics/epix/spline_data.h
@@ -0,0 +1,51 @@
+/*
+ * splinee_data.h -- ePiX parametric spline functions
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.4
+ * Last Change: June 18, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_SPLINE_DATA
+#define EPIX_SPLINE_DATA
+
+namespace ePiX {
+
+ template <typename T>
+ T spl_pt(const T& p1, const T& p2, const T& p3, double t)
+ {
+ return (1-t)*(1-t)*p1 + 2*t*(1-t)*p2 + t*t*p3;
+ }
+
+ template <typename T>
+ T spl_pt(const T& p1, const T& p2, const T& p3, const T& p4, double t)
+ {
+ const double s(1-t);
+ return s*s*(s*p1 + 3*t*p2) + t*t*(3*s*p3 + t*p4);
+ }
+} // end of namespace
+
+#endif /* EPIX_SPLINE_DATA */
diff --git a/graphics/epix/state.cc b/graphics/epix/state.cc
new file mode 100644
index 0000000000..44802bf991
--- /dev/null
+++ b/graphics/epix/state.cc
@@ -0,0 +1,509 @@
+/*
+ * state.cc -- ePiX's current drawing state
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "constants.h"
+#include "errors.h"
+#include "triples.h"
+#include "Color.h"
+
+#include "length.h"
+
+#include "camera.h"
+
+#include "angle_units.h"
+#include "arrow_style.h"
+#include "label_style.h"
+#include "marker_style.h"
+#include "paint_style.h"
+#include "path_style.h"
+
+#include "active_screen.h"
+#include "screen.h"
+
+#include "clipping.h"
+
+#include "state.h"
+
+namespace ePiX {
+
+ // set camera position
+ void viewpoint(const P& arg)
+ {
+ cam().at(arg);
+ }
+
+ void viewpoint(double x1, double x2, double x3)
+ {
+ cam().at(P(x1, x2, x3));
+ }
+
+ // Set angular mode
+ void radians()
+ {
+ the_angle_style().set_radians_mode();
+ }
+
+ void degrees()
+ {
+ the_angle_style().set_degrees_mode();
+ }
+
+ void revolutions()
+ {
+ the_angle_style().set_revolutions_mode();
+ }
+
+
+ // number of current units in a full turn
+ double full_turn()
+ {
+ return the_angle_style().from_degrees(360.0);
+ }
+
+
+ // clipping is always on
+ void clip(bool arg) { }
+
+ void clip_box()
+ {
+ the_clip_box() = clip_state();
+ }
+
+ void clip_box(const P& arg1, const P& arg2)
+ {
+ the_clip_box() = clip_state(arg1, arg2);
+ }
+
+ void clip_to(const P& arg)
+ {
+ the_clip_box() = clip_state(P(0,0,0), arg);
+ }
+
+ void clip_box(const P& arg)
+ {
+ the_clip_box() = clip_state(-arg, arg);
+ }
+
+ // add a clip face; perp points inward
+ void clip_face(const P& loc, const P& perp)
+ {
+ the_clip_box().add_face(loc, perp);
+ }
+
+ // add parallel clip planes
+ void clip_slice(const P& loc, const P& perp)
+ {
+ the_clip_box().add_face(loc-0.5*EPIX_EPSILON*perp, perp)
+ .add_face(loc+0.5*EPIX_EPSILON*perp, -perp);
+ }
+
+ void clip_slice(const P& perp, double thickness)
+ {
+ clip_slice(P(0,0,0), perp, thickness);
+ }
+
+ void clip_slice(const P& perp)
+ {
+ clip_slice(P(0,0,0), perp);
+ }
+
+ void clip_slice(const P& loc, const P& perp, double thickness)
+ {
+ the_clip_box().add_face(loc-0.5*thickness*perp, perp)
+ .add_face(loc+0.5*thickness*perp, -perp);
+ }
+
+ // remove user-specified clip planes, preserve clip box settings
+ void clip_restore()
+ {
+ the_clip_box().clear_extras();
+ }
+
+
+ // Set crop state and select region
+ void set_crop(bool arg)
+ {
+ active_screen()->set_crop(arg);
+ }
+
+ void crop()
+ {
+ active_screen()->crop();
+ }
+
+ void crop_rectangle(const P& sw, const P& ne)
+ {
+ active_screen()->crop_mask_rectangle(sw, ne).set_crop(true);
+ }
+
+ void crop_ellipse(const P& sw, const P& ne)
+ {
+ active_screen()->crop_mask_ellipse(sw, ne).set_crop(true);
+ }
+
+ void crop_diamond(const P& sw, const P& ne)
+ {
+ active_screen()->crop_mask_diamond(sw, ne).set_crop(true);
+ }
+
+ void crop_rectangle()
+ {
+ active_screen()->crop_mask_rectangle().set_crop(true);
+ }
+
+ void crop_ellipse()
+ {
+ active_screen()->crop_mask_ellipse().set_crop(true);
+ }
+
+ void crop_diamond()
+ {
+ active_screen()->crop_mask_diamond().set_crop(true);
+ }
+
+
+ void crop_box(const P& arg1, const P& arg2)
+ {
+ active_screen()->crop_mask_rectangle(arg1, arg2).set_crop(true);
+ }
+
+ void crop_box() // (re)set active crop box to active bounding box
+ {
+ active_screen()->crop_mask_rectangle().set_crop(true);
+ }
+
+
+ // Set font size and face, label angle, mask color
+ void font_size(const std::string& arg)
+ {
+ the_label_style().fontsize(arg);
+ }
+
+ void font_face(const std::string& arg)
+ {
+ the_label_style().fontface(arg);
+ }
+
+ void label_color(const Color& col)
+ {
+ the_label_style().text_color(col);
+ }
+
+ void label_angle(double th)
+ {
+ the_label_style().label_angle(th);
+ }
+
+ void label_mask(const Color& arg)
+ {
+ the_label_style().mask_color(arg);
+ }
+
+ void label_mask()
+ {
+ the_label_style().mask_color(White());
+ }
+
+ void label_pad(std::string len)
+ {
+ the_label_style().label_padding(length(len));
+ }
+
+ void label_border(const Color& col, double len)
+ {
+ the_label_style().label_border(pen_data(col, length(len)));
+ }
+
+ void label_border(const Color& col, std::string len)
+ {
+ the_label_style().label_border(pen_data(col, len));
+ }
+
+ // set color only
+ void label_border(const Color& col)
+ {
+ length len(the_label_style().label_border().width());
+ the_label_style().label_border(pen_data(col, len));
+ }
+
+ // set width only
+ void label_border(double len)
+ {
+ Color col(the_label_style().label_border().color());
+ the_label_style().label_border(pen_data(col, length(len)));
+ }
+
+ void label_border(std::string len)
+ {
+ Color col(the_label_style().label_border().color());
+ the_label_style().label_border(pen_data(col, len));
+ }
+
+ void no_label_border()
+ {
+ label_border("0pt");
+ }
+
+
+ // Gray depth, path filling, [fill color]
+ void gray(double depth)
+ {
+ the_paint_style().fill_color(Black(depth));
+ }
+
+ // new function
+ void fill(const Color& col)
+ {
+ the_paint_style().fill_color(col);
+ the_paint_style().fill_flag(!col.is_unset());
+ }
+
+ void fill(bool arg)
+ {
+ the_paint_style().fill_flag(arg);
+ if (arg && the_paint_style().fill_color().is_unset())
+ the_paint_style().fill_color(White());
+ }
+
+ void nofill()
+ {
+ the_paint_style().fill_flag(false);
+ }
+
+
+ // Arrowhead parameters
+ void arrow_width(double w)
+ {
+ the_arrowhead_style().width(w);
+ }
+
+ void arrow_ratio(double r)
+ {
+ the_arrowhead_style().ratio(r);
+ }
+
+ void arrow_inset(double arg)
+ {
+ the_arrowhead_style().inset(arg);
+ }
+
+ void arrow_fill(bool fill)
+ {
+ the_arrowhead_style().fill(fill);
+ }
+
+
+ // Set (approximate) length of dashes, dot separation
+ void dash_size(double len)
+ {
+ the_path_style().separation(len);
+ }
+
+ void dot_sep(double len)
+ {
+ dash_size(len);
+ }
+
+ // Dot/box marker size
+ void dot_size(double diam)
+ {
+ the_mark_size().dot_size(diam);
+ }
+
+ void tick_size(double len)
+ {
+ the_mark_size().tick_size(len);
+ }
+
+ // Line style
+ void line_style(std::string style)
+ {
+ the_path_style() = path_state(style);
+ }
+
+ void solid()
+ {
+ line_style("-");
+ }
+
+ void dashed()
+ {
+ line_style("- -");
+ }
+
+ void dotted()
+ {
+ line_style(" . ");
+ }
+
+
+ // Line width
+ void pen(const std::string& len)
+ {
+ the_paint_style().line_width(length(len));
+ }
+
+ void pen(double wd)
+ {
+ the_paint_style().line_width(length(wd));
+ }
+
+
+ void bbold()
+ {
+ the_paint_style().line_width(BBOLD_WIDTH);
+ }
+
+ void bold()
+ {
+ the_paint_style().line_width(BOLD_WIDTH);
+ }
+
+ void plain()
+ {
+ the_paint_style().line_width(PLAIN_WIDTH);
+ }
+
+ // line width and color
+ void bbold(const Color& col)
+ {
+ the_paint_style().line_color(col);
+ the_paint_style().line_width(BBOLD_WIDTH);
+ }
+
+ void bold(const Color& col)
+ {
+ the_paint_style().line_color(col);
+ the_paint_style().line_width(BOLD_WIDTH);
+ }
+
+ void plain(const Color& col)
+ {
+ the_paint_style().line_color(col);
+ the_paint_style().line_width(PLAIN_WIDTH);
+ }
+
+ void pen(const Color& col)
+ {
+ the_paint_style().line_color(col);
+ }
+ void pen(const Color& col, double len)
+ {
+ the_paint_style().line_color(col);
+ the_paint_style().line_width(length(len));
+ }
+ void pen(const Color& col, std::string len)
+ {
+ the_paint_style().line_color(col);
+ the_paint_style().line_width(length(len));
+ }
+
+ // base width and color
+ void base(const Color& col)
+ {
+ the_paint_style().base_color(col);
+ }
+ void base(const Color& col, double len)
+ {
+ the_paint_style().base_color(col);
+ the_paint_style().base_width(length(len));
+ }
+ void base(const Color& col, std::string len)
+ {
+ the_paint_style().base_color(col);
+ the_paint_style().base_width(length(len));
+ }
+
+
+ // Red-Blue-Green
+ void rgb(double r, double g, double b)
+ {
+ the_paint_style().line_color(RGB(r, g, b));
+ the_paint_style().fill_color(RGB(r, g, b));
+ the_label_style().text_color(RGB(r, g, b));
+ }
+
+ // Cyan-Magenta-Yellow-Black
+ void cmyk(double c, double m, double y, double k)
+ {
+ the_paint_style().line_color(CMYK(c, m, y, k));
+ the_paint_style().fill_color(CMYK(c, m, y, k));
+ the_label_style().text_color(CMYK(c, m, y, k));
+ }
+
+ void rgb(const P& arg)
+ {
+ rgb(arg.x1(), arg.x2(), arg.x3());
+ }
+
+ void cmyk(const P& arg)
+ {
+ cmyk(arg.x1(), arg.x2(), arg.x3(), 0);
+ }
+
+ // primary colors
+ void red(double d)
+ {
+ rgb(d,0,0);
+ }
+ void green(double d)
+ {
+ rgb(0,d,0);
+ }
+ void blue(double d)
+ {
+ rgb(0,0,d);
+ }
+ void white(double d)
+ {
+ rgb(d,d,d);
+ }
+ void black(double d)
+ {
+ rgb(1-d,1-d,1-d);
+ }
+
+ void cyan(double d)
+ {
+ cmyk(d,0,0,0);
+ }
+ void magenta(double d)
+ {
+ cmyk(0,d,0,0);
+ }
+ void yellow(double d)
+ {
+ cmyk(0,0,d,0);
+ }
+} // end of namespace
diff --git a/graphics/epix/state.h b/graphics/epix/state.h
new file mode 100644
index 0000000000..207a39b33e
--- /dev/null
+++ b/graphics/epix/state.h
@@ -0,0 +1,213 @@
+/*
+ * state.h -- ePiX global functions to control current drawing state
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.22
+ * Last Change: September 24, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file contains the (old) user interface governing:
+ *
+ * [] Angular mode
+ * [] Clipping and cropping
+ * [] Font size and face, label angle, mask color
+ * [] Gray depth, path filling, fill color
+ * [] Whether to use PSTricks macros
+ * [] Arrowhead parameters
+ * [] Line style, dash length, dot size
+ * [] Line width
+ * [] Line/text color
+ */
+
+#ifndef EPIX_STATE
+#define EPIX_STATE
+
+#include <string>
+
+namespace ePiX {
+
+ class Color;
+ class P;
+
+ // set camera position
+ void viewpoint(const P&);
+ void viewpoint(double, double, double);
+
+ // Set angular mode
+ void radians();
+ void degrees();
+ void revolutions();
+
+ // number of current angle units in one full turn
+ double full_turn();
+
+ // set clip box
+ void clip(bool arg=true); // no effect
+ void clip_box(); // default (very large)
+ void clip_box(const P& arg1, const P& arg2);
+ void clip_to(const P& arg);
+ void clip_box(const P& arg);
+
+ // add a clip face; perp points inward
+ void clip_face(const P& loc, const P& perp);
+
+ // add parallel clip planes
+ void clip_slice(const P& loc, const P& perp);
+ void clip_slice(const P& loc, const P& perp, double thickness);
+
+ // loc = origin
+ void clip_slice(const P& perp);
+ void clip_slice(const P& perp, double thickness);
+
+ // remove user-specified clip planes, preserve clip box settings
+ void clip_restore();
+
+ // set flag on active screen; contents unchanged
+ void set_crop(bool arg=true);
+
+ // crop contents of active screen
+ void crop();
+
+ //// New cropping functions ////
+ // set crop mask of active screen
+ void crop_rectangle(const P&, const P&);
+ void crop_ellipse(const P&, const P&);
+ void crop_diamond(const P&, const P&);
+
+ void crop_rectangle();
+ void crop_ellipse();
+ void crop_diamond();
+
+ void crop_box(const P&, const P&);
+ void crop_box(); // (re)set crop box to bounding box
+
+ // Set label attributes
+ void font_size(const std::string& arg="nsz");
+ void font_face(const std::string& arg="rm");
+
+ void label_color(const Color&);
+
+ void label_angle(double t=0);
+ void label_mask(const Color& col);
+ void label_mask();
+
+ void label_pad(std::string);
+ void label_border(const Color&, double);
+ void label_border(const Color&, std::string);
+ void label_border(const Color&);
+
+ void label_border(double);
+ void label_border(std::string);
+ void no_label_border();
+
+ // Gray depth, path filling, [fill color]
+ void gray(double depth=0.3);
+ void fill(const Color&); // set fill color
+ void fill(bool arg=true); // set fill flag
+ void nofill();
+ // void fill_color(const std::string& arg);
+
+ // Arrowhead parameters
+ void arrow_width(double w=3);
+ void arrow_ratio(double r=5.5);
+ void arrow_inset(double arg=0);
+ void arrow_fill(bool arg=true);
+
+ // Dash pattern length
+ void dash_size(double len=0);
+ void dot_sep(double len=0);
+
+ // Dot and box marker size
+ void dot_size(double diam=0);
+
+ // Tick length
+ void tick_size(double len=0);
+
+ // Line style
+ void line_style(std::string style="-"); // solid by default
+
+ void solid();
+ void dashed();
+ void dotted();
+
+ // Line width
+ void pen(const std::string&);
+ void pen(double);
+
+ void bbold();
+ void bold();
+ void plain();
+
+ // Line width and color
+ void bbold(const Color&);
+ void bold(const Color&);
+ void plain(const Color&);
+
+ void pen(const Color&);
+ void pen(const Color&, double);
+ void pen(const Color&, std::string);
+
+ void base(const Color&);
+ void base(const Color&, double);
+ void base(const Color&, std::string);
+
+ // Line and text color
+ // ePiX provides rgb/cmyk colors via xcolor. The following are equivalent:
+ // red();
+ // rgb(1,0,0);
+ //
+ // cmyk(0,1,1,0); is visually equivalent but not the same.
+ //
+ // Densities outside the unit interval [0,1] are truncated, e.g.,
+ // rgb(2, -1, 0.3) = rgb(1, 0, 0.3).
+
+ // red-green-blue
+ void rgb(double r, double g, double b); // must pass args by value
+ // cyan-magenta-yellow-black
+ void cmyk(double c, double m, double y, double k);
+
+ // P arguments, for easy function control
+ void rgb(const P&);
+ void cmyk(const P&);
+
+ // primary colors
+ void red(double d=1);
+ void green(double d=1);
+ void blue(double d=1);
+ void white(double d=1);
+ void black(double d=1);
+
+ void cyan(double d=1);
+ void magenta(double d=1);
+ void yellow(double d=1);
+
+} // end of namespace
+
+#endif /* EPIX_STATE */
diff --git a/graphics/epix/surface.cc b/graphics/epix/surface.cc
new file mode 100644
index 0000000000..0da2210fb6
--- /dev/null
+++ b/graphics/epix/surface.cc
@@ -0,0 +1,1072 @@
+/*
+ * surface.cc -- Shaded surface plotting
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+
+#include "constants.h"
+#include "errors.h"
+
+#include "triples.h"
+#include "frame.h"
+
+#include "camera.h"
+#include "Color.h"
+
+#include "pen_data.h"
+#include "state.h"
+
+#include "domain.h"
+
+#include "facet.h"
+#include "surface.h"
+
+namespace ePiX {
+
+ typedef std::list<domain>::const_iterator dolci;
+
+ static double id(double x) { return x; }
+
+ scenery::scenery() : m_cull(0) { }
+
+ scenery::scenery(P F(double, double), const domain& R) : m_cull(0)
+ {
+ // construct sorted list of facet*s
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2));
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2));
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2));
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double), const domain& R)
+
+
+ scenery::scenery(P F(double, double, double), const domain& R) : m_cull(0)
+ {
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x1(),
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ 0, du, dv, N1, N2));
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2(),
+ R.corner1_x3() + j*R.step3(),
+ du, 0, dv, N1, N2));
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ R.corner1_x3(),
+ du, dv, 0, N1, N2));
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double, double), const domain& R)
+
+
+ //// Color-dependent constructors ////
+ // position-valued color
+ scenery::scenery(P F(double, double), const domain& R,
+ P color(double, double, double)) : m_cull(0)
+ {
+ // construct sorted list of facet*s
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P posn(F(R.corner1_x2() + (i+0.5)*R.step2(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2,
+ RGB(col.x1(),col.x2(),col.x3())));
+ }
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P posn(F(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P posn(F(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x2() + (j+0.5)*R.step2()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double), const domain& R)
+
+
+ scenery::scenery(P F(double, double, double), const domain& R,
+ P color(double, double, double)) : m_cull(0)
+ {
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P posn(F(R.corner1_x1(),
+ R.corner1_x2() + (i+0.5)*R.step2(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1(),
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ 0, du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ P posn(F(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x2(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2(),
+ R.corner1_x3() + j*R.step3(),
+ du, 0, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ P posn(F(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x2() + (j+0.5)*R.step2(),
+ R.corner1_x3()));
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ R.corner1_x3(),
+ du, dv, 0, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double, double), const domain& R)
+
+
+ //// domain-valued color ////
+ scenery::scenery(P F(double, double), const domain& R,
+ P color(double, double)) : m_cull(0)
+ {
+ // construct sorted list of facet*s
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ P col(color(R.corner1_x2() + (i+0.5)*R.step2(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2,
+ RGB(col.x1(),col.x2(),col.x3())));
+ }
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P col(color(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x3() + j*R.step3(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ // use mesh center to approximate facet's location
+ P col(color(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x2() + (j+0.5)*R.step2()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double), const domain& R)
+
+
+ scenery::scenery(P F(double, double, double), const domain& R,
+ P color(double, double)) : m_cull(0)
+ {
+ if (R.dim() != 2)
+ {
+ epix_warning("scenery() requires a 2-dimensional domain");
+ return;
+ }
+ // else may assume dim(R)=2
+
+ // exactly one test of first three should succeed
+ if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n2()/R.coarse_n2());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx2());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n2(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ // Color indep of x1
+ P col(color(R.corner1_x2() + (i+0.5)*R.step2(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1(),
+ R.corner1_x2() + i*R.step2(),
+ R.corner1_x3() + j*R.step3(),
+ 0, du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ // if dx2() == 0, use (u,v) = (x,z)
+ else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n3()/R.coarse_n3());
+
+ const double du(R.dx1());
+ const double dv(R.dx3());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n3(); ++j)
+ {
+ P col(color(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x3() + (j+0.5)*R.step3()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2(),
+ R.corner1_x3() + j*R.step3(),
+ du, 0, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON)
+ {
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ P col(color(R.corner1_x1() + (i+0.5)*R.step1(),
+ R.corner1_x2() + (j+0.5)*R.step2()));
+
+ m_data.push_back(new facet(F,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ R.corner1_x3(),
+ du, dv, 0, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3())));
+ }
+ }
+
+ else
+ {
+ epix_warning("scenery() internal error!");
+ // clean up
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ return;
+ }
+
+ m_data.sort(by_distance());
+ // sort(m_data.begin(), m_data.end(), by_distance());
+ } // end of scenery(P F(double, double, double), const domain& R)
+
+
+ scenery::scenery(const scenery& sc)
+ : m_cull(sc.m_cull)
+ {
+ for (std::list<facet*>::const_iterator p=sc.m_data.begin();
+ p!=sc.m_data.end(); ++p)
+ m_data.push_back((*p)->clone());
+ }
+
+ scenery& scenery::operator= (const scenery& sc)
+ {
+ if (this != &sc)
+ {
+ std::list<facet*> tmp;
+ // get facets from sc
+ for (std::list<facet*>::const_iterator p=sc.m_data.begin();
+ p!=sc.m_data.end(); ++p)
+ tmp.push_back((*p)->clone());
+
+ // free memory
+ for (std::list<facet*>::iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ delete *p;
+
+ swap(m_data, tmp);
+
+ m_cull=sc.m_cull;
+ }
+
+ return *this;
+ }
+
+ scenery::~scenery()
+ {
+ for (std::list<facet*>::iterator p=m_data.begin(); p!=m_data.end(); ++p)
+ delete *p;
+ }
+
+
+ scenery& scenery::add(P F(double, double), const domain& R)
+ {
+ scenery tmp(F, R);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain& R)
+ {
+ scenery tmp(F, R);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double), const domain_list& DL)
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain_list& DL)
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+
+ //// Color-dependent versions ////
+ // position-dependent color
+ scenery& scenery::add(P F(double, double), const domain& R,
+ P color(double, double, double))
+ {
+ scenery tmp(F, R, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain& R,
+ P color(double, double, double))
+ {
+ scenery tmp(F, R, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double), const domain_list& DL,
+ P color(double, double, double))
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain_list& DL,
+ P color(double, double, double))
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+
+ //domain-dependent color
+ scenery& scenery::add(P F(double, double), const domain& R,
+ P color(double, double))
+ {
+ scenery tmp(F, R, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain& R,
+ P color(double, double))
+ {
+ scenery tmp(F, R, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double), const domain_list& DL,
+ P color(double, double))
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+ scenery& scenery::add(P F(double, double, double), const domain_list& DL,
+ P color(double, double))
+ {
+ for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p)
+ {
+ scenery tmp(F, *p, color);
+ (*this).m_data.merge(tmp.m_data, by_distance());
+ }
+
+ return *this;
+ }
+
+
+ scenery& scenery::cull(int c)
+ {
+ if (c == 0)
+ m_cull=0;
+ else if (c > 0)
+ m_cull=1;
+ else
+ m_cull=-1;
+ return *this;
+ }
+
+ void scenery::draw(int cull) const
+ {
+ for (std::list<facet*>::const_iterator p=m_data.begin();
+ p!=m_data.end(); ++p)
+ (*p)->draw(cull);
+ }
+
+
+ //// User-accessible functions ////
+ void surface(P F(double, double), const domain& R, int cull)
+ {
+ scenery surf(F, R);
+ surf.draw(cull);
+ }
+
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R, int cull)
+ {
+ scenery surf(F, R);
+ surf.draw(cull);
+ }
+
+ void surface(P F(double, double, double), const domain_list& R, int cull)
+ {
+ scenery tmp;
+
+ for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p)
+ tmp.add(F, *p);
+
+ tmp.draw(cull);
+ }
+
+
+ void surface_rev(double f(double), double g(double),
+ double min_x, double max_x, int i_max, int j_max, int cull)
+ {
+ surface_rev(f, g,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), frame(), cull);
+ }
+
+ void surface_rev(double f(double),
+ double min_x, double max_x, int i_max, int j_max, int cull)
+ {
+ surface_rev(id, f,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), frame(), cull);
+ }
+
+ void surface_rev(double f(double), double g(double),
+ const domain& R, const frame& coords, int cull)
+ {
+ if (R.dx3() > 0)
+ epix_warning("surface_rev() ignores domain's third coordinate");
+
+ std::list<facet*> mesh;
+
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ mesh.push_back(new facet(f, g,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2, coords));
+
+ mesh.sort(by_distance());
+ // sort(mesh.begin(), mesh.end(), by_distance());
+
+ for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p)
+ {
+ (*p)->draw(cull);
+ delete *p;
+ }
+ }
+
+ //// Color-dependent versions ////
+ // location-dependent color
+ void surface(P F(double, double), const domain& R,
+ P color(double, double, double), int cull)
+ {
+ scenery surf(F, R, color);
+ surf.draw(cull);
+ }
+
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R,
+ P color(double, double, double), int cull)
+ {
+ scenery surf(F, R, color);
+ surf.draw(cull);
+ }
+
+ void surface(P F(double, double, double), const domain_list& R,
+ P color(double, double, double), int cull)
+ {
+ scenery tmp;
+
+ for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p)
+ tmp.add(F, *p, color);
+
+ tmp.draw(cull);
+ }
+
+
+ void surface_rev(double f(double), double g(double),
+ double min_x, double max_x, int i_max, int j_max,
+ P color(double, double, double), int cull)
+ {
+ surface_rev(f, g,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), color,
+ frame(), cull);
+ }
+
+ void surface_rev(double f(double),
+ double min_x, double max_x, int i_max, int j_max,
+ P color(double, double, double), int cull)
+ {
+ surface_rev(id, f,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), color,
+ frame(), cull);
+ }
+
+ void surface_rev(double f(double), double g(double),
+ const domain& R, P color(double, double, double),
+ const frame& coords, int cull)
+ {
+ if (R.dx3() > 0)
+ epix_warning("surface_rev() ignores domain's third coordinate");
+
+ std::list<facet*> mesh;
+
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ const double u0(R.corner1_x1());
+ const double v0(R.corner1_x2());
+ const double DU(R.step1());
+ const double DV(R.step2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ // mesh center approximates facet's location
+ P posn(f(u0 + (i+0.5)*DU)*coords.sea() +
+ g(u0 + (i+0.5)*DU)*Cos(v0 + (j+0.5)*DV)*coords.sky() +
+ g(u0 + (i+0.5)*DU)*Sin(v0 + (j+0.5)*DV)*coords.eye());
+
+ P col(color(posn.x1(), posn.x2(), posn.x3()));
+
+ mesh.push_back(new facet(f, g,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3()), coords));
+ }
+
+ mesh.sort(by_distance());
+ // sort(mesh.begin(), mesh.end(), by_distance());
+
+ for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p)
+ {
+ (*p)->draw(cull);
+ delete *p;
+ }
+ }
+
+ // domain-dependent color
+ void surface(P F(double, double), const domain& R,
+ P color(double, double), int cull)
+ {
+ scenery surf(F, R, color);
+ surf.draw(cull);
+ }
+
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R,
+ P color(double, double), int cull)
+ {
+ scenery surf(F, R, color);
+ surf.draw(cull);
+ }
+
+ void surface(P F(double, double, double), const domain_list& R,
+ P color(double, double), int cull)
+ {
+ scenery tmp;
+
+ for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p)
+ tmp.add(F, *p, color);
+
+ tmp.draw(cull);
+ }
+
+
+ void surface_rev(double f(double), double g(double),
+ double min_x, double max_x, int i_max, int j_max,
+ P color(double, double), int cull)
+ {
+ surface_rev(f, g,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), color,
+ frame(), cull);
+ }
+
+ void surface_rev(double f(double),
+ double min_x, double max_x, int i_max, int j_max,
+ P color(double, double), int cull)
+ {
+ surface_rev(id, f,
+ domain(P(min_x, 0), P(max_x, full_turn()),
+ mesh(i_max, j_max), mesh(i_max, j_max)), color,
+ frame(), cull);
+ }
+
+ void surface_rev(double f(double), double g(double),
+ const domain& R, P color(double, double),
+ const frame& coords, int cull)
+ {
+ if (R.dx3() > 0)
+ epix_warning("surface_rev() ignores domain's third coordinate");
+
+ std::list<facet*> mesh;
+
+ const unsigned int N1(R.fine_n1()/R.coarse_n1());
+ const unsigned int N2(R.fine_n2()/R.coarse_n2());
+ const double du(R.dx1());
+ const double dv(R.dx2());
+
+ const double u0(R.corner1_x1());
+ const double v0(R.corner1_x2());
+ const double DU(R.step1());
+ const double DV(R.step2());
+
+ for (int i=0; i<R.coarse_n1(); ++i)
+ for (int j=0; j<R.coarse_n2(); ++j)
+ {
+ // mesh center approximates facet's location
+ P posn(f(u0 + (i+0.5)*DU)*coords.sea() +
+ g(u0 + (i+0.5)*DU)*Cos(v0 + (j+0.5)*DV)*coords.sky() +
+ g(u0 + (i+0.5)*DU)*Sin(v0 + (j+0.5)*DV)*coords.eye());
+
+ P col(color(u0 + (i+0.5)*DU, v0 + (j+0.5)*DV));
+
+ mesh.push_back(new facet(f, g,
+ R.corner1_x1() + i*R.step1(),
+ R.corner1_x2() + j*R.step2(),
+ du, dv, N1, N2,
+ RGB(col.x1(), col.x2(), col.x3()), coords));
+ }
+
+ mesh.sort(by_distance());
+ // sort(mesh.begin(), mesh.end(), by_distance());
+
+ for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p)
+ {
+ (*p)->draw(cull);
+ delete *p;
+ }
+ }
+} // end of namespace
diff --git a/graphics/epix/surface.h b/graphics/epix/surface.h
new file mode 100644
index 0000000000..9c5be67a0c
--- /dev/null
+++ b/graphics/epix/surface.h
@@ -0,0 +1,194 @@
+/*
+ * surface.h -- Shaded surface plotting
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 08, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#include <list>
+
+#include "triples.h"
+#include "frame.h"
+
+#include "path.h"
+
+namespace ePiX
+{
+ class domain;
+ class domain_list;
+ class facet;
+
+ // manipulable collection of surface-like objects
+ class scenery {
+ public:
+ scenery();
+ scenery(P F(double, double), const domain& R);
+ scenery(P F(double, double, double), const domain& R);
+
+ // third arg is RGB-valued function of position
+ scenery(P F(double, double), const domain& R,
+ P color(double, double, double));
+
+ scenery(P F(double, double, double), const domain& R,
+ P color(double, double, double));
+
+ // third arg is RGB-valued function of domain location
+ scenery(P F(double, double), const domain& R,
+ P color(double, double));
+
+ scenery(P F(double, double, double), const domain& R,
+ P color(double, double));
+
+ scenery(const scenery&);
+ scenery& operator= (const scenery&);
+ ~scenery();
+
+ scenery& add(P F(double, double), const domain& R);
+ scenery& add(P F(double, double, double), const domain& R);
+
+ scenery& add(P F(double, double), const domain_list&);
+ scenery& add(P F(double, double, double), const domain_list&);
+
+ // color-dependent
+ // location-colored
+ scenery& add(P F(double, double), const domain& R,
+ P color(double, double, double));
+ scenery& add(P F(double, double, double), const domain& R,
+ P color(double, double, double));
+
+ scenery& add(P F(double, double), const domain_list&,
+ P color(double, double, double));
+ scenery& add(P F(double, double, double), const domain_list&,
+ P color(double, double, double));
+
+ // domain-colored
+ scenery& add(P F(double, double), const domain& R,
+ P color(double, double));
+ scenery& add(P F(double, double, double), const domain& R,
+ P color(double, double));
+
+ scenery& add(P F(double, double), const domain_list&,
+ P color(double, double));
+ scenery& add(P F(double, double, double), const domain_list&,
+ P color(double, double));
+
+ // remove backward-pointing faces? 0=no, -1=front, 1=back
+ scenery& cull(int);
+ void draw(int cull=0) const;
+
+ private:
+ int m_cull;
+
+ std::list<facet*> m_data;
+ }; // end of class scenery
+
+
+ //// global functions ////
+ // except as noted, dim(R) must be 2
+ // cosine-shaded surface with fake z-buffered hidden object removal
+ void surface(P F(double, double), const domain& R, int cull=0);
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R, int cull=0);
+
+ // plot multiple slices
+ void surface(P F(double, double, double), const domain_list& R, int cull=0);
+
+ // Surface from revolving the curve (f(t),g(t)) about the x-axis...
+ void surface_rev(double f(double), double g(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes=24, int cull=0);
+
+ void surface_rev(double f(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes=24, int cull=0);
+
+ // or about the specified axis, with specified angle range
+ void surface_rev(double f(double), double g(double),
+ const domain& R, const frame& coords=frame(), int cull=0);
+
+
+
+ //// location-colored versions ////
+ void surface(P F(double, double), const domain& R,
+ P color(double, double, double), int cull=0);
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R,
+ P color(double, double, double), int cull=0);
+
+ // plot multiple slices
+ void surface(P F(double, double, double), const domain_list& R,
+ P color(double, double, double), int cull=0);
+
+ // Surface from revolving the curve (f(t),g(t)) about the x-axis...
+ void surface_rev(double f(double), double g(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes,
+ P color(double, double, double), int cull=0);
+
+ void surface_rev(double f(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes,
+ P color(double, double, double), int cull=0);
+
+ // or about the specified axis, with specified angle range
+ void surface_rev(double f(double), double g(double),
+ const domain& R, P color(double, double, double),
+ const frame& coords=frame(), int cull=0);
+
+
+ //// domain-colored versions ////
+ void surface(P F(double, double), const domain& R,
+ P color(double, double), int cull=0);
+
+ // for slices of maps R^3 -> R^3
+ void surface(P F(double, double, double), const domain& R,
+ P color(double, double), int cull=0);
+
+ // plot multiple slices
+ void surface(P F(double, double), const domain_list& R,
+ P color(double, double, double), int cull=0);
+
+ // Surface from revolving the curve (f(t),g(t)) about the x-axis...
+ void surface_rev(double f(double), double g(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes,
+ P color(double, double), int cull=0);
+
+ void surface_rev(double f(double),
+ double t_min, double t_max,
+ int latitudes, int longitudes,
+ P color(double, double), int cull=0);
+
+ // or about the specified axis, with specified angle range
+ void surface_rev(double f(double), double g(double),
+ const domain& R, P color(double, double),
+ const frame& coords=frame(), int cull=0);
+} // end of namespace ePiX
diff --git a/graphics/epix/tikz.cc b/graphics/epix/tikz.cc
new file mode 100644
index 0000000000..b28a4832e4
--- /dev/null
+++ b/graphics/epix/tikz.cc
@@ -0,0 +1,312 @@
+/*
+ * tikz.cc -- ePiX::tikz output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 07, 2007
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <list>
+
+#include <string>
+#include <sstream>
+
+#include <set>
+
+#include "constants.h"
+
+#include "utils.h"
+
+#include "pairs.h"
+#include "edge_data.h"
+
+#include "Color.h"
+
+#include "path_style.h"
+#include "pen_data.h"
+
+// need to get units from the_picture
+#include "picture_data.h"
+#include "picture.h"
+
+#include "format.h"
+#include "tikz.h"
+
+namespace ePiX {
+
+ tikz::tikz()
+ : m_fill(Neutral()), m_stroke(Black()), m_lwidth(PLAIN_WIDTH),
+ m_units(the_picture().the_unitlength.units()) { }
+
+
+ tikz* tikz::clone() const
+ {
+ return new tikz(*this);
+ }
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string tikz::print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fc,
+ const pen_data& line,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+ obuf << set_fill_state(fc) << set_pen_state(line);
+
+ // compute attribute string
+ std::stringstream attribs;
+
+ if ( !(fc.is_unset()) )
+ {
+ attribs << "[fill";
+
+ if (fc.alpha() < 1)
+ attribs << ",opacity=" << fc.alpha();
+
+ attribs << "]";
+ }
+
+ obuf << print_paths(edges, offset, attribs.str(), len);
+
+ return obuf.str();
+ }
+
+ // Unfilled region, specified Cartesian edges
+ std::string tikz::print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line,
+ const pen_data& base,
+ const path_state& style,
+ const std::string& len) const
+ {
+ std::string value;
+
+ // draw *solid* base first
+ if (line.width() < base.width() && !base.color().is_unset())
+ {
+ std::stringstream battr;
+ battr << "[color=" << format::print(base.color()) << ","
+ << "line width=" << format::print(base.width()) << "]";
+
+ value += format::print_line(edges, offset, base, path_state(),
+ battr.str(), len);
+ }
+
+ value += set_pen_state(line);
+
+ return value += format::print_line(edges, offset, line, style, "", len);
+ }
+
+ // Print color declaration strings: model, name, densities
+ std::string tikz::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3) const
+ {
+ return format::xdefinecolor(model, name, d1, d2, d3);
+ }
+
+ std::string tikz::print_color(const std::string& model,
+ const std::string& name,
+ double d1, double d2,
+ double d3, double d4) const
+ {
+ return format::xdefinecolor(model, name, d1, d2, d3, d4);
+ }
+
+
+ // One-line comment
+ std::string tikz::print_comment(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << "%% " << msg << std::endl;
+
+ return obuf.str();
+ }
+
+ // verbatim string, newline protected
+ std::string tikz::print_verbatim(const std::string& msg) const
+ {
+ std::stringstream obuf;
+ obuf << msg << "%" << std::endl;
+
+ return obuf.str();
+ }
+
+
+ // start/end a picture-like environment, set unit length
+ std::string tikz::start_picture(const pair& sz, const pair& offset) const
+ {
+ std::stringstream obuf;
+ obuf << "\\begin{tikzpicture}" << std::endl
+ << "\\pgfsetlinewidth{" << format::print(PLAIN_WIDTH) << "}"
+ << std::endl
+ << "\\useasboundingbox " << print(offset)
+ << " rectangle " << print(sz + offset) << ";"
+ << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string tikz::end_picture() const
+ {
+ std::stringstream obuf;
+ obuf << "\\end{tikzpicture}" << std::endl;
+
+ return obuf.str();
+ }
+
+ // Actual work done in start_picture
+ std::string tikz::set_unitlength(const std::string& len) const
+ {
+ return "";
+ /*
+ std::stringstream obuf;
+
+ obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl;
+
+ return obuf.str();
+ */
+ }
+
+
+ void tikz::reset_state() const
+ {
+ m_fill = Neutral();
+ m_stroke = Black();
+ m_lwidth = PLAIN_WIDTH;
+ }
+
+ //// private member functions ////
+ std::string tikz::path_connector() const
+ {
+ return "--";
+ }
+
+
+ std::string tikz::usepackages() const
+ {
+ return "usepackages tikz";
+ }
+
+ // string argument for passing attributes local to this path/loop
+ std::string tikz::start_open_path(const std::string& attribs) const
+ {
+ return "\\draw " + attribs;
+ }
+
+ std::string tikz::end_open_path(const std::string&) const
+ {
+ std::stringstream obuf;
+ obuf << ";" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string tikz::start_closed_path(const std::string& attribs) const
+ {
+ return "\\draw " + attribs;
+ }
+
+ std::string tikz::end_closed_path(const std::string&) const
+ {
+ std::stringstream obuf;
+ obuf << "--cycle;" << std::endl;
+
+ return obuf.str();
+ }
+
+ // print declarations to set state of output format
+ std::string tikz::set_fill_state(const Color& col) const
+ {
+ std::stringstream buf;
+ if (col != m_fill && !col.is_unset())
+ buf << "\\pgfsetfillcolor{" << format::print(col) << "}" << std::endl;
+
+ m_fill = col;
+ return buf.str();
+ }
+
+ std::string tikz::set_pen_state(const pen_data& pen) const
+ {
+ std::stringstream buf;
+ if (pen.color() != m_stroke)
+ {
+ buf << "\\pgfsetstrokecolor{" << format::print(pen.color()) << "}"
+ << std::endl;
+
+ m_stroke = pen.color();
+ }
+
+ if (pen.width() != m_lwidth)
+ {
+ buf << "\\pgfsetlinewidth{" << format::print(pen.width()) << "}"
+ << std::endl;
+
+ m_lwidth = pen.width();
+ }
+
+ return buf.str();
+ }
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string tikz::put_box(const pair& loc, const std::string& msg) const
+ {
+ std::stringstream obuf;
+
+ obuf << "\\pgftext[at={\\pgfpoint{"
+ << truncate(loc.x1()) << m_units << "}{"
+ << truncate(loc.x2()) << m_units
+ << "}}] {" << msg << "}" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string tikz::print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const
+ {
+ std::stringstream obuf;
+ obuf << "\\";
+
+ if (fill)
+ obuf << "fill";
+
+ obuf << "draw[color=" << format::print(color) << "] "
+ << print(here) << " circle(" << 0.5*diam << len << ");" << std::endl;
+
+ return obuf.str();
+ }
+
+ std::string tikz::print(const pair& arg) const
+ {
+ std::stringstream o;
+ o << "(" << truncate(arg.x1()) << m_units
+ << "," << truncate(arg.x2()) << m_units << ")";
+ return o.str();
+ }
+} // end of namespace
diff --git a/graphics/epix/tikz.h b/graphics/epix/tikz.h
new file mode 100644
index 0000000000..e437edb122
--- /dev/null
+++ b/graphics/epix/tikz.h
@@ -0,0 +1,152 @@
+/*
+ * tikz.h -- ePiX::tikz output format
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.15
+ * Last Change: September 07, 2007
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_TIKZ
+#define EPIX_TIKZ
+
+#include <set>
+#include <list>
+#include <string>
+
+#include "edge_data.h"
+
+namespace ePiX {
+
+ class Color;
+ class pair;
+ class path_state;
+ class pen_data;
+
+ class tikz : public format {
+ public:
+ tikz();
+
+ // Return a copy of this
+ tikz* clone() const;
+
+ // Filled region with specified Cartesian edges, offset, and color
+ std::string print_fill(const std::list<edge2d>& edges,
+ const pair& offset,
+ const Color& fill,
+ const pen_data& line,
+ const std::string& len) const;
+
+ // Unfilled region, specified Cartesian edges. Should generally be
+ // trivially implemented using one-pen function (supplied).
+ std::string print_line(const std::list<edge2d>& edges,
+ const pair& offset,
+ const pen_data& line_pen,
+ const pen_data& base_pen,
+ const path_state& style,
+ const std::string& len) const;
+
+ /*
+ * Picture start and finish:
+ * Size and offset in page units,
+ * pallet (set of colors contained in the screen),
+ * unitlength
+ *
+ * These functions have default implementations, see format.cc.
+ * If the new format can use the default implementation, these
+ * functions declarations should be removed.
+ *
+ std::string pic_header(const pair& sizes,
+ const pair& offsets,
+ const std::set<Color>& pallet,
+ const std::string& len) const;
+
+ std::string pic_footer() const;
+ */
+
+ // Print color declaration strings: model, name, densities
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double) const;
+
+ std::string print_color(const std::string&,
+ const std::string&,
+ double,
+ double,
+ double,
+ double) const;
+
+ // One-line comment
+ std::string print_comment(const std::string&) const;
+
+ // Verbatim output
+ std::string print_verbatim(const std::string&) const;
+
+
+ // begin and end a picture-like environment, set the unit length
+ std::string start_picture(const pair&, const pair&) const;
+ std::string end_picture() const;
+
+ std::string set_unitlength(const std::string& len) const;
+
+ // State data, if any, must be mutable
+ void reset_state() const;
+
+ private:
+ mutable Color m_fill;
+ mutable Color m_stroke;
+ mutable length m_lwidth;
+
+ std::string m_units;
+
+ // override: inserted between path points
+ std::string path_connector() const;
+
+ std::string usepackages() const;
+
+ // string argument for passing attributes local to this path/loop
+ std::string start_open_path(const std::string&) const;
+ std::string end_open_path(const std::string&) const;
+
+ std::string start_closed_path(const std::string&) const;
+ std::string end_closed_path(const std::string&) const;
+
+ // print declarations to set state of output format
+ std::string set_fill_state(const Color&) const;
+ std::string set_pen_state(const pen_data&) const;
+
+ // place a LaTeX box of width zero (containing string) at location (pair)
+ std::string put_box(const pair&, const std::string&) const;
+
+ std::string print_circle_marker(const pair& here, double diam,
+ bool fill, const Color& color,
+ const std::string& len) const;
+
+ std::string print(const pair&) const; // override base class, print units
+ }; // end of class tikz
+} // end of namespace
+
+#endif /* EPIX_TIKZ */
diff --git a/graphics/epix/tile.cc b/graphics/epix/tile.cc
new file mode 100644
index 0000000000..a7717a818c
--- /dev/null
+++ b/graphics/epix/tile.cc
@@ -0,0 +1,38 @@
+/*
+ * tile.cc -- ePiX::tile destructor
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 14, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include "tile.h"
+
+namespace ePiX {
+ tile::~tile() { }
+
+} // end of namespace
diff --git a/graphics/epix/tile.h b/graphics/epix/tile.h
new file mode 100644
index 0000000000..da4639e694
--- /dev/null
+++ b/graphics/epix/tile.h
@@ -0,0 +1,62 @@
+/*
+ * tile.h -- ePiX::screen object base class (tile)
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.0.23
+ * Last Change: January 14, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+#ifndef EPIX_TILE
+#define EPIX_TILE
+
+#include <string>
+
+namespace ePiX {
+
+ class format;
+ class length;
+ class affine;
+ class screen;
+ class screen_mask;
+
+ class tile {
+ public:
+ virtual ~tile();
+
+ virtual tile* clone() const = 0;
+ virtual tile& map_by(const affine&) = 0;
+ virtual tile& crop_to(const screen_mask&) = 0;
+
+ virtual bool is_empty() const = 0;
+
+ // pass length for (e.g.) dash length, marker size
+ virtual std::string print_to(const format&, const std::string&) const = 0;
+ virtual void add_to_pallet() const = 0;
+ }; // end of class tile
+
+} // end of namespace
+
+#endif /* EPIX_TILE */
diff --git a/graphics/epix/triples.cc b/graphics/epix/triples.cc
new file mode 100644
index 0000000000..f62076d4f7
--- /dev/null
+++ b/graphics/epix/triples.cc
@@ -0,0 +1,211 @@
+/*
+ * triples.cc -- ePiX::P class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.9
+ * Last Change: August 01, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <cmath>
+
+#include "constants.h"
+#include "errors.h"
+#include "triples.h"
+
+namespace ePiX {
+
+ P::P(double arg1, double arg2, double arg3)
+ : m_x1(arg1), m_x2(arg2), m_x3(arg3) { }
+
+ double P::x1() const
+ {
+ return m_x1;
+ }
+
+ double P::x2() const
+ {
+ return m_x2;
+ }
+
+ double P::x3() const
+ {
+ return m_x3;
+ }
+
+ bool P::is_valid() const
+ {
+ using std::isnan;
+ using std::isinf;
+
+ return
+ !isinf(m_x3) && !isnan(m_x3)
+ && !isinf(m_x2) && !isnan(m_x2)
+ && !isinf(m_x1) && !isnan(m_x1)
+ && m_x1*m_x1 + m_x2*m_x2 + m_x3*m_x3 < EPIX_INFTY;
+ }
+
+ // increment operators
+ P& P::operator += (const P& arg)
+ {
+ m_x1 += arg.m_x1;
+ m_x2 += arg.m_x2;
+ m_x3 += arg.m_x3;
+
+ return *this;
+ }
+
+ P& P::operator -= (const P& arg)
+ {
+ m_x1 -= arg.m_x1;
+ m_x2 -= arg.m_x2;
+ m_x3 -= arg.m_x3;
+
+ return *this;
+ }
+
+ // scalar multipication
+ P& P::operator *= (double c)
+ {
+ m_x1 *= c;
+ m_x2 *= c;
+ m_x3 *= c;
+
+ return *this;
+ }
+
+ // cross product
+ P& P::operator *= (const P& v)
+ {
+ P temp(*this);
+
+ m_x1 = (temp.m_x2 * v.m_x3 - temp.m_x3 * v.m_x2);
+ m_x2 = (temp.m_x3 * v.m_x1 - temp.m_x1 * v.m_x3);
+ m_x3 = (temp.m_x1 * v.m_x2 - temp.m_x2 * v.m_x1);
+
+ return *this;
+ }
+
+ // componentwise product
+ P& P::operator &= (const P& v)
+ {
+ m_x1 *= v.m_x1;
+ m_x2 *= v.m_x2;
+ m_x3 *= v.m_x3;
+
+ return *this;
+ }
+
+ // orthogonalization: u %= v is the vector of the form u-k*v perp to v
+ P& P::operator%= (const P& v)
+ {
+ double denom(v.m_x1*v.m_x1 + v.m_x2*v.m_x2 + v.m_x3*v.m_x3);
+ if (denom < EPIX_EPSILON)
+ {
+ epix_warning("Orthogonalizing by zero vector, no action");
+ return *this;
+ }
+
+ // else c=(u|v)/(v|v)
+ double c((m_x1*v.m_x1 + m_x2*v.m_x2 + m_x3*v.m_x3)/denom);
+
+ m_x1 -= c*v.m_x1;
+ m_x2 -= c*v.m_x2;
+ m_x3 -= c*v.m_x3;
+
+ return *this;
+ }
+ // end of class functions
+
+ // vector space operations
+ P operator- (P u)
+ {
+ return u *= -1;
+ }
+
+ P operator+ (P u, const P& v)
+ {
+ return u += v;
+ }
+
+ P operator- (P u, const P& v)
+ {
+ return u -= v;
+ }
+
+ // scalar multiplication
+ P operator* (double c, P v)
+ {
+ return v *= c;
+ }
+
+ // cross product
+ P operator* (P u, const P& v)
+ {
+ return u *= v;
+ }
+
+ P J(P arg)
+ {
+ // E_3 * arg, but E_3 is const
+ return arg *= -E_3;
+ }
+
+ // dot product
+ double operator | (const P& u, const P& v)
+ {
+ return u.x1()*v.x1() + u.x2()*v.x2() + u.x3()*v.x3();
+ }
+
+ double norm(const P& u)
+ {
+ return sqrt(u|u);
+ }
+
+ // componentwise product (a,b,c)&(x,y,z)=(ax,by,cz)
+ P operator& (P u, const P& v)
+ {
+ return u &= v;
+ }
+
+ P operator% (P u, const P& v)
+ {
+ return u %= v;
+ }
+
+ // (in)equality
+ bool operator == (const P& u, const P& v)
+ {
+ return (norm(u-v) < EPIX_EPSILON);
+ }
+
+ bool operator != (const P& u, const P& v)
+ {
+ return !(u==v);
+ }
+} // end of namespace
diff --git a/graphics/epix/triples.h b/graphics/epix/triples.h
new file mode 100644
index 0000000000..54f5c5581b
--- /dev/null
+++ b/graphics/epix/triples.h
@@ -0,0 +1,115 @@
+/*
+ * triples.h -- ePiX::P class
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.10
+ * Last Change: August 04, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+/*
+ * This file provides:
+ *
+ * The P class (ordered triple of <double>s) and operators
+ *
+ * - P(), P() (default to origin), E_1, E_2, E_3 (standard basis)
+ * - Vector space operators
+ * - Other vector operators, operands (a,b,c), (x,y,z)
+ * | dot product ax + by + cz
+ * norm(p) = sqrt(p|p)
+ * & componentwise product (ax, by, cz)
+ * * cross product (bz-cy, cx-az, ay-bx)
+ * J rotate (x1,x2,0)-plane 1/4 turn (-b,a,0)
+ * % orthogonalization u%v = u - ((u|v)/(v|v))*v
+ */
+#ifndef EPIX_TRIPLES
+#define EPIX_TRIPLES
+
+namespace ePiX {
+
+ class P {
+ public:
+ P(double arg1=0, double arg2=0, double arg3=0);
+
+ double x1() const;
+ double x2() const;
+ double x3() const;
+
+ bool is_valid() const; // coords not inf or nan
+
+ // increment operators
+ P& operator += (const P&);
+ P& operator -= (const P&);
+ P& operator *= (double); // scalar multipication
+
+ // cross product
+ P& operator *= (const P&);
+
+ // componentwise product
+ P& operator &= (const P&);
+
+ // orthogonalization: u %= v is the vector of the form u-k*v perp to v
+ P& operator %= (const P&);
+
+ private:
+ double m_x1, m_x2, m_x3;
+ }; // end of class P
+
+
+ // standard basis in global namespace
+ const P E_1(1,0,0);
+ const P E_2(0,1,0);
+ const P E_3(0,0,1);
+
+ // vector space operations
+ P operator- (P u); // unary negation
+ P operator+ (P u, const P& v);
+ P operator- (P u, const P& v);
+ // scalar multiplication
+ P operator* (double c, P v);
+
+ // cross product
+ P operator* (P, const P&);
+ P J(P); // quarter turn about E_3-axis
+
+ // dot product
+ double operator | (const P&, const P&);
+ double norm(const P&);
+
+ // componentwise product (a,b,c)&(x,y,z)=(ax,by,cz)
+ P operator& (P, const P&);
+ // orthogonalization
+ P operator% (P, const P&);
+
+ // (in)equality
+ bool operator == (const P&, const P&);
+ bool operator != (const P&, const P&);
+
+} // end of namespace
+
+#endif /* EPIX_TRIPLES */
diff --git a/graphics/epix/utils.cc b/graphics/epix/utils.cc
new file mode 100644
index 0000000000..2b57ddf1ea
--- /dev/null
+++ b/graphics/epix/utils.cc
@@ -0,0 +1,124 @@
+/*
+ * utils.cc -- global utility functions for ePiX
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <string>
+#include <cmath>
+#include <ctime>
+
+#include "constants.h"
+#include "utils.h"
+
+namespace ePiX {
+
+ const std::string epix_version()
+ {
+ return "1.2.1";
+ }
+
+ double truncate(double arg)
+ {
+ return fabs(arg) < EPIX_EPSILON ? 0 : arg;
+ }
+
+ std::string date_and_time()
+ {
+ ////// N.B.: Revise this if time format string changes!
+ const int max_len = 31;
+ char buf[max_len];
+ time_t t=time(0);
+
+ // strftime(buf, max_len, "%c", localtime(&t));
+
+ // Sat Jul 1 23:25:39 2006 (GMT)
+ strftime(buf, max_len, "%a %b %d %X %Y (%Z)", gmtime(&t));
+ return std::string(buf);
+ }
+
+
+ // remove everything from arg except chars in srch
+ std::string get_chars(std::string arg, const std::string& srch)
+ {
+ std::string::size_type curr(0);
+ std::string::size_type next(arg.find_first_of(srch));
+
+ while (next != std::string::npos)
+ {
+ arg.erase(curr, next-curr);
+
+ curr = arg.find_first_not_of(srch);
+ next = arg.find_first_of(srch, curr);
+ }
+
+ if (next != curr)
+ arg.erase(curr, next);
+
+ return arg;
+ }
+
+ // add linebreaks before opening parentheses to make lines at most
+ // FILE_WIDTH characters long; return reference to arg
+ std::string break_lines(std::string arg, const std::string& path_break)
+ {
+ std::string value; // append here; swap with arg at end
+
+ // initialize markers prev, curr, next
+ std::string::size_type prev(0); // position of last line break
+ std::string::size_type next(arg.find_first_of("("));
+ std::string::size_type curr(next);
+
+ unsigned int pbk_sz(path_break.size());
+
+ while (next != std::string::npos)
+ {
+ // seek next break points
+ while (next-prev <= EPIX_FILE_WIDTH - pbk_sz)
+ {
+ curr = next;
+ next = arg.find_first_of("(", ++next);
+ }
+
+ value.append(arg, prev, curr-prev); // append current line
+ // Magic number 20 (greater than width of a printed pair)
+ if (next - prev <= 20+EPIX_FILE_WIDTH) // not at end of data
+ value += path_break; // and formatting string
+ prev = curr; // update front of line
+ }
+
+ // get remaining characters
+ value.append(arg, prev, next-prev);
+
+ swap(arg, value);
+ return arg;
+ }
+} // end of namespace
diff --git a/graphics/epix/utils.h b/graphics/epix/utils.h
new file mode 100644
index 0000000000..018efcdfca
--- /dev/null
+++ b/graphics/epix/utils.h
@@ -0,0 +1,56 @@
+/*
+ * utils.h -- global utility functions for ePiX
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.18
+ * Last Change: September 15, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_UTILS
+#define EPIX_UTILS
+
+#include <string>
+
+namespace ePiX {
+
+ const std::string epix_version();
+
+ double truncate(double); // return 0 if fabs(arg) < epsilon
+
+ // print GMT string for file header
+ std::string date_and_time();
+
+ // remove everything from arg except chars in srch
+ std::string get_chars(std::string arg, const std::string& srch);
+
+ // Use break to split arg into lines of at most FILE_WIDTH characters,
+ // return mangled copy of arg
+ std::string break_lines(std::string arg, const std::string& break_str);
+}
+#endif /* EPIX_UTILS */
diff --git a/graphics/epix/verbatim.cc b/graphics/epix/verbatim.cc
new file mode 100644
index 0000000000..8f7df3b3fb
--- /dev/null
+++ b/graphics/epix/verbatim.cc
@@ -0,0 +1,80 @@
+/*
+ * verbatim.cc -- ePiX screen implemenation for verbatim text
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 14, 2007
+ */
+
+/*
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#include <sstream>
+
+#include "format.h"
+#include "verbatim.h"
+
+namespace ePiX {
+
+ class affine;
+ class screen_mask;
+
+ verbatim::verbatim(const std::string& text) : m_text(text)
+ {
+ }
+
+ verbatim& verbatim::map_by(const affine& f)
+ {
+ return *this;
+ }
+
+ verbatim& verbatim::crop_to(const screen_mask& M)
+ {
+ return *this;
+ }
+
+ verbatim* verbatim::clone() const
+ {
+ return new verbatim(*this);
+ }
+
+ bool verbatim::is_empty() const
+ {
+ return (m_text == "");
+ }
+
+ std::string verbatim::print_to(const format& fmt, const std::string& L) const
+ {
+ if (is_empty())
+ return "";
+
+ // else
+ return fmt.print_verbatim(m_text);
+ }
+
+ void verbatim::add_to_pallet() const { }
+} // end of namespace
+
diff --git a/graphics/epix/verbatim.h b/graphics/epix/verbatim.h
new file mode 100644
index 0000000000..39b2d3b9d5
--- /dev/null
+++ b/graphics/epix/verbatim.h
@@ -0,0 +1,66 @@
+/*
+ * verbatim.h -- ePiX screen implemenation of verbatim text
+ *
+ * This file is part of ePiX, a C++ library for creating high-quality
+ * figures in LaTeX
+ *
+ * Version 1.1.7
+ * Last Change: July 14, 2007
+ *
+ *
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh>
+ * 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
+ */
+
+#ifndef EPIX_VERBATIM
+#define EPIX_VERBATIM
+
+#include <string>
+
+#include "tile.h"
+
+namespace ePiX {
+
+ class format;
+ class affine;
+ class screen_mask;
+
+ class verbatim : public tile {
+ public:
+ verbatim(const std::string& text="");
+
+ verbatim& map_by(const affine&);
+ verbatim& crop_to(const screen_mask&);
+
+ verbatim* clone() const;
+
+ bool is_empty() const;
+
+ std::string print_to(const format&, const std::string&) const;
+ void add_to_pallet() const;
+
+ private:
+ std::string m_text;
+ }; // end of class verbatim
+
+} // end of namespace
+
+#endif /* EPIX_VERBATIM */