summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-06-08 00:57:31 +0000
committerKarl Berry <karl@freefriends.org>2009-06-08 00:57:31 +0000
commit9e32dd6aee7faf4e59888cfbd7a927d497b563ad (patch)
tree5068ec13390f4352be663383dd58e22147e68201 /Build
parent3f49bad6cd5234b4e0ea156f6f68f6430643c10f (diff)
asymptote 1.76
git-svn-id: svn://tug.org/texlive/trunk@13664 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/utils/README6
-rw-r--r--Build/source/utils/asymptote/ChangeLog232
-rw-r--r--Build/source/utils/asymptote/Makefile.in2
-rw-r--r--Build/source/utils/asymptote/ReleaseNotes15
-rw-r--r--Build/source/utils/asymptote/asymptote.spec2
-rw-r--r--Build/source/utils/asymptote/base/bezulate.asy37
-rw-r--r--Build/source/utils/asymptote/base/fontsize.asy2
-rw-r--r--Build/source/utils/asymptote/base/labelpath3.asy27
-rw-r--r--Build/source/utils/asymptote/base/plain_Label.asy20
-rw-r--r--Build/source/utils/asymptote/base/plain_paths.asy10
-rw-r--r--Build/source/utils/asymptote/base/plain_pens.asy6
-rw-r--r--Build/source/utils/asymptote/base/plain_strings.asy19
-rw-r--r--Build/source/utils/asymptote/base/three.asy106
-rw-r--r--Build/source/utils/asymptote/base/three_light.asy47
-rw-r--r--Build/source/utils/asymptote/base/three_surface.asy16
-rwxr-xr-xBuild/source/utils/asymptote/configure18
-rw-r--r--Build/source/utils/asymptote/configure.ac2
-rw-r--r--Build/source/utils/asymptote/doc/CAD.pdfbin67399 -> 67399 bytes
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/asy-faq.info2
-rw-r--r--Build/source/utils/asymptote/doc/asymptote.pdfbin1558385 -> 1559735 bytes
-rw-r--r--Build/source/utils/asymptote/doc/asymptote.sty10
-rw-r--r--Build/source/utils/asymptote/doc/asymptote.texi31
-rw-r--r--Build/source/utils/asymptote/doc/ocg.sty127
-rw-r--r--Build/source/utils/asymptote/doc/png/Makefile.in3
-rw-r--r--Build/source/utils/asymptote/doc/png/asymptote.info9643
-rw-r--r--Build/source/utils/asymptote/drawclipend.h3
-rw-r--r--Build/source/utils/asymptote/drawfill.cc12
-rw-r--r--Build/source/utils/asymptote/drawlabel.cc38
-rw-r--r--Build/source/utils/asymptote/drawlabel.h10
-rw-r--r--Build/source/utils/asymptote/examples/BezierSurface.asy2
-rw-r--r--Build/source/utils/asymptote/examples/condor.asy2
-rw-r--r--Build/source/utils/asymptote/examples/layers.asy44
-rw-r--r--Build/source/utils/asymptote/examples/logo3.asy2
-rw-r--r--Build/source/utils/asymptote/examples/pdb.asy2
-rw-r--r--Build/source/utils/asymptote/examples/pipeintersection.asy2
-rw-r--r--Build/source/utils/asymptote/examples/teapot.asy1
-rw-r--r--Build/source/utils/asymptote/examples/trefoilknot.asy2
-rw-r--r--Build/source/utils/asymptote/examples/wedge.asy2
-rw-r--r--Build/source/utils/asymptote/pen.h7
-rw-r--r--Build/source/utils/asymptote/picture.cc2
-rw-r--r--Build/source/utils/asymptote/picture.h4
-rw-r--r--Build/source/utils/asymptote/runtime.cc4641
-rw-r--r--Build/source/utils/asymptote/runtime.in96
-rw-r--r--Build/source/utils/asymptote/settings.cc7
-rw-r--r--Build/source/utils/asymptote/settings.h1
-rw-r--r--Build/source/utils/asymptote/texfile.cc13
-rw-r--r--Build/source/utils/asymptote/texfile.h3
47 files changed, 12592 insertions, 2687 deletions
diff --git a/Build/source/utils/README b/Build/source/utils/README
index 979efb6f700..ac6736b9e00 100644
--- a/Build/source/utils/README
+++ b/Build/source/utils/README
@@ -5,9 +5,9 @@ You may freely use, modify and/or distribute this file.
Extra utilities we (optionally) compile for TeX Live.
See comments in ../texk/README.
-asymptote 1.75 - checked 4jun09
- http://superb-east.dl.sourceforge.net/sourceforge/asymptote/asymptote-1.75.src.tgz
- configure --enable-tetex-build --disable-gc # if gc make check fails
+asymptote 1.76 - checked 8jun09
+ get from CTAN, to include prebuild doc.
+ ...
make CFLAGS="-g -DBROKEN_COMPILER" if redefinition of solvedKnot3.
dialog 1.1-20080819 - checked 20mar09
diff --git a/Build/source/utils/asymptote/ChangeLog b/Build/source/utils/asymptote/ChangeLog
index 6a178c70393..905536aa324 100644
--- a/Build/source/utils/asymptote/ChangeLog
+++ b/Build/source/utils/asymptote/ChangeLog
@@ -1,4 +1,236 @@
------------------------------------------------------------------------
+r4386 | jcbowman | 2009-06-05 21:23:37 -0600 (Fri, 05 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+
+Remove texunits (not required).
+
+------------------------------------------------------------------------
+r4385 | jcbowman | 2009-06-05 21:06:43 -0600 (Fri, 05 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/png/Makefile.in
+
+Don't split info files.
+
+------------------------------------------------------------------------
+r4384 | jcbowman | 2009-06-05 20:45:25 -0600 (Fri, 05 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Fix bezulate bug: determine the number of intersections of a path with a
+line segment directly from the intersections routine.
+
+------------------------------------------------------------------------
+r4383 | jcbowman | 2009-06-05 07:36:55 -0600 (Fri, 05 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r4382 | jcbowman | 2009-06-05 07:06:37 -0600 (Fri, 05 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/teapot.asy
+
+Restore example.
+
+------------------------------------------------------------------------
+r4381 | jcbowman | 2009-06-04 10:42:35 -0600 (Thu, 04 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Rename inside(int,pen) to interior(int,pen).
+
+------------------------------------------------------------------------
+r4380 | jcbowman | 2009-06-04 10:41:19 -0600 (Thu, 04 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Suppress "cannot find an interior point" warning for degenerate paths.
+
+------------------------------------------------------------------------
+r4379 | jcbowman | 2009-06-03 23:19:05 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implement addAllViews function to exhibit all six standard 3D views.
+
+------------------------------------------------------------------------
+r4378 | jcbowman | 2009-06-03 21:36:49 -0600 (Wed, 03 Jun 2009) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/condor.asy
+ M /trunk/asymptote/examples/logo3.asy
+ M /trunk/asymptote/examples/pdb.asy
+ M /trunk/asymptote/examples/pipeintersection.asy
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/examples/trefoilknot.asy
+ M /trunk/asymptote/examples/wedge.asy
+
+Rename adobe light to White; update parameters to agree with PDF32000-1:2008.
+
+Add ambient light to Headlamp (other parameters in PDF32000-1:2008 appear to be
+incorrect).
+
+------------------------------------------------------------------------
+r4377 | jcbowman | 2009-06-03 12:55:50 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Turn off light in certain examples to avoid confusion.
+
+------------------------------------------------------------------------
+r4376 | jcbowman | 2009-06-03 12:48:50 -0600 (Wed, 03 Jun 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix filename for attach=true mode.
+
+Add hiresbb option to includegraphics.
+
+------------------------------------------------------------------------
+r4375 | jcbowman | 2009-06-03 12:21:11 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Improve texpath resolution by preshifting.
+
+------------------------------------------------------------------------
+r4374 | jcbowman | 2009-06-03 12:02:54 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/fontsize.asy
+
+Make fontsize package conditional on latex().
+
+------------------------------------------------------------------------
+r4373 | jcbowman | 2009-06-03 12:02:29 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Improve texpath caching.
+
+------------------------------------------------------------------------
+r4372 | jcbowman | 2009-06-03 12:01:42 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix degenerate transform3.
+
+------------------------------------------------------------------------
+r4371 | jcbowman | 2009-06-03 01:50:28 -0600 (Wed, 03 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Add real[] texsize(string, pen=currentpen) command returning raw TeX
+dimensions {width,height,depth}.
+
+------------------------------------------------------------------------
+r4370 | jcbowman | 2009-06-03 01:46:42 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Add missing ps2tex scaling.
+
+------------------------------------------------------------------------
+r4369 | jcbowman | 2009-06-03 01:45:14 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Make texpath aware of baseline for PDF tex engines.
+
+------------------------------------------------------------------------
+r4368 | jcbowman | 2009-06-03 01:42:23 -0600 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/labelpath3.asy
+
+Simplify alignment.
+
+------------------------------------------------------------------------
+r4367 | jcbowman | 2009-06-02 12:02:03 -0600 (Tue, 02 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/labelpath3.asy
+
+Remove unwanted assignments.
+
+------------------------------------------------------------------------
+r4366 | jcbowman | 2009-06-02 11:33:59 -0600 (Tue, 02 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+
+Tune headlamp parameters.
+
+------------------------------------------------------------------------
+r4365 | jcbowman | 2009-06-02 11:33:38 -0600 (Tue, 02 Jun 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Tune alignment between rendered and PRC images for perspective projections.
+
+Fix angle for absolute projection rendering.
+
+------------------------------------------------------------------------
+r4364 | jcbowman | 2009-06-02 10:26:20 -0600 (Tue, 02 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+
+Add headlamp light that approximates 3Dlights=Headlamp.
+
+------------------------------------------------------------------------
+r4363 | jcbowman | 2009-06-02 01:28:17 -0600 (Tue, 02 Jun 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add hiresbb option to graphic.
+
+Remove 2 pixel offset.
+
+------------------------------------------------------------------------
+r4362 | jcbowman | 2009-06-02 00:37:23 -0600 (Tue, 02 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Improve rendered and PRC alignment.
+
+------------------------------------------------------------------------
+r4361 | jcbowman | 2009-06-01 21:57:28 -0600 (Mon, 01 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Handle holes in surface constructor for superpaths when planar=true.
+
+------------------------------------------------------------------------
+r4360 | jcbowman | 2009-06-01 17:18:19 -0600 (Mon, 01 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ A /trunk/asymptote/doc/ocg.sty
+ A /trunk/asymptote/examples/layers.asy
+
+Add support for OCG layers.
+
+------------------------------------------------------------------------
+r4359 | jcbowman | 2009-06-01 02:43:51 -0600 (Mon, 01 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.76svn.
+------------------------------------------------------------------------
r4358 | jcbowman | 2009-06-01 00:04:03 -0600 (Mon, 01 Jun 2009) | 2 lines
Changed paths:
M /trunk/asymptote/doc/FAQ/Makefile
diff --git a/Build/source/utils/asymptote/Makefile.in b/Build/source/utils/asymptote/Makefile.in
index 31a5d010eab..256c4a64726 100644
--- a/Build/source/utils/asymptote/Makefile.in
+++ b/Build/source/utils/asymptote/Makefile.in
@@ -32,7 +32,7 @@ EXTRA = asy-mode.el asy-init.el asy.vim asymptote.py reload.js nopapersize.ps
EXEXTRA = piicon.eps *.views *.dat
DOCEXTRA = *.asy *.csv *.dat latexusage.tex externalprc.tex pixel.pdf
KEYWORDS = base $(ASYMPTOTE_SITEDIR)
-LATEXFILES = asymptote.sty asycolors.sty
+LATEXFILES = asymptote.sty asycolors.sty ocg.sty
CONTEXTFILES = colo-asy.tex
ASY = ./asy -dir base -config "" -render=0
diff --git a/Build/source/utils/asymptote/ReleaseNotes b/Build/source/utils/asymptote/ReleaseNotes
index 48619da6be8..218878d8bbe 100644
--- a/Build/source/utils/asymptote/ReleaseNotes
+++ b/Build/source/utils/asymptote/ReleaseNotes
@@ -1,3 +1,16 @@
+Release Notes for Version 1.76
+
+A bezulate bug was fixed. The resolution and caching of texpath were
+improved; for PDF tex engines, the basealign pen attribute is now
+respected. Support for OCG layers was added. Lights Headlamp and White were
+implemented; the predefined adobe light was removed. Holes are now handled
+in superpath-to-surface constructor when planar=true. A degenerate
+transform3 issue was fixed. The alignment of rendered and PRC images was
+improved; the angle for rendering absolute projections was fixed. Inaccurate
+TeX and ConTeXt font scalings were fixed. A texsize(string, pen=currentpen)
+function returns the raw TeX dimensions {width,height,depth}. A new version
+of asymptote.sty (1.07) fixes attach=true mode.
+
Release Notes for Version 1.75
Issues with 3D labels and texpath, both in inlinetex mode and with the
@@ -5,7 +18,7 @@ ConTeXt TeX engine, were resolved. A bug in bezulate was fixed. A partial
workaround was added for the unimplememented -output-directory ConTeXt
option (the current directory must still be writeable). The aspect ratio
and viewportmargin calculation in module three was improved, with tighter
-3D bounds. A bug in the intersectionpoints(path3, surface) routine was fixed.
+3D bounds. A bug in the intersections(path3, surface) routine was fixed.
Release Notes for Version 1.74
diff --git a/Build/source/utils/asymptote/asymptote.spec b/Build/source/utils/asymptote/asymptote.spec
index c242a4b8ce3..90162a83b1d 100644
--- a/Build/source/utils/asymptote/asymptote.spec
+++ b/Build/source/utils/asymptote/asymptote.spec
@@ -1,7 +1,7 @@
%{!?_texmf: %define _texmf %(eval "echo `kpsewhich -expand-var '$TEXMFLOCAL'`")}
Name: asymptote
-Version: 1.75
+Version: 1.76
Release: 1%{?dist}
Summary: Descriptive vector graphics language
diff --git a/Build/source/utils/asymptote/base/bezulate.asy b/Build/source/utils/asymptote/base/bezulate.asy
index 01b3024f7b6..2b852623faf 100644
--- a/Build/source/utils/asymptote/base/bezulate.asy
+++ b/Build/source/utils/asymptote/base/bezulate.asy
@@ -1,13 +1,19 @@
// Bezier triangulation routines written by Orest Shardt, 2008.
-private real fuzz=1e-6;
+private real fuzz=sqrtEpsilon;
real duplicateFuzz=1e-3; // Work around font errors.
+private real[][] intersections(pair a, pair b, path p)
+{
+ pair delta=fuzz*unit(b-a);
+ return intersections(a-delta--b+delta,p,fuzz);
+}
+
int countIntersections(path[] p, pair start, pair end)
{
int intersects=0;
for(path q : p)
- intersects += intersections(q,start--end,fuzz).length;
+ intersects += intersections(start,end,q).length;
return intersects;
}
@@ -101,27 +107,23 @@ void connect(path[] paths, path[] result, path[] patch)
pair start=point(inners[curveIndex],0);
// find first intersection of line segment with outer curve
- path line = start--start+d*direction;
- real[][] ints=intersections(line,outer,fuzz);
+ real[][] ints=intersections(start,start+d*direction,outer);
assert(ints.length != 0);
real endtime=ints[0][1]; // endtime is time on outer
pair end = point(outer,endtime);
- line = start--end;
- path rline = reverse(line);
- // find first intersection of rline segment with any inner curve
+ // find first intersection of end--start with any inner curve
real starttime=0; // starttime is time on inners[curveIndex]
real earliestTime=1;
for(int j=0; j < inners.length; ++j) {
- real[][] ints=intersections(rline,inners[j],fuzz);
+ real[][] ints=intersections(end,start,inners[j]);
if(ints.length > 0 && ints[0][0] < earliestTime) {
- earliestTime=ints[0][0]; // time on rline
+ earliestTime=ints[0][0]; // time on end--start
starttime=ints[0][1]; // time on inner curve
curveIndex=j;
}
}
start=point(inners[curveIndex],starttime);
- line = start--end;
real timeoffset=2;
bool found=false;
@@ -146,7 +148,7 @@ void connect(path[] paths, path[] result, path[] patch)
}
}
- if(!found)timeoffset=-2;
+ if(!found) timeoffset=-2;
while(!found && timeoffset < -fuzz) {
timeoffset /= 2;
if(countIntersections(allCurves,start,
@@ -179,20 +181,11 @@ void connect(path[] paths, path[] result, path[] patch)
}
}
-int countIntersections(path g, pair p, pair q)
-{
- int ints=0;
- int l=length(g);
- for(int i=1; i <= l; ++i)
- ints += intersections(subpath(g,i-1,i),p--q,fuzz).length;
- return ints;
-}
-
bool checkSegment(path g, pair p, pair q)
{
pair mid=0.5*(p+q);
- return countIntersections(g,p,q) == 4 && inside(g,mid,zerowinding) &&
- intersections(g,mid).length == 0;
+ return intersections(p,q,g).length == 2 &&
+ inside(g,mid,zerowinding) && intersections(g,mid).length == 0;
}
path subdivide(path p)
diff --git a/Build/source/utils/asymptote/base/fontsize.asy b/Build/source/utils/asymptote/base/fontsize.asy
index 0c0c6a0dcca..4575f3480fa 100644
--- a/Build/source/utils/asymptote/base/fontsize.asy
+++ b/Build/source/utils/asymptote/base/fontsize.asy
@@ -1 +1 @@
-usepackage("fix-cm");
+if(latex()) usepackage("fix-cm");
diff --git a/Build/source/utils/asymptote/base/labelpath3.asy b/Build/source/utils/asymptote/base/labelpath3.asy
index acfa64d528f..b8a946a07ae 100644
--- a/Build/source/utils/asymptote/base/labelpath3.asy
+++ b/Build/source/utils/asymptote/base/labelpath3.asy
@@ -2,11 +2,7 @@
// Author: Jens Schwaiger
import three;
-size(7.5cm,0);
-real eps=100*realEpsilon;
-currentprojection=perspective(20,18,8);
-currentlight=light(8,10,2);
-//texpreamble("\textwidth=50cm"); // Avoid line breaking in long texts
+private real eps=100*realEpsilon;
triple nextnormal(triple p, triple q)
{
@@ -34,13 +30,14 @@ triple[] nextframe(path3 p, real reltimestart, triple[] start, real
real lg=reltimeend-reltimestart;
if(lg <= 0) return start;
bf[0]=start;
- for(int i=1; i < subdiv+1; i=i+1) {
+ int n=subdiv+1;
+ for(int i=1; i < n; ++i)
bf[i][0]=dir(p,reltime(p,reltimestart+(i/subdiv)*lg));
- };
- for(int i=1; i < subdiv+1; i=i+1) {
+
+ for(int i=1; i < n; ++i) {
bf[i][1]=nextnormal(bf[i-1][1],bf[i][0]);
bf[i][2]=cross(bf[i][0],bf[i][1]);
- };
+ }
return bf[subdiv];
}
@@ -48,8 +45,7 @@ surface labelpath(string txt, path3 p, real angle=90, triple optional=O)
{
real Cos=Cos(angle);
real Sin=Sin(angle);
- path[] text=shift(-labelmargin(currentpen)*NE)*
- texpath(Label(txt,(0,0),NE,basealign));
+ path[] text=texpath(Label(txt,(0,0),Align,basealign));
text=scale(1/(max(text).x-min(text).x))*text;
path[][] decompose=containmentTree(text);
@@ -59,7 +55,7 @@ surface labelpath(string txt, path3 p, real angle=90, triple optional=O)
xpos[i][1]=i;
real pos0=0.5(max(decompose[i]).x+min(decompose[i]).x);
xpos[i][0]=pos0;
- };
+ }
xpos=sort(xpos); // sort by distance from 0;
triple[] pos=new triple[decompose.length];
real lg=arclength(p);
@@ -70,17 +66,18 @@ surface labelpath(string txt, path3 p, real angle=90, triple optional=O)
triple[][] bfr=new triple[decompose.length][3];
for(int j=0; j < decompose.length; ++j) {
bfr[j]=nextframe(p,tm0,t0,xpos[j][0]);
- tm0=xpos[j][0]; t0=bfr[j];};
+ tm0=xpos[j][0]; t0=bfr[j];
+ }
transform3[] mt=new transform3[bfr.length];
for(int j=0; j < bfr.length; ++j) {
triple f2=Cos*bfr[j][1]+Sin*bfr[j][2];
triple f3=Sin*bfr[j][1]+Cos*bfr[j][2];
mt[j]=shift(relpoint(p,xpos[j][0]))*transform3(bfr[j][0],f2,f3);
- };
+ }
for(int j=0; j < bfr.length; ++j) {
path[] dc=decompose[(int) xpos[j][1]];
pair pos0=(0.5(max(dc).x+min(dc).x),0);
sf.append(mt[j]*surface(scale(lg)*shift(-pos0)*dc));
- };
+ }
return sf;
}
diff --git a/Build/source/utils/asymptote/base/plain_Label.asy b/Build/source/utils/asymptote/base/plain_Label.asy
index 1279880ca3a..3c11a2cedbd 100644
--- a/Build/source/utils/asymptote/base/plain_Label.asy
+++ b/Build/source/utils/asymptote/base/plain_Label.asy
@@ -571,7 +571,12 @@ path[] texpath(Label L, bool tex=settings.tex != "none")
path[] g;
string s=L.s;
- pen p=L.p;
+ pen p=fontcommand(font(L.p))+fontsize(fontsize(L.p));
+
+ // PDF tex engines lose track of the baseline.
+ bool adjust=tex && basealign(L.p) == 1 && pdf();
+ if(adjust) p=p+basealign;
+
int k=0;
int i;
while((i=find(stringcache == s,++k)) >= 0) {
@@ -582,7 +587,16 @@ path[] texpath(Label L, bool tex=settings.tex != "none")
}
if(i == -1) {
- g=tex ? _texpath(s,p) : textpath(s,p);
+ if(tex) {
+ if(adjust) {
+ g=_texpath("."+s,p);
+ if(g.length == 0) return g;
+ real y=min(g[0]).y;
+ g.delete(0);
+ g=shift(0,-y)*g;
+ } else g=_texpath(s,p);
+ } else g=textpath(s,p);
+
stringcache.push(s);
pencache.push(p);
pathcache.push(g);
@@ -593,7 +607,7 @@ path[] texpath(Label L, bool tex=settings.tex != "none")
pair m=min(g);
pair M=max(g);
pair dir=rectify(inverse(L.T)*-L.align.dir);
- if(basealign(p) == 1)
+ if(tex && basealign(L.p) == 1)
dir -= (0,(1-dir.y)*m.y/(M.y-m.y));
a=m+realmult(dir,M-m);
diff --git a/Build/source/utils/asymptote/base/plain_paths.asy b/Build/source/utils/asymptote/base/plain_paths.asy
index 486f3f0cc7b..d457fa5bc28 100644
--- a/Build/source/utils/asymptote/base/plain_paths.asy
+++ b/Build/source/utils/asymptote/base/plain_paths.asy
@@ -329,19 +329,21 @@ pair inside(path p, pen fillrule=currentpen)
int n=length(p);
for(int i=0; i < n; ++i) {
pair z=point(p,i);
- real[] T=intersections(p,z,z+I*dir(p,i));
+ pair dir=dir(p,i);
+ if(dir == 0) continue;
+ real[] T=intersections(p,z,z+I*dir);
// Check midpoints of line segments formed between the
// corresponding intersection points and z.
for(int j=0; j < T.length; ++j) {
if(T[j] != i) {
pair w=point(p,T[j]);
pair m=0.5*(z+w);
- if(inside(windingnumber(p,m),fillrule)) return m;
+ if(interior(windingnumber(p,m),fillrule)) return m;
}
}
}
- abort("cannot find an interior point");
- return 0;
+ // cannot find an interior point: path is degenerate
+ return point(p,0);
}
// Return all intersection times of path g with the vertical line through (x,0).
diff --git a/Build/source/utils/asymptote/base/plain_pens.asy b/Build/source/utils/asymptote/base/plain_pens.asy
index 003c79149c7..09993d44da8 100644
--- a/Build/source/utils/asymptote/base/plain_pens.asy
+++ b/Build/source/utils/asymptote/base/plain_pens.asy
@@ -25,7 +25,9 @@ restricted pen beveljoin=linejoin(2);
restricted pen zerowinding=fillrule(0);
restricted pen evenodd=fillrule(1);
-bool inside(int windingnumber, pen fillrule) {
+
+bool interior(int windingnumber, pen fillrule)
+{
return windingnumber != undefined &&
(fillrule(fillrule) == 1 ? windingnumber % 2 == 1 : windingnumber != 0);
}
@@ -351,5 +353,3 @@ pen[] mean(pen[][] palette, real opacity(real[])=min)
return sequence(new pen(int i) {return mean(palette[i],opacity);},
palette.length);
}
-
-
diff --git a/Build/source/utils/asymptote/base/plain_strings.asy b/Build/source/utils/asymptote/base/plain_strings.asy
index 801e63e83cf..e3d0a797d86 100644
--- a/Build/source/utils/asymptote/base/plain_strings.asy
+++ b/Build/source/utils/asymptote/base/plain_strings.asy
@@ -190,3 +190,22 @@ string phantom(string s)
{
return "\phantom{"+s+"}";
}
+
+restricted int ocgindex=0;
+
+void begin(picture pic=currentpicture, string name, string id="",
+ bool visible=true)
+{
+ if(!latex() || !pdf()) return;
+ settings.twice=true;
+ if(id == "") id=string(++ocgindex);
+ tex(pic,"\begin{ocg}{"+name+"}{"+id+"}{"+(visible ? "1" : "0")+"}");
+ layer(pic);
+}
+
+void end(picture pic=currentpicture)
+{
+ if(!latex() || !pdf()) return;
+ tex(pic,"\end{ocg}");
+ layer(pic);
+}
diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy
index 8e0fab6e8d0..0af0d2c3bdf 100644
--- a/Build/source/utils/asymptote/base/three.asy
+++ b/Build/source/utils/asymptote/base/three.asy
@@ -3,10 +3,12 @@ private import math;
if(inXasyMode) settings.render=0;
if(prc0()) {
- access embed;
- Embed=embed.embed;
- Link=embed.link;
if(settings.tex == "context") settings.prc=false;
+ else {
+ access embed;
+ Embed=embed.embed;
+ Link=embed.link;
+ }
}
real defaultshininess=0.25;
@@ -14,12 +16,12 @@ real defaultgranularity=0;
real linegranularity=0.01;
real tubegranularity=0.003;
real dotgranularity=0.0001;
-pair viewportmargin=0; // Horizontal and vertical viewport margins.
-real viewportfactor=1.005; // Factor used to expand orthographic viewport.
-
-real angleprecision=1e-3; // Precision for centering perspective projections.
+pair viewportmargin=0; // Horizontal and vertical viewport margins.
+real viewportfactor=1.002; // Factor used to expand orthographic viewport.
+real viewportpadding=1.2; // Offset used to expand PRC viewport.
+real angleprecision=1e-3; // Precision for centering perspective projections.
real anglefactor=max(1.005,1+angleprecision);
- // Factor used to expand perspective viewport.
+// Factor used to expand perspective viewport.
string defaultembed3Doptions;
string defaultembed3Dscript;
@@ -1690,7 +1692,8 @@ transform3 transform3(projection P)
triple v=unit(P.oblique ? P.camera : P.vector());
triple u=unit(perp(P.up,v));
if(u == O) u=cross(perp(v),v);
- return transform3(cross(u,v),u);
+ v=cross(u,v);
+ return v != O ? transform3(v,u) : identity(4);
}
triple[] triples(real[] x, real[] y, real[] z)
@@ -2203,7 +2206,7 @@ function asyProjection() {"+
(infinity ? "activeCamera.projectionType=activeCamera.TYPE_ORTHOGRAPHIC;" :
"activeCamera.projectionType=activeCamera.TYPE_PERSPECTIVE;")+"
activeCamera.viewPlaneSize="+string(viewplanesize)+";
-activeCamera.binding=activeCamera.BINDING_VERTICAL;
+activeCamera.binding=activeCamera.BINDING_"+(infinity ? "MAX" : "VERTICAL")+";
}
asyProjection();
@@ -2252,7 +2255,7 @@ void writeJavaScript(string name, string preamble, string script)
file3.push(name);
}
-pair viewportmargin(projection P, real width, real height)
+pair viewportmargin(real width, real height)
{
pair viewportmargin=viewportmargin;
real xmargin=viewportmargin.x;
@@ -2281,10 +2284,11 @@ string embed3D(string label="", string text=label, string prefix,
real viewplanesize;
if(P.infinity) {
triple lambda=max3(f)-min3(f);
- real margin=(viewportfactor-1.0)*lambda.y+
- viewportmargin(P,lambda.x,lambda.y).y;
- viewplanesize=(lambda.y+2*margin)/cm;
- }
+ pair margin=viewportpadding*(1,1)+viewportmargin(lambda.x,lambda.y);
+ viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/cm;
+ } else
+ if(!P.absolute) angle=2*aTan(Tan(0.5*angle)-viewportpadding/P.target.z);
+
string name=prefix+".js";
writeJavaScript(name,lightscript+projection(P.infinity,viewplanesize),script);
@@ -2308,7 +2312,7 @@ string embed3D(string label="", string text=label, string prefix,
if(defaultembed3Doptions != "") options3 += ","+defaultembed3Doptions;
if((settings.render < 0 || !settings.embed) && settings.auto3D)
options3 += ",poster";
- options3 += ",text="+text+",label="+label+
+ options3 += ",text={"+text+"},label="+label+
",toolbar="+(settings.toolbar ? "true" : "false")+
",3Daac="+format(P.absolute ? P.angle : angle)+
",3Dc2c="+format(u)+
@@ -2402,7 +2406,7 @@ object embed(string label="", string text=label,
pair m2=pic2.min(s);
pair M2=pic2.max(s);
pair lambda=M2-m2;
- pair viewportmargin=viewportmargin(P,lambda.x,lambda.y);
+ pair viewportmargin=viewportmargin(lambda.x,lambda.y);
real width=ceil(lambda.x+2*viewportmargin.x);
real height=ceil(lambda.y+2*viewportmargin.y);
@@ -2435,6 +2439,11 @@ object embed(string label="", string text=label,
if(P.infinity) {
triple m=min3(f);
triple M=max3(f);
+ triple lambda=M-m;
+ viewportmargin=viewportmargin(lambda.x,lambda.y);
+ width=lambda.x+2*viewportmargin.x;
+ height=lambda.y+2*viewportmargin.y;
+
triple s=(-0.5(m.x+M.x),-0.5*(m.y+M.y),0);
f=shift(s)*f; // Eye will be at (0,0,0).
} else {
@@ -2513,13 +2522,14 @@ object embed(string label="", string text=label,
if(P.absolute) {
modelview=P.modelview();
f=modelview*f;
- P=modelview*P;
+ Q=modelview*P;
m=min3(f);
M=max3(f);
real r=0.5*abs(M-m);
zcenter=0.5*(M.z+m.z);
M=(M.x,M.y,zcenter+r);
m=(m.x,m.y,zcenter-r);
+ angle=P.angle;
} else {
m=min3(f);
M=max3(f);
@@ -2530,9 +2540,9 @@ object embed(string label="", string text=label,
}
if(P.infinity) {
- triple margin=(viewportfactor-1.0)*(abs(M.x-m.x),
- abs(M.y-m.y),0)+
- viewportfactor*(0,viewportmargin.y,0);
+ triple margin=(viewportfactor-1.0)*(abs(M.x-m.x),abs(M.y-m.y),0)
+ +(viewportmargin.x,viewportmargin.y,0);
+
M += margin;
m -= margin;
} else if(M.z >= 0) abort("camera too close");
@@ -2552,11 +2562,10 @@ object embed(string label="", string text=label,
if(settings.inlinetex) image += "_0";
image += "."+nativeformat();
if(!settings.inlinetex) file3.push(image);
- image=graphic(image);
+ image=graphic(image,"hiresbb");
}
if(prc) F.L=embed3D(label,text=image,prefix,f,format,
- width,height,angle,options,script,light,
- P.absolute ? P : Q);
+ width,height,angle,options,script,light,Q);
}
if(!is3D) {
@@ -2600,27 +2609,60 @@ currentpicture.fitter=new frame(string prefix, picture pic, string format,
if(currentlight.background != nullpen)
box(f,currentlight.background,Fill,above=false);
} else if(!view)
- label(f,graphic(prefix));
+ label(f,graphic(prefix,"hiresbb"));
}
}
return f;
};
void addViews(picture dest, picture src, bool group=true,
- filltype filltype=NoFill, bool above=true)
+ filltype filltype=NoFill)
{
+ if(group) begingroup(dest);
frame Front=src.fit(FrontView);
- add(dest,Front,group,filltype,above);
+ add(dest,Front,filltype);
frame Top=src.fit(TopView);
- add(dest,shift(0,min(Front).y-max(Top).y)*Top,group,filltype,above);
+ add(dest,shift(0,min(Front).y-max(Top).y)*Top,filltype);
frame Right=src.fit(RightView);
- add(dest,shift(min(Front).x-max(Right).x)*Right,group,filltype,above);
+ add(dest,shift(min(Front).x-max(Right).x)*Right,filltype);
+ if(group) endgroup(dest);
+}
+
+void addViews(picture src, bool group=true, filltype filltype=NoFill)
+{
+ addViews(currentpicture,src,group,filltype);
+}
+
+void addAllViews(picture dest, picture src,
+ real xmargin=0, real ymargin=xmargin,
+ bool group=true,
+ filltype filltype=NoFill)
+{
+ picture picL,picM,picR,picLM;
+ if(xmargin == 0) xmargin=sqrtEpsilon;
+ if(ymargin == 0) ymargin=sqrtEpsilon;
+
+ add(picL,src.fit(FrontView),(0,0),ymargin*N);
+ add(picL,src.fit(BackView),(0,0),ymargin*S);
+
+ add(picM,src.fit(TopView),(0,0),ymargin*N);
+ add(picM,src.fit(BottomView),(0,0),ymargin*S);
+
+ add(picR,src.fit(RightView),(0,0),ymargin*N);
+ add(picR,src.fit(LeftView),(0,0),ymargin*S);
+
+ add(picLM,picL.fit(),(0,0),xmargin*W);
+ add(picLM,picM.fit(),(0,0),xmargin*E);
+
+ if(group) begingroup(dest);
+ add(dest,picLM.fit(),(0,0),xmargin*W,filltype);
+ add(dest,picR.fit(),(0,0),xmargin*E,filltype);
+ if(group) endgroup(dest);
}
-void addViews(picture src, bool group=true, filltype filltype=NoFill,
- bool above=true)
+void addAllViews(picture src, bool group=true, filltype filltype=NoFill)
{
- addViews(currentpicture,src,group,filltype,above);
+ addAllViews(currentpicture,src,group,filltype);
}
// Force an array of 3D pictures to be as least as large as picture all.
diff --git a/Build/source/utils/asymptote/base/three_light.asy b/Build/source/utils/asymptote/base/three_light.asy
index 54ca7a47151..8e5a6281795 100644
--- a/Build/source/utils/asymptote/base/three_light.asy
+++ b/Build/source/utils/asymptote/base/three_light.asy
@@ -82,42 +82,45 @@ struct light {
pen background; // Background color of the 3D canvas.
real specularfactor;
bool viewport; // Are the lights specified (and fixed) in the viewport frame?
- triple[] position; // Only directional lights are implemented.
+ triple[] position; // Only directional lights are currently implemented.
transform3 T=identity(4); // Transform to apply to normal vectors.
bool on() {return position.length > 0;}
- void operator init(pen[] diffuse=array(position.length,white),
- pen[] ambient=array(position.length,black),
- pen[] specular=diffuse, pen background=nullpen,
+ void operator init(pen[] diffuse,
+ pen[] ambient=array(diffuse.length,black),
+ pen[] specular=diffuse, pen background=nullpen,
real specularfactor=1,
- bool viewport=true, triple[] position) {
- this.position=new triple[position.length];
- this.diffuse=new real[position.length][];
- this.ambient=new real[position.length][];
- this.specular=new real[position.length][];
+ bool viewport=true, triple[] position) {
+ int n=diffuse.length;
+ assert(ambient.length == n && specular.length == n && position.length == n);
+
+ this.diffuse=new real[n][];
+ this.ambient=new real[n][];
+ this.specular=new real[n][];
this.background=background;
+ this.position=new triple[n];
for(int i=0; i < position.length; ++i) {
- this.position[i]=unit(position[i]);
this.diffuse[i]=rgba(diffuse[i]);
this.ambient[i]=rgba(ambient[i]);
this.specular[i]=rgba(specular[i]);
+ this.position[i]=unit(position[i]);
}
this.specularfactor=specularfactor;
this.viewport=viewport;
}
void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse,
- pen background=nullpen, real specularfactor=1,
- bool viewport=true...triple[] position) {
+ pen background=nullpen, real specularfactor=1,
+ bool viewport=true...triple[] position) {
int n=position.length;
operator init(array(n,diffuse),array(n,ambient),array(n,specular),
- background,specularfactor,viewport,position);
+ background,specularfactor,viewport,position);
}
void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse,
- pen background=nullpen, bool viewport=true,
+ pen background=nullpen, bool viewport=true,
real x, real y, real z) {
operator init(diffuse,ambient,specular,background,viewport,(x,y,z));
}
@@ -146,9 +149,9 @@ struct light {
triple L=viewport ? position[i] : T*position[i];
real Ldotn=max(dot(normal,L),0);
p += ambient[i]*Ambient+Ldotn*diffuse[i]*Diffuse;
-// Apply specularfactor to partially compensate non-pixel-based rendering.
+ // Apply specularfactor to partially compensate non-pixel-based rendering.
if(Ldotn > 0) // Phong-Blinn model of specular reflection
- p += dot(normal,unit(L+Z))^s*specularfactor*specular[i]*Specular;
+ p += dot(normal,unit(L+Z))^s*specularfactor*specular[i]*Specular;
}
return rgb(p[0],p[1],p[2])+opacity(opacity(m.diffuse()));
}
@@ -165,10 +168,14 @@ light operator * (transform3 t, light light)
light operator cast(triple v) {return light(v);}
-light currentlight=light(ambient=rgb(0.1,0.1,0.1),specularfactor=3,
+light currentlight=light(ambient=gray(0.1),specularfactor=3,
(0.25,-0.25,1));
-light adobe=light(gray(0.4),specularfactor=3,viewport=false,
- (0.5,-0.5,-0.25),(0.5,0.5,0.25),
- (0.5,-0.5,0.2),(-0.5,0.5,-0.2));
+light White=light(new pen[] {rgb(0.38,0.38,0.45),rgb(0.6,0.6,0.67),
+ rgb(0.5,0.5,0.57)},specularfactor=3,viewport=false,
+ new triple[] {(-2,-1.5,-0.5),(2,1.1,-2.5),(-0.5,0,2)});
+
+light Headlamp=light(gray(0.9),ambient=gray(0.1),specularfactor=3,
+ (0.5,0.5,1/sqrt(2)),specular=gray(0.7));
+
light nolight;
diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy
index 55060cb516d..3c49b382133 100644
--- a/Build/source/utils/asymptote/base/three_surface.asy
+++ b/Build/source/utils/asymptote/base/three_surface.asy
@@ -681,6 +681,22 @@ struct surface {
triple[][] normals=new triple[][],
pen[][] colors=new pen[][], bool3 planar=default) {
s=new patch[];
+ if(planar == true) {// Assume all path3 elements share a common normal.
+ if(external.length != 0) {
+ triple n=normal(external[0]);
+ if(n != O) {
+ transform3 T=align(n);
+ external=transpose(T)*external;
+ T *= shift(0,0,point(external[0],0).z);
+ path[] g=sequence(new path(int i) {return path(external[i]);},
+ external.length);
+ for(patch p : surface(g).s)
+ s.push(T*p);
+ return;
+ }
+ }
+ }
+
for(int i=0; i < external.length; ++i)
construct(external[i],
internal.length == 0 ? new triple[] : internal[i],
diff --git a/Build/source/utils/asymptote/configure b/Build/source/utils/asymptote/configure
index c6167746edd..8672c154c7b 100755
--- a/Build/source/utils/asymptote/configure
+++ b/Build/source/utils/asymptote/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for Asymptote 1.75.
+# Generated by GNU Autoconf 2.63 for Asymptote 1.76.
#
# Report bugs to <http://sourceforge.net/projects/asymptote>.
#
@@ -596,8 +596,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='Asymptote'
PACKAGE_TARNAME='asymptote'
-PACKAGE_VERSION='1.75'
-PACKAGE_STRING='Asymptote 1.75'
+PACKAGE_VERSION='1.76'
+PACKAGE_STRING='Asymptote 1.76'
PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote'
# Factoring default headers for most tests.
@@ -1294,7 +1294,7 @@ 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 Asymptote 1.75 to adapt to many kinds of systems.
+\`configure' configures Asymptote 1.76 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1355,7 +1355,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Asymptote 1.75:";;
+ short | recursive ) echo "Configuration of Asymptote 1.76:";;
esac
cat <<\_ACEOF
@@ -1465,7 +1465,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Asymptote configure 1.75
+Asymptote configure 1.76
generated by GNU Autoconf 2.63
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1479,7 +1479,7 @@ 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 Asymptote $as_me 1.75, which was
+It was created by Asymptote $as_me 1.76, which was
generated by GNU Autoconf 2.63. Invocation command line was
$ $0 $@
@@ -11495,7 +11495,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Asymptote $as_me 1.75, which was
+This file was extended by Asymptote $as_me 1.76, which was
generated by GNU Autoconf 2.63. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -11554,7 +11554,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-Asymptote config.status 1.75
+Asymptote config.status 1.76
configured by $0, generated by GNU Autoconf 2.63,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/Build/source/utils/asymptote/configure.ac b/Build/source/utils/asymptote/configure.ac
index e80f07cc599..8959f489806 100644
--- a/Build/source/utils/asymptote/configure.ac
+++ b/Build/source/utils/asymptote/configure.ac
@@ -3,7 +3,7 @@
# this file.
AC_PREREQ(2)
-AC_INIT([Asymptote],[1.75],[http://sourceforge.net/projects/asymptote])
+AC_INIT([Asymptote],[1.76],[http://sourceforge.net/projects/asymptote])
VERSION=$PACKAGE_VERSION
AC_SUBST(VERSION)
diff --git a/Build/source/utils/asymptote/doc/CAD.pdf b/Build/source/utils/asymptote/doc/CAD.pdf
index 5c22ad7eaa3..6eff3f523ca 100644
--- a/Build/source/utils/asymptote/doc/CAD.pdf
+++ b/Build/source/utils/asymptote/doc/CAD.pdf
Binary files differ
diff --git a/Build/source/utils/asymptote/doc/FAQ/asy-faq.info b/Build/source/utils/asymptote/doc/FAQ/asy-faq.info
index 5d56d06d3c5..a00526b0aa7 100644
--- a/Build/source/utils/asymptote/doc/FAQ/asy-faq.info
+++ b/Build/source/utils/asymptote/doc/FAQ/asy-faq.info
@@ -9,7 +9,7 @@ END-INFO-DIR-ENTRY
File: $prefix.info, Node: Top, Next: Question 1.1, Up: (dir)
ASYMPTOTE FREQUENTLY ASKED QUESTIONS
- 01 Jun 2009
+ 05 Jun 2009
This is the list of Frequently Asked Questions about Asymptote (asy).
diff --git a/Build/source/utils/asymptote/doc/asymptote.pdf b/Build/source/utils/asymptote/doc/asymptote.pdf
index b536a5100f2..2050f1e4059 100644
--- a/Build/source/utils/asymptote/doc/asymptote.pdf
+++ b/Build/source/utils/asymptote/doc/asymptote.pdf
Binary files differ
diff --git a/Build/source/utils/asymptote/doc/asymptote.sty b/Build/source/utils/asymptote/doc/asymptote.sty
index 487ddaaafac..1099c183116 100644
--- a/Build/source/utils/asymptote/doc/asymptote.sty
+++ b/Build/source/utils/asymptote/doc/asymptote.sty
@@ -3,7 +3,7 @@
%%% Modified by John Bowman
%%% Adapted from comment.sty (Under GPL v2)
-\ProvidesPackage{asymptote}[2009/03/29 v1.06 Asymptote style file for LaTeX]
+\ProvidesPackage{asymptote}[2009/06/03 v1.07 Asymptote style file for LaTeX]
\RequirePackage{keyval}
\RequirePackage{ifthen}
\newif\ifASYinline
@@ -182,12 +182,12 @@
\else
\ifASYattach
\ifASYPDF
- \openin\AsyTestStream=\Jobname-\the\c@asy-0.pdf
+ \openin\AsyTestStream=\Jobname-\the\c@asy+0.pdf
\fi
\ifeof\AsyTestStream
- \setbox\ASYbox=\hbox{\includegraphics{\Jobname-\the\c@asy}}%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{\Jobname-\the\c@asy}}%
\else
- \setbox\ASYbox=\hbox{\includegraphics{\Jobname-\the\c@asy-0}}%
+ \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{\Jobname-\the\c@asy+0}}%
\fi
\textattachfile{\Jobname-\the\c@asy.pdf}{\phantom{\copy\ASYbox}}%
\vskip-\ht\ASYbox%
@@ -195,7 +195,7 @@
\box\ASYbox%
\closein\AsyTestStream%
\else
- \includegraphics{\Jobname-\the\c@asy}%
+ \includegraphics[hiresbb]{\Jobname-\the\c@asy}%
\fi
\fi
\fi
diff --git a/Build/source/utils/asymptote/doc/asymptote.texi b/Build/source/utils/asymptote/doc/asymptote.texi
index b04a940decb..aeacf580096 100644
--- a/Build/source/utils/asymptote/doc/asymptote.texi
+++ b/Build/source/utils/asymptote/doc/asymptote.texi
@@ -75,7 +75,7 @@ Installation
* Search paths:: Where @code{Asymptote} looks for your files
* Compiling from UNIX source:: Building @code{Asymptote} from scratch
* Editing modes:: Convenient @code{emacs} and @code{vim} modes
-* Subversion::
+* Subversion:: Getting the latest development source
* Uninstall:: Goodbye, @code{Asymptote}!
Drawing commands
@@ -265,7 +265,7 @@ Links to many external resources, including an excellent user-written
* Search paths:: Where @code{Asymptote} looks for your files
* Compiling from UNIX source:: Building @code{Asymptote} from scratch
* Editing modes:: Convenient @code{emacs} and @code{vim} modes
-* Subversion::
+* Subversion:: Getting the latest development source
* Uninstall:: Goodbye, @code{Asymptote}!
@end menu
@@ -2431,9 +2431,14 @@ returns the winding number of the cyclic path @code{p} relative to the point
counterclockwise direction. If @code{z} lies on @code{p} the constant
@code{undefined} (defined to be the largest odd integer) is returned.
+@cindex @code{interior}
+@item bool interior(int windingnumber, pen fillrule)
+returns true if @code{windingnumber} corresponds to an interior point
+according to @code{fillrule}.
+
@cindex @code{inside}
@item bool inside(path p, pair z, pen fillrule=currentpen);
-returns @code{true} iff the point @code{z} is inside or on the edge of
+returns @code{true} iff the point @code{z} lies inside or on the edge of
the region bounded by the cyclic path @code{p} according to the fill
rule @code{fillrule} (@pxref{fillrule}).
@@ -5847,7 +5852,7 @@ need to remove the files @code{latexusage-*}, @code{latexusage_.pre}, and
One can specify @code{width}, @code{height},
@code{viewportwidth}, @code{viewportheight}, and @code{attach}
@code{keyval}-style options to the @code{asy} environment.
-The current version (1.06) of @code{asymptote.sty} supports the
+The current version (1.07) of @code{asymptote.sty} supports the
embedding of 3D @acronym{PRC} files, either inline or, using the
@code{attach} option with the @code{attachfile2} (or older
@code{attachfile}) @code{LaTeX} package,
@@ -7391,9 +7396,9 @@ surface surface(path3 external, triple[] internal=new triple[],
@noindent
and then filled:
@verbatim
-draw(surface(path3(polygon(5))),red);
-draw(surface(unitcircle3),red);
-draw(surface(unitcircle3,new pen[] {red,green,blue,black}));
+draw(surface(path3(polygon(5))),red,nolight);
+draw(surface(unitcircle3),red,nolight);
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}),nolight);
@end verbatim
@noindent
The last example constructs a patch with vertex-specific colors.
@@ -7723,11 +7728,21 @@ projection TopView=orthographic(Z,showtarget=true);
The function
@verbatim
void addViews(picture dest=currentpicture, picture src, bool group=true,
- filltype filltype=NoFill, bool above=true);
+ filltype filltype=NoFill);
@end verbatim
@noindent
adds picture @code{pic} as seen with @code{FrontView} aligned above the
projection @code{TopView} and to the right of the projection @code{RightView}.
+Alternatively, the function
+@verbatim
+void addAllViews(picture dest=currentpicture, picture src,
+ real xmargin=0, real ymargin=xmargin,
+ bool group=true, filltype filltype=NoFill);
+@end verbatim
+@noindent
+may be used to exhibit all six standard views, with FrontView,
+TopView, RightView in the upper row and BackView, BottomView, LeftView
+in the lower row.
A triple or path3 can be projected to a pair or path,
with @code{project(triple, projection P=currentprojection)} or
diff --git a/Build/source/utils/asymptote/doc/ocg.sty b/Build/source/utils/asymptote/doc/ocg.sty
new file mode 100644
index 00000000000..3ba555b58e8
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/ocg.sty
@@ -0,0 +1,127 @@
+%% Copyright (C) 2007 by Michael Ritzert <michael.ritz...@gmail.com>
+%% Spurious spaces removed by John Bowman [2009/06/01].
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{ocg}[2009/06/01]
+
+\RequirePackage{ifpdf}
+\ifpdf
+\else
+ \PackageWarningNoLine{ocg}{%
+ Loading aborted, because pdfTeX is not running in PDF mode%
+ }%
+ \expandafter\endinput
+\fi
+
+\DeclareOption*{}\ProcessOptions*\relax %allow anything as option for the moment
+
+%testing for correct pdfTeX version
+%TODO: find out minimum required version!
+\ifnum\pdftexversion<120
+ \PackageError{ocg}{%
+ pdfeTeX, version >= 1.20, required%
+ }{%
+ Install a newer version!%
+ }%
+\fi
+
+% Next OCG id -- TODO: autogenerate. but keep possibility to reopen an OCG.
+\newcount\@ocg@num\@ocg@num=0
+
+\gdef\@ocg@layersnames{}
+
+% called from the aux file
+\def\@ocg@makeknown#1#2#3{% #1: OCG name, #2: OC id, #3: on/off
+ \@ifundefined{OCG#2}{%
+ \message{OCG#2}
+ \expandafter\gdef\csname OCG#2\endcsname{#1}%
+ \immediate\pdfobj{<< /Type /OCG /Name (#1) >>}% new ocg
+ \xdef\@ocg@curocg{\the\pdflastobj\space 0 R}% reference to id
+ \xdef\@ocg@ocgs{\@ocg@ocgs\space\@ocg@curocg}% list of all OCGs in "first defined" order
+ \ifnum#3=1 %on
+ \xdef\@ocg@ocgson{\@ocg@ocgson\space\@ocg@curocg}% list of all default-on OCGs
+ \else%
+ \xdef\@ocg@ocgsoff{\@ocg@ocgsoff\space\@ocg@curocg}% list of all default-off OCGs
+ \fi%
+ \xdef\@ocg@layersnames{%
+ \@ocg@layersnames\space/OC#2\space\@ocg@curocg% name-to-id mapping
+ }%
+ }{%
+ \message{OCG#2 reopened}
+ % layer reopened
+ }
+}
+
+\AtBeginDocument{%
+ % the auxfile has been read if available. register the OCGs in the page resources.
+ \@ocg@addresource
+ \let\@ocg@makeknown\@gobble
+}
+
+% set page resources to include the layers defined in the aux file
+\def\@ocg@addresource{%
+ \immediate\pdfobj{<<\@ocg@layersnames\space>>}%
+ \xdef\@ocg@namesobj{\the\pdflastobj\space 0 R}%
+ % append to pageresources
+ \begingroup
+ \edef\x{\endgroup
+ \pdfpageresources{%
+ \the\pdfpageresources
+ /Properties \@ocg@namesobj%
+ }%
+ }%
+ \x
+}
+
+\newcount\@ocg@@ocgs
+\pdfobj reserveobjnum
+\@ocg@@ocgs=\pdflastobj
+
+\newcount\@ocg@@layersconfig
+\pdfobj reserveobjnum
+\@ocg@@layersconfig=\pdflastobj
+
+\pdfcatalog{%
+ /OCProperties <<
+ /OCGs \the\@ocg@@ocgs\space0 R\space
+ /D \the\@ocg@@layersconfig\space0 R\space
+ >>%
+}
+\def\@ocg@ocgs{}
+\def\@ocg@ocgson{}
+\def\@ocg@ocgsoff{}
+\AtEndDocument{%
+ \immediate\pdfobj useobjnum \@ocg@@ocgs {%
+ [\@ocg@ocgs\space]%
+ }%
+ \immediate\pdfobj useobjnum \@ocg@@layersconfig {%
+ <<
+ /Order [\@ocg@ocgs\space]
+ /ON [\@ocg@ocgson\space]
+ /OFF [\@ocg@ocgsoff\space]
+ >>%
+ }%
+}%
+
+% schedule a OCG for creation on the next pdflatex run (via the auxfile)
+\def\@ocg@newocg#1#2#3{% #1:name, #2:num, #3:on
+ \if@filesw%
+ \immediate\write\@auxout{%
+ \string\@ocg@makeknown{#1}{#2}{#3}%
+ }%
+ \fi%
+}
+
+% TODO: Are nested OCGs allowed?
+\newenvironment{ocg}[3]{%
+ \@ocg@newocg{#1}{#2}{#3}%
+ \gdef\@ocg@curnum{#2}%
+ \pdfliteral{/OC /OC\@ocg@curnum\space BDC}%
+ \message{/OC\@ocg@curnum}%
+ \ignorespaces
+}{%
+ \pdfliteral{EMC}%
+ %\unskip%
+ %\endgroup%
+ \ignorespacesafterend
+}
diff --git a/Build/source/utils/asymptote/doc/png/Makefile.in b/Build/source/utils/asymptote/doc/png/Makefile.in
index 798fb9ef969..a2eaa52f32a 100644
--- a/Build/source/utils/asymptote/doc/png/Makefile.in
+++ b/Build/source/utils/asymptote/doc/png/Makefile.in
@@ -20,7 +20,7 @@ index.html: $(SOURCE) $(ASYFILES:.asy=.png)
makeinfo --html ../asymptote -o .
asymptote.info: $(SOURCE) $(ASYFILES:.asy=.png)
- makeinfo ../asymptote
+ makeinfo --no-split ../asymptote
html: index.html
@@ -35,7 +35,6 @@ distclean: FORCE clean
install:
${INSTALL} -d -m 755 $(infodir)
${INSTALL} -p -m 644 asymptote.info $(infodir)
- -${INSTALL} -p -m 644 asymptote.info-* $(infodir)
-if test -z "$(DESTDIR)"; then \
install-info --infodir=$(infodir) asymptote.info; \
fi
diff --git a/Build/source/utils/asymptote/doc/png/asymptote.info b/Build/source/utils/asymptote/doc/png/asymptote.info
index 5a6a1156c0d..729aca905aa 100644
--- a/Build/source/utils/asymptote/doc/png/asymptote.info
+++ b/Build/source/utils/asymptote/doc/png/asymptote.info
@@ -1,7 +1,7 @@
This is asymptote.info, produced by makeinfo version 4.13 from
../asymptote.texi.
-This file documents `Asymptote', version 1.75.
+This file documents `Asymptote', version 1.76.
`http://asymptote.sourceforge.net'
@@ -18,150 +18,9507 @@ START-INFO-DIR-ENTRY
END-INFO-DIR-ENTRY

-Indirect:
-asymptote.info-1: 578
-asymptote.info-2: 295810
+File: asymptote.info, Node: Top, Next: Description, Up: (dir)
+
+Asymptote
+*********
+
+This file documents `Asymptote', version 1.76.
+
+ `http://asymptote.sourceforge.net'
+
+ Copyright (C) 2004-9 Andy Hammerlindl, John Bowman, and Tom Prince.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Lesser General Public License
+ (see the file LICENSE in the top-level source directory).
+
+
+* Menu:
+
+* Description:: What is `Asymptote'?
+* Installation:: Downloading and installing
+* Tutorial:: Getting started
+* Drawing commands:: Four primitive graphics commands
+* Programming:: The `Asymptote' vector graphics language
+* LaTeX usage:: Embedding `Asymptote' commands within `LaTeX'
+* Base modules:: Base modules shipped with `Asymptote'
+* Options:: Command-line options
+* Interactive mode:: Typing `Asymptote' commands interactively
+* GUI:: Graphical user interface
+* PostScript to Asymptote:: `Asymptote' backend to `pstoedit'
+* Help:: Where to get help and submit bug reports
+* Debugger:: Squish those bugs!
+* Credits:: Contributions and acknowledgments
+* Index:: General index
+
+ --- The Detailed Node Listing ---
+
+Installation
+
+* UNIX binary distributions:: Prebuilt `UNIX' binaries
+* MacOS X binary distributions:: Prebuilt `MacOS X' binaries
+* Microsoft Windows:: Prebuilt `Microsoft Windows' binary
+* Configuring:: Configuring `Asymptote' for your system
+* Search paths:: Where `Asymptote' looks for your files
+* Compiling from UNIX source:: Building `Asymptote' from scratch
+* Editing modes:: Convenient `emacs' and `vim' modes
+* Subversion:: Getting the latest development source
+* Uninstall:: Goodbye, `Asymptote'!
+
+Drawing commands
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+Programming
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides::
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external `Asymptote' packages
+* Static:: Where to allocate your variable?
+
+Operators
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+Functions
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+
+Arrays
+
+* Slices:: Python-style array slices
+
+Base modules
+
+* plain:: Default `Asymptote' base file
+* simplex:: Linear programming: simplex method
+* math:: Extend `Asymptote''s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded PDF and MPEG movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with `Asymptote'
+* MetaPost:: `MetaPost' compatibility routines
+* unicode:: Accept `unicode' (UTF-8) characters
+* latin1:: Accept `ISO 8859-1' characters
+* babel:: Interface to `LaTeX' `babel' package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your PDF files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* slopefield:: Slope fields
+
+
+Graphical User Interface
+
+* GUI Installation:: Installing `xasy'
+* GUI Usage::
+
+
+File: asymptote.info, Node: Description, Next: Installation, Prev: Top, Up: Top
+
+1 Description
+*************
+
+`Asymptote' is a powerful descriptive vector graphics language that
+provides a mathematical coordinate-based framework for technical
+drawings. Labels and equations are typeset with `LaTeX', for overall
+document consistency, yielding the same high-quality level of
+typesetting that `LaTeX' provides for scientific text. By default it
+produces `PostScript' output, but it can also generate any format that
+the `ImageMagick' package can produce.
+
+ A major advantage of `Asymptote' over other graphics packages is
+that it is a high-level programming language, as opposed to just a
+graphics program: it can therefore exploit the best features of the
+script (command-driven) and graphical-user-interface (GUI) methods for
+producing figures. The rudimentary GUI `xasy' included with the package
+allows one to move script-generated objects around. To make `Asymptote'
+accessible to the average user, this GUI is currently being developed
+into a full-fledged interface that can generate objects directly.
+However, the script portion of the language is now ready for general
+use by users who are willing to learn a few simple `Asymptote' graphics
+commands (*note Drawing commands::).
+
+ `Asymptote' is mathematically oriented (e.g. one can use complex
+multiplication to rotate a vector) and uses `LaTeX' to do the
+typesetting of labels. This is an important feature for scientific
+applications. It was inspired by an earlier drawing program (with a
+weaker syntax and capabilities) called `MetaPost'.
+
+ The `Asymptote' vector graphics language provides:
+
+ * a standard for typesetting mathematical figures, just as
+ TeX/`LaTeX' is the de-facto standard for typesetting equations.
+
+ * `LaTeX' typesetting of labels, for overall document consistency;
+
+ * a natural coordinate-based framework for technical drawings,
+ inspired by `MetaPost', with a much cleaner, powerful C++-like
+ programming syntax;
+
+ * compilation of figures into virtual machine code for speed, without
+ sacrificing portability;
+
+ * the power of a script-based language coupled to the convenience of
+ a GUI;
+
+ * customization using its own C++-like graphics programming language;
+
+ * sensible defaults for graphical features, with the ability to
+ override;
+
+ * a high-level mathematically oriented interface to the `PostScript'
+ language for vector graphics, including affine transforms and
+ complex variables;
+
+ * functions that can create new (anonymous) functions;
+
+ * deferred drawing that uses the simplex method to solve overall size
+ constraint issues between fixed-sized objects (labels and
+ arrowheads) and objects that should scale with figure size;
+
+
+ Many of the features of `Asymptote' are written in the `Asymptote'
+language itself. While the stock version of `Asymptote' is designed for
+mathematics typesetting needs, one can write `Asymptote' modules that
+tailor it to specific applications. A scientific graphing module has
+already been written (*note graph::). Examples of `Asymptote' code and
+output, including animations, are available at
+
+ `http://asymptote.sourceforge.net/gallery/'.
+ Links to many external resources, including an excellent user-written
+`Asymptote' tutorial can be found at
+
+ `http://asymptote.sourceforge.net/links.html'.
+
+
+File: asymptote.info, Node: Installation, Next: Tutorial, Prev: Description, Up: Top
+
+2 Installation
+**************
+
+* Menu:
+
+* UNIX binary distributions:: Prebuilt `UNIX' binaries
+* MacOS X binary distributions:: Prebuilt `MacOS X' binaries
+* Microsoft Windows:: Prebuilt `Microsoft Windows' binary
+* Configuring:: Configuring `Asymptote' for your system
+* Search paths:: Where `Asymptote' looks for your files
+* Compiling from UNIX source:: Building `Asymptote' from scratch
+* Editing modes:: Convenient `emacs' and `vim' modes
+* Subversion:: Getting the latest development source
+* Uninstall:: Goodbye, `Asymptote'!
+
+ After following the instructions for your specific distribution,
+please see also *note Configuring::.
+
+We recommend subscribing to new release announcements at
+
+ `http://freshmeat.net/projects/asy'
+ Users may also wish to monitor the `Asymptote' forum:
+
+ `http://sourceforge.net/forum/monitor.php?forum_id=409349'
+
+
+File: asymptote.info, Node: UNIX binary distributions, Next: MacOS X binary distributions, Up: Installation
+
+2.1 UNIX binary distributions
+=============================
+
+We release both `tgz' and RPM binary distributions of `Asymptote'. The
+root user can install the `Linux i386' `tgz' distribution of version
+`x.xx' of `Asymptote' with the commands:
+tar -C / -zxf asymptote-x.xx.i386.tgz
+texhash
+ The `texhash' command, which installs LaTeX style files, is optional.
+The executable file will be `/usr/local/bin/asy') and example code will
+be installed by default in `/usr/local/share/doc/asymptote/examples'.
+
+Fedora users can easily install the most recent version of `Asymptote'
+with the command
+yum --enablerepo=rawhide install asymptote
+
+To install the latest version of `Asymptote' on a Debian-based
+distribution (e.g. Ubuntu, Mepis, Linspire) follow the instructions for
+compiling from `UNIX' source (*note Compiling from UNIX source::).
+Alternatively, Debian users can install one of Hubert Chan's prebuilt
+`Asymptote' binaries from
+
+ `http://ftp.debian.org/debian/pool/main/a/asymptote'
+
+
+File: asymptote.info, Node: MacOS X binary distributions, Next: Microsoft Windows, Prev: UNIX binary distributions, Up: Installation
+
+2.2 MacOS X binary distributions
+================================
+
+`MacOS X' users can either compile the `UNIX' source code (*note
+Compiling from UNIX source::) or install the contributed `Asymptote'
+binary available at
+
+`http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote/'
+
+Because these preconfigured binary distributions have strict
+architecture and library dependencies that many installations do not
+satisfy, we recommend installing `Asymptote' directly from the official
+source:
+
+ `http://sourceforge.net/project/showfiles.php?group_id=120000'
+
+Note that many `MacOS X' (and FreeBSD) systems inexplicably ship with
+an extremely old GNU `readline' version (4.1, dated 21 March 2000). For
+full interactive functionality, `readline' version 4.2 or later (16
+April 2001) is required.
+
+
+File: asymptote.info, Node: Microsoft Windows, Next: Configuring, Prev: MacOS X binary distributions, Up: Installation
+
+2.3 Microsoft Windows
+=====================
+
+Users of the `Microsoft Windows' operating system can install the
+self-extracting `Asymptote' executable `asymptote-x.xx-setup.exe',
+where `x.xx' denotes the latest version.
+
+ A working TeX implementation (such as the one available at
+`http://www.miktex.org') will be required to typeset labels. You will
+also need to install `GPL Ghostscript' from
+`http://sourceforge.net/projects/ghostscript/'. To view the default
+`PostScript' output, you can install the program `gsview' available from
+`http://www.cs.wisc.edu/~ghost/gsview/'.
+
+ The `ImageMagick' package from
+
+ `http://www.imagemagick.org/script/binary-releases.php'
+
+is required to support output formats other than EPS and PDF (*note
+convert::). The `Python' interpreter from `http://www.python.org' is
+only required if you wish to try out the graphical user interface
+(*note GUI::).
+
+Example code will be installed by default in the `examples'
+subdirectory of the installation directory (by default, `C:\Program
+Files\Asymptote').
+
+
+File: asymptote.info, Node: Configuring, Next: Search paths, Prev: Microsoft Windows, Up: Installation
+
+2.4 Configuring
+===============
+
+In interactive mode, or when given the `-V' option (the default when
+running `Asymptote' on a single file under `MSDOS'), `Asymptote' will
+automatically invoke the `PostScript' viewer `gv' (under `UNIX') or
+`gsview' (under `MSDOS' to display graphical output. These defaults may
+be overridden with the configuration variable `psviewer'. The
+`PostScript' viewer should be capable of automatically redrawing
+whenever the output file is updated. The default `UNIX' `PostScript'
+viewer `gv' supports this (via a `SIGHUP' signal). Version `gv-3.6.3'
+or later (from `http://ftp.gnu.org/gnu/gv/') is required for
+interactive mode to work properly. Users of `ggv' will need to enable
+`Watch file' under `Edit/Postscript Viewer Preferences'. Users of
+`gsview' will need to enable `Options/Auto Redisplay' (however, under
+`MSDOS' it is still necessary to click on the `gsview' window; under
+`UNIX' one must manually redisplay by pressing the `r' key).
+
+ Configuration variables are most easily set as `Asymptote' variables
+in the configuration file (by default, `.asy/config.asy' in the user's
+home directory or `%USERPROFILE%\.asy\config.asy' under `MSDOS'); *note
+configuration file::. Here are the default values of several important
+configuration variables under `UNIX':
+
+
+import settings;
+psviewer="gv";
+pdfviewer="acroread";
+gs="gs";
+python="";
+
+The (installation-dependent) default values of these configuration
+variables under `MSDOS' are determined automatically from the
+`Microsoft Windows' registry.
+
+ For PDF format output, the `gs' setting specifies the location of
+the `PostScript'-to-PDF processor `Ghostscript', available from
+`http://sourceforge.net/projects/ghostscript/'.
+
+ The setting `pdfviewer' specifies the location of the PDF viewer. On
+`UNIX' systems, to support automatic document reloading in `Adobe
+Reader', we recommend copying the file `reload.js' from the `Asymptote'
+system directory (by default, `/usr/local/share/asymptote' under `UNIX'
+to `~/.adobe/Acrobat/x.x/JavaScripts/', where `x.x' represents the
+appropriate `Adobe Reader' version number. The automatic document
+reload feature must then be explicitly enabled by putting
+import settings;
+pdfreload=true;
+pdfreloadOptions="-tempFile";
+ in the `Asymptote' configuration file. This reload feature is not
+useful under `MSDOS' since the document cannot be updated anyway on
+that operating system until it is first closed by `Adobe Reader'.
+
+ The graphical user interface may also require setting the variable
+`python' if `Python' is installed in a nonstandard location.
+
+ The configuration variable `dir' can be used to adjust the search
+path (*note Search paths::).
+
+ By default, `Asymptote' attempts to center the figure on the page,
+assuming that the paper type is `letter'. The default paper type may be
+changed to `a4' with the configuration variable `papertype'. Alignment
+to other paper sizes can be obtained by setting the configuration
+variables `paperwidth' and `paperheight'.
+
+ The following configuration variables normally do not require
+adjustment:
+texpath
+texcommand
+texdvicommand
+dvips
+convert
+display
+animate
+xasy
+ The `texdvicommand' is used for `3D' label typesetting, which requires
+`dvips' output. An empty string indicates the default setting of
+`latex'/`tex', depending on the setting of `texengine'.
+
+ Configuration variables may also be set or overwritten with a
+command-line option:
+asy -psviewer=gsview -V venn
+
+ Alternatively, system environment versions of the above configuration
+variables may be set in the conventional way. The corresponding
+environment variable name is obtained by converting the configuration
+variable name to upper case and prepending `ASYMPTOTE_': for example,
+to set the environment variable
+ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe";
+ under `Microsoft Windows XP':
+ 1. Click on the `Start' button;
+
+ 2. Right-click on `My Computer';
+
+ 3. Choose `Properties' from the popup menu;
+
+ 4. Click the `Advanced' tab;
+
+ 5. Click the `Environment Variables' button.
+
+
+File: asymptote.info, Node: Search paths, Next: Compiling from UNIX source, Prev: Configuring, Up: Installation
+
+2.5 Search paths
+================
+
+In looking for `Asymptote' system files, `asy' will search the
+following paths, in the order listed:
+ 1. The current directory;
+
+ 2. A list of one or more directories specified by the configuration
+ variable `dir' (separated by `:' under UNIX and `;' under `MSDOS');
+
+ 3. The directory `.asy' in the user's home directory
+ (`%USERPROFILE%\.asy' under `MSDOS');
+
+ 4. The `Asymptote' system directory (by default,
+ `/usr/local/share/asymptote' under `UNIX' and `C:\Program
+ Files\Asymptote' under `MSDOS').
+
+
+File: asymptote.info, Node: Compiling from UNIX source, Next: Editing modes, Prev: Search paths, Up: Installation
+
+2.6 Compiling from UNIX source
+==============================
+
+To compile and install a `UNIX' executable from a source release
+`x.xx', first execute the commands:
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+ By default the system version of the Boehm garbage collector will be
+used; if it is old we recommend first putting
+`http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.1.tar.gz'
+in the `Asymptote' source directory.
+
+If your graphics card supports multisampling, we recommend using SVN
+revision 761 (or later) of `freeglut' to support antialiasing in
+`Asymptote''s adaptive `OpenGL' 3D renderer (`MacOS X' users can skip
+this step since `Asymptote' is configured to use the native glut
+library on that platform). Download
+
+ `http://freeglut.svn.sourceforge.net/viewvc/freeglut/trunk/freeglut/freeglut.tar.gz'
+ and type (as the root user):
+tar -zxf freeglut.tar.gz
+cd freeglut
+sh autogen.sh
+./configure --prefix=/usr
+make install
+cd ..
+ Then compile `Asymptote' with the commands
+./configure
+make all
+make install
+ Be sure to use GNU `make' (on non-GNU systems this command may be
+called `gmake'). To build the documentation, you may need to install
+the `texinfo-tex' package. If you get errors from a broken `texinfo' or
+`pdftex' installation, simply put
+
+ `http://asymptote.sourceforge.net/asymptote.pdf'
+ in the directory `doc' and repeat the command `make all'.
+
+For a (default) system-wide installation, the last command should be
+done as the root user. To install without root privileges, change the
+`./configure' command to
+./configure --prefix=$HOME/asymptote
+ One can disable use of the Boehm garbage collector by configuring with
+`./configure --disable-gc'. For a list of other configuration options,
+say `./configure --help'. For example, one can tell configure to look
+for header files and libraries in nonstandard locations:
+./configure CFLAGS=-I/opt/usr/include LDFLAGS=-L/opt/usr/lib
+
+ If you are compiling `Asymptote' with `gcc', you will need a
+relatively recent version (e.g. 3.4.4 or later). For full interactive
+functionality, you will need version 4.2 or later of the GNU `readline'
+library. The file `gcc3.3.2curses.patch' in the `patches' directory can
+be used to patch the broken curses.h header file (or a local copy
+thereof in the current directory) on some `AIX' and `IRIX' systems.
+
+ The `FFTW' library is only required if you want `Asymptote' to be
+able to take Fourier transforms of data (say, to compute an audio power
+spectrum). The `GSL' library is only required if you require the
+special functions that it supports.
+
+ If you don't want to install `Asymptote' system wide, just make sure
+the compiled binary `asy' and GUI script `xasy' are in your path and
+set the configuration variable `dir' to point to the directory `base'
+(in the top level directory of the `Asymptote' source code).
+
+
+File: asymptote.info, Node: Editing modes, Next: Subversion, Prev: Compiling from UNIX source, Up: Installation
+
+2.7 Editing modes
+=================
+
+Users of `emacs' can edit `Asymptote' code with the mode `asy-mode',
+after enabling it by putting the following lines in their `.emacs'
+initialization file, replacing `ASYDIR' with the location of the
+`Asymptote' system directory (by default, `/usr/local/share/asymptote'
+or `C:\Program Files\Asymptote' under `MSDOS'):
+(add-to-list 'load-path "ASYDIR")
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+ Particularly useful key bindings in this mode are `C-c C-c', which
+compiles and displays the current buffer, and the key binding `C-c ?',
+which shows the available function prototypes for the command at the
+cursor. For full functionality you should also install the Apache
+Software Foundation package `two-mode-mode':
+
+ `http://www.dedasys.com/freesoftware/files/two-mode-mode.el'
+ Once installed, you can use the hybrid mode `lasy-mode' to edit a
+LaTeX file containing embedded `Asymptote' code (*note LaTeX usage::).
+This mode can be enabled within `latex-mode' with the key sequence `M-x
+lasy-mode <RET>'. On `UNIX' systems, additional keywords will be
+generated from all `asy' files in the space-separated list of
+directories specified by the environment variable `ASYMPTOTE_SITEDIR'.
+Further documentation of `asy-mode' is available within `emacs' by
+pressing the sequence keys `C-h f asy-mode <RET>'.
+
+ Fans of `vim' can customize `vim' for `Asymptote' with
+
+`cp /usr/local/share/asymptote/asy.vim ~/.vim/syntax/asy.vim'
+
+and add the following to their `~/.vimrc' file:
+augroup filetypedetect
+au BufNewFile,BufRead *.asy setf asy
+augroup END
+filetype plugin on
+
+ If any of these directories or files don't exist, just create them.
+To set `vim' up to run the current asymptote script using `:make' just
+add to `~/.vim/ftplugin/asy.vim':
+setlocal makeprg=asy\ %
+setlocal errorformat=%f:\ %l.%c:\ %m
+
+
+File: asymptote.info, Node: Subversion, Next: Uninstall, Prev: Editing modes, Up: Installation
+
+2.8 Subversion (SVN)
+====================
+
+The following commands are needed to install the latest development
+version of `Asymptote' using Subversion:
+svn co http://asymptote.svn.sourceforge.net/svnroot/asymptote/trunk/asymptote
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+
+To compile without optimization, use the command `make CFLAGS=-g'.
+
+
+File: asymptote.info, Node: Uninstall, Prev: Subversion, Up: Installation
+
+2.9 Uninstall
+=============
+
+To uninstall an `Linux i386' binary distribution, use the commands
+tar -zxvf asymptote-x.xx.i386.tgz | xargs --replace=% rm /%
+texhash
+
+To uninstall all `Asymptote' files installed from a source
+distribution, use the command
+make uninstall
+
+
+File: asymptote.info, Node: Tutorial, Next: Drawing commands, Prev: Installation, Up: Top
+
+3 Tutorial
+**********
+
+_An excellent user-written `Asymptote' tutorial is also available from_
+
+ `http://www.artofproblemsolving.com/Wiki/index.php/Asymptote:_Basics'
+
+To draw a line from coordinate (0,0) to coordinate (100,100) using
+`Asymptote''s interactive mode, type at the command prompt:
+asy
+draw((0,0)--(100,100));
+
+
+
+The units here are `PostScript' "big points" (1 `bp' = 1/72 `inch');
+`--' means join with a linear segment. In `Asymptote' coordinates like
+`(0,0)' and `(1000,100)' are called _pairs_.
+
+ At this point you can type in further draw commands, which will be
+added to the displayed figure, or type `quit' to exit interactive mode.
+You can use the arrow keys in interactive mode to edit previous lines
+(assuming that you have support for the GNU `readline' library
+enabled). The tab key will automatically complete unambiguous words;
+otherwise, hitting tab again will show the possible choices. Further
+commands specific to interactive mode are described in *note
+Interactive mode::.
+
+ In batch mode, `Asymptote' reads commands directly from a file. To
+try this out, type
+
+draw((0,0)--(100,100));
+ into a file, say test.asy. Then execute this file with the `MSDOS' or
+`UNIX' command
+asy -V test
+ `MSDOS' users can drag and drop the file onto the Desktop `asy' icon
+or make `Asymptote' the default application for files with the
+extension `asy'.
+
+The `-V' option opens up a `PostScript' viewer window so you can
+immediately view the encapsulated `PostScript' output. By default the
+output will be written to the file `test.eps'; the prefix of the output
+file may be changed with the `-o' command-line option.
+
+ One can draw a line with more than two points and create a cyclic
+path like this square:
+
+draw((0,0)--(100,0)--(100,100)--(0,100)--cycle);
+
+
+
+It is often inconvenient to work directly with `PostScript' coordinates.
+The next example draws a unit square scaled to width 101 bp and height
+101 bp. The output is identical to that of the previous example.
+size(101,101);
+draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
+
+ For convenience, the path `(0,0)--(1,0)--(1,1)--(0,1)--cycle' may be
+replaced with the predefined variable `unitsquare', or equivalently,
+`box((0,0),(1,1))'.
+
+ One can also specify the size in `pt' (1 `pt' = 1/72.27 `inch'),
+`cm', `mm', or `inches'. If 0 is given as a size argument, no
+restriction is made in that direction; the overall scaling will be
+determined by the other direction (*note size::):
+
+size(0,3cm);
+draw(unitsquare);
+
+
+
+To make the user coordinates represent multiples of exactly `1cm':
+unitsize(1cm);
+draw(unitsquare);
+
+ One can also specify different x and y unit sizes:
+unitsize(1cm,2cm);
+draw(unitsquare);
+
+ Adding labels is easy in `Asymptote'; one specifies the label as a
+double-quoted `LaTeX' string, a coordinate, and an optional alignment
+direction:
+
+size(0,3cm);
+draw(unitsquare);
+label("$A$",(0,0),SW);
+label("$B$",(1,0),SE);
+label("$C$",(1,1),NE);
+label("$D$",(0,1),NW);
+
+
+
+`Asymptote' uses the standard compass directions `E=(1,0)', `N=(0,1)',
+`NE=unit(N+E)', and `ENE=unit(E+NE)', etc., which along with the
+directions `up', `down', `right', and `left' are defined as pairs in
+the `Asymptote' base module `plain'. A user who has a local variable
+named `E' may access the compass direction `E' by prefixing it with the
+name of the module where it is defined: `plain.E'.
+
+ This example draws a path that approximates a quarter circle:
+
+size(100,0);
+draw((1,0){up}..{left}(0,1));
+
+
+
+In general, a path is specified as a list of pairs (or other paths)
+interconnected with `--', which denotes a straight line segment, or
+`..', which denotes a cubic spline. Specifying a final node `cycle'
+creates a cyclic path that connects smoothly back to the initial node,
+as in this approximation (accurate to within 0.06%) of a unit circle:
+path unitcircle=E..N..W..S..cycle;
+
+ Each interior node of a cubic spline may be given a direction prefix
+or suffix `{dir}': the direction of the pair `dir' specifies the
+direction of the incoming or outgoing tangent, respectively, to the
+curve at that node. Exterior nodes may be given direction specifiers
+only on their interior side.
+
+ A cubic spline between the node z_0, with postcontrol point c_0, and
+the node z_1, with precontrol point c_1, is computed as the Bezier curve
+
+
+
+As illustrated in the diagram below, the third-order midpoint (m_5)
+constructed from two endpoints z_0 and z_1 and two control points c_0
+and c_1, is the point corresponding to t=1/2 on the Bezier curve formed
+by the quadruple (z_0, c_0, c_1, z_1). This allows one to recursively
+construct the desired curve, by using the newly extracted third-order
+midpoint as an endpoint and the respective second- and first-order
+midpoints as control points:
+
+
+
+Here m_0, m_1 and m_2 are the first-order midpoints, m_3 and m_4 are
+the second-order midpoints, and m_5 is the third-order midpoint. The
+curve is then constructed by recursively applying the algorithm to
+(z_0, m_0, m_3, m_5) and (m_5, m_4, m_2, z_1).
+
+ In fact, an analogous property holds for points located at any
+fraction t in [0,1] of each segment, not just for midpoints (t=1/2).
+
+ The Bezier curve constructed in this manner has the following
+properties:
+ * It is entirely contained in the convex hull of the given four
+ points.
+
+ * It starts heading from the first endpoint to the first control
+ point and finishes heading from the second control point to the
+ second endpoint.
+
+
+ The user can specify explicit control points between two nodes like
+this:
+draw((0,0)..controls (0,100) and (100,100)..(100,0));
+
+ However, it is usually more convenient to just use the `..'
+operator, which tells `Asymptote' to choose its own control points
+using the algorithms described in Donald Knuth's monograph, The
+MetaFontbook, Chapter 14. The user can still customize the guide (or
+path) by specifying direction, tension, and curl values.
+
+ The higher the tension, the straighter the curve is, and the more it
+approximates a straight line. One can change the spline tension from
+its default value of 1 to any real value greater than or equal to 0.75
+(cf. John D. Hobby, Discrete and Computational Geometry 1, 1986):
+draw((100,0)..tension 2 ..(100,100)..(0,100));
+draw((100,0)..tension 2 and 1 ..(100,100)..(0,100));
+draw((100,0)..tension atleast 1 ..(100,100)..(0,100));
+
+ The curl parameter specifies the curvature at the endpoints of a path
+(0 means straight; the default value of 1 means approximately circular):
+draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));
+
+ The `MetaPost ...' path connector, which requests, when possible, an
+inflection-free curve confined to a triangle defined by the endpoints
+and directions, is implemented in `Asymptote' as the convenient
+abbreviation `::' for `..tension atleast 1 ..' (the ellipsis `...' is
+used in `Asymptote' to indicate a variable number of arguments; *note
+Rest arguments::). For example, compare
+
+draw((0,0){up}..(100,25){right}..(200,0){down});
+
+
+with
+
+draw((0,0){up}::(100,25){right}::(200,0){down});
+
+
+
+The `---' connector is an abbreviation for `..tension atleast
+infinity..' and the `&' connector concatenates two paths, after first
+stripping off the last node of the first path (which normally should
+coincide with the first node of the second path).
+
+ An `Asymptote' path, being connected, is equivalent to a `Postscript
+subpath'. The `^^' binary operator, which requests that the pen be
+moved (without drawing or affecting endpoint curvatures) from the final
+point of the left-hand path to the initial point of the right-hand
+path, may be used to group several `Asymptote' paths into a `path[]'
+array (equivalent to a `PostScript' path):
+
+size(0,100);
+path unitcircle=E..N..W..S..cycle;
+path g=scale(2)*unitcircle;
+filldraw(unitcircle^^g,evenodd+yellow,black);
+
+
+
+The `PostScript' even-odd fill rule here specifies that only the region
+bounded between the two unit circles is filled (*note fillrule::). In
+this example, the same effect can be achieved by using the default zero
+winding number fill rule, if one is careful to alternate the
+orientation of the paths:
+filldraw(unitcircle^^reverse(g),yellow,black);
+
+ The `^^' operator is used by the `box(triple, triple)' function in
+`three.asy' to construct the edges of a cube `unitbox' without
+retracing steps:
+
+import three;
+dotgranularity=0; // Render dots as spheres.
+
+currentprojection=orthographic(5,4,2,center=true);
+
+size(5cm);
+size3(3cm,5cm,8cm);
+
+draw(unitbox);
+
+dot(unitbox,red);
+
+label("$O$",(0,0,0),NW);
+label("(1,0,0)",(1,0,0),S);
+label("(0,1,0)",(0,1,0),E);
+label("(0,0,1)",(0,0,1),Z);
+
+
+
+See section *note graph:: (or the online `Asymptote' gallery and
+external links posted at `http://asymptote.sourceforge.net') for
+further examples, including two and three-dimensional scientific
+graphs. Additional examples have been posted by Philippe Ivaldi at
+`http://piprim.tuxfamily.org/asymptote/'.
+
+
+File: asymptote.info, Node: Drawing commands, Next: Programming, Prev: Tutorial, Up: Top
+
+4 Drawing commands
+******************
+
+All of `Asymptote''s graphical capabilities are based on four primitive
+commands. The three `PostScript' drawing commands `draw', `fill', and
+`clip' add objects to a picture in the order in which they are
+executed, with the most recently drawn object appearing on top. The
+labeling command `label' can be used to add text labels and external
+EPS images, which will appear on top of the `PostScript' objects (since
+this is normally what one wants), but again in the relative order in
+which they were executed. After drawing objects on a picture, the
+picture can be output with the `shipout' function (*note shipout::).
+
+ If you wish to draw `PostScript' objects on top of labels (or
+verbatim `tex' commands; *note tex::), the `layer' command may be used
+to start a new `PostScript/LaTeX' layer:
+void layer(picture pic=currentpicture);
+
+ The `layer' function gives one full control over the order in which
+objects are drawn. Layers are drawn sequentially, with the most recent
+layer appearing on top. Within each layer, labels, images, and verbatim
+`tex' commands are always drawn after the `PostScript' objects in that
+layer.
+
+ While some of these drawing commands take many options, they all
+have sensible default values (for example, the picture argument
+defaults to currentpicture).
+
+* Menu:
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+
+File: asymptote.info, Node: draw, Next: fill, Up: Drawing commands
+
+4.1 draw
+========
+
+void draw(picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
+ Label legend="", marker marker=nomarker);
+
+Draw the path `g' on the picture `pic' using pen `p' for drawing, with
+optional drawing attributes (Label `L', explicit label alignment
+`align', arrows and bars `arrow' and `bar', margins `margin', legend,
+and markers `marker'). Only one parameter, the path, is required. For
+convenience, the arguments `arrow' and `bar' may be specified in either
+order. The argument `legend' is a Label to use in constructing an
+optional legend entry.
+
+ Bars are useful for indicating dimensions. The possible values of
+`bar' are `None', `BeginBar', `EndBar' (or equivalently `Bar'), and
+`Bars' (which draws a bar at both ends of the path). Each of these bar
+specifiers (except for `None') will accept an optional real argument
+that denotes the length of the bar in `PostScript' coordinates. The
+default bar length is `barsize(pen)'.
+
+ The possible values of `arrow' are `None', `Blank' (which draws no
+arrows or path), `BeginArrow', `MidArrow', `EndArrow' (or equivalently
+`Arrow'), and `Arrows' (which draws an arrow at both ends of the path).
+All of the arrow specifiers except for `None' and `Blank' may be given
+the optional arguments arrowhead `arrowhead' (one of the predefined
+arrowhead styles `DefaultHead', `SimpleHead', `HookHead', `TeXHead'),
+real `size' (arrowhead size in `PostScript' coordinates), real `angle'
+(arrowhead angle in degrees), filltype `filltype' (one of `FillDraw',
+`Fill', `NoFill', `UnFill', `Draw') and (except for `MidArrow' and
+`Arrows') a relative real `position' along the path (an `arctime') where
+the tip of the arrow should be placed. The default arrowhead size when
+drawn with a pen `p' is `arrowsize(p)'. There are also arrow versions
+with slightly modified default values of `size' and `angle' suitable for
+curved arrows: `BeginArcArrow', `EndArcArrow' (or equivalently
+`ArcArrow'), `MidArcArrow', and `ArcArrows'.
+
+ Margins can be used to shrink the visible portion of a path by
+`labelmargin(p)' to avoid overlap with other drawn objects. Typical
+values of `margin' are `NoMargin', `BeginMargin', `EndMargin' (or
+equivalently `Margin'), and `Margins' (which leaves a margin at both
+ends of the path). One may use `Margin(real begin, real end)' to
+specify the size of the beginning and ending margin, respectively, in
+multiples of the units `labelmargin(p)' used for aligning labels.
+Alternatively, `BeginPenMargin', `EndPenMargin' (or equivalently
+`PenMargin'), `PenMargins', `PenMargin(real begin, real end)' specify a
+margin in units of the pen line width, taking account of the pen line
+width when drawing the path or arrow. For example, use `DotMargin', an
+abbreviation for `PenMargin(-0.5*dotfactor,0.5*dotfactor)', to draw
+from the usual beginning point just up to the boundary of an end dot of
+width `dotfactor*linewidth(p)'. The qualifiers `BeginDotMargin',
+`EndDotMargin', and `DotMargins' work similarly. The qualifier
+`TrueMargin(real begin, real end)' allows one to specify a margin
+directly in `PostScript' units, independent of the pen line width.
+
+ The use of arrows, bars, and margins is illustrated by the examples
+`Pythagoras.asy', `sqrtx01.asy', and `triads.asy'.
+
+ The legend for a picture `pic' can be fit and aligned to a frame
+with the routine:
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen);
+ Here `xmargin' and `ymargin' specify the surrounding x and y margins,
+`perline' specifies the number of entries per line (default 1; 0 means
+choose this number automatically), `linelength' specifies the length of
+the path lines, `hskip' and `vskip' specify the line skip (as a
+multiple of the legend entry size), `maxwidth' and `maxheight' specify
+optional upper limits on the width and height of the resulting legend
+(0 means unlimited), `hstretch' and `vstretch' allow the legend to
+stretch horizontally or vertically, and `p' specifies the pen used to
+draw the bounding box. The legend frame can then be added and aligned
+about a point on a picture `dest' using `add' or `attach' (*note add
+about::).
+
+ To draw a dot, simply draw a path containing a single point. The
+`dot' command defined in the module `plain' draws a dot having a
+diameter equal to an explicit pen line width or the default line width
+magnified by `dotfactor' (6 by default), using the specified filltype
+(*note filltype::):
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=Fill);
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=Fill);
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=Fill)
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=Fill);
+
+ If the variable `Label' is given as the `Label' argument to the
+second routine, the `format' argument will be used to format a string
+based on the dot location (here `defaultformat' is `"$%.4g$"'). The
+third routine draws a dot at every point of a pair array `z'. One can
+also draw a dot at every node of a path:
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=Fill);
+ See *note pathmarkers:: and *note markers:: for more general methods
+for marking path nodes.
+
+ To draw a fixed-sized object (in `PostScript' coordinates) about the
+user coordinate `origin', use the routine
+void draw(pair origin, picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend="",
+ marker marker=nomarker);
+
+
+File: asymptote.info, Node: fill, Next: clip, Prev: draw, Up: Drawing commands
+
+4.2 fill
+========
+
+void fill(picture pic=currentpicture, path g, pen p=currentpen);
+
+Fill the interior region bounded by the cyclic path `g' on the picture
+`pic', using the pen `p'.
+
+ There is also a convenient `filldraw' command, which fills the path
+and then draws in the boundary. One can specify separate pens for each
+operation:
+void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen,
+ pen drawpen=currentpen);
+
+ This fixed-size version of `fill' allows one to fill an object
+described in `PostScript' coordinates about the user coordinate
+`origin':
+void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen);
+
+This is just a convenient abbreviation for the commands:
+picture opic;
+fill(opic,g,p);
+add(pic,opic,origin);
+
+ The routine
+void filloutside(picture pic=currentpicture, path g, pen p=currentpen);
+ fills the region exterior to the path `g', out to the current boundary
+of picture `pic'.
+
+ Lattice gradient shading varying smoothly over a two-dimensional
+array of pens `p', using fill rule `fillrule', can be produced with
+void latticeshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p)
+ If `stroke=true', the region filled is the same as the region that
+would be drawn by `draw(pic,g,fillrule+zerowinding)'; in this case the
+path `g' need not be cyclic. The pens in `p' must belong to the same
+color space. One can use the functions `rgb(pen)' or `cmyk(pen)' to
+promote pens to a higher color space, as illustrated in the example file
+`latticeshading.asy'.
+
+ Axial gradient shading varying smoothly from `pena' to `penb' in the
+direction of the line segment `a--b' can be achieved with
+void axialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a,
+ pen penb, pair b);
+
+ Radial gradient shading varying smoothly from `pena' on the circle
+with center `a' and radius `ra' to `penb' on the circle with center `b'
+and radius `rb' is similar:
+void radialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, real ra,
+ pen penb, pair b, real rb);
+ Illustrations of radial shading are provided in the example files
+`shade.asy', `ring.asy', and `shadestroke.asy'.
+
+ Gouraud shading using fill rule `fillrule' and the vertex colors in
+the pen array `p' on a triangular lattice defined by the vertices `z'
+and edge flags `edges' is implemented with
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z,
+ int[] edges);
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges);
+ In the second form, the elements of `z' are taken to be successive
+nodes of path `g'. The pens in `p' must belong to the same color space.
+Illustrations of Gouraud shading are provided in the example file
+`Gouraud.asy' and in the solid geometry module `solids.asy'. The edge
+flags used in Gouraud shading are documented here:
+
+ `http://partners.adobe.com/public/developer/en/ps/sdk/TN5600.SmoothShading.pdf'.
+
+ Tensor product shading using fill rule `fillrule' on patches bounded
+by the n cyclic paths of length 4 in path array `b', using the vertex
+colors specified in the n \times 4 pen array `p' and internal control
+points in the n \times 4 array `z', is implemented with
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][]);
+ If the array `z' is empty, Coons shading, in which the color control
+points are calculated automatically, is used. The pens in `p' must
+belong to the same color space. A simpler interface for the case of a
+single patch (n=1) is also available:
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, path b=g,
+ pair[] z=new pair[]);
+ One can also smoothly shade the regions between consecutive paths of a
+sequence using a given array of pens:
+void draw(picture pic=currentpicture, path[] g, pen[] p);
+ Illustrations of tensor product and Coons shading are provided in the
+example files `tensor.asy', `Coons.asy', `BezierSurface.asy', and
+`rainbow.asy'.
+
+ More general shading possibilities are available with the `pdflatex',
+`context', and `pdftex' TeX engines: the routine
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader);
+ shades on picture `pic' the interior of path `g' according to fill
+rule `fillrule' using the `PostScript' calculator routine specified by
+the string `shader'; this routine takes 2 arguments, each in [0,1], and
+returns `colors(fillrule).length' color components. Function shading
+is illustrated in the example `functionshading.asy'.
+
+ The following routine uses `evenodd' clipping together with the `^^'
+operator to unfill a region:
+
+void unfill(picture pic=currentpicture, path g);
+
+
+File: asymptote.info, Node: clip, Next: label, Prev: fill, Up: Drawing commands
+
+4.3 clip
+========
+
+void clip(picture pic=currentpicture, path g, stroke=false,
+ pen fillrule=currentpen);
+
+Clip the current contents of picture `pic' to the region bounded by the
+path `g', using fill rule `fillrule' (*note fillrule::). If
+`stroke=true', the clipped portion is the same as the region that would
+be drawn with `draw(pic,g,fillrule+zerowinding)'; in this case the path
+`g' need not be cyclic. For an illustration of picture clipping, see
+the first example in *note LaTeX usage::.
+
+
+File: asymptote.info, Node: label, Prev: clip, Up: Drawing commands
+
+4.4 label
+=========
+
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)
+
+Draw Label `L' on picture `pic' using pen `p'. If `align' is `NoAlign',
+the label will be centered at user coordinate `position'; otherwise it
+will be aligned in the direction of `align' and displaced from
+`position' by the `PostScript' offset `align*labelmargin(p)'. The
+constant `Align' can be used to align the bottom-left corner of the
+label at `position'. If `p' is `nullpen', the pen specified within the
+Label, which defaults to `currentpen', will be used. The Label `L' can
+either be a string or the structure obtained by calling one of the
+functions
+Label Label(string s="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(string s="", align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+Label Label(Label L, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+ The text of a Label can be scaled, slanted, rotated, or shifted by
+multiplying it on the left by an affine transform (*note Transforms::).
+For example, `rotate(45)*xscale(2)*L' first scales `L' in the x
+direction and then rotates it counterclockwise by 45 degrees. The final
+position of a Label can also be shifted by a `PostScript' coordinate
+translation: `shift(10,0)*L'. The `embed' argument determines how the
+Label should transform with the embedding picture:
+`Shift'
+ only shift with embedding picture;
+
+`Rotate'
+ only shift and rotate with embedding picture (default);
+
+`Rotate(pair z)'
+ rotate with (picture-transformed) vector `z'.
+
+`Slant'
+ only shift, rotate, slant, and reflect with embedding picture;
+
+`Scale'
+ shift, rotate, slant, reflect, and scale with embedding picture.
+
+
+ To add a label to a path, use
+void label(picture pic=currentpicture, Label L, path g, align align=NoAlign,
+ pen p=nullpen, filltype filltype=NoFill);
+ By default the label will be positioned at the midpoint of the path.
+An alternative label location (an `arctime' value between 0 and
+`length(g)' *note arctime::) may be specified as real value for
+`position' in constructing the Label. The position `Relative(real)'
+specifies a location relative to the total arclength of the path. These
+convenient abbreviations are predefined:
+position BeginPoint=Relative(0);
+position MidPoint=Relative(0.5);
+position EndPoint=Relative(1);
+
+ Path labels are aligned in the direction `align', which may be
+specified as an absolute compass direction (pair) or a direction
+`Relative(pair)' measured relative to a north axis in the local
+direction of the path. For convenience `LeftSide', `Center', and
+`RightSide' are defined as `Relative(W)', `Relative((0,0))', and
+`Relative(E)', respectively. Multiplying `LeftSide', `Center',
+`RightSide' on the left by a real scaling factor will move the label
+further away from or closer to the path.
+
+ A label with a fixed-size arrow of length `arrowlength' pointing to
+`b' from direction `dir' can be produced with the routine
+void arrow(picture pic=currentpicture, Label L="", pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin);
+ If no alignment is specified (either in the Label or as an explicit
+argument), the optional Label will be aligned in the direction `dir',
+using margin `margin'.
+
+ The function `string graphic(string name, string options="")'
+returns a string that can be used to include an encapsulated
+`PostScript' (EPS) file. Here, `name' is the name of the file to
+include and `options' is a string containing a comma-separated list of
+optional bounding box (`bb=llx lly urx ury'), width (`width=value'),
+height (`height=value'), rotation (`angle=value'), scaling
+(`scale=factor'), clipping (`clip=bool'), and draft mode (`draft=bool')
+parameters. The `layer()' function can be used to force future objects
+to be drawn on top of the included image:
+label(graphic("file.eps","width=1cm"),(0,0),NE);
+layer();
+
+ The `string baseline(string s, string template="\strut")' function
+can be used to enlarge the bounding box of labels to match a given
+template, so that their baselines will be typeset on a horizontal line.
+See `Pythagoras.asy' for an example.
+
+ One can prevent labels from overwriting one another with the
+`overwrite' pen attribute (*note overwrite::).
+
+ The structure `object' defined in `plain_Label.asy' allows Labels
+and frames to be treated in a uniform manner. A group of objects may
+be packed together into single frame with the routine
+frame pack(pair align=2S ... object inset[]);
+ To draw or fill a box (or ellipse or other path) around a Label and
+return the bounding object, use one of the routines
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+ Here `envelope' is a boundary-drawing routine such as `box',
+`roundbox', or `ellipse' defined in `plain_boxes.asy' (*note
+envelope::).
+
+ The function `path[] texpath(Label L)' returns the path array that
+TeX would fill to draw the Label `L'.
+
+ The `string minipage(string s, width=100pt)' function can be used to
+format string `s' into a paragraph of width `width'. This example uses
+`minipage', `clip', and `graphic' to produce a CD label:
+
+
+size(11.7cm,11.7cm);
+asy(nativeformat(),"logo");
+fill(unitcircle^^(scale(2/11.7)*unitcircle),
+ evenodd+rgb(124/255,205/255,124/255));
+label(scale(1.1)*minipage(
+"\centering\scriptsize \textbf{\LARGE {\tt Asymptote}\\
+\smallskip
+\small The Vector Graphics Language}\\
+\smallskip
+\textsc{Andy Hammerlindl, John Bowman, and Tom Prince}
+http://asymptote.sourceforge.net\\
+",8cm),(0,0.6));
+label(graphic("logo."+nativeformat(),"height=7cm"),(0,-0.22));
+clip(unitcircle^^(scale(2/11.7)*unitcircle),evenodd);
+
+
+File: asymptote.info, Node: Programming, Next: LaTeX usage, Prev: Drawing commands, Up: Top
+
+5 Programming
+*************
+
+Here is a short introductory example to the `Asymptote' programming
+language that highlights the similarity of its control structures with
+those of C, C++, and Java:
+// This is a comment.
+
+// Declaration: Declare x to be a real variable;
+real x;
+
+// Assignment: Assign the real variable x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write("x equals 1.0");
+} else {
+ write("x is not equal to 1.0");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}
+
+ `Asymptote' supports `while', `do', `break', and `continue'
+statements just as in C/C++. It also supports the Java-style shorthand
+for iterating over all elements of an array:
+
+// Iterate over an array
+int[] array={1,1,2,3,5};
+for(int k : array) {
+ write(k);
+}
+ In addition, it supports many features beyond the ones found in those
+languages.
+
+* Menu:
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides::
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external `Asymptote' packages
+* Static:: Where to allocate your variable?
+
+
+File: asymptote.info, Node: Data types, Next: Paths and guides, Up: Programming
+
+5.1 Data types
+==============
+
+`Asymptote' supports the following data types (in addition to
+user-defined types):
+
+`void'
+ The void type is used only by functions that take or return no
+ arguments.
+
+`bool'
+ a boolean type that can only take on the values `true' or `false'.
+ For example: bool b=true;
+
+ defines a boolean variable `b' and initializes it to the value
+ `true'. If no initializer is given: bool b;
+
+ the value `false' is assumed.
+
+`bool3'
+ an extended boolean type that can take on the values `true',
+ `default', or `false'. A bool3 type can be cast to or from a bool.
+ The default initializer for bool3 is `default'.
+
+`int'
+ an integer type; if no initializer is given, the implicit value `0'
+ is assumed. The minimum allowed value of an integer is `intMin'
+ and the maximum value is `intMax'.
+
+`real'
+ a real number; this should be set to the highest-precision native
+ floating-point type on the architecture. The implicit initializer
+ for reals is `0.0'. Real numbers have precision `realEpsilon',
+ with `realDigits' significant digits. The smallest positive real
+ number is `realMin' and the largest positive real number is
+ `realMax'.
+
+`pair'
+ complex number, that is, an ordered pair of real components
+ `(x,y)'. The real and imaginary parts of a pair `z' can read as
+ `z.x' and `z.y'. We say that `x' and `y' are virtual members of
+ the data element pair; they cannot be directly modified, however.
+ The implicit initializer for pairs is `(0.0,0.0)'.
+
+ There are a number of ways to take the complex conjugate of a pair:
+ pair z=(3,4);
+ z=(z.x,-z.y);
+ z=z.x-I*z.y;
+ z=conj(z);
+
+ Here `I' is the pair `(0,1)'. A number of built-in functions are
+ defined for pairs:
+
+ `pair conj(pair z)'
+ returns the conjugate of `z';
+
+ `real length(pair z)'
+ returns the complex modulus `|z|' of its argument `z'. For
+ example,
+ pair z=(3,4);
+ length(z);
+ returns the result 5. A synonym for `length(pair)' is
+ `abs(pair)';
+
+ `real angle(pair z, bool warn=true)'
+ returns the angle of `z' in radians in the interval
+ [-`pi',`pi'] or `0' if `warn' is `false' and `z=(0,0)'
+ (rather than producing an error);
+
+ `real degrees(pair z, bool warn=true)'
+ returns the angle of `z' in degrees in the interval [0,360)
+ or `0' if `warn' is `false' and `z=(0,0)' (rather than
+ producing an error);
+
+ `pair unit(pair z)'
+ returns a unit vector in the direction of the pair `z';
+
+ `pair expi(real angle)'
+ returns a unit vector in the direction `angle' measured in
+ radians;
+
+ `pair dir(real degrees)'
+ returns a unit vector in the direction `degrees' measured in
+ degrees;
+
+ `real xpart(pair z)'
+ returns `z.x';
+
+ `real ypart(pair z)'
+ returns `z.y';
+
+ `pair realmult(pair z, pair w)'
+ returns the element-by-element product `(z.x*w.x,z.y*w.y)';
+
+ `real dot(pair z, pair w)'
+ returns the dot product `z.x*w.x+z.y*w.y';
+
+ `pair minbound(pair z, pair w)'
+ returns `(min(z.x,w.x),min(z.y,w.y))';
+
+ `pair maxbound(pair z, pair w)'
+ returns `(max(z.x,w.x),max(z.y,w.y))'.
+
+
+`triple'
+ an ordered triple of real components `(x,y,z)' used for
+ three-dimensional drawings. The respective components of a triple
+ `v' can read as `v.x', `v.y', and `v.z'. The implicit initializer
+ for triples is `(0.0,0.0,0.0)'.
+
+ Here are the built-in functions for triples:
+ `real length(triple v)'
+ returns the length `|v|' of the vector `v'. A synonym for
+ `length(triple)' is `abs(triple)';
+
+ `real polar(triple v, bool warn=true)'
+ returns the colatitude of `v' measured from the z axis in
+ radians or `0' if `warn' is `false' and `v=O' (rather than
+ producing an error);
+
+ `real azimuth(triple v, bool warn=true)'
+ returns the longitude of `v' measured from the x axis in
+ radians or `0' if `warn' is `false' and `v.x=v.y=0' (rather
+ than producing an error);
+
+ `real colatitude(triple v, bool warn=true)'
+ returns the colatitude of `v' measured from the z axis in
+ degrees or `0' if `warn' is `false' and `v=O' (rather than
+ producing an error);
+
+ `real latitude(triple v, bool warn=true)'
+ returns the latitude of `v' measured from the xy plane in
+ degrees or `0' if `warn' is `false' and `v=O' (rather than
+ producing an error);
+
+ `real longitude(triple v, bool warn=true)'
+ returns the longitude of `v' measured from the x axis in
+ degrees or `0' if `warn' is `false' and `v.x=v.y=0' (rather
+ than producing an error);
+
+ `triple unit(triple v)'
+ returns a unit triple in the direction of the triple `v';
+
+ `triple expi(real polar, real azimuth)'
+ returns a unit triple in the direction `(polar,azimuth)'
+ measured in radians;
+
+ `triple dir(real colatitude, real longitude)'
+ returns a unit triple in the direction
+ `(colatitude,longitude)' measured in degrees;
+
+ `real xpart(triple v)'
+ returns `v.x';
+
+ `real ypart(triple v)'
+ returns `v.y';
+
+ `real zpart(triple v)'
+ returns `v.z';
+
+ `real dot(triple u, triple v)'
+ returns the dot product `u.x*v.x+u.y*v.y+u.z*v.z';
+
+ `triple cross(triple u, triple v)'
+ returns the cross product
+
+ `(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)';
+
+ `triple minbound(triple u, triple v)'
+ returns `(min(u.x,v.x),min(u.y,v.y),min(u.z,v.z))';
+
+ `triple maxbound(triple u, triple v)'
+ returns `(max(u.x,v.x),max(u.y,v.y),max(u.z,v.z)').
+
+
+`string'
+ a character string, implemented using the STL `string' class.
+
+ Strings delimited by double quotes (`"') are subject to the
+ following mappings to allow the use of double quotes in TeX (e.g.
+ for using the `babel' package, *note babel::):
+
+ * \" maps to "
+
+ * \\ maps to \\
+
+ Strings delimited by single quotes (`'') have the same mappings as
+ character strings in ANSI `C':
+
+ * \' maps to '
+
+ * \" maps to "
+
+ * \? maps to ?
+
+ * \\ maps to backslash
+
+ * \a maps to alert
+
+ * \b maps to backspace
+
+ * \f maps to form feed
+
+ * \n maps to newline
+
+ * \r maps to carriage return
+
+ * \t maps to tab
+
+ * \v maps to vertical tab
+
+ * \0-\377 map to corresponding octal byte
+
+ * \x0-\xFF map to corresponding hexadecimal byte
+
+ The implicit initializer for strings is the empty string `""'.
+ Strings may be concatenated with the `+' operator. In the following
+ string functions, position `0' denotes the start of the string:
+ `int length(string s)'
+ returns the length of the string `s';
+
+ `int find(string s, string t, int pos=0)'
+ returns the position of the first occurrence of string `t' in
+ string `s' at or after position `pos', or -1 if `t' is not a
+ substring of `s';
+
+ `int rfind(string s, string t, int pos=-1)'
+ returns the position of the last occurrence of string `t' in
+ string `s' at or before position `pos' (if `pos'=-1, at the
+ end of the string `s'), or -1 if `t' is not a substring of
+ `s';
+
+ `string insert(string s, int pos, string t)'
+ returns the string formed by inserting string `t' at position
+ `pos' in `s';
+
+ `string erase(string s, int pos, int n)'
+ returns the string formed by erasing the string of length `n'
+ (if `n'=-1, to the end of the string `s') at position `pos'
+ in `s';
+
+ `string substr(string s, int pos, int n=-1)'
+ returns the substring of `s' starting at position `pos' and
+ of length `n' (if `n'=-1, until the end of the string `s');
+
+ `string reverse(string s)'
+ returns the string formed by reversing string `s';
+
+ `string replace(string s, string before, string after)'
+ returns a string with all occurrences of the string `before'
+ in the string `s' changed to the string `after';
+
+ `string replace(string s, string[][] table)'
+ returns a string constructed by translating in string `s' all
+ occurrences of the string `before' in an array `table' of
+ string pairs {`before',`after'} to the corresponding string
+ `after';
+
+ `string[] split(string s, string delimiter)'
+ returns an array of strings obtained by splitting `s' into
+ substrings delimited by `delimiter';
+
+ `string format(string s, int n)'
+ returns a string containing `n' formatted according to the
+ C-style format string `s' using the current locale;
+
+ `string format(string s, real x, string locale="")'
+ returns a string containing `x' formatted according to the
+ C-style format string `s' using locale `locale' (or the
+ current locale if an empty string is specified), following
+ the behaviour of the C function `fprintf'), except that only
+ one data field is allowed, trailing zeros are removed by
+ default (unless `#' is specified), and TeX is used to typeset
+ scientific notation;
+
+ `int hex(string s);'
+ casts a hexidecimal string `s' to an integer.
+
+ `string string(real x, int digits=realDigits)'
+ casts `x' to a string using precision `digits' and the C
+ locale;
+
+ `string locale(string s="")'
+ sets the locale to the given string, if nonempty, and returns
+ the current locale.
+
+ `string time(string format="%a %b %d %T %Z %Y")'
+ returns the current time formatted by the ANSI C routine
+ `strftime' according to the string `format' using the current
+ locale. Thus time();
+ time("%a %b %d %H:%M:%S %Z %Y");
+
+ are equivalent ways of returning the current time in the
+ default format used by the `UNIX' `date' command;
+
+ `int seconds(string t="", string format="")'
+ returns the time measured in seconds after the Epoch (Thu Jan
+ 01 00:00:00 UTC 1970) as determined by the ANSI C routine
+ `strptime' according to the string `format' using the current
+ locale, or the current time if `t' is the empty string. Note
+ that the `"%Z"' extension to the POSIX `strptime'
+ specification is ignored by the current GNU C Library. If an
+ error occurs, the value -1 is returned. Here are some
+ examples: seconds("Mar 02 11:12:36 AM PST 2007","%b %d %r PST %Y");
+ seconds(time("%b %d %r %z %Y"),"%b %d %r %z %Y");
+ seconds(time("%b %d %r %Z %Y"),"%b %d %r "+time("%Z")+" %Y");
+ 1+(seconds()-seconds("Jan 1","%b %d"))/(24*60*60);
+ The last example returns today's ordinal date, measured from
+ the beginning of the year.
+
+ `string time(int seconds, string format="%a %b %d %T %Z %Y")'
+ returns the time corresponding to `seconds' seconds after the
+ Epoch (Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C
+ routine `strftime' according to the string `format' using the
+ current locale. For example, to return the date corresponding
+ to 24 hours ago: time(seconds()-24*60*60);
+
+ `void abort(string s)'
+ aborts execution (with a non-zero return code in batch mode);
+ if string `s' is nonempty, a diagnostic message constructed
+ from the source file, line number, and `s' is printed;
+
+ `void exit()'
+ exits with a zero error return code in batch mode;
+
+ `void sleep(int seconds)'
+ pauses for the given number of seconds;
+
+ `void usleep(int microseconds)'
+ pauses for the given number of microseconds;
+
+ `void beep()'
+ produces a beep on the console;
+
+
+
+ As in C/C++, complicated types may be abbreviated with `typedef'
+(see the example in *note Functions::).
+
+
+File: asymptote.info, Node: Paths and guides, Next: Pens, Prev: Data types, Up: Programming
+
+5.2 Paths and guides
+====================
+
+`path'
+ a cubic spline resolved into a fixed path. The implicit
+ initializer for paths is `nullpath'.
+
+ For example, the routine `circle(pair c, real r)', which returns a
+ Bezier curve approximating a circle of radius `r' centered on `c',
+ is based on `unitcircle' (*note unitcircle::): path circle(pair c, real r)
+ {
+ return shift(c)*scale(r)*unitcircle;
+ }
+ If high accuracy is needed, a true circle may be produced with the
+ routine `Circle' defined in the module `graph.asy': import graph;
+ path Circle(pair c, real r, int n=nCircle);
+
+ A circular arc consistent with `circle' centered on `c' with
+ radius `r' from `angle1' to `angle2' degrees, drawing
+ counterclockwise if `angle2 >= angle1', can be constructed with path arc(pair c, real r, real angle1, real angle2);
+ One may also specify the direction explicitly: path arc(pair c, real r, real angle1, real angle2, bool direction);
+ Here the direction can be specified as CCW (counter-clockwise) or
+ CW (clockwise). For convenience, an arc centered at `c' from pair
+ `z1' to `z2' (assuming `|z2-c|=|z1-c|') in the may also be
+ constructed with path arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW)
+
+ If high accuracy is needed, true arcs may be produced with routines
+ in the module `graph.asy' that produce Bezier curves with `n'
+ control points: import graph;
+ path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle);
+ path Arc(pair c, real r, real angle1, real angle2, int n=nCircle);
+ path Arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW, int n=nCircle);
+
+ An ellipse can be drawn with the routine @cindex @code{ellipse}
+ path ellipse(pair c, real a, real b)
+ {
+ return shift(c)*scale(a,b)*unitcircle;
+ }
+
+ This example illustrates the use of all five guide connectors
+ discussed in *note Tutorial::: size(300,0);
+ pair[] z=new pair[10];
+
+ z[0]=(0,100); z[1]=(50,0); z[2]=(180,0);
+
+ for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0);
+
+ path p=z[0]..z[1]---z[2]::{up}z[3]
+ &z[3]..z[4]--z[5]::{up}z[6]
+ &z[6]::z[7]---z[8]..{up}z[9];
+
+ draw(p,grey+linewidth(4mm));
+
+ dot(z);
+
+
+
+ Here are some useful functions for paths:
+
+ `int length(path p);'
+ This is the number of (linear or cubic) segments in path `p'.
+ If `p' is cyclic, this is the same as the number of nodes in
+ `p'.
+
+ `int size(path p);'
+ This is the number of nodes in the path `p'. If `p' is
+ cyclic, this is the same as `length(p)'.
+
+ `bool cyclic(path p);'
+ returns `true' iff path `p' is cyclic.
+
+ `bool straight(path p, int i);'
+ returns `true' iff the segment of path `p' between node `i'
+ and node `i+1' is straight.
+
+ `bool piecewisestraight(path p)'
+ returns `true' iff the path `p' is piecewise straight.
+
+ `pair point(path p, int t);'
+ If `p' is cyclic, return the coordinates of node `t' mod
+ `length(p)'. Otherwise, return the coordinates of node `t',
+ unless `t' < 0 (in which case `point(0)' is returned) or `t'
+ > `length(p)' (in which case `point(length(p))' is returned).
+
+ `pair point(path p, real t);'
+ This returns the coordinates of the point between node
+ `floor(t)' and `floor(t)+1' corresponding to the cubic spline
+ parameter `t-floor(t)' (*note Bezier::). If `t' lies outside
+ the range [0,`length(p)'], it is first reduced modulo
+ `length(p)' in the case where `p' is cyclic or else converted
+ to the corresponding endpoint of `p'.
+
+ `pair dir(path p, int t, int sign=0, bool normalize=true);'
+ If `sign < 0', return the direction (as a pair) of the
+ incoming tangent to path `p' at node `t'; if `sign > 0',
+ return the direction of the outgoing tangent. If `sign=0',
+ the mean of these two directions is returned.
+
+ `pair dir(path p, real t, bool normalize=true);'
+ returns the direction of the tangent to path `p' at the point
+ between node `floor(t)' and `floor(t)+1' corresponding to the
+ cubic spline parameter `t-floor(t)' (*note Bezier::).
+
+ `pair accel(path p, int t, int sign=0);'
+ If `sign < 0', return the acceleration of the incoming path
+ `p' at node `t'; if `sign > 0', return the acceleration of
+ the outgoing path. If `sign=0', the mean of these two
+ accelerations is returned.
+
+ `pair accel(path p, real t);'
+ returns the acceleration of the path `p' at the point `t'.
+
+ `pair radius(path p, real t);'
+ returns the radius of curvature of the path `p' at the point
+ `t'.
+
+ `pair precontrol(path p, int t);'
+ returns the precontrol point of `p' at node `t'.
+
+ `pair precontrol(path p, real t);'
+ returns the effective precontrol point of `p' at parameter
+ `t'.
+
+ `pair postcontrol(path p, int t);'
+ returns the postcontrol point of `p' at node `t'.
+
+ `pair postcontrol(path p, real t);'
+ returns the effective postcontrol point of `p' at parameter
+ `t'.
+
+ `real arclength(path p);'
+ returns the length (in user coordinates) of the piecewise
+ linear or cubic curve that path `p' represents.
+
+ `real arctime(path p, real L);'
+ returns the path "time", a real number between 0 and the
+ length of the path in the sense of `point(path p, real t)',
+ at which the cumulative arclength (measured from the
+ beginning of the path) equals `L'.
+
+ `real dirtime(path p, pair z);'
+ returns the first "time", a real number between 0 and the
+ length of the path in the sense of `point(path, real)', at
+ which the tangent to the path has the direction of pair `z',
+ or -1 if this never happens.
+
+ `real reltime(path p, real l);'
+ returns the time on path `p' at the relative fraction `l' of
+ its arclength.
+
+ `pair relpoint(path p, real l);'
+ returns the point on path `p' at the relative fraction `l' of
+ its arclength.
+
+ `pair midpoint(path p);'
+ returns the point on path `p' at half of its arclength.
+
+ `path reverse(path p);'
+ returns a path running backwards along `p'.
+
+ `path subpath(path p, int a, int b);'
+ returns the subpath of `p' running from node `a' to node `b'.
+ If `a' < `b', the direction of the subpath is reversed.
+
+ `path subpath(path p, real a, real b);'
+ returns the subpath of `p' running from path time `a' to path
+ time `b', in the sense of `point(path, real)'. If `a' < `b',
+ the direction of the subpath is reversed.
+
+ `real[] intersect(path p, path q, real fuzz=-1);'
+ If `p' and `q' have at least one intersection point, return a
+ real array of length 2 containing the times representing the
+ respective path times along `p' and `q', in the sense of
+ `point(path, real)', for one such intersection point (as
+ chosen by the algorithm described on page 137 of `The
+ MetaFontbook'). The computations are performed to the
+ absolute error specified by `fuzz', or if `fuzz < 0', to
+ machine precision. If the paths do not intersect, return a
+ real array of length 0.
+
+ `real[][] intersections(path p, path q, real fuzz=-1);'
+ Return all (unless there are infinitely many) intersection
+ times of paths `p' and `q' as a sorted array of real arrays
+ of length 2 (*note sort::). The computations are performed to
+ the absolute error specified by `fuzz', or if `fuzz < 0', to
+ machine precision.
+
+ `real[] intersections(path p, explicit pair a, explicit pair b,'
+ real fuzz=-1); Return all (unless there are infinitely many)
+ intersection times of path `p' with the (infinite) line
+ through points `a' and `b' as a sorted array. The
+ intersections returned are guaranteed to be correct to within
+ the absolute error specified by `fuzz', or if `fuzz < 0', to
+ machine precision.
+
+ `real[] times(path p, real x)'
+ returns all intersection times of path `p' with the vertical
+ line through `(x,0)'.
+
+ `real[] times(path p, explicit pair z)'
+ returns all intersection times of path `p' with the
+ horizontal line through `(0,z.y)'.
+
+ `real[] mintimes(path p)'
+ returns an array of length 2 containing times at which path
+ `p' reaches its minimal horizontal and vertical extents,
+ respectively.
+
+ `real[] maxtimes(path p)'
+ returns an array of length 2 containing the times at which
+ path `p' reaches its maximal horizontal and vertical extents,
+ respectively.
+
+ `pair intersectionpoint(path p, path q, real fuzz=-1);'
+ returns the intersection point
+ `point(p,intersect(p,q,fuzz)[0])'.
+
+ `pair[] intersectionpoints(path p, path q, real fuzz=-1);'
+ returns an array containing all intersection points of the
+ paths `p' and `q'.
+
+ `pair extension(pair P, pair Q, pair p, pair q);'
+ returns the intersection point of the extensions of the line
+ segments `P--Q' and `p--q', or if the lines are parallel,
+ `(infinity,infinity)'.
+
+ `slice cut(path p, path knife, int n);'
+ returns the portions of path `p' before and after the `n'th
+ intersection of `p' with path `knife' as a structure `slice'
+ (if no intersection exist is found, the entire path is
+ considered to be `before' the intersection): struct slice {
+ path before,after;
+ }
+ The argument `n' is treated as modulo the number of
+ intersections.
+
+ `slice firstcut(path p, path knife);'
+ equivalent to `cut(p,knife,0);' Note that `firstcut.after'
+ plays the role of the `MetaPost cutbefore' command.
+
+ `slice lastcut(path p, path knife);'
+ equivalent to `cut(p,knife,-1);' Note that `lastcut.before'
+ plays the role of the `MetaPost cutafter' command.
+
+ `path buildcycle(... path[] p);'
+ This returns the path surrounding a region bounded by a list
+ of two or more consecutively intersecting paths, following
+ the behaviour of the `MetaPost buildcycle' command.
+
+ `pair min(path p);'
+ returns the pair (left,bottom) for the path bounding box of
+ path `p'.
+
+ `pair max(path p);'
+ returns the pair (right,top) for the path bounding box of
+ path `p'.
+
+ `int windingnumber(path p, pair z);'
+ returns the winding number of the cyclic path `p' relative to
+ the point `z'. The winding number is positive if the path
+ encircles `z' in the counterclockwise direction. If `z' lies
+ on `p' the constant `undefined' (defined to be the largest
+ odd integer) is returned.
+
+ `bool interior(int windingnumber, pen fillrule)'
+ returns true if `windingnumber' corresponds to an interior
+ point according to `fillrule'.
+
+ `bool inside(path p, pair z, pen fillrule=currentpen);'
+ returns `true' iff the point `z' lies inside or on the edge of
+ the region bounded by the cyclic path `p' according to the
+ fill rule `fillrule' (*note fillrule::).
+
+ `int inside(path p, path q, pen fillrule=currentpen);'
+ returns `1' if the cyclic path `p' strictly contains `q'
+ according to the fill rule `fillrule' (*note fillrule::), `-1'
+ if the cyclic path `q' strictly contains `p', and `0'
+ otherwise.
+
+ `pair inside(path p, pen fillrule=currentpen);'
+ returns an arbitrary point strictly inside a cyclic path `p'
+ according to the fill rule `fillrule' (*note fillrule::).
+
+ `path[] strokepath(path g, pen p=currentpen);'
+ returns the path array that `PostScript' would fill in
+ drawing path `g' with pen `p'.
+
+
+`guide'
+ an unresolved cubic spline (list of cubic-spline nodes and control
+ points). The implicit initializer for a guide is `nullpath'; this
+ is useful for building up a guide within a loop.
+
+ A guide is similar to a path except that the computation of the
+ cubic spline is deferred until drawing time (when it is resolved
+ into a path); this allows two guides with free endpoint conditions
+ to be joined together smoothly. The solid curve in the following
+ example is built up incrementally as a guide, but only resolved at
+ drawing time; the dashed curve is incrementally resolved at each
+ iteration, before the entire set of nodes (shown in red) is known:
+
+ size(200);
+
+ real mexican(real x) {return (1-8x^2)*exp(-(4x^2));}
+
+ int n=30;
+ real a=1.5;
+ real width=2a/n;
+
+ guide hat;
+ path solved;
+
+ for(int i=0; i < n; ++i) {
+ real t=-a+i*width;
+ pair z=(t,mexican(t));
+ hat=hat..z;
+ solved=solved..z;
+ }
+
+ draw(hat);
+ dot(hat,red);
+ draw(solved,dashed);
+
+
+
+ We point out an efficiency distinction in the use of guides and
+ paths: guide g;
+ for(int i=0; i < 10; ++i)
+ g=g--(i,i);
+ path p=g;
+
+ runs in linear time, whereas path p;
+ for(int i=0; i < 10; ++i)
+ p=p--(i,i);
+
+ runs in quadratic time, as the entire path up to that point is
+ copied at each step of the iteration.
+
+ The following routines can be used to examine the individual
+ elements of a guide without actually resolving the guide to a
+ fixed path (except for internal cycles, which are resolved):
+
+ `int size(guide g);'
+ Analogous to `size(path p)'.
+
+ `int length(guide g);'
+ Analogous to `length(path p)'.
+
+ `bool cyclic(path p);'
+ Analogous to `cyclic(path p)'.
+
+ `pair point(guide g, int t);'
+ Analogous to `point(path p, int t)'.
+
+ `guide reverse(guide g);'
+ Analogous to `reverse(path p)'. If `g' is cyclic and also
+ contains a secondary cycle, it is first solved to a path,
+ then reversed. If `g' is not cyclic but contains an internal
+ cycle, only the internal cycle is solved before reversal. If
+ there are no internal cycles, the guide is reversed but not
+ solved to a path.
+
+ `pair[] dirSpecifier(guide g, int i);'
+ This returns a pair array of length 2 containing the outgoing
+ (in element 0) and incoming (in element 1) direction
+ specifiers (or `(0,0)' if none specified) for the segment of
+ guide `g' between nodes `i' and `i+1'.
+
+ `pair[] controlSpecifier(guide g, int i);'
+ If the segment of guide `g' between nodes `i' and `i+1' has
+ explicit outgoing and incoming control points, they are
+ returned as elements 0 and 1, respectively, of a two-element
+ array. Otherwise, an empty array is returned.
+
+ `tensionSpecifier tensionSpecifier(guide g, int i);'
+ This returns the tension specifier for the segment of guide
+ `g' between nodes `i' and `i+1'. The individual components of
+ the `tensionSpecifier' type can be accessed as the virtual
+ members `in', `out', and `atLeast'.
+
+ `real[] curlSpecifier(guide g);'
+ This returns an array containing the initial curl specifier
+ (in element 0) and final curl specifier (in element 1) for
+ guide `g'.
+
+
+ As a technical detail we note that a direction specifier given to
+ `nullpath' modifies the node on the other side: the guides a..{up}nullpath..b;
+ c..nullpath{up}..d;
+ e..{up}nullpath{down}..f;
+ are respectively equivalent to a..nullpath..{up}b;
+ c{up}..nullpath..d;
+ e{down}..nullpath..{up}f;
+
+
+
+File: asymptote.info, Node: Pens, Next: Transforms, Prev: Paths and guides, Up: Programming
+
+5.3 Pens
+========
+
+In `Asymptote', pens provide a context for the four basic drawing
+commands (*note Drawing commands::). They are used to specify the
+following drawing attributes: color, line type, line width, line cap,
+line join, fill rule, text alignment, font, font size, pattern,
+overwrite mode, and calligraphic transforms on the pen nib. The default
+pen used by the drawing routines is called `currentpen'. This provides
+the same functionality as the `MetaPost' command `pickup'. The
+implicit initializer for pens is `defaultpen'.
+
+ Pens may be added together with the nonassociative binary operator
+`+'. This will add the colors of the two pens. All other non-default
+attributes of the rightmost pen will override those of the leftmost
+pen. Thus, one can obtain a yellow dashed pen by saying
+`dashed+red+green' or `red+green+dashed' or `red+dashed+green'. The
+binary operator `*' can be used to scale the color of a pen by a real
+number, until it saturates with one or more color components equal to 1.
+
+ * Colors are specified using one of the following colorspaces:
+ `pen gray(real g);'
+ This produces a grayscale color, where the intensity `g' lies
+ in the interval [0,1], with 0.0 denoting black and 1.0
+ denoting white.
+
+ `pen rgb(real r, real g, real b);'
+ This produces an RGB color, where each of the red, green, and
+ blue intensities `r', `g', `b', lies in the interval [0,1].
+
+ `pen cmyk(real c, real m, real y, real k);'
+ This produces a CMYK color, where each of the cyan, magenta,
+ yellow, and black intensities `c', `m', `y', `k', lies in the
+ interval [0,1].
+
+ `pen invisible;'
+ This special pen writes in invisible ink, but adjusts the
+ bounding box as if something had been drawn (like the
+ `\phantom' command in TeX). The function `bool
+ invisible(pen)' can be used to test whether a pen is
+ invisible.
+
+
+ The default color is `black'; this may be changed with the routine
+ `defaultpen(pen)'. The function `colorspace(pen p)' returns the
+ colorspace of pen `p' as a string (`"gray"', `"rgb"', `"cmyk"', or
+ `""').
+
+ The function `real[] colors(pen)' returns the color components of
+ a pen. The functions `pen gray(pen)', `pen rgb(pen)', and `pen
+ cmyk(pen)' return new pens obtained by converting their arguments
+ to the respective color spaces. The function
+ `colorless(pen=currentpen)' returns a copy of its argument with
+ the color attributes stripped (to avoid color mixing).
+
+ A 6-character RGB hexidecimal string can be converted to a pen with
+ the routine pen rgb(string s);
+
+ Various shades and mixtures of the grayscale primary colors
+ `black' and `white', RGB primary colors `red', `green', and
+ `blue', and RGB secondary colors `cyan', `magenta', and `yellow'
+ are defined as named colors, along with the CMYK primary colors
+ `Cyan', `Magenta', `Yellow', and `Black', in the module `plain':
+
+
+
+ The standard 140 RGB `X11' colors can be imported with the command import x11colors;
+ and the standard 68 CMYK TeX colors can be imported with the
+ command import texcolors;
+ Note that there is some overlap between these two standards and
+ the definitions of some colors (e.g. `Green') actually disagree.
+
+ `Asymptote' also comes with a `asycolors.sty' `LaTeX' package that
+ defines to `LaTeX' CMYK versions of `Asymptote''s predefined
+ colors, so that they can be used directly within `LaTeX' strings.
+ Normally, such colors are passed to `LaTeX' via a pen argument;
+ however, to change the color of only a portion of a string, say
+ for a slide presentation, (*note slide::) it may be desirable to
+ specify the color directly to `LaTeX'. This file can be passed to
+ `LaTeX' with the `Asymptote' command usepackage("asycolors");
+
+ The structure `hsv' defined in `plain_pens.asy' may be used to
+ convert between HSV and RGB spaces, where the hue `h' is an angle
+ in [0,360) and the saturation `s' and value `v' lie in `[0,1]': pen p=hsv(180,0.5,0.75);
+ write(p); // ([default], red=0.375, green=0.75, blue=0.75)
+ hsv q=p;
+ write(q.h,q.s,q.v); // 180 0.5 0.75
+
+ * Line types are specified with the function `pen linetype(string s,
+ real offset=0, bool scale=true, bool adjust=true)', where `s' is a
+ string of integer or real numbers separated by spaces. The
+ optional parameter `offset' specifies where in the pattern to
+ begin. The first number specifies how far (if `scale' is `true',
+ in units of the pen line width; otherwise in `PostScript' units)
+ to draw with the pen on, the second number specifies how far to
+ draw with the pen off, and so on. If `adjust' is `true', these
+ spacings are automatically adjusted by `Asymptote' to fit the
+ arclength of the path. Here are the predefined line types: pen solid=linetype("");
+ pen dotted=linetype("0 4");
+ pen dashed=linetype("8 8");
+ pen longdashed=linetype("24 8");
+ pen dashdotted=linetype("8 8 0 8");
+ pen longdashdotted=linetype("24 8 0 8");
+ pen Dotted=dotted+1.0;
+ pen Dotted(pen p=currentpen) {return dotted+2*linewidth(p);}
+
+
+
+ The default line type is `solid'; this may be changed with
+ `defaultpen(pen)'. The line type of a pen is returned by `int
+ linetype(pen p=currentpen)'.
+
+ * The pen line width is specified in `PostScript' units with `pen
+ linewidth(real)'. The default line width is 0.5 bp; this value may
+ be changed with `defaultpen(pen)'. The line width of a pen is
+ returned by `real linewidth(pen p=currentpen)'. For convenience,
+ in the module `plain' we define static void defaultpen(real w) {defaultpen(linewidth(w));}
+ static pen operator +(pen p, real w) {return p+linewidth(w);}
+ static pen operator +(real w, pen p) {return linewidth(w)+p;}
+ so that one may set the line width like this: defaultpen(2);
+ pen p=red+0.5;
+
+ * A pen with a specific `PostScript' line cap is returned on calling
+ `linecap' with an integer argument: pen squarecap=linecap(0);
+ pen roundcap=linecap(1);
+ pen extendcap=linecap(2);
+
+ The default line cap, `roundcap', may be changed with
+ `defaultpen(pen)'. The line cap of a pen is returned by `int
+ linecap(pen p=currentpen)'.
+
+ * A pen with a specific `PostScript' join style is returned on
+ calling `linejoin' with an integer argument: pen miterjoin=linejoin(0);
+ pen roundjoin=linejoin(1);
+ pen beveljoin=linejoin(2);
+
+ The default join style, `roundjoin', may be changed with
+ `defaultpen(pen)'.The join style of a pen is returned by `int
+ linejoin(pen p=currentpen)'.
+
+ * A pen with a specific `PostScript' miter limit is returned by
+ calling `miterlimit(real)'. The default miterlimit, `10.0', may
+ be changed with `defaultpen(pen)'. The miter limit of a pen is
+ returned by `real miterlimit(pen p=currentpen)'.
+
+ * A pen with a specific `PostScript' fill rule is returned on
+ calling `fillrule' with an integer argument: pen zerowinding=fillrule(0);
+ pen evenodd=fillrule(1);
+
+ The fill rule, which identifies the algorithm used to determine the
+ insideness of a path or array of paths, only affects the `clip',
+ `fill', and `inside' functions. For the `zerowinding' fill rule, a
+ point `z' is outside the region bounded by a path if the number of
+ upward intersections of the path with the horizontal line
+ `z--z+infinity' minus the number of downward intersections is
+ zero. For the `evenodd' fill rule, `z' is considered to be outside
+ the region if the total number of such intersections is even. The
+ default fill rule, `zerowinding', may be changed with
+ `defaultpen(pen)'. The fill rule of a pen is returned by `int
+ fillrule(pen p=currentpen)'.
+
+ * A pen with a specific text alignment setting is returned on
+ calling `basealign' with an integer argument: pen nobasealign=basealign(0);
+ pen basealign=basealign(1);
+
+ The default setting, `nobasealign',which may be changed with
+ `defaultpen(pen)', causes the label alignment routines to use the
+ full label bounding box for alignment. In contrast, `basealign'
+ requests that the TeX baseline be respected. The base align
+ setting of a pen is returned by `int basealigin(pen p=currentpen)'.
+
+ * The font size is specified in TeX points (1 pt = 1/72.27 inches)
+ with the function `pen fontsize(real size, real
+ lineskip=1.2*size)'. The default font size, 12pt, may be changed
+ with `defaultpen(pen)'. Nonstandard font sizes may require
+ inserting import fontsize;
+ at the beginning of the file (this requires the `fix-cm' package
+ available from
+
+ `http://www.ctan.org/tex-archive/help/Catalogue/entries/fix-cm'
+ and included in recent `LaTeX' distributions). The font size and
+ line skip of a pen can be examined with the routines `real
+ fontsize(pen p=currentpen)' and `real lineskip(pen p=currentpen)',
+ respectively.
+
+ * A pen using a specific `LaTeX' `NFSS' font is returned by calling
+ the function `pen font(string encoding, string family, string
+ series, string shape)'. The default setting,
+ `font("OT1","cmr","m","n")', corresponds to 12pt Computer Modern
+ Roman; this may be changed with `defaultpen(pen)'. The font
+ setting of a pen is returned by `string font(pen p=currentpen)'.
+ Support for standardized international characters is provided by
+ the `unicode' package (*note unicode::).
+
+ Alternatively, one may select a fixed-size TeX font (on which
+ `fontsize' has no effect) like `"cmr12"' (12pt Computer Modern
+ Roman) or `"pcrr"' (Courier) using the function `pen font(string
+ name)'. An optional size argument can also be given to scale the
+ font to the requested size: `pen font(string name, real size)'.
+
+ A nonstandard font command can be generated with `pen
+ fontcommand(string)'.
+
+ A convenient interface to the following standard `PostScript'
+ fonts is also provided: pen AvantGarde(string series="m", string shape="n");
+ pen Bookman(string series="m", string shape="n");
+ pen Courier(string series="m", string shape="n");
+ pen Helvetica(string series="m", string shape="n");
+ pen NewCenturySchoolBook(string series="m", string shape="n");
+ pen Palatino(string series="m", string shape="n");
+ pen TimesRoman(string series="m", string shape="n");
+ pen ZapfChancery(string series="m", string shape="n");
+ pen Symbol(string series="m", string shape="n");
+ pen ZapfDingbats(string series="m", string shape="n");
+
+ * The transparency of a pen can be changed with the command: pen opacity(real opacity=1, string blend="Compatible");
+ The opacity can be varied from `0' (fully transparent) to the
+ default value of `1' (opaque), and `blend' specifies one of the
+ following foreground-background blending operations: "Compatible","Normal","Multiply","Screen","Overlay","SoftLight",
+ "HardLight","ColorDodge","ColorBurn","Darken","Lighten","Difference",
+ "Exclusion","Hue","Saturation","Color","Luminosity",
+ as described in
+
+ `http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf'.
+ Since `PostScript' does not support transparency, this feature is
+ only effective with the `-f pdf' output format option; other
+ formats can be produced from the resulting PDF file with the
+ `ImageMagick' `convert' program. Labels are always drawn with an
+ `opacity' of 1. A simple example of transparent filling is
+ provided in the example file `transparency.asy'.
+
+ * `PostScript' commands within a `picture' may be used to create a
+ tiling pattern, identified by the string `name', for `fill' and
+ `draw' operations by adding it to the global `PostScript' frame
+ `currentpatterns', with optional left-bottom margin `lb' and
+ right-top margin `rt'. import patterns;
+ void add(string name, picture pic, pair lb=0, pair rt=0);
+
+ To `fill' or `draw' using pattern `name', use the pen
+ `pattern("name")'. For example, rectangular tilings can be
+ constructed using the routines `picture tile(real Hx=5mm, real
+ Hy=0, pen p=currentpen, filltype filltype=NoFill)', `picture
+ checker(real Hx=5mm, real Hy=0, pen p=currentpen)', and `picture
+ brick(real Hx=5mm, real Hy=0, pen p=currentpen)' defined in
+ `patterns.asy': size(0,90);
+ import patterns;
+
+ add("tile",tile());
+ add("filledtilewithmargin",tile(6mm,4mm,red,Fill),(1mm,1mm),(1mm,1mm));
+ add("checker",checker());
+ add("brick",brick());
+
+ real s=2.5;
+ filldraw(unitcircle,pattern("tile"));
+ filldraw(shift(s,0)*unitcircle,pattern("filledtilewithmargin"));
+ filldraw(shift(2s,0)*unitcircle,pattern("checker"));
+ filldraw(shift(3s,0)*unitcircle,pattern("brick"));
+
+
+
+ Hatch patterns can be generated with the routines `picture
+ hatch(real H=5mm, pair dir=NE, pen p=currentpen)', `picture
+ crosshatch(real H=5mm, pen p=currentpen)': size(0,100);
+ import patterns;
+
+ add("hatch",hatch());
+ add("hatchback",hatch(NW));
+ add("crosshatch",crosshatch(3mm));
+
+ real s=1.25;
+ filldraw(unitsquare,pattern("hatch"));
+ filldraw(shift(s,0)*unitsquare,pattern("hatchback"));
+ filldraw(shift(2s,0)*unitsquare,pattern("crosshatch"));
+
+
+
+ You may need to turn off aliasing in your `PostScript' viewer for
+ patterns to appear correctly. Custom patterns can easily be
+ constructed, following the examples in `patterns.asy'. The tiled
+ pattern can even incorporate shading (*note gradient shading::),
+ as illustrated in this example (not included in the manual because
+ not all printers support `PostScript' 3): size(0,100);
+ import patterns;
+
+ real d=4mm;
+ picture tiling;
+ path square=scale(d)*unitsquare;
+ axialshade(tiling,square,white,(0,0),black,(d,d));
+ fill(tiling,shift(d,d)*square,blue);
+ add("shadedtiling",tiling);
+
+ filldraw(unitcircle,pattern("shadedtiling"));
+
+
+
+ * One can specify a custom pen nib as an arbitrary polygonal path
+ with `pen makepen(path)'; this path represents the mark to be
+ drawn for paths containing a single point. This pen nib path can be
+ recovered from a pen with `path nib(pen)'. Unlike in `MetaPost',
+ the path need not be convex:
+
+ size(200);
+ pen convex=makepen(scale(10)*polygon(8))+grey;
+ draw((1,0.4),convex);
+ draw((0,0)---(1,1)..(2,0)--cycle,convex);
+
+ pen nonconvex=scale(10)*
+ makepen((0,0)--(0.25,-1)--(0.5,0.25)--(1,0)--(0.5,1.25)--cycle)+red;
+ draw((0.5,-1.5),nonconvex);
+ draw((0,-1.5)..(1,-0.5)..(2,-1.5),nonconvex);
+
+
+
+ The value `nullpath' represents a circular pen nib (the default);
+ an elliptical pen can be achieved simply by multiplying the pen by
+ a transform: `yscale(2)*currentpen'.
+
+ * One can prevent labels from overwriting one another by using the
+ pen attribute `overwrite', which takes a single argument:
+
+ `Allow'
+ Allow labels to overwrite one another. This is the default
+ behaviour (unless overridden with `defaultpen(pen)'.
+
+ `Suppress'
+ Suppress, with a warning, each label that would overwrite
+ another label.
+
+ `SuppressQuiet'
+ Suppress, without warning, each label that would overwrite
+ another label.
+
+ `Move'
+ Move a label that would overwrite another out of the way and
+ issue a warning. As this adjustment is during the final
+ output phase (in `PostScript' coordinates) it could result in
+ a larger figure than requested.
+
+ `MoveQuiet'
+ Move a label that would overwrite another out of the way,
+ without warning. As this adjustment is during the final
+ output phase (in `PostScript' coordinates) it could result in
+ a larger figure than requested.
+
+
+
+ The routine `defaultpen()' returns the current default pen
+attributes. Calling the routine `resetdefaultpen()' resets all pen
+default attributes to their initial values.
+
+
+File: asymptote.info, Node: Transforms, Next: Frames and pictures, Prev: Pens, Up: Programming
+
+5.4 Transforms
+==============
+
+`Asymptote' makes extensive use of affine transforms. A pair `(x,y)' is
+transformed by the transform `t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)' to
+`(x',y')', where
+x' = t.x + t.xx * x + t.xy * y
+y' = t.y + t.yx * x + t.yy * y
+ This is equivalent to the `PostScript' transformation `[t.xx t.yx t.xy
+t.yy t.x t.y]'.
+
+ Transforms can be applied to pairs, guides, paths, pens, strings,
+transforms, frames, and pictures by multiplication (via the binary
+operator `*') on the left (*note circle:: for an example). Transforms
+can be composed with one another and inverted with the function
+`transform inverse(transform t)'; they can also be raised to any
+integer power with the `^' operator.
+
+ The built-in transforms are:
+
+`transform identity();'
+ the identity transform;
+
+`transform shift(pair z);'
+ translates by the pair `z';
+
+`transform shift(real x, real y);'
+ translates by the pair `(x,y)';
+
+`transform xscale(real x);'
+ scales by `x' in the x direction;
+
+`transform yscale(real y);'
+ scales by `y' in the y direction;
+
+`transform scale(real s);'
+ scale by `s' in both x and y directions;
+
+`transform scale(real x, real y);'
+ scale by `x' in the x direction and by `y' in the y direction;
+
+`transform slant(real s);'
+ maps `(x,y)' -> `(x+s*y,y)';
+
+`transform rotate(real angle, pair z=(0,0));'
+ rotates by `angle' in degrees about `z';
+
+`transform reflect(pair a, pair b);'
+ reflects about the line `a--b'.
+
+ The implicit initializer for transforms is `identity()'. The
+routines `shift(transform t)' and `shiftless(transform t)' return the
+transforms `(t.x,t.y,0,0,0,0)' and `(0,0,t.xx,t.xy,t.yx,t.yy)'
+respectively.
+
+
+File: asymptote.info, Node: Frames and pictures, Next: Files, Prev: Transforms, Up: Programming
+
+5.5 Frames and pictures
+=======================
+
+`frame'
+ Frames are canvases for drawing in `PostScript' coordinates. While
+ working with frames directly is occasionally necessary for
+ constructing deferred drawing routines, pictures are usually more
+ convenient to work with. The implicit initializer for frames is
+ `newframe'. The function `bool empty(frame f)' returns `true' only
+ if the frame `f' is empty. A frame may be erased with the
+ `erase(frame)' routine. The functions `pair min(frame)' and `pair
+ max(frame)' return the (left,bottom) and (right,top) coordinates
+ of the frame bounding box, respectively. The contents of frame
+ `src' may be appended to frame `dest' with the command void add(frame dest, frame src);
+ or prepended with void prepend(frame dest, frame src);
+ A frame obtained by aligning frame `f' in the direction `align',
+ in a manner analogous to the `align' argument of `label' (*note
+ label::), is returned by frame align(frame f, pair align);
+
+ To draw or fill a box or ellipse around a label or frame and
+ return the boundary as a path, use one of the predefined
+ `envelope' routines path box(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+ path roundbox(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+ path ellipse(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+
+`picture'
+ Pictures are high-level structures (*note Structures::) defined in
+ the module `plain' that provide canvases for drawing in user
+ coordinates. The default picture is called `currentpicture'. A
+ new picture can be created like this: picture pic;
+ Anonymous pictures can be made by the expression `new picture'.
+
+ The `size' routine specifies the dimensions of the desired picture:
+
+ void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=Aspect);
+
+ If the `x' and `y' sizes are both 0, user coordinates will be
+ interpreted as `PostScript' coordinates. In this case, the
+ transform mapping `pic' to the final output frame is `identity()'.
+
+ If exactly one of `x' or `y' is 0, no size restriction is imposed
+ in that direction; it will be scaled the same as the other
+ direction.
+
+ If `keepAspect' is set to `Aspect' or `true', the picture will be
+ scaled with its aspect ratio preserved such that the final width
+ is no more than `x' and the final height is no more than `y'.
+
+ If `keepAspect' is set to `IgnoreAspect' or `false', the picture
+ will be scaled in both directions so that the final width is `x'
+ and the height is `y'.
+
+ To make the user coordinates of picture `pic' represent multiples
+ of `x' units in the x direction and `y' units in the y direction,
+ use void unitsize(picture pic=currentpicture, real x, real y=x);
+ When nonzero, these `x' and `y' values override the corresponding
+ size parameters of picture `pic'.
+
+ The routine void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max);
+ forces the final picture scaling to map the user coordinates
+ `box(min,max)' to a region of width `xsize' and height `ysize'
+ (when these parameters are nonzero).
+
+ Alternatively, calling the routine transform fixedscaling(picture pic=currentpicture, pair min,
+ pair max, pen p=nullpen, bool warn=false);
+ will cause picture `pic' to use a fixed scaling to map user
+ coordinates in `box(min,max)' to the (already specified) picture
+ size, taking account of the width of pen `p'. A warning will be
+ issued if the final picture exceeds the specified size.
+
+ A picture `pic' can be fit to a frame and output to a file
+ `prefix'.`format' using image format `format' by calling the
+ `shipout' function: void shipout(string prefix=defaultfilename, picture pic=currentpicture,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ projection P=currentprojection);
+ The default output format, `PostScript', may be changed with the
+ `-f' or `-tex' command-line options. The `options', `script', and
+ `projection' parameters are only relevant for 3D pictures.
+
+ A `shipout()' command is added implicitly at file exit if no
+ previous `shipout' commands have been executed. The default page
+ orientation is `Portrait'; this may be modified by changing the
+ variable `orientation'. To output in landscape mode, simply set
+ the variable `orientation=Landscape' or issue the command shipout(Landscape);
+
+ To rotate the page by -90 degrees, use the orientation `Seascape'. The
+ orientation `UpsideDown' rotates the page by 180 degrees.
+
+ A picture `pic' can be explicitly fit to a frame by calling frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect);
+ The default size and aspect ratio settings are those given to the
+ `size' command (which default to `0', `0', and `true',
+ respectively). The transformation that would currently be used to
+ fit a picture `pic' to a frame is returned by the member function
+ `pic.calculateTransform()'.
+
+ In certain cases (e.g. 2D graphs) where only an approximate size
+ estimate for `pic' is available, the picture fitting routine frame pic.scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect);
+ (which scales the resulting frame, including labels and fixed-size
+ objects) will enforce perfect compliance with the requested size
+ specification, but should not normally be required.
+
+ To draw a bounding box with margins around a picture, fit the
+ picture to a frame using the function frame bbox(picture pic=currentpicture, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill);
+ Here `filltype' specifies one of the following fill types:
+ `FillDraw'
+ Fill the interior and draw the boundary.
+
+ `FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen,'
+ `pen drawpen=nullpen);' If `fillpen' is `nullpen', fill with
+ the drawing pen; otherwise fill with pen `fillpen'. If
+ `drawpen' is `nullpen', draw the boundary with `fillpen';
+ otherwise with `drawpen'. An optional margin of `xmargin' and
+ `ymargin' can be specified.
+
+ `Fill'
+ Fill the interior.
+
+ `Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)'
+ If `p' is `nullpen', fill with the drawing pen; otherwise
+ fill with pen `p'. An optional margin of `xmargin' and
+ `ymargin' can be specified.
+
+ `NoFill'
+ Do not fill.
+
+ `Draw'
+ Draw only the boundary.
+
+ `Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)'
+ If `p' is `nullpen', draw the boundary with the drawing pen;
+ otherwise draw with pen `p'. An optional margin of `xmargin'
+ and `ymargin' can be specified.
+
+ `UnFill'
+ Clip the region.
+
+ `UnFill(real xmargin=0, real ymargin=xmargin)'
+ Clip the region and surrounding margins `xmargin' and
+ `ymargin'.
+
+ `RadialShade(pen penc, pen penr)'
+ Fill varying radially from `penc' at the center of the
+ bounding box to `penr' at the edge.
+
+
+ For example, to draw a bounding box around a picture with a 0.25 cm
+ margin and output the resulting frame, use the command: shipout(bbox(0.25cm));
+ A `picture' may be fit to a frame with the background color of
+ pen `p' with the function `bbox(p,Fill)'.
+
+ The functions pair min(picture pic, user=false);
+ pair max(picture pic, user=false);
+ pair size(picture pic, user=false);
+ calculate the `PostScript' bounds that picture `pic' would have
+ if it were currently fit to a frame using its default size
+ specification. If `user' is `false' the returned value is in
+ `PostScript' coordinates, otherwise it is in user coordinates.
+
+ The function pair point(picture pic=currentpicture, pair dir, bool user=true);
+ is a convenient way of determining the point on the bounding box
+ of `pic' in the direction `dir' relative to its center, ignoring
+ the contributions from fixed-size objects (such as labels and
+ arrowheads). If `user' is `true' the returned value is in user
+ coordinates, otherwise it is in `PostScript' coordinates.
+
+ The function pair truepoint(picture pic=currentpicture, pair dir, bool user=true);
+ is identical to `point', except that it also accounts for
+ fixed-size objects, using the scaling transform that picture `pic'
+ would have if currently fit to a frame using its default size
+ specification. If `user' is `true' the returned value is in user
+ coordinates, otherwise it is in `PostScript' coordinates.
+
+ Sometimes it is useful to draw objects on separate pictures and
+ add one picture to another using the `add' function: void add(picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void add(picture dest, picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ The first example adds `src' to `currentpicture'; the second one
+ adds `src' to `dest'. The `group' option specifies whether or not
+ the graphical user interface `xasy' should treat all of the
+ elements of `src' as a single entity (*note GUI::), `filltype'
+ requests optional background filling or clipping, and `above'
+ specifies whether to add `src' above or below existing objects.
+
+ There are also routines to add a picture or frame `src' specified
+ in postscript coordinates to another picture `dest' (or
+ `currentpicture') about the user coordinate `position': void add(picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void add(picture dest, picture src, pair position,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+ void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+ void add(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true);
+
+ The optional `align' argument in the last three forms specifies a
+ direction to use for aligning the frame, in a manner analogous to
+ the `align' argument of `label' (*note label::). However, one key
+ difference is that when `align' is not specified, labels are
+ centered, whereas frames and pictures are aligned so that their
+ origin is at `position'. Illustrations of frame alignment can be
+ found in the examples *note errorbars:: and *note image::. If you
+ want to align three or more subpictures, group them two at a time:
+
+ picture pic1;
+ real size=50;
+ size(pic1,size);
+ fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
+
+ picture pic2;
+ size(pic2,size);
+ fill(pic2,unitcircle,green);
+
+ picture pic3;
+ size(pic3,size);
+ fill(pic3,unitsquare,blue);
+
+ picture pic;
+ add(pic,pic1.fit(),(0,0),N);
+ add(pic,pic2.fit(),(0,0),10S);
+
+ add(pic.fit(),(0,0),N);
+ add(pic3.fit(),(0,0),10S);
+
+
+
+ Alternatively, one can use `attach' to automatically increase the
+ size of picture `dest' to accommodate adding a frame `src' about
+ the user coordinate `position': void attach(picture dest=currentpicture, frame src,
+ pair position=0, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+ void attach(picture dest=currentpicture, frame src,
+ pair position, pair align, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+
+ To erase the contents of a picture (but not the size
+ specification), use the function void erase(picture pic=currentpicture);
+
+ To save a snapshot of `currentpicture', `currentpen', and
+ `currentprojection', use the function `save()'.
+
+ To restore a snapshot of `currentpicture', `currentpen', and
+ `currentprojection', use the function `restore()'.
+
+ Many further examples of picture and frame operations are provided
+ in the base module `plain'.
+
+ It is possible to insert verbatim `PostScript' commands in a
+ picture with one of the routines void postscript(picture pic=currentpicture, string s);
+ void postscript(picture pic=currentpicture, string s, pair min,
+ pair max)
+ Here `min' and `max' can be used to specify explicit bounds
+ associated with the resulting `PostScript' code.
+
+ Verbatim TeX commands can be inserted in the intermediate `LaTeX'
+ output file with one of the functions void tex(picture pic=currentpicture, string s);
+ void tex(picture pic=currentpicture, string s, pair min, pair max)
+ Here `min' and `max' can be used to specify explicit bounds
+ associated with the resulting TeX code.
+
+ To issue a global TeX command (such as a TeX macro definition) in
+ the TeX preamble (valid for the remainder of the top-level module)
+ use: void texpreamble(string s);
+
+ The TeX environment can be reset to its initial state, clearing all
+ macro definitions, with the function void texreset();
+
+ The routine void usepackage(string s, string options="");
+ provides a convenient abbreviation for texpreamble("\usepackage["+options+"]{"+s+"}");
+ that can be used for importing `LaTeX' packages.
+
+
+
+File: asymptote.info, Node: Files, Next: Variable initializers, Prev: Frames and pictures, Up: Programming
+
+5.6 Files
+=========
+
+`Asymptote' can read and write text files (including comma-separated
+value) files and portable XDR (External Data Representation) binary
+files.
+
+ An input file must first be opened with `input(string name, bool
+check=true, string comment="#")'; reading is then done by assignment:
+file fin=input("test.txt");
+real a=fin;
+
+ If the optional boolean argument `check' is `false', no check will
+be made that the file exists. If the file does not exist or is not
+readable, the function `bool error(file)' will return `true'. The
+first character of the string `comment' specifies a comment character.
+If this character is encountered in a data file, the remainder of the
+line is ignored. When reading strings, a comment character followed
+immediately by another comment character is treated as a single literal
+comment character.
+
+ If the `-globalwrite' (or `-nosafe') option is enabled, one can
+change the current working directory to the contents of the string `s'
+with the function `string cd(string s)', which returns the new working
+directory. If `string s' is empty, the path is reset to the value it
+had at program startup.
+
+ When reading pairs, the enclosing parenthesis are optional. Strings
+are also read by assignment, by reading characters up to but not
+including a newline. In addition, `Asymptote' provides the function
+`string getc(file)' to read the next character (treating the comment
+character as an ordinary character) and return it as a string.
+
+ A file named `name' can be open for output with
+file output(string name, bool update=false);
+ If `update=false', any existing data in the file will be erased and
+only write operations can be used on the file. If `update=true', any
+existing data will be preserved, the position will be set to the
+end-of-file, and both reading and writing operations will be enabled.
+For security reasons, writing to files in directories other than the
+current directory is allowed only if the `-globalwrite' (or `-nosafe')
+command-line option is specified.
+
+ There are two special files: `stdin', which reads from the keyboard,
+and `stdout', which writes to the terminal. The implicit initializer
+for files is `null'.
+
+ Data of a built-in type `T' can be written to an output file by
+calling one of the functions
+write(string s="", T x, suffix suffix=endl ... T[]);
+write(file file, string s="", T x, suffix suffix=none ... T[]);
+write(file file=stdout, string s="", explicit T[] x ... T[][]);
+write(file file=stdout, T[][]);
+write(file file=stdout, T[][][]);
+write(suffix suffix=endl);
+write(file file, suffix suffix=none);
+ If `file' is not specified, `stdout' is used and terminated by default
+with a newline. If specified, the optional identifying string `s' is
+written before the data `x'. An arbitrary number of data values may be
+listed when writing scalars or one-dimensional arrays. The `suffix' may
+be one of the following: `none' (do nothing), `flush' (output buffered
+data), `endl' (terminate with a newline and flush), `newl' (terminate
+with a newline), `tab' (terminate with a tab), or `comma' (terminate
+with a comma). Here are some simple examples of data output:
+file fout=output("test.txt");
+write(fout,1); // Writes "1"
+write(fout); // Writes a new line
+write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
+ A file may also be opened with `xinput' or `xoutput', instead of
+`input' or `output', to read or write double precision (64-bit) real
+values and single precision (32-bit) integer values in Sun
+Microsystem's XDR (External Data Representation) portable binary format
+(available on all `UNIX' platforms). A file may also be opened with
+`binput' or `boutput' to read or write double precision values in the
+native (nonportable) machine binary format. The function `file
+single(file,0.0)' may be used to set a file to read single precision
+real XDR or binary values; calling `file single(file,0.0,false)' sets
+it back to read doubles again. The functions `file single(file,0)' and
+`file single(file,0,false)' can be used to change the default integer
+precision (single). The functions `file single(file)' and `file
+single(file,false)' may be used to set the precision for both real and
+integer values.
+
+ One can test a file for end-of-file with the boolean function
+`eof(file)', end-of-line with `eol(file)', and for I/O errors with
+`error(file)'. One can flush the output buffers with `flush(file)',
+clear a previous I/O error with `clear(file)', and close the file with
+`close(file)'. The function `int precision(file file=stdout, int
+digits=0)' sets the number of digits of output precision for `file' to
+`digits', provided `digits' is nonzero, and returns the previous
+precision setting. The function `int tell(file)' returns the current
+position in a file relative to the beginning. The routine `seek(file
+file, int pos)' can be used to change this position, where a negative
+value for the position `pos' is interpreted as relative to the
+end-of-file. For example, one can rewind a file `file' with the command
+`seek(file,0)' and position to the final character in the file with
+`seek(file,-1)'. The command `seekeof(file)' sets the position to the
+end of the file.
+
+ Assigning `settings.scroll=n' for a positive integer `n' requests a
+pause after every `n' output lines to `stdout'. One may then press
+`Enter' to continue to the next `n' output lines, `s' followed by
+`Enter' to scroll without further interruption, or `q' followed by
+`Enter' to quit the current output operation. If `n' is negative, the
+output scrolls a page at a time (i.e. by one less than the current
+number of display lines). The default value, `settings.scroll=0',
+specifies continuous scrolling.
+
+ The routines
+string getstring(string name="", string default="", string prompt="",
+ bool store=true);
+int getint(string name="", int default=0, string prompt="",
+ bool store=true);
+real getreal(string name="", real default=0, string prompt="",
+ bool store=true);
+pair getpair(string name="", pair default=0, string prompt="",
+ bool store=true);
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true);
+ defined in the module `plain' may be used to prompt for a value from
+`stdin' using the GNU `readline' library. If `store=true', the history
+of values for `name' is stored in the file `".asy_history_"+name'
+(*note history::). The most recent value in the history will be used to
+provide a default value for subsequent runs. The default value
+(initially `default') is displayed after `prompt'. These functions are
+based on the internal routines
+string readline(string prompt="", string name="", bool tabcompletion=false);
+void saveline(string name, string value, bool store=true);
+ Here, `readline' prompts the user with the default value formatted
+according to `prompt', while `saveline' is used to save the string
+`value' in a local history named `name', optionally storing the local
+history in a file `".asy_history_"+name'.
+
+ The routine `history(string name, int n=1)' can be used to look up
+the `n' most recent values (or all values up to `historylines' if
+`n=0') entered for string `name'. The routine `history(int n=0)'
+returns the interactive history. For example,
+write(output("transcript.asy"),history());
+ outputs the interactive history to the file `transcript.asy'.
+
+ The function `int delete(string s)' deletes the file named by the
+string `s'. Unless the `-globalwrite' (or `-nosafe') option is enabled,
+the file must reside in the current directory. The function `int
+rename(string from, string to)' may be used to rename file `from' to
+file `to'. Unless the `-globalwrite' (or `-nosafe') option is enabled,
+this operation is restricted to the current directory. The functions
+int convert(string args="", string file="", string format="");
+int animate(string args="", string file="", string format="");
+ call the `ImageMagick' commands `convert' and `animate', respectively,
+with the arguments `args' and the file name constructed from the
+strings `file' and `format'. If the setting `safe' is false, then the
+function `int system(string s)' can be used to call the arbitrary system
+command `s'.
+
+
+File: asymptote.info, Node: Variable initializers, Next: Structures, Prev: Files, Up: Programming
+
+5.7 Variable initializers
+=========================
+
+A variable can be assigned a value when it is declared, as in `int
+x=3;' where the variable `x' is assigned the value `3'. As well as
+literal constants such as `3', arbitary expressions can be used as
+initializers, as in `real x=2*sin(pi/2);'.
+
+ A variable is not added to the namespace until after the initializer
+is evaluated, so for example, in
+
+int x=2;
+int x=5*x;
+ the `x' in the initializer on the second line refers to the variable
+`x' declared on the first line. The second line, then, declares a
+variable `x' shadowing the original `x' and initializes it to the value
+`10'.
+
+ Variables of most types can be declared without an explicit
+initializer and they will be initialized by the default initializer of
+that type:
+
+ * Variables of the numeric types `int', `real', and `pair' are all
+ initialized to zero; variables of type `triple' are initialized to
+ `O=(0,0,0)'.
+
+ * `boolean' variables are initialized to `false'.
+
+ * `string' variables are initialized to the empty string.
+
+ * `transform' variables are initialized to the identity
+ transformation.
+
+ * `path' and `guide' variables are initialized to `nullpath'.
+
+ * `pen' variables are initialized to the default pen.
+
+ * `frame' and `picture' variables are initialized to empty frames
+ and pictures, respectively.
+
+ * `file' variables are initialized to `null'.
+
+ The default initializers for user-defined array, structure, and
+function types are explained in their respective sections. Some types,
+such as `code', do not have default initializers. When a variable of
+such a type is introduced, the user must initialize it by explicitly
+giving it a value.
+
+ The default initializer for any type `T' can be redeclared by
+defining the function `T operator init()'. For instance, `int'
+variables are usually initialized to zero, but in
+
+int operator init() {
+ return 3;
+}
+int y;
+
+the variable `y' is initialized to `3'. This example was given for
+illustrative purposes; redeclaring the initializers of built-in types
+is not recommended. Typically, `operator init' is used to define
+sensible defaults for user-defined types.
+
+
+File: asymptote.info, Node: Structures, Next: Operators, Prev: Variable initializers, Up: Programming
+
+5.8 Structures
+==============
+
+Users may also define their own data types as structures, along with
+user-defined operators, much as in C++. By default, structure members
+are `public' (may be read and modified anywhere in the code), but may be
+optionally declared `restricted' (readable anywhere but writeable only
+inside the structure where they are defined) or `private' (readable and
+writable only inside the structure). In a structure definition, the
+keyword `this' can be used as an expression to refer to the enclosing
+structure. Any code at the top-level scope within the structure is
+executed on initialization.
+
+ Variables hold references to structures. That is, in the example:
+
+struct T {
+ int x;
+}
+
+T foo=new T;
+T bar=foo;
+bar.x=5;
+
+ The variable `foo' holds a reference to an instance of the structure
+`T'. When `bar' is assigned the value of `foo', it too now holds a
+reference to the same instance as `foo' does. The assignment `bar.x=5'
+changes the value of the field `x' in that instance, so that `foo.x'
+will also be equal to `5'.
+
+ The expression `new T' creates a new instance of the structure `T'
+and returns a reference to that instance. In creating the new
+instance, any code in the body of the record definition is executed.
+For example:
+
+int Tcount=0;
+struct T {
+ int x;
+ ++Tcount;
+}
+
+T foo=new T;
+
+ Here, the expression `new T' will produce a new instance of the
+class, but will also cause `Tcount' to be incremented, so that it keeps
+track of the number of instances produced.
+
+ The expression `null' can be cast to any structure type to yield a
+null reference, a reference that does not actually refer to any
+instance of the structure. Trying to use a field of a null reference
+will cause an error.
+
+ The function `bool alias(T,T)' checks to see if two structure
+references refer to the same instance of the structure (or both to
+`null'). For example, in the example code at the start of the section,
+`alias(foo,bar)' would return true, but `alias(foo,new T)' would return
+false, as `new T' creates a new instance of the structure `T'. The
+boolean operators `==' and `!=' are by default equivalent to `alias' and
+`!alias' respectively, but may be overwritten for a particular type
+(for example, to do a deep comparison).
+
+ After the definition of a structure `T', a variable of type `T' is
+initialized to a new instance (`new T') by default. During the
+definition of the structure, however, variables of type `T' are
+initialized to `null' by default. This special behaviour is to avoid
+infinite recursion of creating new instances in code such as
+
+struct tree {
+ int value;
+ tree left;
+ tree right;
+}
+
+ Here is a simple example that illustrates the use of structures:
+
+struct S {
+ real a=1;
+ real f(real a) {return a+this.a;}
+}
+
+S s; // Initializes s with new S;
+
+write(s.f(2)); // Outputs 3
+
+S operator + (S s1, S s2)
+{
+ S result;
+ result.a=s1.a+s2.a;
+ return result;
+}
+
+write((s+s).f(0)); // Outputs 2
+
+ It is often convenient to have functions that construct new
+instances of a structure. Say we have a `Person' structure:
+
+struct Person {
+ string firstname;
+ string lastname;
+}
+
+Person joe=new Person;
+joe.firstname="Joe";
+joe.lastname="Jones";
+ Creating a new Person is a chore; it takes three lines to create a new
+instance and to initialize its fields (that's still considerably less
+effort than creating a new person in real life, though).
+
+ We can reduce the work by defining a constructor function
+`Person(string,string)':
+
+struct Person {
+ string firstname;
+ string lastname;
+
+ static Person Person(string firstname, string lastname) {
+ Person p=new Person;
+ p.firstname=firstname;
+ p.lastname=lastname;
+ return p;
+ }
+}
+
+Person joe=Person.Person("Joe", "Jones");
+
+ While it is now easier than before to create a new instance, we still
+have to refer to the constructor by the qualified name `Person.Person'.
+If we add the line
+
+from Person unravel Person;
+ immediately after the structure definition, then the constructor can
+be used without qualification: `Person joe=Person("Joe", "Jones");'.
+
+ The constructor is now easy to use, but it is quite a hassle to
+define. If you write a lot of constructors, you will find that you are
+repeating a lot of code in each of them. Fortunately, your friendly
+neighbourhood Asymptote developers have devised a way to automate much
+of the process.
+
+ If, in the body of a structure, Asymptote encounters the definition
+of a function of the form `void operator init(ARGS)', it implicitly
+defines a constructor function of the arguments `ARGS' that uses the
+`void operator init' function to initialize a new instance of the
+structure. That is, it essentially defines the following constructor
+(assuming the structure is called `Foo'):
+
+ static Foo Foo(ARGS) {
+ Foo instance=new Foo;
+ instance.operator init(ARGS);
+ return instance;
+ }
+
+ This constructor is also implicitly copied to the enclosing scope
+after the end of the structure definition, so that it can used
+subsequently without qualifying it by the structure name. Our `Person'
+example can thus be implemented as:
+
+struct Person {
+ string firstname;
+ string lastname;
+
+ void operator init(string firstname, string lastname) {
+ this.firstname=firstname;
+ this.lastname=lastname;
+ }
+}
+
+Person joe=Person("Joe", "Jones");
+
+ The use of `operator init' to implicitly define constructors should
+not be confused with its use to define default values for variables
+(*note Variable initializers::). Indeed, in the first case, the return
+type of the `operator init' must be `void' while in the second, it must
+be the (non-`void') type of the variable.
+
+ The function `cputime()' returns a structure `cputime' with
+cumulative CPU times broken down into the fields `parent.user',
+`parent.system', `child.user', and `child.system'. For convenience, the
+incremental fields `change.user' and `change.system' indicate the
+change in the corresponding total parent and child CPU times since the
+last call to `cputime()'. The function
+void write(file file=stdout, string s="", cputime c,
+ string format=cputimeformat, suffix suffix=none);
+ displays the incremental user cputime followed by "u", the incremental
+system cputime followed by "s", the total user cputime followed by "U",
+and the total system cputime followed by "S".
+
+ Much like in C++, casting (*note Casts::) provides for an elegant
+implementation of structure inheritance, including virtual functions:
+struct parent {
+ real x=1;
+ void virtual(int) {write (0);}
+ void f() {virtual(1);}
+}
+
+void write(parent p) {write(p.x);}
+
+struct child {
+ parent parent;
+ real y=2;
+ void virtual(int x) {write (x);}
+ parent.virtual=virtual;
+ void f()=parent.f;
+}
+
+parent operator cast(child child) {return child.parent;}
+
+parent p;
+child c;
+
+write(c); // Outputs 1;
+
+p.f(); // Outputs 0;
+c.f(); // Outputs 1;
+
+write(c.parent.x); // Outputs 1;
+write(c.y); // Outputs 2;
+
+ For further examples of structures, see `Legend' and `picture' in
+the `Asymptote' base module `plain'.
+
+
+File: asymptote.info, Node: Operators, Next: Implicit scaling, Prev: Structures, Up: Programming
+
+5.9 Operators
+=============
+
+* Menu:
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+
+File: asymptote.info, Node: Arithmetic & logical, Next: Self & prefix operators, Up: Operators
+
+5.9.1 Arithmetic & logical operators
+------------------------------------
+
+`Asymptote' uses the standard binary arithmetic operators. However,
+when one integer is divided by another, both arguments are converted to
+real values before dividing and a real quotient is returned (since this
+is usually what is intended). The function `int quotient(int x, int y)'
+returns the greatest integer less than or equal to `x/y'. In all other
+cases both operands are promoted to the same type, which will also be
+the type of the result:
+`+'
+ addition
+
+`-'
+ subtraction
+
+`*'
+ multiplication
+
+`/'
+ division
+
+`%'
+ modulo; the result always has the same sign as the divisor. In
+ particular, this makes `q*quotient(p,q)+p%q == p' for all integers
+ `p' and nonzero integers `q'.
+
+`^'
+ power; if the exponent (second argument) is an int, recursive
+ multiplication is used; otherwise, logarithms and exponentials are
+ used (`**' is a synonym for `^').
+
+
+ The usual boolean operators are also defined:
+`=='
+ equals
+
+`!='
+ not equals
+
+`<'
+ less than
+
+`<='
+ less than or equals
+
+`>='
+ greater than or equals
+
+`>'
+ greater than
+
+`&&'
+ and (with conditional evaluation of right-hand argument)
+
+`&'
+ and
+
+`||'
+ or (with conditional evaluation of right-hand argument)
+
+`|'
+ or
+
+`^'
+ xor
+
+`!'
+ not
+
+ `Asymptote' also supports the C-like conditional syntax:
+bool positive=(pi >= 0) ? true : false;
+
+ The function `T interp(T a, T b, real t)' returns `(1-t)*a+t*b' for
+nonintegral built-in arithmetic types `T'. If `a' and `b' are pens,
+they are first promoted to the same color space.
+
+ `Asymptote' also defines bitwise functions `int AND(int,int)', `int
+OR(int,int)', `int XOR(int,int)', and `int NOT(int)'.
+
+
+File: asymptote.info, Node: Self & prefix operators, Next: User-defined operators, Prev: Arithmetic & logical, Up: Operators
+
+5.9.2 Self & prefix operators
+-----------------------------
+
+As in C, each of the arithmetic operators `+', `-', `*', `/', `%', and
+`^' can be used as a self operator. The prefix operators `++'
+(increment by one) and `--' (decrement by one) are also defined. For
+example,
+int i=1;
+i += 2;
+int j=++i;
+
+is equivalent to the code
+int i=1;
+i=i+2;
+int j=i=i+1;
+
+ However, postfix operators like `i++' and `i--' are not defined
+(because of the inherent ambiguities that would arise with the `--'
+path-joining operator). In the rare instances where `i++' and `i--' are
+really needed, one can substitute the expressions `(++i-1)' and
+`(--i+1)', respectively.
+
+
+File: asymptote.info, Node: User-defined operators, Prev: Self & prefix operators, Up: Operators
+
+5.9.3 User-defined operators
+----------------------------
+
+The following symbols may be used with `operator' to define or redefine
+operators on structures and built-in types:
+- + * / % ^ ! < > == != <= >= & | ^^ .. :: -- --- ++
+<< >> $ $$ @ @@
+ The operators on the second line have precedence one higher than the
+boolean operators `<', `>', `<=', and `>='.
+
+ Guide operators like `..' may be overloaded, say, to write a user
+function that produces a new guide from a given guide:
+guide dots(... guide[] g)=operator ..;
+
+guide operator ..(... guide[] g) {
+ guide G;
+ if(g.length > 0) {
+ write(g[0]);
+ G=g[0];
+ }
+ for(int i=1; i < g.length; ++i) {
+ write(g[i]);
+ write();
+ G=dots(G,g[i]);
+ }
+ return G;
+}
+
+guide g=(0,0){up}..{SW}(100,100){NE}..{curl 3}(50,50)..(10,10);
+write("g=",g);
+
+
+File: asymptote.info, Node: Implicit scaling, Next: Functions, Prev: Operators, Up: Programming
+
+5.10 Implicit scaling
+=====================
+
+If a numeric literal is in front of certain types of expressions, then
+the two are multiplied:
+int x=2;
+real y=2.0;
+real cm=72/2.540005;
+
+write(3x);
+write(2.5x);
+write(3y);
+write(-1.602e-19 y);
+write(0.5(x,y));
+write(2x^2);
+write(3x+2y);
+write(3(x+2y));
+write(3sin(x));
+write(3(sin(x))^2);
+write(10cm);
+
+ This produces the output
+6
+5
+6
+-3.204e-19
+(1,1)
+8
+10
+18
+2.72789228047704
+2.48046543129542
+283.464008929116
+
+
+File: asymptote.info, Node: Functions, Next: Arrays, Prev: Implicit scaling, Up: Programming
+
+5.11 Functions
+==============
+
+`Asymptote' functions are treated as variables with a signature
+(non-function variables have null signatures). Variables with the same
+name are allowed, so long as they have distinct signatures.
+
+ Functions arguments are passed by value. To pass an argument by
+reference, simply enclose it in a structure (*note Structures::).
+
+ Here are some significant features of `Asymptote' functions:
+
+ 1. Variables with signatures (functions) and without signatures
+ (nonfunction variables) are distinct: int x, x();
+ x=5;
+ x=new int() {return 17;};
+ x=x(); // calls x() and puts the result, 17, in the scalar x
+
+ 2. Traditional function definitions are allowed: int sqr(int x)
+ {
+ return x*x;
+ }
+ sqr=null; // but the function is still just a variable.
+
+ 3. Casting can be used to resolve ambiguities: int a, a(), b, b(); // Valid: creates four variables.
+ a=b; // Invalid: assignment is ambiguous.
+ a=(int) b; // Valid: resolves ambiguity.
+ (int) (a=b); // Valid: resolves ambiguity.
+ (int) a=b; // Invalid: cast expressions cannot be L-values.
+
+ int c();
+ c=a; // Valid: only one possible assignment.
+
+ 4. Anonymous (so-called "high-order") functions are also allowed: typedef int intop(int);
+ intop adder(int m)
+ {
+ return new int(int n) {return m+n;};
+ }
+ intop addby7=adder(7);
+ write(addby7(1)); // Writes 8.
+
+ 5. One may redefine a function `f', even for calls to `f' in
+ previously declared functions, by assigning another (anonymous or
+ named) function to it. However, if `f' is overloaded by a new
+ function definition, previous calls will still access the original
+ version of `f', as illustrated in this example: void f() {
+ write("hi");
+ }
+
+ void g() {
+ f();
+ }
+
+ g(); // writes "hi"
+
+ f=new void() {write("bye");};
+
+ g(); // writes "bye"
+
+ void f() {write("overloaded");};
+
+ f(); // writes "overloaded"
+ g(); // writes "bye"
+
+ 6. Anonymous functions can be used to redefine a function variable
+ that has been declared (and implicitly initialized to the null
+ function) but not yet explicitly defined: void f(bool b);
+
+ void g(bool b) {
+ if(b) f(b);
+ else write(b);
+ }
+
+ f=new void(bool b) {
+ write(b);
+ g(false);
+ };
+
+ g(true); // Writes true, then writes false.
+
+
+ `Asymptote' is the only language we know of that treats functions as
+variables, but allows overloading by distinguishing variables based on
+their signatures.
+
+ Functions are allowed to call themselves recursively. As in C++,
+infinite nested recursion will generate a stack overflow (reported as a
+segmentation fault, unless a fully working version of the GNU library
+`libsigsegv' (e.g. 2.4 or later) is installed at configuration time).
+
+* Menu:
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+
+File: asymptote.info, Node: Default arguments, Next: Named arguments, Up: Functions
+
+5.11.1 Default arguments
+------------------------
+
+`Asymptote' supports a more flexible mechanism for default function
+arguments than C++: they may appear anywhere in the function prototype.
+Because certain data types are implicitly cast to more sophisticated
+types (*note Casts::) one can often avoid ambiguities by ordering
+function arguments from the simplest to the most complicated. For
+example, given
+real f(int a=1, real b=0) {return a+b;}
+ then `f(1)' returns 1.0, but `f(1.0)' returns 2.0.
+
+ The value of a default argument is determined by evaluating the
+given `Asymptote' expression in the scope where the called function is
+defined.
+
+
+File: asymptote.info, Node: Named arguments, Next: Rest arguments, Prev: Default arguments, Up: Functions
+
+5.11.2 Named arguments
+----------------------
+
+It is sometimes difficult to remember the order in which arguments
+appear in a function declaration. Named (keyword) arguments make calling
+functions with multiple arguments easier. Unlike in the C and C++
+languages, an assignment in a function argument is interpreted as an
+assignment to a parameter of the same name in the function signature,
+_not within the local scope_. The command-line option `-d' may be used
+to check `Asymptote' code for cases where a named argument may be
+mistaken for a local assignment.
+
+ When matching arguments to signatures, first all of the keywords are
+matched, then the arguments without names are matched against the
+unmatched formals as usual. For example,
+int f(int x, int y) {
+ return 10x+y;
+}
+write(f(4,x=3));
+ outputs 34, as `x' is already matched when we try to match the unnamed
+argument `4', so it gets matched to the next item, `y'.
+
+ For the rare occasions where it is desirable to assign a value to
+local variable within a function argument (generally _not_ a good
+programming practice), simply enclose the assignment in parentheses.
+For example, given the definition of `f' in the previous example,
+int x;
+write(f(4,(x=3)));
+ is equivalent to the statements
+int x;
+x=3;
+write(f(4,3));
+ and outputs 43.
+
+ As a technical detail, we point out that, since variables of the same
+name but different signatures are allowed in the same scope, the code
+int f(int x, int x()) {
+ return x+x();
+}
+int seven() {return 7;}
+ is legal in `Asymptote', with `f(2,seven)' returning 9. A named
+argument matches the first unmatched formal of the same name, so
+`f(x=2,x=seven)' is an equivalent call, but `f(x=seven,2)' is not, as
+the first argument is matched to the first formal, and `int ()' cannot
+be implicitly cast to `int'. Default arguments do not affect which
+formal a named argument is matched to, so if `f' were defined as
+int f(int x=3, int x()) {
+ return x+x();
+}
+ then `f(x=seven)' would be illegal, even though `f(seven)' obviously
+would be allowed.
+
+
+File: asymptote.info, Node: Rest arguments, Next: Mathematical functions, Prev: Named arguments, Up: Functions
+
+5.11.3 Rest arguments
+---------------------
+
+Rest arguments allow one to write functions that take a variable number
+of arguments:
+// This function sums its arguments.
+int sum(... int[] nums) {
+ int total=0;
+ for(int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+
+// This function subtracts subsequent arguments from the first.
+int subtract(int start ... int[] subs) {
+ for(int i=0; i < subs.length; ++i)
+ start -= subs[i];
+ return start;
+}
+
+subtract(10,1,2); // returns 7
+subtract(10); // returns 10
+subtract(); // illegal
+
+ Putting an argument into a rest array is called _packing_. One can
+give an explicit list of arguments for the rest argument, so `subtract'
+could alternatively be implemented as
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+
+ One can even combine normal arguments with rest arguments:
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+ This builds a new six-element array that is passed to `sum' as `nums'.
+The opposite operation, _unpacking_, is not allowed:
+subtract(... new int[] {10, 1, 2});
+ is illegal, as the start formal is not matched.
+
+ If no arguments are packed, then a zero-length array (as opposed to
+`null') is bound to the rest parameter. Note that default arguments are
+ignored for rest formals and the rest argument is not bound to a
+keyword.
+
+ The overloading resolution in `Asymptote' is similar to the function
+matching rules used in C++. Every argument match is given a score.
+Exact matches score better than matches with casting, and matches with
+formals (regardless of casting) score better than packing an argument
+into the rest array. A candidate is maximal if all of the arguments
+score as well in it as with any other candidate. If there is one
+unique maximal candidate, it is chosen; otherwise, there is an
+ambiguity error.
+
+int f(path g);
+int f(guide g);
+f((0,0)--(100,100)); // matches the second; the argument is a guide
+
+int g(int x, real y);
+int g(real x, int x);
+
+g(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second argument
+
+int h(... int[] rest);
+int h(real x ... int[] rest);
+
+h(1,2); // the second definition matches, even though there is a cast,
+ // because casting is preferred over packing
+
+int i(int x ... int[] rest);
+int i(real x, real y ... int[] rest);
+
+i(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second one
+
+
+File: asymptote.info, Node: Mathematical functions, Prev: Rest arguments, Up: Functions
+
+5.11.4 Mathematical functions
+-----------------------------
+
+`Asymptote' has built-in versions of the standard `libm' mathematical
+real(real) functions `sin', `cos', `tan', `asin', `acos', `atan',
+`exp', `log', `pow10', `log10', `sinh', `cosh', `tanh', `asinh',
+`acosh', `atanh', `sqrt', `cbrt', `fabs', `expm1', `log1p', as well as
+the identity function `identity'. `Asymptote' also defines the order
+`n' Bessel functions of the first kind `J(int n, real)' and second kind
+`Y(int n, real)', as well as the gamma function `gamma', the error
+function `erf', and the complementary error function `erfc'. The
+standard real(real, real) functions `atan2', `hypot', `fmod',
+`remainder' are also included.
+
+ The functions `degrees(real radians)' and `radians(real degrees)'
+can be used to convert between radians and degrees. The function
+`Degrees(real radians)' returns the angle in degrees in the interval
+[0,360). For convenience, `Asymptote' defines variants `Sin', `Cos',
+`Tan', `aSin', `aCos', and `aTan' of the standard trigonometric
+functions that use degrees rather than radians. We also define complex
+versions of the `sqrt', `sin', `cos', `exp', `log', and `gamma'
+functions.
+
+ The functions `floor', `ceil', and `round' differ from their usual
+definitions in that they all return an int value rather than a real
+(since that is normally what one wants). The functions `Floor',
+`Ceil', and `Round' are respectively similar, except that if the result
+cannot be converted to a valid int, they return `intMax' for positive
+arguments and `intMin' for negative arguments, rather than generating
+an integer overflow. We also define a function `sgn', which returns
+the sign of its real argument as an integer (-1, 0, or 1).
+
+ There is an `abs(int)' function, as well as an `abs(real)' function
+(equivalent to `fabs(real)'), an `abs(pair)' function (equivalent to
+`length(pair)').
+
+ Random numbers can be seeded with `srand(int)' and generated with
+the `int rand()' function, which returns a random integer between 0 and
+the integer `randMax'. The `unitrand()' function returns a random
+number uniformly distributed in the interval [0,1]. A Gaussian random
+number generator `Gaussrand' and a collection of statistics routines,
+including `histogram', are provided in the base file `stats.asy'. The
+functions `factorial(int n)', which returns n!, and `choose(int n, int
+k)', which returns n!/(k!(n-k)!), are also defined.
+
+ When configured with the GNU Scientific Library (GSL), available from
+`http://www.gnu.org/software/gsl/', `Asymptote' contains an internal
+module `gsl' that defines the airy functions `Ai(real)', `Bi(real)',
+`Ai_deriv(real)', `Bi_deriv(real)', `zero_Ai(int)', `zero_Bi(int)',
+`zero_Ai_deriv(int)', `zero_Bi_deriv(int)', the Bessel functions
+`I(int, real)', `K(int, real)', `j(int, real)', `y(int, real)',
+`i_scaled(int, real)', `k_scaled(int, real)', `J(real, real)', `Y(real,
+real)', `I(real, real)', `K(real, real)', `zero_J(real, int)', the
+elliptic functions `F(real, real)', `E(real, real)', and `P(real,
+real)', the exponential/trigonometric integrals `Ei', `Si', and `Ci',
+the Legendre polynomials `Pl(int, real)', and the Riemann zeta function
+`zeta(real)'. For example, to compute the sine integral `Si' of 1.0:
+import gsl;
+write(Si(1.0));
+
+ `Asymptote' also provides a few general purpose numerical routines:
+
+``real newton(int iterations=100, real f(real), real fprime(real), real x, bool verbose=false);''
+ Use Newton-Raphson iteration to solve for a root of a real-valued
+ differentiable function `f', given its derivative `fprime' and an
+ initial guess `x'. Diagnostics for each iteration are printed if
+ `verbose=true'. If the iteration fails after the maximum allowed
+ number of loops (`iterations'), `realMax' is returned.
+
+``real newton(int iterations=100, real f(real), real fprime(real), real x1, real x2, bool verbose=false);''
+ Use bracketed Newton-Raphson bisection to solve for a root of a
+ real-valued differentiable function `f' within an interval
+ [`x1',`x2'] (on which the endpoint values of `f' have opposite
+ signs), given its derivative `fprime'. Diagnostics for each
+ iteration are printed if `verbose=true'. If the iteration fails
+ after the maximum allowed number of loops (`iterations'),
+ `realMax' is returned.
+
+``real simpson(real f(real), real a, real b, real acc=realEpsilon, real dxmax=b-a)''
+ returns the integral of `f' from `a' to `b' using adaptive Simpson
+ integration.
+
+
+
+File: asymptote.info, Node: Arrays, Next: Casts, Prev: Functions, Up: Programming
+
+5.12 Arrays
+===========
+
+* Menu:
+
+* Slices:: Python-style array slices
+
+ Appending `[]' to a built-in or user-defined type yields an array.
+The array element `i' of an array `A' can be accessed as `A[i]'. By
+default, attempts to access or assign to an array element using a
+negative index generates an error. Reading an array element with an
+index beyond the length of the array also generates an error; however,
+assignment to an element beyond the length of the array causes the
+array to be resized to accommodate the new element. One can also index
+an array `A' with an integer array `B': the array `A[B]' is formed by
+indexing array `A' with successive elements of array `B'. A convenient
+Java-style shorthand exists for iterating over all elements of an
+array; see *note array iteration::.
+
+ The declaration
+real[] A;
+
+initializes `A' to be an empty (zero-length) array. Empty arrays should
+be distinguished from null arrays. If we say
+real[] A=null;
+
+then `A' cannot be dereferenced at all (null arrays have no length and
+cannot be read from or assigned to).
+
+ Arrays can be explicitly initialized like this:
+real[] A={0,1,2};
+
+ Array assignment in `Asymptote' does a shallow copy: only the
+pointer is copied (if one copy if modified, the other will be too).
+The `copy' function listed below provides a deep copy of an array.
+
+ Every array `A' of type `T[]' has the virtual members
+ * `int length',
+
+ * `void cyclic(bool b)',
+
+ * `bool cyclicflag',
+
+ * `int[] keys',
+
+ * `T push(T x)',
+
+ * `void append(T[] a)',
+
+ * `T pop()',
+
+ * `void insert(int i ... T[] x)',
+
+ * `void delete(int i, int j=i)',
+
+ * `void delete()', and
+
+ * `bool initialized(int n)'.
+
+ The member `A.length' evaluates to the length of the array. Setting
+`A.cyclic(true)' signifies that array indices should be reduced modulo
+the current array length. Reading from or writing to a nonempty cyclic
+array never leads to out-of-bounds errors or array resizing. The member
+`A.cyclicflag' returns the current setting of the `cyclic' flag.
+
+ The member `A.keys' evaluates to an array of integers containing the
+indices of initialized entries in the array in ascending order. Hence,
+for an array of length `n' with all entries initialized, `A.keys'
+evaluates to the array of integers from `0' to `n-1' inclusive. A new
+keys array is produced each time `A.keys' is evaluated.
+
+ The functions `A.push' and `A.append' append their arguments onto
+the end of the array, while `A.insert(int i ... T[] x)' inserts `x'
+into the array at index `i'. For convenience `A.push' returns the
+pushed item. The function `A.pop()' pops and returns the last element,
+while `A.delete(int i, int j=i)' deletes elements with indices in the
+range [`i',`j'], shifting the position of all higher-indexed elements
+down. If no arguments are given, `A.delete()' provides a convenient way
+of deleting all elements of `A'. The routine `A.initialized(int n)' can
+be used to examine whether the element at index `n' is initialized.
+Like all `Asymptote' functions, `cyclic', `push', `append', `pop',
+`insert', `delete', and `initialized' can be "pulled off" of the array
+and used on their own. For example,
+int[] A={1};
+A.push(2); // A now contains {1,2}.
+A.append(A); // A now contains {1,2,1,2}.
+int f(int)=A.push;
+f(3); // A now contains {1,2,1,2,3}.
+int g()=A.pop;
+write(g()); // Outputs 3.
+A.delete(0); // A now contains {2,1,2}.
+A.delete(0,1); // A now contains {2}.
+A.insert(1,3); // A now contains {2,3}.
+A.insert(1 ... A); // A now contains {2,2,3,3}
+A.insert(2,4,5); // A now contains {2,2,4,5,3,3}.
+
+ The `[]' suffix can also appear after the variable name; this is
+sometimes convenient for declaring a list of variables and arrays of
+the same type:
+real a,A[];
+ This declares `a' to be `real' and implicitly declares `A' to be of
+type `real[]'.
+
+ In the following list of built-in array functions, `T' represents a
+generic type. Note that the internal functions `alias', `array',
+`copy', `concat', `sequence', `map', and `transpose', which depend on
+type `T[]', are defined only after the first declaration of a variable
+of type `T[]'.
+
+`new T[]'
+ returns a new empty array of type `T[]';
+
+`new T[] {list}'
+ returns a new array of type `T[]' initialized with `list' (a comma
+ delimited list of elements).
+
+`new T[n]'
+ returns a new array of `n' elements of type `T[]'. These `n'
+ array elements are not initialized unless they are arrays
+ themselves (in which case they are each initialized to empty
+ arrays).
+
+`T[] array(int n, T value, int depth=intMax)'
+ returns an array consisting of `n' copies of value. By default, if
+ `value' is itself an array, a deep copy of that array is made for
+ each entry in the new array. If `depth' is specified, this deep
+ copying only recurses to the number of levels specified.
+
+`int[] sequence(int n)'
+ if `n >= 1' returns the array `{0,1,...,n-1}' (otherwise returns a
+ null array);
+
+`int[] sequence(int n, int m)'
+ if `m >= n' returns an array `{n,n+1,...,m}' (otherwise returns a
+ null array);
+
+`T[] sequence(T f(int), int n)'
+ if `n >= 1' returns the sequence `{f_i :i=0,1,...n-1}' given a
+ function `T f(int)' and integer `int n' (otherwise returns a null
+ array);
+
+`T[] map(T f(T), T[] a)'
+ returns the array obtained by applying the function `f' to each
+ element of the array `a'. This is equivalent to `sequence(new
+ T(int i) {return f(a[i]);},a.length)'.
+
+`int[] reverse(int n)'
+ if `n >= 1' returns the array `{n-1,n-2,...,0}' (otherwise returns
+ a null array);
+
+`int[] complement(int[] a, int n)'
+ returns the complement of the integer array `a' in
+ `{0,1,2,...,n-1}', so that `b[complement(a,b.length)]' yields the
+ complement of `b[a]'.
+
+`real[] uniform(real a, real b, int n)'
+ if `n >= 1' returns a uniform partition of `[a,b]' into `n'
+ subintervals (otherwise returns a null array);
+
+`int find(bool[], int n=1)'
+ returns the index of the `n'th `true' value or -1 if not found.
+ If `n' is negative, search backwards from the end of the array for
+ the `-n'th value;
+
+`int search(T[] a, T key)'
+ For built-in ordered types `T', searches a sorted ordered array
+ `a' of `n' elements to find an interval containing `key',
+ returning `-1' if `key' is less than the first element, `n-1' if
+ `key' is greater than or equal to the last element, and otherwise
+ the index corresponding to the left-hand (smaller) endpoint.
+
+`T[] copy(T[] a)'
+ returns a deep copy of the array `a';
+
+`T[][] copy(T[][] a)'
+ returns a deep copy of the array `a';
+
+`T[][][] copy(T[][][] a)'
+ returns a deep copy of the array `a';
+
+`T[] concat(... T[][] a)'
+ returns a new array formed by concatenating the arrays given as
+ arguments;
+
+`bool alias(T[] a, T[] b)'
+ returns `true' if the arrays `a' and `b' are identical;
+
+`T[] sort(T[] a)'
+ For built-in ordered types `T', returns a copy of `a' sorted in
+ ascending order;
+
+`T[][] sort(T[][] a)'
+ For built-in ordered types `T', returns a copy of `a' with the rows
+ sorted by the first column, breaking ties with successively higher
+ columns. For example: string[][] a={{"bob","9"},{"alice","5"},{"pete","7"},
+ {"alice","4"}};
+ // Row sort (by column 0, using column 1 to break ties):
+ write(sort(a));
+
+ produces alice 4
+ alice 5
+ bob 9
+ pete 7
+
+`T[] sort(T[] a, bool compare(T i, T j))'
+ returns a copy of `a' stably sorted in ascending order such that
+ element `i' precedes element `j' if `compare(i,j)' is true.
+
+`T[][] transpose(T[][] a)'
+ returns the transpose of `a'.
+
+`T[][][] transpose(T[][][] a, int[] perm)'
+ returns the 3D transpose of `a' obtained by applying the
+ permutation `perm' of `new int[]{0,1,2}' to the indices of each
+ entry.
+
+`T sum(T[] a)'
+ For arithmetic types `T', returns the sum of `a'. In the case
+ where `T' is `bool', the number of true elements in `a' is
+ returned.
+
+`T min(T[] a)'
+
+`T min(T[][] a)'
+
+`T min(T[][][] a)'
+ For built-in ordered types `T', returns the minimum element of `a'.
+
+`T max(T[] a)'
+
+`T max(T[][] a)'
+
+`T max(T[][][] a)'
+ For built-in ordered types `T', returns the maximum element of `a'.
+
+`T[] min(T[] a, T[] b)'
+ For built-in ordered types `T', and arrays `a' and `b' of the same
+ length, returns an array composed of the minimum of the
+ corresponding elements of `a' and `b'.
+
+`T[] max(T[] a, T[] b)'
+ For built-in ordered types `T', and arrays `a' and `b' of the same
+ length, returns an array composed of the maximum of the
+ corresponding elements of `a' and `b'.
+
+`pair[] pairs(real[] x, real[] y);'
+ For arrays `x' and `y' of the same length, returns the pair array
+ `sequence(new pair(int i) {return (x[i],y[i]);},x.length)'.
+
+`pair[] fft(pair[] a, int sign=1)'
+ returns the Fast Fourier Transform of `a' (if the optional `FFTW'
+ package is installed), using the given `sign'. Here is a simple
+ example: int n=4;
+ pair[] f=sequence(n);
+ write(f);
+ pair[] g=fft(f,-1);
+ write();
+ write(g);
+ f=fft(g,1);
+ write();
+ write(f/n);
+
+`real dot(real[] a, real[] b)'
+ returns the dot product of the vectors `a' and `b'.
+
+`real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);'
+ Solve the periodic tridiagonal problem L`x'=`f' and return the
+ solution `x', where `f' is an n vector and L is the n \times n
+ matrix [ b[0] c[0] a[0] ]
+ [ a[1] b[1] c[1] ]
+ [ a[2] b[2] c[2] ]
+ [ ... ]
+ [ c[n-1] a[n-1] b[n-1] ]
+ For Dirichlet boundary conditions (denoted here by `u[-1]' and
+ `u[n]'), replace `f[0]' by `f[0]-a[0]u[-1]' and
+ `f[n-1]-c[n-1]u[n]'; then set `a[0]=c[n-1]=0'.
+
+`real[] solve(real[][] a, real[] b, bool warn=true)'
+ Solve the linear equation `a'x=`b' by LU decomposition and return
+ the solution x, where `a' is an n \times n matrix and `b' is an
+ array of length n. For example: import math;
+ real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+ real[] b={7,19,33,3};
+ real[] x=solve(a,b);
+ write(a); write();
+ write(b); write();
+ write(x); write();
+ write(a*x);
+ If `a' is a singular matrix and `warn' is `false', return an
+ empty array. If the matrix `a' is tridiagonal, the routine
+ `tridiagonal' provides a more efficient algorithm (*note
+ tridiagonal::).
+
+`real[][] solve(real[][] a, real[][] b, bool warn=true)'
+ Solve the linear equation `a'x=`b' and return the solution x,
+ where `a' is an n \times n matrix and `b' is an n \times m matrix.
+ If `a' is a singular matrix and `warn' is `false', return an empty
+ matrix.
+
+`real[][] identity(int n);'
+ returns the n \times n identity matrix.
+
+`real[][] diagonal(... real[] a)'
+ returns the diagonal matrix with diagonal entries given by a.
+
+`real[][] inverse(real[][] a)'
+ returns the inverse of a square matrix `a'.
+
+``real[] quadraticroots(real a, real b, real c);''
+ This numerically robust solver returns the real roots of the
+ quadratic equation ax^2+bx+c=0, in ascending order. Multiple roots
+ are listed separately.
+
+``pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);''
+ This numerically robust solver returns the two complex roots of the
+ quadratic equation ax^2+bx+c=0.
+
+``real[] cubicroots(real a, real b, real c, real d);''
+ This numerically robust solver returns the real roots of the cubic
+ equation ax^3+bx^2+cx+d=0. Multiple roots are listed separately.
+
+
+ `Asymptote' includes a full set of vectorized array instructions for
+arithmetic (including self) and logical operations. These
+element-by-element instructions are implemented in C++ code for speed.
+Given
+real[] a={1,2};
+real[] b={3,2};
+ then `a == b' and `a >= 2' both evaluate to the vector `{false, true}'. To
+test whether all components of `a' and `b' agree, use the boolean
+function `all(a == b)'. One can also use conditionals like `(a >= 2) ?
+a : b', which returns the array `{3,2}', or `write((a >= 2) ? a :
+null', which returns the array `{2}'.
+
+ All of the standard built-in `libm' functions of signature
+`real(real)' also take a real array as an argument, effectively like an
+implicit call to `map'.
+
+ As with other built-in types, arrays of the basic data types can be
+read in by assignment. In this example, the code
+file fin=input("test.txt");
+real[] A=fin;
+
+reads real values into `A' until the end-of-file is reached (or an I/O
+error occurs). If line mode is set with `line(file)', then reading will
+stop once the end of the line is reached instead (line mode may be
+cleared with `line(file,false)'):
+file fin=input("test.txt");
+real[] A=line(fin);
+
+ Since string reads by default read up to the end of line anyway,
+line mode normally has no effect on string array reads. However, there
+is a white-space delimiter mode for reading strings, set with
+`word(file)' and cleared with `word(file,false)', which causes string
+reads to respect white-space delimiters, instead of the default
+end-of-line delimiter:
+file fin=word(line(input("test.txt")));
+real[] A=fin;
+
+ Another useful mode is comma-separated-value mode, set with
+`csv(file)' and cleared with `csv(file,false)', which causes reads to
+respect comma delimiters:
+file fin=csv(input("test.txt"));
+real[] A=fin;
+
+ To restrict the number of values read, use the `dimension(file,int)'
+function:
+file fin=input("test.txt");
+real[] A=dimension(fin,10);
+
+ This reads 10 values into A, unless end-of-file (or end-of-line in
+line mode) occurs first. Attempting to read beyond the end of the file
+will produce a runtime error message. Specifying a value of 0 for the
+integer limit is equivalent to the previous example of reading until
+end-of-file (or end-of-line in line mode) is encountered.
+
+ Two- and three-dimensional arrays of the basic data types can be read
+in like this:
+file fin=input("test.txt");
+real[][] A=dimension(fin,2,3);
+real[][][] B=dimension(fin,2,3,4);
+ Again, an integer limit of zero means no restriction.
+
+ Sometimes the array dimensions are stored with the data as integer
+fields at the beginning of an array. Such arrays can be read in with the
+functions `read1', `read2', and `read3', respectively:
+file fin=input("test.txt");
+real[] A=read1(fin);
+real[][] B=read2(fin);
+real[][][] C=read3(fin);
+
+ One, two, and three-dimensional arrays of the basic data types can be
+output with the functions `write(file,T[])', `write(file,T[][])',
+`write(file,T[][][])', respectively.
+
+
+File: asymptote.info, Node: Slices, Up: Arrays
+
+5.12.1 Slices
+-------------
+
+Asymptote allows a section of an array to be addressed as a slice using
+a Python-like syntax. If `A' is an array, the expression `A[m:n]'
+returns a new array consisting of the elements of `A' with indices from
+`m' up to but not including `n'. For example,
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[2:6]; // y={2,3,4,5};
+int[] z=x[5:10]; // z={5,6,7,8,9};
+
+ If the left index is omitted, it is taken be `0'. If the right
+index is omitted it is taken to be the length of the array. If both
+are omitted, the slice then goes from the start of the array to the
+end, producing a non-cyclic deep copy of the array. For example:
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[:4]; // y={0,1,2,3}
+int[] z=x[5:]; // z={5,6,7,8,9}
+int[] w=x[:]; // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
+
+ If A is a non-cyclic array, it is illegal to use negative values for
+either of the indices. If the indices exceed the length of the array,
+however, they are politely truncated to that length.
+
+ For cyclic arrays, the slice `A[m:n]' still consists of the cells
+with indices in the set [`m',`n'), but now negative values and values
+beyond the length of the array are allowed. The indices simply wrap
+around. For example:
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+x.cyclic(true);
+int[] y=x[8:15]; // y={8,9,0,1,2,3,4}.
+int[] z=x[-5:5]; // z={5,6,7,8,9,0,1,2,3,4}
+int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
+
+ Notice that with cyclic arrays, it is possible to include the same
+element of the original array multiple times within a slice.
+Regardless of the original array, arrays produced by slices are always
+non-cyclic.
+
+ If the left and right indices of a slice are the same, the result is
+an empty array. If the array being sliced is empty, the result is an
+empty array. Any slice with a left index greater than its right index
+will yield an error.
+
+ Slices can also be assigned to, changing the value of the original
+array. If the array being assigned to the slice has a different length
+than the slice itself, elements will be inserted or removed from the
+array to accommodate it. For instance:
+
+string[] toppings={"mayo", "salt", "ham", "lettuce"};
+toppings[0:2]=new string[] {"mustard", "pepper"};
+ // Now toppings={"mustard", "pepper", "ham", "lettuce"}
+toppings[2:3]=new string[] {"turkey", "bacon" };
+ // Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
+toppings[0:3]=new string[] {"tomato"};
+ // Now toppings={"tomato", "bacon", "lettuce"}
+
+ If an array is assigned to a slice of itself, a copy of the original
+array is assigned to the slice. That is, code such as `x[m:n]=x' is
+equivalent to `x[m:n]=copy(x)'. One can use the shorthand `x[m:m]=y'
+to insert the contents of the array `y' into the array `x' starting at
+the location just before `x[m]'.
+
+ For a cyclic array, a slice is bridging if it addresses cells up to
+the end of the array and then continues on to address cells at the
+start of the array. For instance, if `A' is a cyclic array of length
+10, `A[8:12]', `A[-3:1]', and `A[5:25]' are bridging slices whereas
+`A[3:7]', `A[7:10]', `A[-3:0]' and `A[103:107]' are not. Bridging
+slices can only be assigned to if the number of elements in the slice
+is exactly equal to the number of elements we are assigning to it.
+Otherwise, there is no clear way to decide which of the new entries
+should be `A[0]' and an error is reported. Non-bridging slices may be
+assigned an array of any length.
+
+ For a cyclic array `A' an expression of the form
+`A[A.length:A.length]' is equivalent to the expression `A[0:0]' and so
+assigning to this slice will insert values at the start of the array.
+`A.append()' can be used to insert values at the end of the array.
+
+ It is illegal to assign to a slice of a cyclic array that repeats
+any of the cells.
+
+
+File: asymptote.info, Node: Casts, Next: Import, Prev: Arrays, Up: Programming
+
+5.13 Casts
+==========
+
+`Asymptote' implicitly casts `int' to `real', `int' to `pair', `real'
+to `pair', `pair' to `path', `pair' to `guide', `path' to `guide',
+`guide' to `path', `real' to `pen', `pair[]' to `guide[]', `pair[]' to
+`path[]', `path' to `path[]', and `guide' to `path[]', along with
+various three-dimensional casts defined in `three.asy'. Implicit casts
+are automatically attempted on assignment and when trying to match
+function calls with possible function signatures. Implicit casting can
+be inhibited by declaring individual arguments `explicit' in the
+function signature, say to avoid an ambiguous function call in the
+following example, which outputs 0:
+
+int f(pair a) {return 0;}
+int f(explicit real x) {return 1;}
+
+write(f(0));
+
+ Other conversions, say `real' to `int' or `real' to `string',
+require an explicit cast:
+int i=(int) 2.5;
+string s=(string) 2.5;
+
+real[] a={2.5,-3.5};
+int[] b=(int []) a;
+write(stdout,b); // Outputs 2,-3
+
+ Casting to user-defined types is also possible using `operator cast':
+struct rpair {
+ real radius;
+ real angle;
+}
+
+pair operator cast(rpair x) {
+ return (x.radius*cos(x.angle),x.radius*sin(x.angle));
+}
+
+rpair x;
+x.radius=1;
+x.angle=pi/6;
+
+write(x); // Outputs (0.866025403784439,0.5)
+
+ One must use care when defining new cast operators. Suppose that in
+some code one wants all integers to represent multiples of 100. To
+convert them to reals, one would first want to multiply them by 100.
+However, the straightforward implementation
+real operator cast(int x) {return x*100;}
+ is equivalent to an infinite recursion, since the result `x*100' needs
+itself to be cast from an integer to a real. Instead, we want to use
+the standard conversion of int to real:
+real convert(int x) {return x*100;}
+real operator cast(int x)=convert;
+
+ Explicit casts are implemented similarly, with `operator ecast'.
+
+
+File: asymptote.info, Node: Import, Next: Static, Prev: Casts, Up: Programming
+
+5.14 Import
+===========
+
+While `Asymptote' provides many features by default, some applications
+require specialized features contained in external `Asymptote' modules.
+For instance, the lines
+access graph;
+graph.axes();
+ draw x and y axes on a two-dimensional graph. Here, the command looks
+up the module under the name `graph' in a global dictionary of modules
+and puts it in a new variable named `graph'. The module is a
+structure, and we can refer to its fields as we usually would with a
+structure.
+
+ Often, one wants to use module functions without having to specify
+the module name. The code
+from graph access axes;
+ adds the `axes' field of `graph' into the local name space, so that
+subsequently, one can just write `axes()'. If the given name is
+overloaded, all types and variables of that name are added. To add
+more than one name, just use a comma-separated list:
+
+from graph access axes, xaxis, yaxis;
+ Wild card notation can be used to add all non-private fields and types
+of a module to the local name space:
+
+from graph access *;
+
+ Similarly, one can add the non-private fields and types of a
+structure to the local environment with the `unravel' keyword:
+
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
+ Alternatively, one can unravel selective fields:
+real det(matrix m) {
+ from m unravel a,b,c as C,d;
+ return a*d-b*C;
+}
+
+ The command
+import graph;
+ is a convenient abbreviation for the commands
+access graph;
+unravel graph;
+ That is, `import graph' first loads a module into a structure called
+`graph' and then adds its non-private fields and types to the local
+environment. This way, if a member variable (or function) is
+overwritten with a local variable (or function of the same signature),
+the original one can still be accessed by qualifying it with the module
+name.
+
+ Wild card importing will work fine in most cases, but one does not
+usually know all of the internal types and variables of a module, which
+can also change as the module writer adds or changes features of the
+module. As such, it is prudent to add `import' commands at the start
+of an `Asymptote' file, so that imported names won't shadow locally
+defined functions. Still, imported names may shadow other imported
+names, depending on the order in which they were imported, and imported
+functions may cause overloading resolution problems if they have the
+same name as local functions defined later.
+
+ To rename modules or fields when adding them to the local
+environment, use `as':
+
+access graph as graph2d;
+from graph access xaxis as xline, yaxis as yline;
+
+ The command
+import graph as graph2d;
+ is a convenient abbreviation for the commands
+access graph as graph2d;
+unravel graph2d;
+
+ Except for a few built-in modules, such as `settings', all modules
+are implemented as `Asymptote' files. When looking up a module that
+has not yet been loaded, `Asymptote' searches the standard search paths
+(*note Search paths::) for the matching file. The file corresponding
+to that name is read and the code within it is interpreted as the body
+of a structure defining the module.
+
+ If the file name contains nonalphanumeric characters, enclose it
+with quotation marks:
+
+`access "/usr/local/share/asymptote/graph.asy" as graph;'
+
+`from "/usr/local/share/asymptote/graph.asy" access axes;'
+
+`import "/usr/local/share/asymptote/graph.asy" as graph;'
+
+ It is an error if modules import themselves (or each other in a
+cycle). The module name to be imported must be known at compile time.
+
+ However, you can import an `Asymptote' module determined by the
+string `s' at runtime like this:
+eval("import "+s,true);
+
+ To conditionally execute an array of asy files, use
+void asy(string format, bool overwrite ... string[] s);
+ The file will only be processed, using output format `format', if
+overwrite is `true' or the output file is missing.
+
+ One can evaluate an `Asymptote' expression (without any return
+value, however) contained in the string `s' with:
+void eval(string s, bool embedded=false);
+ It is not necessary to terminate the string `s' with a semicolon. If
+`embedded' is `true', the string will be evaluated at the top level of
+the current environment. If `embedded' is `false' (the default), the
+string will be evaluated in an independent environment, sharing the same
+`settings' module (*note settings::).
+
+ One can evaluate arbitrary `Asymptote' code (which may contain
+unescaped quotation marks) with the command
+void eval(code s, bool embedded=false);
+ Here `code' is a special type used with `quote {}' to enclose
+`Asymptote code' like this:
+real a=1;
+code s=quote {
+ write(a);
+};
+eval(s,true); // Outputs 1
+
+ To include the contents of a file `graph' verbatim (as if the
+contents of the file were inserted at that point), use one of the forms:
+include graph;
+
+`include "/usr/local/share/asymptote/graph.asy";'
+
+ To list all global functions and variables defined in a module named
+by the contents of the string `s', use the function
+void list(string s, bool imports=false);
+ Imported global functions and variables are also listed if `imports'
+is `true'.
+
+
+File: asymptote.info, Node: Static, Prev: Import, Up: Programming
+
+5.15 Static
+===========
+
+Static qualifiers allocate the memory address of a variable in a higher
+enclosing level.
+
+ For a function body, the variable is allocated in the block where the
+function is defined; so in the code
+struct s {
+ int count() {
+ static int c=0;
+ ++c;
+ return c;
+ }
+}
+
+there is one instance of the variable `c' for each object `s' (as
+opposed to each call of `count').
+
+ Similarly, in
+int factorial(int n) {
+ int helper(int k) {
+ static int x=1;
+ x *= k;
+ return k == 1 ? x : helper(k-1);
+ }
+ return helper(n);
+}
+
+there is one instance of `x' for every call to `factorial' (and not for
+every call to `helper'), so this is a correct, but ugly, implementation
+of factorial.
+
+ Similarly, a static variable declared within a structure is
+allocated in the block where the structure is defined. Thus,
+struct A {
+ struct B {
+ static pair z;
+ }
+}
+
+creates one object `z' for each object of type `A' created.
+
+ In this example,
+int pow(int n, int k) {
+ struct A {
+ static int x=1;
+ void helper() {
+ x *= n;
+ }
+ }
+ for(int i=0; i < k; ++i) {
+ A a;
+ a.helper();
+ }
+ return A.x;
+}
+
+there is one instance of `x' for each call to `pow', so this is an ugly
+implementation of exponentiation.
+
+ Loop constructs allocate a new frame in every iteration. This is so
+that higher-order functions can refer to variables of a specific
+iteration of a loop:
+
+void f();
+for(int i=0; i < 10; ++i) {
+ int x=i;
+ if(x==5) {
+ f=new void () { write(x); }
+ }
+}
+f();
+
+ Here, every iteration of the loop has its own variable `x', so `f()'
+will write `5'. If a variable in a loop is declared static, it will be
+allocated where the enclosing function or structure was defined (just
+as if it were declared static outside of the loop). For instance, in:
+
+void f() {
+ static int x;
+ for(int i=0; i < 10; ++i) {
+ static int y;
+ }
+}
+ both `x' and `y' will be allocated in the same place, which is also
+where `f' is also allocated.
+
+ Statements may also be declared static, in which case they are run
+at the place where the enclosing function or structure is defined.
+Declarations or statements not enclosed in a function or structure
+definition are already at the top level, so static modifiers are
+meaningless. A warning is given in such a case.
+
+ Since structures can have static fields, it is not always clear for
+a qualified name whether the qualifier is a variable or a type. For
+instance, in:
+
+struct A {
+ static int x;
+}
+pair A;
+
+int y=A.x;
+ does the `A' in `A.x' refer to the structure or to the pair variable.
+It is the convention in Asymptote that, if there is a non-function
+variable with the same name as the qualifier, the qualifier refers to
+that variable, and not to the type. This is regardless of what fields
+the variable actually possesses.
+
+
+File: asymptote.info, Node: LaTeX usage, Next: Base modules, Prev: Programming, Up: Top
+
+6 `LaTeX' usage
+***************
+
+`Asymptote' comes with a convenient `LaTeX' style file `asymptote.sty'
+that makes `LaTeX' `Asymptote'-aware. Entering `Asymptote' code
+directly into the `LaTeX' source file, at the point where it is needed,
+keeps figures organized and avoids the need to invent new file names
+for each figure. Simply add the line `\usepackage{asymptote}' at the
+beginning of your file and enclose your `Asymptote' code within a
+`\begin{asy}...\end{asy}' environment. As with the `LaTeX' `comment'
+environment, the `\end{asy}' command must appear on a line by itself,
+with no leading spaces or trailing commands/comments.
+
+ The sample `LaTeX' file below, named `latexusage.tex', can be run as
+follows:
+latex latexusage
+asy latexusage
+latex latexusage
+
+or
+
+pdflatex latexusage
+asy latexusage
+pdflatex latexusage
+
+ To switch between using `latex' and `pdflatex' you may first need to
+remove the files `latexusage-*', `latexusage_.pre', and
+`latexusage.aux'.
+
+ One can specify `width', `height', `viewportwidth',
+`viewportheight', and `attach' `keyval'-style options to the `asy'
+environment. The current version (1.07) of `asymptote.sty' supports the
+embedding of 3D PRC files, either inline or, using the `attach' option
+with the `attachfile2' (or older `attachfile') `LaTeX' package, as
+annotated (but printable) attachments. For many applications, the
+annotated attachment method tends to be more convenient. The default
+value of `viewportwidth' is `\the\linewidth' for inline 3D figures and
+`0' for attachments.
+
+ If the `inline' option is given to the `asymptote.sty' package,
+inline `LaTeX' code is generated instead of EPS or PDF files. This
+makes LaTeX symbols visible to the `\begin{asy}...\end{asy}'
+environment. In this mode, Asymptote correctly aligns LaTeX symbols
+defined outside of `\begin{asy}...\end{asy}', but treats their size as
+zero; an optional second string can be given to `Label' to provide an
+estimate of the unknown label size.
+
+ Note that if `latex' is used with the `inline' option, the labels
+might not show up in DVI viewers that cannot handle raw `PostScript'
+code. One can use `dvips'/`dvipdf' to produce `PostScript'/PDF output
+(we recommend using the modified version of `dvipdf' in the `Asymptote'
+patches directory, which accepts the `dvips -z' hyperdvi option).
+
+ An excellent tutorial by Dario Teixeira on integrating `Asymptote'
+and `LaTeX' is available at `http://dario.dse.nl/projects/asylatex/'.
+
+ Here now is `latexusage.tex':
+
+\documentclass[12pt]{article}
+
+% Use this form to include EPS (latex) or PDF (pdflatex) files:
+\usepackage{asymptote}
+
+% Use this form with latex or pdflatex to include inline LaTeX code:
+%\usepackage[inline]{asymptote}
+
+% Enable this line to support PDF hyperlinks:
+%\usepackage[setpagesize=false]{hyperref}
+
+% Enable this line for PDF attachments with asy environment option attach=true:
+%\usepackage[dvips]{attachfile2}
+
+\begin{document}
+
+\begin{asydef}
+// Global Asymptote definitions can be put here.
+usepackage("bm");
+texpreamble("\def\V#1{\bm{#1}}");
+// One can globally override the default toolbar settings here:
+// settings.toolbar=true;
+\end{asydef}
+
+Here is a venn diagram produced with Asymptote, drawn to width 4cm:
+
+\def\A{A}
+\def\B{\V{B}}
+
+%\begin{figure}
+\begin{center}
+\begin{asy}
+size(4cm,0);
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection=new picture;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+//draw("$\A$",box,z1); // Requires [inline] package option.
+//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option.
+draw("$A$",box,z1);
+draw("$\V{B}$",box,z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
+\end{asy}
+%\caption{Venn diagram}\label{venn}
+\end{center}
+%\end{figure}
+
+Each graph is drawn in its own environment. One can specify the width
+and height to \LaTeX\ explicitly. This 3D example can be viewed
+interactively either with Adobe Reader or Asymptote's fast OpenGL-based
+renderer. It is often desirable to embed such files as annotated attachments;
+this requires the optional \verb+\usepackage{attachfile2}+ package and
+the \verb+{attach=true}+ option:
+\begin{center}
+\begin{asy}[height=4cm,attach=false]
+import three;
+currentprojection=orthographic(5,4,2);
+draw(unitcube,blue);
+label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17));
+\end{asy}
+\end{center}
+
+One can also scale the figure to the full line width:
+\begin{center}
+\begin{asy}[width=\the\linewidth]
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+\end{asy}
+\end{center}
+\end{document}
+
+
+
+File: asymptote.info, Node: Base modules, Next: Options, Prev: LaTeX usage, Up: Top
+
+7 Base modules
+**************
+
+`Asymptote' currently ships with the following base modules:
+
+* Menu:
+
+* plain:: Default `Asymptote' base file
+* simplex:: Linear programming: simplex method
+* math:: Extend `Asymptote''s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded PDF and MPEG movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with `Asymptote'
+* MetaPost:: `MetaPost' compatibility routines
+* unicode:: Accept `unicode' (UTF-8) characters
+* latin1:: Accept `ISO 8859-1' characters
+* babel:: Interface to `LaTeX' `babel' package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your PDF files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* slopefield:: Slope fields
+
+
+File: asymptote.info, Node: plain, Next: simplex, Up: Base modules
+
+7.1 `plain'
+===========
+
+This is the default `Asymptote' base file, which defines key parts of
+the drawing language (such as the `picture' structure).
+
+ By default, an implicit `private import plain;' occurs before
+translating a file and before the first command given in interactive
+mode. This also applies when translating files for module definitions
+(except when translating `plain', of course). This means that the
+types and functions defined in `plain' are accessible in almost all
+`Asymptote' code. Use the `-noautoplain' command-line option to disable
+this feature.
+
+
+File: asymptote.info, Node: simplex, Next: math, Prev: plain, Up: Base modules
+
+7.2 `simplex'
+=============
+
+This package solves the two-variable linear programming problem using
+the simplex method. It is used by the module `plain' for automatic
+sizing of pictures.
+
+
+File: asymptote.info, Node: math, Next: interpolate, Prev: simplex, Up: Base modules
+
+7.3 `math'
+==========
+
+This package extends `Asymptote''s mathematical capabilities with
+intersection algorithms and matrix arithmetic:
+
+`void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen);'
+ draw the visible portion of the (infinite) line going through `P'
+ and `Q', without altering the size of picture `pic', using pen `p'.
+
+`real intersect(triple P, triple Q, triple n, triple Z);'
+ returns the intersection time of the extension of the line segment
+ `PQ' with the plane perpendicular to `n' and passing through `Z'.
+
+`triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);'
+ Return any point on the intersection of the two planes with normals
+ `n0' and `n1' passing through points `P0' and `P1', respectively.
+ If the planes are parallel, return `(infinity,infinity,infinity)'.
+
+``pair[] quarticroots(real a, real b, real c, real d, real e);''
+ returns the four complex roots of the quartic equation
+ ax^4+bx^3+cx^2+dx+e=0.
+
+
+
+File: asymptote.info, Node: interpolate, Next: geometry, Prev: math, Up: Base modules
+
+7.4 `interpolate'
+=================
+
+This module implements Lagrange, Hermite, and standard cubic spline
+interpolation in `Asymptote', as illustrated in the example
+`interpolate1.asy'.
+
+
+File: asymptote.info, Node: geometry, Next: trembling, Prev: interpolate, Up: Base modules
+
+7.5 `geometry'
+==============
+
+This module, written by Philippe Ivaldi, provides an extensive set of
+geometry routines, including `perpendicular' symbols and a `triangle'
+structure. It is documented here:
+`http://asymptote.sourceforge.net/geometry_en.pdf', including an
+extensive set of examples,
+`http://piprim.tuxfamily.org/asymptote/geometry/index.html', and an
+index:
+
+ `http://piprim.tuxfamily.org/asymptote/geometry/modules/geometry.asy.index.type.html'
+
+
+File: asymptote.info, Node: trembling, Next: stats, Prev: geometry, Up: Base modules
+
+7.6 `trembling'
+===============
+
+This module, written by Philippe Ivaldi and illustrated in the example
+`floatingdisk.asy', allows one to draw wavy lines, as if drawn by hand.
+Further examples are posted at
+`http://piprim.tuxfamily.org/asymptote/trembling/index.html'
+
+
+File: asymptote.info, Node: stats, Next: patterns, Prev: trembling, Up: Base modules
+
+7.7 `stats'
+===========
+
+This package implements a Gaussian random number generator and a
+collection of statistics routines, including `histogram' and
+`leastsquares'.
+
+
+File: asymptote.info, Node: patterns, Next: markers, Prev: stats, Up: Base modules
+
+7.8 `patterns'
+==============
+
+This package implements `Postscript' tiling patterns and includes
+several convenient pattern generation routines.
+
+
+File: asymptote.info, Node: markers, Next: tree, Prev: patterns, Up: Base modules
+
+7.9 `markers'
+=============
+
+This package implements specialized routines for marking paths and
+angles. The principal mark routine provided by this package is
+markroutine markinterval(int n=1, frame f, bool rotated=false);
+ which centers `n' copies of frame `f' within uniformly space intervals
+in arclength along the path, optionally rotated by the angle of the
+local tangent.
+
+ The `marker' (*note marker::) routine can be used to construct new
+markers from these predefined frames:
+
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen);
+
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false);
+
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+
+ For convenience, this module also constructs the markers
+`StickIntervalMarker', `CrossIntervalMarker',
+`CircleBarIntervalMarker', and `TildeIntervalMarker' from the above
+frames. The example `markers1.asy' illustrates the use of these markers:
+
+
+
+
+This package also provides a routine for marking an angle AOB:
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, margin margin=NoMargin,
+ marker marker=nomarker);
+ as illustrated in the example `markers2.asy'.
+
+
+
+
+
+File: asymptote.info, Node: tree, Next: binarytree, Prev: markers, Up: Base modules
+
+7.10 `tree'
+===========
+
+This package implements an example of a dynamic binary search tree.
+
+
+File: asymptote.info, Node: binarytree, Next: drawtree, Prev: tree, Up: Base modules
+
+7.11 `binarytree'
+=================
+
+This module can be used to draw an arbitrary binary tree and includes an
+input routine for the special case of a binary search tree, as
+illustrated in the example `binarytreetest.asy':
+
+import binarytree;
+
+picture pic,pic2;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(pic,bt);
+
+binarytree st=searchtree(10,5,2,1,3,4,7,6,8,9,15,13,12,11,14,17,16,18,19);
+draw(pic2,st,blue);
+
+add(pic.fit(),(0,0),10N);
+add(pic2.fit(),(0,0),10S);
+
+
+
+
+File: asymptote.info, Node: drawtree, Next: syzygy, Prev: binarytree, Up: Base modules
+
+7.12 `drawtree'
+===============
+
+This is a simple tree drawing module used by the example `treetest.asy'.
+
+
+File: asymptote.info, Node: syzygy, Next: feynman, Prev: drawtree, Up: Base modules
+
+7.13 `syzygy'
+=============
+
+This module automates the drawing of braids, relations, and syzygies,
+along with the corresponding equations, as illustrated in the example
+`knots.asy'.
+
+
+File: asymptote.info, Node: feynman, Next: roundedpath, Prev: syzygy, Up: Base modules
+
+7.14 `feynman'
+==============
+
+This package, contributed by Martin Wiebusch, is useful for drawing
+Feynman diagrams, as illustrated by the examples `eetomumu.asy' and
+`fermi.asy'.
+
+
+File: asymptote.info, Node: roundedpath, Next: animation, Prev: feynman, Up: Base modules
+
+7.15 `roundedpath'
+==================
+
+This package, contributed by Stefan Knorr, is useful for rounding the
+sharp corners of paths, as illustrated in the example file
+`roundpath.asy'.
+
+
+File: asymptote.info, Node: animation, Next: embed, Prev: roundedpath, Up: Base modules
+
+7.16 `animation'
+================
+
+This module allows one to generate animations, as illustrated by the
+files `wheel.asy', `wavelet.asy', and `cube.asy' in the `animations'
+subdirectory of the examples directory. These animations use the
+`ImageMagick' `convert' program to `merge' multiple images into a GIF
+or MPEG movie.
+
+ The related `animate' module, derived from the `animation' module,
+generates higher-quality portable clickable PDF movies, with optional
+controls. This requires installing the package
+
+ `http://www.ctan.org/tex-archive/macros/latex/contrib/animate/animate.sty'
+ (version 2007/11/30 or later) in a new directory `animate' in the
+local `LaTeX' directory (for example, in
+`/usr/local/share/texmf/tex/latex/animate'). On `UNIX' systems, one
+must then execute the command `texhash'.
+
+ The example `pdfmovie.asy' in the `animations' directory, along with
+the slide presentations `slidemovies.asy' and `intro.asy', illustrate
+the use of embedded PDF movies. The examples `inlinemovie.tex' and
+`inlinemovie3.tex' show how to generate and embed PDF movies directly
+within a `LaTeX' file (*note LaTeX usage::). The member function
+string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true);
+ of the `animate' structure accepts any of the `animate.sty' options,
+as described here:
+
+ `http://www.ctan.org/tex-archive/macros/latex/contrib/animate/doc/animate.pdf'
+
+
+File: asymptote.info, Node: embed, Next: slide, Prev: animation, Up: Base modules
+
+7.17 `embed'
+============
+
+This module provides an interface to the `LaTeX' package (included with
+`MikTeX')
+
+ `http://www.ctan.org/tex-archive/macros/latex/contrib/movie15'
+ for embedding movies, sounds, and 3D objects into a PDF document. However,
+`XeLaTeX' users need to rename the modified version
+`movie15_dvipdfmx.sty' from
+
+ `http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/patches/'
+ to `movie15.sty' and place it in their `LaTeX' path.
+
+ The latest version (2008/10/08) of the `movie15' package requires
+both `pdflatex' version 1.20 or later and the file
+
+ `http://www.ctan.org/tex-archive/macros/latex/contrib/oberdiek/ifdraft.dtx'
+ which can be installed by placing it in a directory `ifdraft' in the
+local `LaTeX' directory (e.g.
+`/usr/local/share/texmf/tex/latex/ifdraft') and executing in that
+directory the commands:
+tex ifdraft.dtx
+texhash
+
+ An example of embedding `U3D' code is provided in the file
+`embeddedu3d.asy'. As of version 7.0.8, `Adobe Reader' supports the
+`U3D' format under Linux.
+
+ Unfortunately, Adobe has not yet made available an embedded movie
+plugin for the Linux version of `Adobe Reader'. A portable method for
+embedding movie files, which should work on any platform and does not
+require the `movie15' or `ifdraft' packages, is provided by using the
+`external' module instead of `embed'. An example of these interfaces is
+provided in the file `embeddedmovie.asy' and `externalmovie.asy' in the
+`animations' subdirectory of the examples directory. For a higher
+quality movie generated directly by `Asymptote', use the `animate'
+module along with the `animate.sty' package to embed a portable PDF
+animation (*note animate::).
+
+
+File: asymptote.info, Node: slide, Next: MetaPost, Prev: embed, Up: Base modules
+
+7.18 `slide'
+============
+
+This package provides a simple yet high-quality facility for making
+presentation slides, including portable embedded PDF animations (see
+the file `slidemovies.asy'). A simple example is provided in the file
+`slidedemo.asy'.
+
+
+File: asymptote.info, Node: MetaPost, Next: unicode, Prev: slide, Up: Base modules
+
+7.19 `MetaPost'
+===============
+
+This package provides some useful routines to help `MetaPost' users
+migrate old `MetaPost' code to `Asymptote'. Further contributions here
+are welcome.
+
+ Unlike `MetaPost', `Asymptote' does not implicitly solve linear
+equations and therefore does not have the notion of a `whatever'
+unknown. The routine `extension' (*note extension::) provides a useful
+replacement for a common use of `whatever': finding the intersection
+point of the lines through `P', `Q' and `p', `q'. For less common
+occurrences of `whatever', one can use the built-in explicit linear
+equation solver `solve' instead.
+
+
+File: asymptote.info, Node: unicode, Next: latin1, Prev: MetaPost, Up: Base modules
+
+7.20 `unicode'
+==============
+
+Import this package at the beginning of the file to instruct `LaTeX' to
+accept `unicode' (UTF-8) standardized international characters. To use
+Cyrillic fonts, you will need to change the font encoding:
+import unicode;
+texpreamble("\usepackage{mathtext}\usepackage[russian]{babel}");
+defaultpen(font("T2A","cmr","m","n"));
+ Support for Chinese, Japanese, and Korean fonts is provided by the CJK
+package:
+
+ `http://www.ctan.org/tex-archive/languages/chinese/CJK/'
+ The following commands enable the CJK song family (within a label,
+you can also temporarily switch to another family, say kai, by
+prepending `"\CJKfamily{kai}"' to the label string):
+texpreamble("\usepackage{CJK}
+\AtBeginDocument{\begin{CJK*}{GBK}{song}}
+\AtEndDocument{\clearpage\end{CJK*}}");
+
+
+File: asymptote.info, Node: latin1, Next: babel, Prev: unicode, Up: Base modules
+
+7.21 `latin1'
+=============
+
+If you don't have `LaTeX' support for `unicode' installed, you can
+enable support for Western European languages (ISO 8859-1) by importing
+the module `latin1'. This module can be used as a template for
+providing support for other ISO 8859 alphabets.
+
+
+File: asymptote.info, Node: babel, Next: labelpath, Prev: latin1, Up: Base modules
+
+7.22 `babel'
+============
+
+This module implements the `LaTeX' `babel' package in `Asymptote'. For
+example:
+import babel;
+babel("german");
+
+
+File: asymptote.info, Node: labelpath, Next: labelpath3, Prev: babel, Up: Base modules
+
+7.23 `labelpath'
+================
+
+This module uses the `PSTricks' `pstextpath' macro to fit labels along
+a path (properly kerned, as illustrated in the example file
+`curvedlabel.asy'), using the command
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen);
+ Here `justify' is one of `LeftJustified', `Centered', or
+`RightJustified'. The x component of a shift transform applied to the
+Label is interpreted as a shift along the curve, whereas the y
+component is interpreted as a shift away from the curve. All other
+Label transforms are ignored. This package requires the `latex' tex
+engine and inherits the limitations of the `PSTricks' `\pstextpath'
+macro.
+
+
+File: asymptote.info, Node: labelpath3, Next: annotate, Prev: labelpath, Up: Base modules
+
+7.24 `labelpath3'
+=================
+
+This module, contributed by Jens Schwaiger, implements a 3D version of
+`labelpath' that does not require the `PSTricks' package. An example
+is provided in `curvedlabel3.asy'.
+
+
+File: asymptote.info, Node: annotate, Next: CAD, Prev: labelpath3, Up: Base modules
+
+7.25 `annotate'
+===============
+
+This module supports PDF annotations for viewing with `Adobe Reader',
+via the function
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position);
+ Annotations are illustrated in the example file `annotation.asy'.
+Currently, annotations are only implemented for the `latex' (default)
+and `tex' TeX engines.
+
+
+File: asymptote.info, Node: CAD, Next: graph, Prev: annotate, Up: Base modules
+
+7.26 `CAD'
+==========
+
+This package, contributed by Mark Henning, provides basic pen
+definitions and measurement functions for simple 2D CAD drawings
+according to DIN 15. It is documented separately, in the file `CAD.pdf'.
+
+
+File: asymptote.info, Node: graph, Next: palette, Prev: CAD, Up: Base modules
+
+7.27 `graph'
+============
+
+This package implements two-dimensional linear and logarithmic graphs,
+including automatic scale and tick selection (with the ability to
+override manually). A graph is a `guide' (that can be drawn with the
+draw command, with an optional legend) constructed with one of the
+following routines:
+
+ * guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture `pic'
+ (*note automatic scaling::) of the function `f' on the interval
+ [`T'(`a'),`T'(`b')], sampling at `n' points evenly spaced in
+ [`a',`b'], optionally restricted by the bool3 function `cond' on
+ [`a',`b']. If `cond' is:
+ * `true', the point is added to the existing guide;
+
+ * `default', the point is added to a new guide;
+
+ * `false', the point is omitted and a new guide is begun.
+ Th points are connected using the interpolation specified by
+ `join':
+ * `operator --' (linear interpolation; the abbreviation
+ `Straight' is also accepted);
+
+ * `operator ..' (piecewise Bezier cubic spline interpolation;
+ the abbreviation `Spline' is also accepted);
+
+ * `Hermite' (standard cubic spline interpolation using boundary
+ condition `notaknot', `natural', `periodic', `clamped(real
+ slopea, real slopeb)'), or `monotonic'. The abbreviation
+ `Hermite' is equivalent to `Hermite(notaknot)' for
+ nonperiodic data and `Hermite(periodic)' for periodic data).
+
+
+ * guide graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture `pic' of
+ the parametrized function (`x'(t),`y'(t)) for t in the interval
+ [`T'(`a'),`T'(`b')], sampling at `n' points evenly spaced in
+ [`a',`b'], optionally restricted by the bool3 function `cond' on
+ [`a',`b'], using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture `pic' of
+ the parametrized function `z'(t) for t in the interval
+ [`T'(`a'),`T'(`b')], sampling at `n' points evenly spaced in
+ [`a',`b'], optionally restricted by the bool3 function `cond' on
+ [`a',`b'], using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, pair[] z,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture `pic' of
+ the elements of the array `z', optionally restricted to those
+ indices for which the elements of the boolean array `cond' are
+ `true', using the given interpolation type.
+
+ * guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --);
+ guide[] graph(picture pic=currentpicture, real[] x, real[] y,
+ bool3[] cond, interpolate join=operator --);
+
+ Returns a graph using the scaling information for picture `pic' of
+ the elements of the arrays (`x',`y'), optionally restricted to
+ those indices for which the elements of the boolean array `cond'
+ are `true', using the given interpolation type.
+
+ * guide polargraph(picture pic=currentpicture, real f(real), real a,
+ real b, int n=ngraph, interpolate join=operator --);
+
+ Returns a polar-coordinate graph using the scaling information for
+ picture `pic' of the function `f' on the interval [`a',`b'],
+ sampling at `n' evenly spaced points, with the given interpolation
+ type.
+
+
+
+
+ An axis can be drawn on a picture with one of the following commands:
+
+ * void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+
+ Draw an x axis on picture `pic' from x=`xmin' to x=`xmax' using
+ pen `p', optionally labelling it with Label `L'. The relative
+ label location along the axis (a real number from [0,1]) defaults
+ to 1 (*note Label::), so that the label is drawn at the end of the
+ axis. An infinite value of `xmin' or `xmax' specifies that the
+ corresponding axis limit will be automatically determined from the
+ picture limits. The optional `arrow' argument takes the same
+ values as in the `draw' command (*note arrows::). The axis is
+ drawn before any existing objects in the current picture unless
+ `above=true'. The axis placement is determined by one of the
+ following `axis' types:
+
+ `YZero(bool extend=true)'
+ Request an x axis at y=0 (or y=1 on a logarithmic axis)
+ extending to the full dimensions of the picture, unless
+ `extend'=false.
+
+ `YEquals(real Y, bool extend=true)'
+ Request an x axis at y=`Y' extending to the full dimensions
+ of the picture, unless `extend'=false.
+
+ `Bottom(bool extend=false)'
+ Request a bottom axis.
+
+ `Top(bool extend=false)'
+ Request a top axis.
+
+ `BottomTop(bool extend=false)'
+ Request a bottom and top axis.
+
+
+ Custom axis types can be created by following the examples in
+ `graph.asy'. One can easily override the default values for the
+ standard axis types: import graph;
+
+ YZero=new axis(bool extend=true) {
+ return new void(picture pic, axisT axis) {
+ real y=pic.scale.x.scale.logarithmic ? 1 : 0;
+ axis.value=I*pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=2.5E;
+ axis.value2=Infinity;
+ axis.extend=extend;
+ };
+ };
+ YZero=YZero();
+
+ The default tick option is `NoTicks'. The options `LeftTicks',
+ `RightTicks', or `Ticks' can be used to draw ticks on the left,
+ right, or both sides of the path, relative to the direction in
+ which the path is drawn. These tick routines accept a number of
+ optional arguments: ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen);
+
+ If any of these parameters are omitted, reasonable defaults will
+ be chosen:
+ `Label format'
+ override the default tick label format (`defaultformat',
+ initially "$%.4g$"), rotation, pen, and alignment (for
+ example, `LeftSide', `Center', or `RightSide') relative to
+ the axis. To enable `LaTeX' math mode fonts, the format
+ string should begin and end with `$' *note format::. If the
+ format string is `trailingzero', trailing zeros will be added
+ to the tick labels; if the format string is `"%"', the tick
+ label will be suppressed;
+
+ `ticklabel'
+ is a function `string(real x)' returning the label (by
+ default, format(format.s,x)) for each major tick value `x';
+
+ `bool beginlabel'
+ include the first label;
+
+ `bool endlabel'
+ include the last label;
+
+ `int N'
+ when automatic scaling is enabled (the default; *note
+ automatic scaling::), divide a linear axis evenly into this
+ many intervals, separated by major ticks; for a logarithmic
+ axis, this is the number of decades between labelled ticks;
+
+ `int n'
+ divide each interval into this many subintervals, separated
+ by minor ticks;
+
+ `real Step'
+ the tick value spacing between major ticks (if `N'=`0');
+
+ `real step'
+ the tick value spacing between minor ticks (if `n'=`0');
+
+ `bool begin'
+ include the first major tick;
+
+ `bool end'
+ include the last major tick;
+
+ `tickmodifier modify;'
+ an optional function that takes and returns a `tickvalue'
+ structure having real[] members `major' and `minor'
+ consisting of the tick values (to allow modification of the
+ automatically generated tick values);
+
+ `real Size'
+ the size of the major ticks (in `PostScript' coordinates);
+
+ `real size'
+ the size of the minor ticks (in `PostScript' coordinates);
+
+ `bool extend;'
+ extend the ticks between two axes (useful for drawing a grid
+ on the graph);
+
+ `pen pTick'
+ an optional pen used to draw the major ticks;
+
+ `pen ptick'
+ an optional pen used to draw the minor ticks.
+
+
+ For convenience, the predefined tickmodifier `OmitTick(... real[]
+ x)' tickmodifier can be used to remove specific auto-generated
+ ticks and their labels. The `OmitFormat(string s=defaultformat ...
+ real[] x)' ticklabel can be used to remove specific tick labels
+ but not the corresponding ticks. The tickmodifier `NoZero' is an
+ abbreviation for `OmitTick(0)' and the ticklabel `NoZeroFormat' is
+ an abbrevation for `OmitFormat(0)'.
+
+ It is also possible to specify custom tick locations with
+ `LeftTicks', `RightTicks', and `Ticks' by passing explicit real
+ arrays `Ticks' and (optionally) `ticks' containing the locations
+ of the major and minor ticks, respectively: ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+
+ * void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+
+ Draw a y axis on picture `pic' from y=`ymin' to y=`ymax' using pen
+ `p', optionally labelling it with Label `L'. The relative location
+ of the label (a real number from [0,1]) defaults to 1 (*note
+ Label::). An infinite value of `ymin' or `ymax' specifies that the
+ corresponding axis limit will be automatically determined from the
+ picture limits. The optional `arrow' argument takes the same
+ values as in the `draw' command (*note arrows::). The axis is
+ drawn before any existing objects in the current picture unless
+ `above=true'. The tick type is specified by `ticks' and the axis
+ placement is determined by one of the following `axis' types:
+
+ `XZero(bool extend=true)'
+ Request a y axis at x=0 (or x=1 on a logarithmic axis)
+ extending to the full dimensions of the picture, unless
+ `extend'=false.
+
+ `XEquals(real X, bool extend=true)'
+ Request a y axis at x=`X' extending to the full dimensions of
+ the picture, unless `extend'=false.
+
+ `Left(bool extend=false)'
+ Request a left axis.
+
+ `Right(bool extend=false)'
+ Request a right axis.
+
+ `LeftRight(bool extend=false)'
+ Request a left and right axis.
+
+
+ * For convenience, the functions void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+ and void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+ can be respectively used to call `yaxis' and `xaxis' with the
+ appropriate axis types `XEquals(x,extend)' and
+ `YEquals(y,extend)'. This is the recommended way of drawing
+ vertical or horizontal lines and axes at arbitrary locations.
+
+ * void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, bool above=false);
+ This convenience routine draws both x and y axes on picture `pic'
+ from `min' to `max', with optional labels `xlabel' and `ylabel'
+ and any arrows specified by `arrow'. The axes are drawn on top of
+ existing objects in the current picture only if `above=true'.
+
+ * void axis(picture pic=currentpicture, Label L="", path g,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, int[] divisor=new int[],
+ bool above=false, bool opposite=false);
+
+ This routine can be used to draw on picture `pic' a general axis
+ based on an arbitrary path `g', using pen `p'. One can optionally
+ label the axis with Label `L' and add an arrow `arrow'. The tick
+ type is given by `ticks'. The optional integer array `divisor'
+ specifies what tick divisors to try in the attempt to produce
+ uncrowded tick labels. A `true' value for the flag `opposite'
+ identifies an unlabelled secondary axis (typically drawn opposite
+ a primary axis). The axis is drawn before any existing objects in
+ the current picture unless `above=true'. The tick locator
+ `ticklocate' is constructed by the routine ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero);
+ where `a' and `b' specify the respective tick values at
+ `point(g,0)' and `point(g,length(g))', `S' specifies the
+ autoscaling transformation, the function `real time(real v)'
+ returns the time corresponding to the value `v', and `pair
+ dir(real t)' returns the absolute tick direction as a function of
+ `t' (zero means draw the tick perpendicular to the axis).
+
+ * These routines are useful for manually putting ticks and labels on
+ axes (if the variable `Label' is given as the `Label' argument,
+ the `format' argument will be used to format a string based on the
+ tick location): void xtick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void xtick(picture pic=currentpicture, Label L="", real x,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void ytick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void ytick(picture pic=currentpicture, Label L="", real y,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+ void tick(picture pic=currentpicture, pair z,
+ pair dir, real size=Ticksize, pen p=currentpen);
+ void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=nullpen);
+ void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=nullpen);
+ void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+ void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=nullpen);
+ void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=nullpen);
+ void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=nullpen);
+
+ Here are some simple examples of two-dimensional graphs:
+
+ 1. This example draws a textbook-style graph of y= exp(x), with the y
+ axis starting at y=0: import graph;
+ size(150,0);
+
+ real f(real x) {return exp(x);}
+ pair F(real x) {return (x,f(x));}
+
+ xaxis("$x$");
+ yaxis("$y$",0);
+
+ draw(graph(f,-4,2,operator ..),red);
+
+ labely(1,E);
+ label("$e^x$",F(1),SE);
+
+
+
+ 2. The next example draws a scientific-style graph with a legend.
+ The position of the legend can be adjusted either explicitly or by
+ using the graphical user interface `xasy' (*note GUI::). If an
+ `UnFill(real xmargin=0, real ymargin=xmargin)' or `Fill(pen)'
+ option is specified to `add', the legend will obscure any
+ underlying objects. Here we illustrate how to clip the portion of
+ the picture covered by a label:
+
+ import graph;
+
+ size(400,200,IgnoreAspect);
+
+ real Sin(real t) {return sin(2pi*t);}
+ real Cos(real t) {return cos(2pi*t);}
+
+ draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+ draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ label("LABEL",point(0),UnFill(1mm));
+
+ add(legend(),point(E),20E,UnFill);
+
+
+
+ To specify a fixed size for the graph proper, use `attach': import graph;
+
+ size(250,200,IgnoreAspect);
+
+ real Sin(real t) {return sin(2pi*t);}
+ real Cos(real t) {return cos(2pi*t);}
+
+ draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+ draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ label("LABEL",point(0),UnFill(1mm));
+
+ attach(legend(),truepoint(E),20E,UnFill);
+ A legend can have multiple entries per line: import graph;
+ size(8cm,6cm,IgnoreAspect);
+
+ typedef real realfcn(real);
+ realfcn F(real p) {
+ return new real(real x) {return sin(p*x);};
+ };
+
+ for(int i=1; i < 5; ++i)
+ draw(graph(F(i*pi),0,1),Pen(i),
+ "$\sin("+(i == 1 ? "" : (string) i)+"\pi x)$");
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+ attach(legend(2),(point(S).x,truepoint(S).y),10S,UnFill);
+
+
+
+ 3. This example draws a graph of one array versus another (both of
+ the same size) using custom tick locations and a smaller font size
+ for the tick labels on the y axis. import graph;
+
+ size(200,150,IgnoreAspect);
+
+ real[] x={0,1,2,3};
+ real[] y=x^2;
+
+ draw(graph(x,y),red);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,
+ RightTicks(Label(fontsize(8)),new real[]{0,4,9}));
+
+
+
+ 4. This example shows how to graph columns of data read from a file. import graph;
+
+ size(200,150,IgnoreAspect);
+
+ file in=line(input("filegraph.dat"));
+ real[][] a=dimension(in,0,0);
+ a=transpose(a);
+
+ real[] x=a[0];
+ real[] y=a[1];
+
+ draw(graph(x,y),red);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+
+
+ 5. The next example draws two graphs of an array of coordinate pairs,
+ using frame alignment and data markers. In the left-hand graph, the
+ markers, constructed with marker marker(path g, markroutine markroutine=marknodes,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool above=true);
+ using the path `unitcircle' (*note filltype::), are drawn below
+ each node. Any frame can be converted to a marker, using marker marker(frame f, markroutine markroutine=marknodes,
+ bool above=true);
+ In the right-hand graph, the unit n-sided regular polygon
+ `polygon(int n)' and the unit n-point cyclic cross `cross(int n,
+ bool round=true, real r=0)' (where `r' is an optional "inner"
+ radius) are used to build a custom marker frame. Here
+ `markuniform(bool centered=false, int n, bool rotated=false)' adds
+ this frame at `n' uniformly spaced points along the arclength of
+ the path, optionally rotated by the angle of the local tangent to
+ the path (if centered is true, the frames will be centered within
+ `n' evenly spaced arclength intervals). Alternatively, one can use
+ markroutine `marknodes' to request that the marks be placed at each
+ Bezier node of the path, or markroutine `markuniform(pair z(real
+ t), real a, real b, int n)' to place marks at points `z(t)' for n
+ evenly spaced values of `t' in `[a,b]'.
+
+ These markers are predefined: marker[] Mark={
+ marker(scale(circlescale)*unitcircle),
+ marker(polygon(3)),marker(polygon(4)),
+ marker(polygon(5)),marker(invert*polygon(3)),
+ marker(cross(4)),marker(cross(6))
+ };
+
+ marker[] MarkFill={
+ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
+ marker(polygon(4),Fill),marker(polygon(5),Fill),
+ marker(invert*polygon(3),Fill)
+ };
+
+ The example also illustrates the `errorbar' routines:
+
+ void errorbars(picture pic=currentpicture, pair[] z, pair[] dp,
+ pair[] dm={}, bool[] cond={}, pen p=currentpen,
+ real size=0);
+
+ void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0);
+
+ Here, the positive and negative extents of the error are given by
+ the absolute values of the elements of the pair array `dp' and the
+ optional pair array `dm'. If `dm' is not specified, the positive
+ and negative extents of the error are assumed to be equal. import graph;
+
+ picture pic;
+ real xsize=200, ysize=140;
+ size(pic,xsize,ysize,IgnoreAspect);
+
+ pair[] f={(5,5),(50,20),(90,90)};
+ pair[] df={(0,0),(5,7),(0,5)};
+
+ errorbars(pic,f,df,red);
+ draw(pic,graph(pic,f),"legend",
+ marker(scale(0.8mm)*unitcircle,red,FillDraw(blue),above=false));
+
+ scale(pic,true);
+
+ xaxis(pic,"$x$",BottomTop,LeftTicks);
+ yaxis(pic,"$y$",LeftRight,RightTicks);
+ add(pic,legend(pic),point(pic,NW),20SE,UnFill);
+
+ picture pic2;
+ size(pic2,xsize,ysize,IgnoreAspect);
+
+ frame mark;
+ filldraw(mark,scale(0.8mm)*polygon(6),green,green);
+ draw(mark,scale(0.8mm)*cross(6),blue);
+
+ draw(pic2,graph(pic2,f),marker(mark,markuniform(5)));
+
+ scale(pic2,true);
+
+ xaxis(pic2,"$x$",BottomTop,LeftTicks);
+ yaxis(pic2,"$y$",LeftRight,RightTicks);
+
+ yequals(pic2,55.0,red+Dotted);
+ xequals(pic2,70.0,red+Dotted);
+
+ // Fit pic to W of origin:
+ add(pic.fit(),(0,0),W);
+
+ // Fit pic2 to E of (5mm,0):
+ add(pic2.fit(),(5mm,0),E);
+
+
+
+ 6. A custom mark routine can be also be specified: import graph;
+
+ size(200,100,IgnoreAspect);
+
+ markroutine marks() {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ path p=scale(1mm)*unitcircle;
+ for(int i=0; i <= length(g); ++i) {
+ pair z=point(g,i);
+ frame f;
+ if(i % 4 == 0) {
+ fill(f,p);
+ add(pic,f,z);
+ } else {
+ if(z.y > 50) {
+ pic.add(new void(frame F, transform t) {
+ path q=shift(t*z)*p;
+ unfill(F,q);
+ draw(F,q);
+ });
+ } else {
+ draw(f,p);
+ add(pic,f,z);
+ }
+ }
+ }
+ };
+ }
+
+ pair[] f={(5,5),(40,20),(55,51),(90,30)};
+
+ draw(graph(f),marker(marks()));
+
+ scale(true);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+
+
+ 7. This example shows how to label an axis with arbitrary strings. import graph;
+
+ size(400,150,IgnoreAspect);
+
+ real[] x=sequence(12);
+ real[] y=sin(2pi*x/12);
+
+ scale(false);
+
+ string[] month={"Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"};
+
+ draw(graph(x,y),red,MarkFill[0]);
+
+ xaxis(BottomTop,LeftTicks(new string(real x) {
+ return month[round(x % 12)];}));
+ yaxis("$y$",LeftRight,RightTicks(4));
+
+
+
+ 8. The next example draws a graph of a parametrized curve. The calls
+ to xlimits(picture pic=currentpicture, real min=-infinity,
+ real max=infinity, bool crop=NoCrop);
+ and the analogous function `ylimits' can be uncommented to set
+ the respective axes limits for picture `pic' to the specified
+ `min' and `max' values. Alternatively, the function void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop);
+ can be used to limit the axes to the box having opposite vertices
+ at the given pairs). Existing objects in picture `pic' will be
+ cropped to lie within the given limits if `crop'=`Crop'. The
+ function `crop(picture pic)' can be used to crop a graph to the
+ current graph limits. import graph;
+
+ size(0,200);
+
+ real x(real t) {return cos(2pi*t);}
+ real y(real t) {return sin(2pi*t);}
+
+ draw(graph(x,y,0,1));
+
+ //xlimits(0,1,Crop);
+ //ylimits(-1,0,Crop);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+
+
+ The next example illustrates how one can extract a common axis
+ scaling factor. import graph;
+
+ axiscoverage=0.9;
+ size(200,IgnoreAspect);
+
+ real[] x={-1e-11,1e-11};
+ real[] y={0,1e6};
+
+ real xscale=round(log10(max(x)));
+ real yscale=round(log10(max(y)))-1;
+
+ draw(graph(x*10^(-xscale),y*10^(-yscale)),red);
+
+ xaxis("$x/10^{"+(string) xscale+"}$",BottomTop,LeftTicks);
+ yaxis("$y/10^{"+(string) yscale+"}$",LeftRight,RightTicks(trailingzero));
+
+
+
+ Axis scaling can be requested and/or automatic selection of the
+ axis limits can be inhibited with one of these `scale' routines: void scale(picture pic=currentpicture, scaleT x, scaleT y);
+
+ void scale(picture pic=currentpicture, bool xautoscale=true,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale);
+
+ This sets the scalings for picture `pic'. The `graph' routines
+ accept an optional `picture' argument for determining the
+ appropriate scalings to use; if none is given, it uses those set
+ for `currentpicture'.
+
+ Two frequently used scaling routines `Linear' and `Log' are
+ predefined in `graph'.
+
+ All picture coordinates (including those in paths and those given
+ to the `label' and `limits' functions) are always treated as linear
+ (post-scaled) coordinates. Use pair Scale(picture pic=currentpicture, pair z);
+ to convert a graph coordinate into a scaled picture coordinate.
+
+ The x and y components can be individually scaled using the
+ analogous routines real ScaleX(picture pic=currentpicture, real x);
+ real ScaleY(picture pic=currentpicture, real y);
+
+ The predefined scaling routines can be given two optional boolean
+ arguments: `automin=false' and `automax=automin'. These default to
+ `false' but can be respectively set to `true' to enable automatic
+ selection of "nice" axis minimum and maximum values. The `Linear'
+ scaling can also take as optional final arguments a multiplicative
+ scaling factor and intercept (e.g. for a depth axis, `Linear(-1)'
+ requests axis reversal).
+
+ For example, to draw a log/log graph of a function, use
+ `scale(Log,Log)': import graph;
+
+ size(200,200,IgnoreAspect);
+
+ real f(real t) {return 1/t;}
+
+ scale(Log,Log);
+
+ draw(graph(f,0.1,10));
+
+ //xlimits(1,10);
+ //ylimits(0.1,1);
+
+ dot(Label("(3,5)",align=S),Scale((3,5)));
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$y$",LeftRight,RightTicks);
+
+
+
+ By extending the ticks, one can easily produce a logarithmic grid: import graph;
+ size(200,200,IgnoreAspect);
+
+ real f(real t) {return 1/t;}
+
+ scale(Log,Log);
+ draw(graph(f,0.1,10),red);
+ pen thin=linewidth(0.5*linewidth());
+ xaxis("$x$",BottomTop,LeftTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+ yaxis("$y$",LeftRight,RightTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+
+
+
+ One can also specify custom tick locations and formats for
+ logarithmic axes: import graph;
+
+ size(300,175,IgnoreAspect);
+ scale(Log,Log);
+ draw(graph(identity,5,20));
+ xlimits(5,20);
+ ylimits(1,100);
+ xaxis("$M/M_\odot$",BottomTop,LeftTicks(DefaultFormat,
+ new real[] {6,10,12,14,16,18}));
+ yaxis("$\nu_{\rm upp}$ [Hz]",LeftRight,RightTicks(DefaultFormat));
+
+
+
+ It is easy to draw logarithmic graphs with respect to other bases: import graph;
+ size(200,IgnoreAspect);
+
+ // Base-2 logarithmic scale on y-axis:
+
+ real log2(real x) {static real log2=log(2); return log(x)/log2;}
+ real pow2(real x) {return 2^x;}
+
+ scaleT yscale=scaleT(log2,pow2,logarithmic=true);
+ scale(Linear,yscale);
+
+ real f(real x) {return 1+x^2;}
+
+ draw(graph(f,-4,4));
+
+ yaxis("$y$",ymin=1,ymax=f(5),RightTicks(Label(Fill(white))),EndArrow);
+ xaxis("$x$",xmin=-5,xmax=5,LeftTicks,EndArrow);
+
+
+
+ Here is an example of "broken" linear x and logarithmic y axes
+ that omit the segments [3,8] and [100,1000], respectively. In the
+ case of a logarithmic axis, the break endpoints are automatically
+ rounded to the nearest integral power of the base. import graph;
+
+ size(200,150,IgnoreAspect);
+
+ // Break the x axis at 3; restart at 8:
+ real a=3, b=8;
+
+ // Break the y axis at 100; restart at 1000:
+ real c=100, d=1000;
+
+ scale(Broken(a,b),BrokenLog(c,d));
+
+ real[] x={1,2,4,6,10};
+ real[] y=x^4;
+
+ draw(graph(x,y),red,MarkFill[0]);
+
+ xaxis("$x$",BottomTop,LeftTicks(Break(a,b)));
+ yaxis("$y$",LeftRight,RightTicks(Break(c,d)));
+
+ label(rotate(90)*Break,(a,point(S).y));
+ label(rotate(90)*Break,(a,point(N).y));
+ label(Break,(point(W).x,ScaleY(c)));
+ label(Break,(point(E).x,ScaleY(c)));
+
+
+
+ 9. `Asymptote' can draw secondary axes with the routines picture secondaryX(picture primary=currentpicture, void f(picture));
+ picture secondaryY(picture primary=currentpicture, void f(picture));
+
+ In this example, `secondaryY' is used to draw a secondary linear y
+ axis against a primary logarithmic y axis: import graph;
+ texpreamble("\def\Arg{\mathop {\rm Arg}\nolimits}");
+
+ size(10cm,5cm,IgnoreAspect);
+
+ real ampl(real x) {return 2.5/(1+x^2);}
+ real phas(real x) {return -atan(x)/pi;}
+
+ scale(Log,Log);
+ draw(graph(ampl,0.01,10));
+ ylimits(0.001,100);
+
+ xaxis("$\omega\tau_0$",BottomTop,LeftTicks);
+ yaxis("$|G(\omega\tau_0)|$",Left,RightTicks);
+
+ picture q=secondaryY(new void(picture pic) {
+ scale(pic,Log,Linear);
+ draw(pic,graph(pic,phas,0.01,10),red);
+ ylimits(pic,-1.0,1.5);
+ yaxis(pic,"$\Arg G/\pi$",Right,red,
+ LeftTicks("$% #.1f$",
+ begin=false,end=false));
+ yequals(pic,1,Dotted);
+ });
+ label(q,"(1,0)",Scale(q,(1,0)),red);
+ add(q);
+
+
+
+ A secondary logarithmic y axis can be drawn like this: import graph;
+
+ size(9cm,6cm,IgnoreAspect);
+ string data="secondaryaxis.csv";
+
+ file in=line(csv(input(data)));
+
+ string[] titlelabel=in;
+ string[] columnlabel=in;
+
+ real[][] a=dimension(in,0,0);
+ a=transpose(a);
+ real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
+ real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+
+ scale(true);
+
+ draw(graph(t,susceptible,t >= 10 & t <= 15));
+ draw(graph(t,dead,t >= 10 & t <= 15),dashed);
+
+ xaxis("Time ($\tau$)",BottomTop,LeftTicks);
+ yaxis(Left,RightTicks);
+
+ picture secondary=secondaryY(new void(picture pic) {
+ scale(pic,Linear(true),Log(true));
+ draw(pic,graph(pic,t,infectious,t >= 10 & t <= 15),red);
+ yaxis(pic,Right,red,LeftTicks(begin=false,end=false));
+ });
+
+ add(secondary);
+ label(shift(5mm*N)*"Proportion of crows",point(NW),E);
+
+
+
+ 10. Here is a histogram example, which uses the `stats' module. import graph;
+ import stats;
+
+ size(400,200,IgnoreAspect);
+
+ int n=10000;
+ real[] a=new real[n];
+ for(int i=0; i < n; ++i) a[i]=Gaussrand();
+
+ draw(graph(Gaussian,min(a),max(a)),blue);
+
+ // Optionally calculate "optimal" number of bins a la Shimazaki and Shinomoto.
+ int N=bins(a);
+
+ histogram(a,min(a),max(a),N,normalize=true,low=0,lightred,black,bars=false);
+
+ xaxis("$x$",BottomTop,LeftTicks);
+ yaxis("$dP/dx$",LeftRight,RightTicks(trailingzero));
+
+
+
+ 11. Here is an example of reading column data in from a file and a
+ least-squares fit, using the `stats' module. size(400,200,IgnoreAspect);
+
+ import graph;
+ import stats;
+
+ file fin=line(input("leastsquares.dat"));
+
+ real[][] a=dimension(fin,0,0);
+ a=transpose(a);
+
+ real[] t=a[0], rho=a[1];
+
+ // Read in parameters from the keyboard:
+ //real first=getreal("first");
+ //real step=getreal("step");
+ //real last=getreal("last");
+
+ real first=100;
+ real step=50;
+ real last=700;
+
+ // Remove negative or zero values of rho:
+ t=rho > 0 ? t : null;
+ rho=rho > 0 ? rho : null;
+
+ scale(Log(true),Linear(true));
+
+ int n=step > 0 ? ceil((last-first)/step) : 0;
+
+ real[] T,xi,dxi;
+
+ for(int i=0; i <= n; ++i) {
+ real first=first+i*step;
+ real[] logrho=(t >= first & t <= last) ? log(rho) : null;
+ real[] logt=(t >= first & t <= last) ? -log(t) : null;
+
+ if(logt.length < 2) break;
+
+ // Fit to the line logt=L.m*logrho+L.b:
+ linefit L=leastsquares(logt,logrho);
+
+ T.push(first);
+ xi.push(L.m);
+ dxi.push(L.dm);
+ }
+
+ draw(graph(T,xi),blue);
+ errorbars(T,xi,dxi,red);
+
+ crop();
+
+ ylimits(0);
+
+ xaxis("$T$",BottomTop,LeftTicks);
+ yaxis("$\xi$",LeftRight,RightTicks);
+
+
+
+ 12. Here is an example that illustrates the general `axis' routine. import graph;
+ size(0,100);
+
+ path g=ellipse((0,0),1,2);
+
+ scale(true);
+
+ axis(Label("C",align=10W),g,LeftTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path h=(0,0)--max(abs(max(g)),abs(min(g)))*dir(v);
+ return intersect(g,h)[0];}));
+
+
+
+ 13. To draw a vector field of `n' arrows evenly spaced along the
+ arclength of a path, use the routine picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow);
+ as illustrated in this simple example of a flow field: import graph;
+ defaultpen(1.0);
+
+ size(0,150,IgnoreAspect);
+
+ real arrowsize=4mm;
+ real arrowlength=2arrowsize;
+
+ typedef path vector(real);
+
+ // Return a vector interpolated linearly between a and b.
+ vector vector(pair a, pair b) {
+ return new path(real x) {
+ return (0,0)--arrowlength*interp(a,b,x);
+ };
+ }
+
+ real f(real x) {return 1/x;}
+
+ real epsilon=0.5;
+ path g=graph(f,epsilon,1/epsilon);
+
+ int n=3;
+ draw(g);
+ xaxis("$x$");
+ yaxis("$y$");
+
+ add(vectorfield(vector(W,W),g,n,true));
+ add(vectorfield(vector(NE,NW),(0,0)--(point(E).x,0),n,true));
+ add(vectorfield(vector(NE,NE),(0,0)--(0,point(N).y),n,true));
+
+
+
+ 14. To draw a vector field of `nx'\times`ny' arrows in `box(a,b)', use
+ the routine picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(a,b,nx,ny),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar arrow=Arrow, margin margin=PenMargin)
+ as illustrated in this example: import graph;
+ size(100);
+
+ pair a=(0,0);
+ pair b=(2pi,2pi);
+
+ path vector(pair z) {return (0,0)--(sin(z.x),cos(z.y));}
+
+ add(vectorfield(vector,a,b));
+
+
+
+ 15. The following scientific graphs, which illustrate many features of
+ `Asymptote''s graphics routines, were generated from the examples
+ `diatom.asy' and `westnile.asy', using the comma-separated data in
+ `diatom.csv' and `westnile.csv'.
+
+
+
+
+
+
+
+File: asymptote.info, Node: palette, Next: three, Prev: graph, Up: Base modules
+
+7.28 `palette'
+==============
+
+`Asymptote' can also generate color density images and palettes. The
+following palettes are predefined in `palette.asy':
+
+`pen[] Grayscale(int NColors=256)'
+ a grayscale palette;
+
+`pen[] Rainbow(int NColors=32766)'
+ a rainbow spectrum;
+
+`pen[] BWRainbow(int NColors=32761)'
+ a rainbow spectrum tapering off to black/white at the ends;
+
+`pen[] BWRainbow2(int NColors=32761)'
+ a double rainbow palette tapering off to black/white at the ends,
+ with a linearly scaled intensity.
+
+`pen[] Wheel(int NColors=32766)'
+ a full color wheel palette;
+
+`pen[] Gradient(int NColors=256 ... pen[] p)'
+ a palette varying linearly over the specified array of pens, using
+ NColors in each interpolation interval;
+
+
+ The function `cmyk(pen[] Palette)' may be used to convert any of
+these palettes to the CMYK colorspace.
+
+ A color density plot using palette `palette' can be generated from a
+function `f'(x,y) and added to a picture `pic':
+bounds image(picture pic=currentpicture, real f(real,real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+ The function `f' will be sampled at `nx' and `ny' evenly spaced points
+over a rectangle defined by the points `initial' and `final',
+respecting the current graphical scaling of `pic'. The color space is
+scaled according to the z axis scaling (*note automatic scaling::). A
+bounds structure for the function values is returned:
+struct bounds {
+ real min;
+ real max;
+ // Possible tick intervals:
+ int[] divisor;
+}
+ This information can be used for generating an optional palette bar.
+The palette color space corresponds to a range of values specified by
+the argument `range', which can be `Full', `Automatic', or an explicit
+range `Range(real min, real max)'. Here `Full' specifies a range
+varying from the minimum to maximum values of the function over the
+sampling interval, while `Automatic' selects "nice" limits. The
+example `imagecontour.asy' illustrates how level sets (contour lines)
+can be drawn on a color density plot (*note contour::).
+
+ A color density plot can also be generated from an explicit real[][]
+array `data':
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+ If the initial point is to the left and below the final point, by
+default the array indices are interpreted according to the Cartesian
+convention (first index: x, second index: y) rather than the usual
+matrix convention (first index: -y, second index: x).
+
+ To construct an image from an array of irregularly spaced points and
+an array of values `f' at these points, use one of the routines
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+
+ An optionally labelled palette bar may be generated with the routine
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false);
+ The color space of `palette' is taken to be over bounds `bounds' with
+scaling given by the z scaling of `pic'. The palette orientation is
+specified by `axis', which may be one of `Right', `Left', `Top', or
+`Bottom'. The bar is drawn over the rectangle from `initial' to
+`final'. The argument `paletteticks' is a special tick type (*note
+ticks::) that takes the following arguments:
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen);
+
+ The image and palette bar can be fit to a frame and added and
+optionally aligned to a picture at the desired location:
+
+size(12cm,12cm);
+
+import graph;
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+real[][] v=new real[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=sin(i*ninv)*cos(j*ninv);
+
+pen[] Palette=BWRainbow();
+
+picture bar;
+
+bounds range=image(v,(0,0),(1,1),Palette);
+palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette,
+ PaletteTicks("$%+#.1f$"));
+add(bar.fit(),point(E),30E);
+
+
+
+Here is an example that uses logarithmic scaling of the function values:
+
+import graph;
+import palette;
+
+size(10cm,10cm,IgnoreAspect);
+
+real f(real x, real y) {
+ return 0.9*pow10(2*sin(x/5+2*y^0.25)) + 0.1*(1+cos(10*log(y)));
+}
+
+scale(Linear,Log,Log);
+
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette,
+ PaletteTicks(ptick=linewidth(0.5*linewidth())));
+
+
+
+One can also draw an image directly from a two-dimensional pen array:
+void image(picture pic=currentpicture, pen[][] data,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+ as illustrated in the following example:
+
+size(200);
+
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+pen[][] v=new pen[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=rgb(0.5*(1+sin(i*ninv)),0.5*(1+cos(j*ninv)),0);
+
+image(v,(0,0),(1,1));
+
+
+
+For convenience, the module `palette' also defines functions that may
+be used to construct a pen array from a given function and palette:
+pen[] palette(real[] f, pen[] palette);
+pen[][] palette(real[][] f, pen[] palette);
+
+
+File: asymptote.info, Node: three, Next: obj, Prev: palette, Up: Base modules
+
+7.29 `three'
+============
+
+This module fully extends the notion of guides and paths in `Asymptote'
+to three dimensions. It introduces the new types guide3, path3, and
+surface. Guides in three dimensions are specified with the same syntax
+as in two dimensions except that triples `(x,y,z)' are used in place of
+pairs `(x,y)' for the nodes and direction specifiers. This
+generalization of John Hobby's spline algorithm is shape-invariant under
+three-dimensional rotation, scaling, and shifting, and reduces in the
+planar case to the two-dimensional algorithm used in `Asymptote',
+`MetaPost', and `MetaFont' [cf. J. C. Bowman, Proceedings in Applied
+Mathematics and Mechanics, 7:1, 2010021-2010022 (2007)].
+
+ For example, a unit circle in the XY plane may be filled and drawn
+like this:
+
+import three;
+
+size(100);
+
+path3 g=(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle;
+draw(g);
+draw(O--Z,red+dashed,Arrow3);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
+
+
+and then distorted into a saddle:
+
+import three;
+
+size(100,0);
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+draw(g);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
+
+
+Module `three' provides constructors for converting two-dimensional
+paths to three-dimensional ones, and vice-versa:
+path3 path3(path p, triple plane(pair)=XYplane);
+path path(path3 p, pair P(triple)=xypart);
+
+ A Bezier surface, the natural two-dimensional generalization of
+Bezier curves, is defined in `three_surface.asy' as a structure
+containing an array of Bezier patches. Surfaces may drawn with one of
+the routines
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=light);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=light);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=light);
+ The parameters `nu' and `nv' specify the number of subdivisions for
+drawing optional mesh lines for each Bezier patch. Here material is a
+structure defined in `three_light.asy':
+struct material {
+ pen[] p; // diffusepen,ambientpen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+ real granularity;
+...
+}
+ These material properties are used to implement `OpenGL'-style
+lighting, based on the Phong-Blinn specular model. Sample Bezier
+surfaces are contained in the example files `BezierSurface.asy',
+`teapot.asy', and `parametricsurface.asy'.
+
+ The examples `elevation.asy' and `sphericalharmonic.asy' illustrate
+how to draw a surface with patch-dependent colors. The examples
+`vertexshading' and `smoothelevation' illustrate vertex-dependent
+colors, which is supported for both `Asymptote''s native `OpenGL'
+renderer and two-dimensional projections. Since the PRC output format
+does not currently support vertex shading of Bezier surfaces, PRC
+patches are shaded with the mean of the four vertex colors.
+
+ A surface can be constructed from a cyclic `path3' with the
+constructor
+surface surface(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default);
+ and then filled:
+draw(surface(path3(polygon(5))),red,nolight);
+draw(surface(unitcircle3),red,nolight);
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}),nolight);
+ The last example constructs a patch with vertex-specific colors. A
+three-dimensional planar surface in the plane `plane' can be
+constructed from a two-dimensional cyclic path `g' with the constructor
+surface surface(path p, triple plane(pair)=XYplane);
+ and then filled:
+draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red);
+ Planar Bezier surfaces patches are constructed using Orest Shardt's
+`bezulate' routine, which decomposes (possibly nonsimply connected)
+regions bounded by nonselfintersecting cyclic paths (according to the
+`zerowinding' fill rule) into subregions bounded by cyclic paths of
+length `4' or less.
+
+ Arbitrary thick three-dimensional curves and line caps (which the
+`OpenGL' standard does not require implementations to provide) are
+constructed with the routine
+surface tube(path3 g, real width);
+ which returns a tube of diameter `width' centered on `g'. This can
+make files slow to render, especially with the `Adobe Reader' renderer.
+The setting `thick=false' can be used to disable this feature and force
+all lines to be drawn with `linewidth(0)' (one pixel wide, regardless
+of the resolution). By default mesh and contour lines in
+three-dimensions are always drawn thin, unless an explicit line width
+is given in the pen parameter or the setting `thin' is set to `false'.
+The pens `thin()' and `thick()' defined in plain_pens.asy can also be
+used to override these defaults for specific draw commands.
+
+There are four choices for viewing 3D `Asymptote' output:
+ 1. Use the native `Asymptote' adaptive `OpenGL'-based renderer (with
+ the command-line option `-V' and the default settings
+ `outformat=""' and `render=-1'). If you encounter warnings from
+ your graphics card driver, try specifying `-glOptions=-indirect'
+ on the command line. On `UNIX' systems with graphics support for
+ multisampling, we recommend installing the latest SVN (antialiased)
+ version of the `freeglut' library (*note multisampling::); the
+ sample width can be controlled with the setting `multisample'. An
+ initial screen position can be specified with the pair setting
+ `position', where negative values are interpreted as relative to
+ the corresponding maximum screen dimension. The mouse bindings are:
+ * Left: rotate
+
+ * shift Left: zoom
+
+ * ctrl Left: shift
+
+ * Middle: menu
+
+ * Wheel: zoom
+
+ * Right: zoom
+
+ * Right double click: menu
+
+ * shift Right: rotate about the X axis
+
+ * ctrl Right: rotate about the Y axis
+
+ * alt Right: rotate about the Z axis
+ The keyboard shortcuts are:
+ * h: home
+
+ * f: toggle fitscreen
+
+ * x: spin about the X axis
+
+ * y: spin about the Y axis
+
+ * z: spin about the Z axis
+
+ * s: stop spinning
+
+ * m: rendering mode (solid/mesh/patch)
+
+ * e: export
+
+ * c: show camera parameters
+
+ * +: expand
+
+ * =: expand
+
+ * -: shrink
+
+ * _: shrink
+
+ * q: exit
+
+ * Ctrl-q: exit
+
+ 2. Render the scene to a specified rasterized format `outformat' at
+ the resolution of `n' pixels per `bp', as specified by the setting
+ `render=n'. A negative value of `n' is interpreted as `|2n|' for
+ EPS and PDF formats and `|n|' for other formats. The default value
+ of `render' is -1. By default, the scene is internally rendered
+ at twice the specified resolution; this can be disabled by setting
+ `antialias=1'. High resolution rendering is done by tiling the
+ image. If your graphics card allows it, the rendering can be made
+ more efficient by increasing the maximum tile size `maxtile'
+ beyond the screen dimensions (indicated by `maxtile=(0,0)'. The
+ tile size is also limited by the setting `maxviewport', which
+ restricts the maximum width and height of the viewport. On `UNIX'
+ systems some graphics drivers support batch mode (`-noV')
+ rendering in an iconified window; this can be enabled with the
+ setting `iconify=true'. Other `UNIX' graphics drivers may require
+ the command line setting `-glOptions=-indirect'.
+
+ 3. Embed the 3D PRC format in a PDF file and view the resulting PDF
+ file with version `8.0' or later of `Adobe Reader'. In addition
+ to the default `settings.prc=true', this requires
+ `settings.outformat="pdf"', which can be specified by the command
+ line option `-f pdf', put in the `Asymptote' configuration file
+ (*note configuration file::), or specified in the script before
+ `three.asy' (or `graph3.asy') is imported. Version 2008/10/08 or
+ later of the `movie15' package is also required (*note embed::).
+ The example `pdb.asy' illustrates how one can generate a list of
+ predefined views (see `100d.views'). A stationary preview image
+ with a resolution of `n' pixels per `bp' can be embedded with the
+ setting `render=n'; this allows the file to be viewed with other
+ `PDF' viewers. Alternatively, the file `externalprc.tex'
+ illustrates how the resulting PRC and rendered image files can be
+ extracted and processed in a separate `LaTeX' file. However, see
+ *note LaTeX usage:: for an easier way to embed three-dimensional
+ `Asymptote' pictures within `LaTeX'. The open-source PRC
+ specification is available from
+ `http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/'.
+
+ 4. Project the scene to a two-dimensional vector (EPS or PDF) format
+ with `render=0'. Only limited hidden surface removal facilities
+ are currently available with this approach (*note PostScript3D::).
+
+
+ Automatic picture sizing in three dimensions is accomplished with
+double deferred drawing. The maximal desired dimensions of the scene in
+each of the three dimensions can optionally be specified with the
+routine
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect);
+ The resulting simplex linear programming problem is then solved to
+produce a 3D version of a frame (actually implemented as a 3D picture).
+The result is then fit with another application of deferred drawing to
+the viewport dimensions corresponding to the usual two-dimensional
+picture `size' parameters. The global pair `viewportmargin' may be used
+to add horizontal and vertical margins to the viewport dimensions.
+Alternatively, a minimum `viewportsize' may be specified.
+
+ For convenience, the `three' module defines `O=(0,0,0)',
+`X=(1,0,0)', `Y=(0,1,0)', and `Z=(0,0,1)', along with a unitcircle in
+the XY plane:
+path3 unitcircle3=X..Y..-X..-Y..cycle;
+
+ A general (approximate) circle can be drawn perpendicular to the
+direction `normal' with the routine
+path3 circle(triple c, real r, triple normal=Z);
+
+ A circular arc centered at `c' with radius `r' from
+`c+r*dir(theta1,phi1)' to `c+r*dir(theta2,phi2)', drawing
+counterclockwise relative to the normal vector
+`cross(dir(theta1,phi1),dir(theta2,phi2))' if `theta2 > theta1' or if
+`theta2 == theta1' and `phi2 >= phi1', can be constructed with
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O);
+ The normal must be explicitly specified if `c' and the endpoints are
+colinear. If `r' < 0, the complementary arc of radius `|r|' is
+constructed. For convenience, an arc centered at `c' from triple `v1'
+to `v2' (assuming `|v2-c|=|v1-c|') in the direction CCW
+(counter-clockwise) or CW (clockwise) may also be constructed with
+path3 arc(triple c, triple v1, triple v2, triple normal=O,
+ bool direction=CCW);
+ When high accuracy is needed, the routines `Circle' and `Arc' defined
+in `graph3' may be used instead. See *note GaussianSurface:: for an
+example of a three-dimensional circular arc.
+
+ The representation `O--O+u--O+u+v--O+v--cycle' of the plane passing
+through point `O' with normal `cross(u,v)' is returned by
+path3 plane(triple u, triple v, triple O=O);
+ A three-dimensional box with opposite vertices at triples `v1' and
+`v2' may be drawn with the function
+path3[] box(triple v1, triple v2);
+ For example, a unit box is predefined as
+path3[] unitbox=box(O,(1,1,1));
+ `Asymptote' also provides optimized definitions for the
+three-dimensional paths `unitsquare3' and `unitcircle3', along with the
+surfaces `unitdisk', `unitplane', `unitcube', `unitcylinder',
+`unitcone', `unitsolidcone', `unitfrustum(real t1, real t2)',
+`unitsphere', and `unithemisphere'.
+
+These projections to two dimensions are predefined:
+`oblique'
+
+`oblique(real angle);'
+ The point `(x,y,z)' is projected to `(x-0.5z,y-0.5z)'. If an
+ optional real argument is given, the negative z axis is drawn at
+ this angle in degrees. The projection `obliqueZ' is a synonym for
+ `oblique'.
+
+`obliqueX'
+
+`obliqueX(real angle)'
+ The point `(x,y,z)' is projected to `(y-0.5x,z-0.5x)'. If an
+ optional real argument is given, the negative x axis is drawn at
+ this angle in degrees.
+
+`obliqueY'
+
+`obliqueY(real angle)'
+ The point `(x,y,z)' is projected to `(x+0.5y,z+0.5y)'. If an
+ optional real argument is given, the positive y axis is drawn at
+ this angle in degrees.
+
+`orthographic(triple camera, triple up=Z, triple target=O,
+ bool showtarget=true, bool center=false)'
+ This projects from three to two dimensions using the view as seen
+ at a point infinitely far away in the direction `unit(camera)',
+ orienting the camera so that, if possible, the vector `up' points
+ upwards. Parallel lines are projected to parallel lines. The
+ bounding volume is expanded to include `target' if
+ `showtarget=true'. If `center=true', the target will be adjusted
+ to the center of the bounding volume.
+
+`orthographic(real x, real y, real z, triple up=Z, triple target=O,
+ bool showtarget=true, bool center=false)'
+ This is equivalent to
+ `orthographic((x,y,z),up,target,showtarget,center)'.
+
+`perspective(triple camera, triple up=Z, triple target=O,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)'
+ This projects from three to two dimensions, taking account of
+ perspective, as seen from the location `camera' looking at
+ `target', orienting the camera so that, if possible, the vector
+ `up' points upwards. If `render=0', projection of
+ three-dimensional cubic Bezier splines is implemented by
+ approximating a two-dimensional nonuniform rational B-spline
+ (NURBS) with a two-dimensional Bezier curve containing additional
+ nodes and control points. If `autoadjust=true', the camera will
+ automatically be adjusted to lie outside the bounding volume for
+ all possible interactive rotations about `target'. If
+ `center=true', the target will be adjusted to the center of the
+ bounding volume.
+
+`perspective(real x, real y, real z, triple up=Z, triple target=O,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=autoadjust)'
+ This is equivalent to `perspective((x,y,z),up,target,showtarget,
+ autoadjust,center)'.
+
+The default projection, `currentprojection', is initially set to
+`perspective(5,4,2)'.
+
+ We also define standard orthographic views used in technical drawing:
+projection LeftView=orthographic(-X,showtarget=true);
+projection RightView=orthographic(X,showtarget=true);
+projection FrontView=orthographic(-Y,showtarget=true);
+projection BackView=orthographic(Y,showtarget=true);
+projection BottomView=orthographic(-Z,showtarget=true);
+projection TopView=orthographic(Z,showtarget=true);
+ The function
+void addViews(picture dest=currentpicture, picture src, bool group=true,
+ filltype filltype=NoFill);
+ adds picture `pic' as seen with `FrontView' aligned above the
+projection `TopView' and to the right of the projection `RightView'.
+Alternatively, the function
+void addAllViews(picture dest=currentpicture, picture src,
+ real xmargin=0, real ymargin=xmargin,
+ bool group=true, filltype filltype=NoFill);
+ may be used to exhibit all six standard views, with FrontView,
+TopView, RightView in the upper row and BackView, BottomView, LeftView
+in the lower row.
+
+ A triple or path3 can be projected to a pair or path, with
+`project(triple, projection P=currentprojection)' or `project(path3,
+projection P=currentprojection)'.
+
+ It is occasionally useful to be able to invert a projection, sending
+a pair `z' onto the plane perpendicular to `normal' and passing through
+`point':
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection);
+ A pair `z' on the projection plane can be inverted to a triple with
+the routine
+triple invert(pair z, projection P=currentprojection);
+ A pair direction `dir' on the projection plane can be inverted to a
+triple direction relative to a point `v' with the routine
+triple invert(pair dir, triple v, projection P=currentprojection).
+
+ Three-dimensional objects may be transformed with one of the
+following built-in transform3 types:
+
+`shift(triple v)'
+ translates by the triple `v';
+
+`xscale3(real x)'
+ scales by `x' in the x direction;
+
+`yscale3(real y)'
+ scales by `y' in the y direction;
+
+`zscale3(real z)'
+ scales by `z' in the z direction;
+
+`scale3(real s)'
+ scales by `s' in the x, y, and z directions;
+
+`scale(real x, real y, real z)'
+ scales by `x' in the x direction, by `y' in the y direction, and
+ by `z' in the z direction;
+
+`rotate(real angle, triple v)'
+ rotates by `angle' in degrees about an axis `v' through the origin;
+
+`rotate(real angle, triple u, triple v)'
+ rotates by `angle' in degrees about the axis `u--v';
+
+`reflect(triple u, triple v, triple w)'
+ reflects about the plane through `u', `v', and `w'.
+
+ Three-dimensional TeX Labels, which are by default drawn as Bezier
+surfaces directly on the projection plane, can be transformed from the
+`XY' plane by any of the above transforms or mapped to a specified
+two-dimensional plane with the transform3 types `XY', `YZ', `ZX', `YX',
+`ZY', `ZX'. There are also modified versions of these transforms that
+take an optional argument `projection P=currentprojection' that rotate
+and/or flip the label so that it is more readable from the initial
+viewpoint.
+
+ A transform3 that projects in the direction `dir' onto the plane
+with normal `n' through point `O' is returned by
+transform3 planeproject(triple n, triple O=O, triple dir=n);
+ One can use
+triple normal(path3 p);
+ to find the unit normal vector to a planar three-dimensional path `p'.
+As illustrated in the example `planeproject.asy', a transform3 that
+projects in the direction `dir' onto the plane defined by a planar path
+`p' is returned by
+transform3 planeproject(path3 p, triple dir=normal(p));
+
+ The functions
+surface extrude(path p, triple axis=Z);
+surface extrude(Label L, triple axis=Z);
+ return the surface obtained by extruding path `p' or Label `L' along
+`axis'.
+
+ Three-dimensional versions of the path functions `length', `size',
+`point', `dir', `accel', `radius', `precontrol', `postcontrol',
+`arclength', `arctime', `reverse', `subpath', `intersect',
+`intersections', `intersectionpoint', `intersectionpoints', `min',
+`max', `cyclic', and `straight' are also defined.
+
+ The routine
+real[][] intersections(path3 p, surface s, real fuzz=-1);
+ returns the intersection times of a path `p' with a surface `s' as a
+sorted array of real arrays of length 2, and
+triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);
+ returns the corresponding intersection points. Here, the computations
+are performed to the absolute error specified by `fuzz', or if `fuzz <
+0', to machine precision.
+
+ Here is an example showing all five guide3 connectors:
+
+import graph3;
+
+size(200);
+
+currentprojection=orthographic(500,-500,500);
+
+triple[] z=new triple[10];
+
+z[0]=(0,100,0); z[1]=(50,0,0); z[2]=(180,0,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0,0);
+
+path3 p=z[0]..z[1]---z[2]::{Y}z[3]
+&z[3]..z[4]--z[5]::{Y}z[6]
+&z[6]::z[7]---z[8]..{Y}z[9];
+
+draw(p,grey+linewidth(4mm)+opacity(0.5));
+
+xaxis3(Label(XY()*"$x$",align=-3Y),red,above=true);
+yaxis3(Label(XY()*"$y$",align=-3X),red,above=true);
+
+dot(z);
+
+
+
+Three-dimensional versions of bars or arrows can be drawn with one of
+the specifiers `None', `Blank', `BeginBar3', `EndBar3' (or equivalently
+`Bar3'), `Bars3', `BeginArrow3', `MidArrow3', `EndArrow3' (or
+equivalently `Arrow3'), `Arrows3', `BeginArcArrow3', `EndArcArrow3' (or
+equivalently `ArcArrow3'), `MidArcArrow3', and `ArcArrows3'.
+Three-dimensional bars accept the optional arguments `(real size=0,
+triple dir=O)'. If `size=O', the default bar length is used; if
+`dir=O', the bar is drawn perpendicular to the path and the initial
+viewing direction. The predefined three-dimensional arrowhead styles
+are `DefaultHead3', `HookHead3', `TeXHead3'. Versions of the
+two-dimensional arrowheads lifted to three-dimensional space and
+aligned according to the initial viewpoint (or an optionally specified
+`normal' vector) are also defined: `DefaultHead2(triple normal=O)',
+`HookHead2(triple normal=O)', `TeXHead2(triple normal=O)'. These are
+illustrated in the example `arrows3.asy'.
+
+ Module `three' also defines the three-dimensional margins
+`NoMargin3', `BeginMargin3', `EndMargin3', `Margin3', `Margins3',
+`BeginPenMargin2', `EndPenMargin2', `PenMargin2', `PenMargins2',
+`BeginPenMargin3', `EndPenMargin3', `PenMargin3', `PenMargins3',
+`BeginDotMargin3', `EndDotMargin3', `DotMargin3', `DotMargins3',
+`Margin3', and `TrueMargin3'.
+
+ Further three-dimensional examples are provided in the files
+`near_earth.asy', `conicurv.asy', and (in the `animations'
+subdirectory) `cube.asy'.
+
+ Limited support for projected vector graphics (effectively
+three-dimensional nonrendered `PostScript') is available with the
+setting `render=0'. This currently only works for piecewise planar
+surfaces, such as those produced by the parametric `surface' routines
+in the `graph3' module. Surfaces produced by the `solids' package will
+also be properly rendered if the parameter `nslices' is sufficiently
+large.
+
+ In the module `bsp', hidden surface removal of planar pictures is
+implemented using a binary space partition and picture clipping. A
+planar path is first converted to a structure `face' derived from
+`picture'. A `face' may be given to a two-dimensional drawing routine
+in place of any `picture' argument. An array of such faces may then be
+drawn, removing hidden surfaces:
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection);
+ Labels may be projected to two dimensions, using projection `P', onto
+the plane passing through point `O' with normal `cross(u,v)' by
+multiplying it on the left by the transform
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection);
+
+ Here is an example that shows how a binary space partition may be
+used to draw a two-dimensional vector graphics projection of three
+orthogonal intersecting planes:
+
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+filldraw(faces.push(y),project(y),yellow);
+filldraw(faces.push(l),project(l),lightgrey);
+filldraw(faces.push(g),project(g),green);
+
+add(faces);
+
+
+
+
+File: asymptote.info, Node: obj, Next: graph3, Prev: three, Up: Base modules
+
+7.30 `obj'
+==========
+
+This module allows one to construct surfaces from simple obj files, as
+illustrated in the example files `galleon.asy' and `triceratops.asy'.
+
+
+File: asymptote.info, Node: graph3, Next: grid3, Prev: obj, Up: Base modules
+
+7.31 `graph3'
+=============
+
+This module implements three-dimensional versions of the functions in
+`graph.asy'. To draw an x axis in three dimensions, use the routine
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3, arrowbar3 arrow=None, bool above=false);
+ Analogous routines `yaxis' and `zaxis' can be used to draw y and z
+axes in three dimensions. There is also a routine for drawing all
+three axis:
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None);
+
+The predefined three-dimensional axis types are
+axis YZEquals(real y, real z, triple align=O, bool extend=false);
+axis XZEquals(real x, real z, triple align=O, bool extend=false);
+axis XYEquals(real x, real y, triple align=O, bool extend=false);
+axis YZZero(triple align=O, bool extend=false);
+axis XZZero(triple align=O, bool extend=false);
+axis XYZero(triple align=O, bool extend=false);
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false);
+ The optional `align' parameter to these routines can be used to
+specify the default axis and tick label alignments. The `Bounds' axis
+accepts two type parameters, each of which must be one of `Min', `Max',
+or `Both'. These parameters specify which of the four possible
+three-dimensional bounding box edges should be drawn.
+
+ The three-dimensional tick options are `NoTicks3', `InTicks',
+`OutTicks', and `InOutTicks'. These specify the tick directions for the
+`Bounds' axis type; other axis types inherit the direction that would
+be used for the `Bounds(Min,Min)' axis.
+
+ Here is an example of a helix and bounding box axes with ticks and
+axis labels, using orthographic projection:
+
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,2.7,operator ..);
+
+draw(p,Arrow3);
+
+scale(true);
+
+xaxis3(XZ()*"$x$",Bounds(),red,InTicks(Label,2,2));
+yaxis3(YZ()*"$y$",Bounds(),red,InTicks(beginlabel=false,Label,2,2));
+zaxis3(XZ()*"$z$",Bounds(),red,InTicks);
+
+
+
+The next example illustrates three-dimensional x, y, and z axes,
+without autoscaling of the axis limits:
+
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=perspective(5,2,2);
+
+scale(Linear,Linear,Log);
+
+xaxis3("$x$",0,1,red,OutTicks(2,2));
+yaxis3("$y$",0,1,red,OutTicks(2,2));
+zaxis3("$z$",1,30,red,OutTicks(beginlabel=false));
+
+
+
+One can also place ticks along a general three-dimensional axis:
+
+import graph3;
+
+size(0,100);
+
+path3 g=yscale3(2)*unitcircle3;
+currentprojection=perspective(10,10,10);
+
+axis(Label("C",position=0,align=15X),g,InTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path3 h=O--max(abs(max(g)),abs(min(g)))*dir(90,v);
+ return intersect(g,h)[0];},
+ new triple(real t) {return cross(dir(g,t),Z);}));
+
+
+
+Surface plots of matrices and functions over the region `box(a,b)' in
+the XY plane are also implemented:
+surface surface(real[][] f, pair a, pair b, bool[][] cond={});
+surface surface(real[][] f, pair a, pair b, splinetype splinetype,
+ bool[][] cond={});
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype splinetype=null, bool[][] cond={})
+surface surface(triple[][] f, bool[][] cond={});
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null);
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype splinetype, bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null);
+ The final version draws a parametric surface for a function f(u,v)
+over the parameter space `box(a,b)', as illustrated in the example
+`parametricsurface.asy'. The boolean array or function `cond' can be
+used to control which surface mesh cells are actually drawn (by default
+all mesh cells over `box(a,b)' are drawn). Surface lighting is
+illustrated in the example files `parametricsurface.asy' and `sinc.asy'.
+Lighting can be disabled by setting `light=nolight', as in this example
+of a Gaussian surface:
+
+import graph3;
+
+size(200,0);
+
+currentprojection=perspective(10,8,4);
+
+real f(pair z) {return 0.5+exp(-abs(z)^2);}
+
+draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle);
+
+draw(arc(0.12Z,0.2,90,60,90,25),ArcArrow3);
+
+surface s=surface(f,(-1,-1),(1,1),nx=5,Spline);
+
+xaxis3(Label("$x$"),red,Arrow3);
+yaxis3(Label("$y$"),red,Arrow3);
+zaxis3(XYZero(extend=true),red,Arrow3);
+
+draw(s,lightgray,meshpen=black+thick(),nolight);
+
+label("$O$",O,-Z+Y,red);
+
+
+A mesh can be drawn without surface filling by specifying `nullpen' for
+the surfacepen.
+
+ A vector field of `nu'\times`nv' arrows on a parametric surface `f'
+over `box(a,b)' can be drawn with the routine
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b,
+ int nu=nmesh, int nv=nu, bool truesize=false,
+ real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv),
+ bool cond(pair z)=null, pen p=currentpen,
+ arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
+ as illustrated in the examples `vectorfield3.asy' and
+`vectorfieldsphere.asy'.
+
+
+File: asymptote.info, Node: grid3, Next: solids, Prev: graph3, Up: Base modules
+
+7.32 `grid3'
+============
+
+This module, contributed by Philippe Ivaldi, can be used for drawing 3D
+grids. Here is an example (further examples can be found in `grid3.asy'
+and at `http://piprim.tuxfamily.org/asymptote/grid3/'):
+
+import grid3;
+
+size(8cm,0,IgnoreAspect);
+currentprojection=orthographic(0.5,1,0.5);
+
+scale(Linear, Linear, Log);
+
+limits((-2,-2,1),(0,2,100));
+
+grid3(XYZgrid);
+
+xaxis3(Label("$x$",position=EndPoint,align=S),Bounds(Min,Min),
+ OutTicks());
+yaxis3(Label("$y$",position=EndPoint,align=S),Bounds(Min,Min),OutTicks());
+zaxis3(Label("$z$",position=EndPoint,align=(-1,0.5)),Bounds(Min,Min),
+ OutTicks(beginlabel=false));
+
+
+
+
+File: asymptote.info, Node: solids, Next: tube, Prev: grid3, Up: Base modules
+
+7.33 `solids'
+=============
+
+This solid geometry package defines a structure `revolution' that can
+be used to fill and draw surfaces of revolution. The following example
+uses it to display the outline of a circular cylinder of radius 1 with
+axis `O--1.5unit(Y+Z)' with perspective projection:
+
+import solids;
+
+size(0,100);
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(r,heavygreen);
+
+
+
+Further illustrations are provided in the example files `cylinder.asy',
+`cones.asy', `hyperboloid.asy', and `torus.asy'.
+
+ The structure `skeleton' contains the three-dimensional wireframe
+used to visualize a volume of revolution:
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+
+
+File: asymptote.info, Node: tube, Next: flowchart, Prev: solids, Up: Base modules
+
+7.34 `tube'
+===========
+
+This package extends the routine `tube' defined in `three_arrows.asy'
+to arbitrary cross sections, colors, and spine transformations. The
+routine
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0);
+ draws a tube along `g' with cross section `section', after applying
+the transformation `T(t)' at `relpoint(g,t)'. The parameter `corner'
+controls the number of elementary tubes at the angular points of `g'. A
+nonzero value of `relstep' specifies a fixed relative time step (in the
+sense of `relpoint(g,t)') to use in constructing elementary tubes along
+`g'. The type `coloredpath' is a generalization of `path' to which a
+`path' can be cast:
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ int colortype=coloredSegments;
+}
+ Here `p' defines the cross section and the method `pens(real t)'
+returns an array of pens (interpreted as a cyclic array) used for
+shading the tube patches at `relpoint(g,t)'. If
+`colortype=coloredSegments', the tube patches are filled as if each
+segment of the section was colored with the pen returned by `pens(t)',
+whereas if `colortype=coloredNodes', the tube components are vertex
+shaded as if the nodes of the section were colored.
+
+ A `coloredpath' can be constructed with one of the routines:
+coloredpath coloredpath(path p, pen[] pens(real),
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen pen(real));
+ In the second case, the pens are independent of the relative time. In
+the third case, the array of pens contains only one pen, which depends
+of the relative time.
+
+ The casting of `path' to `coloredpath' allows the use of a `path'
+instead of a `coloredpath'; in this case the shading behaviour is the
+default shading behavior for a surface.
+
+ An example of `tube' is provided in the file `trefoilknot.asy'.
+Further examples can be found at
+`http://piprim.tuxfamily.org/asymptote/tube/'.
+
+
+File: asymptote.info, Node: flowchart, Next: contour, Prev: tube, Up: Base modules
+
+7.35 `flowchart'
+================
+
+This package provides routines for drawing flowcharts. The primary
+structure is a `block', which represents a single block on the
+flowchart. The following eight functions return a position on the
+appropriate edge of the block, given picture transform `t':
+
+pair block.top(transform t=identity());
+pair block.left(transform t=identity());
+pair block.right(transform t=identity());
+pair block.bottom(transform t=identity());
+pair block.topleft(transform t=identity());
+pair block.topright(transform t=identity());
+pair block.bottomleft(transform t=identity());
+pair block.bottomright(transform t=identity());
+
+
+To obtain an arbitrary position along the boundary of the block in user
+coordinates, use:
+pair block.position(real x, transform t=identity());
+
+
+The center of the block in user coordinates is stored in `block.center'
+and the block size in `PostScript' coordinates is given by `block.size'.
+
+A frame containing the block is returned by
+frame block.draw(pen p=currentpen);
+
+
+ The following block generation routines accept a Label, string, or
+frame for their object argument:
+
+"rectangular block with an optional header (and padding `dx' around header and body):"
+ block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight);
+ block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"diamond-shaped flowchart block:"
+ block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"circular flowchart block:"
+ block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter);
+
+"rectangular flowchart block with rounded corners:"
+ block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+
+"rectangular flowchart block with beveled edges:"
+ block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight);
+
+
+ To draw paths joining the pairs in `point' with right-angled lines,
+use the routine:
+path path(pair point[] ... flowdir dir[]);
+ The entries in `dir' identify whether successive segments between the
+pairs specified by `point' should be drawn in the `Horizontal' or
+`Vertical' direction.
+
+ Here is a simple flowchart example:
+
+size(0,300);
+
+import flowchart;
+
+block block1=rectangle(Label("Example",magenta),
+ pack(Label("Start:",heavygreen),"",Label("$A:=0$",blue),
+ "$B:=1$"),(-0.5,3),palegreen,paleblue,red);
+block block2=diamond(Label("Choice?",blue),(0,2),palegreen,red);
+block block3=roundrectangle("Do something",(-1,1));
+block block4=bevel("Don't do something",(1,1));
+block block5=circle("End",(0,0));
+
+draw(block1);
+draw(block2);
+draw(block3);
+draw(block4);
+draw(block5);
+
+add(new void(picture pic, transform t) {
+ draw(pic,path(new pair[]{block1.right(t),block2.top(t)},Horizontal),
+ Arrow,PenMargin);
+ draw(pic,Label("Yes",0.5,NW),path(new pair[]{block2.left(t),block3.top(t)},
+ Horizontal),Arrow,PenMargin);
+ draw(pic,Label("No",0.5,NE),path(new pair[]{block2.right(t),block4.top(t)},
+ Horizontal),Arrow,PenMargin);
+ draw(pic,path(new pair[]{block3.bottom(t),block5.left(t)},Vertical),
+ Arrow,PenMargin);
+ draw(pic,path(new pair[]{block4.bottom(t),block5.right(t)},Vertical),
+ Arrow,PenMargin);
+ });
+
+
+
+
+File: asymptote.info, Node: contour, Next: contour3, Prev: flowchart, Up: Base modules
+
+7.36 `contour'
+==============
+
+This package draws contour lines. To construct contours corresponding
+to the values in an array `c' for a function `f' on `box(a,b)', use
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --);
+ The integers `nx' and `ny' define the resolution. The default
+resolution, `ngraph x ngraph' (here `ngraph' defaults to `100'), can be
+increased for greater accuracy. The default interpolation operator is
+`operator --' (linear). Spline interpolation (`operator ..') may
+produce smoother contours but it can also lead to overshooting.
+
+ To construct contours for an array of data values on a uniform
+two-dimensional lattice on `box(a,b)', use
+guide[][] contour(real[][] f, real[][] midpoint=new real[][],
+ pair a, pair b, real[] c,
+ interpolate join=operator --);
+
+ To construct contours for an array of data values on a nonoverlapping
+regular mesh specified by the two-dimensional array `z', optionally
+specifying the values of `f' at the mesh midpoints, use
+guide[][] contour(pair[][] z, real[][] f,
+ real[][] midpoint=new real[][], real[] c,
+ interpolate join=operator --);
+
+ To construct contours for an array of values `f' specified at
+irregularly positioned points `z', use the routine
+guide[][] contour(pair[] z, real[] f, real[] c,
+ interpolate join=operator --);
+ The contours themselves can be drawn with one of the routines
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen)
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p)
+
+ The following simple example draws the contour at value `1' for the
+function z=x^2+y^2, which is a unit circle:
+
+import contour;
+size(75);
+
+real f(real a, real b) {return a^2+b^2;}
+draw(contour(f,(-1,-1),(1,1),new real[] {1}));
+
+
+
+The next example draws and labels multiple contours for the function
+z=x^2-y^2 with the resolution `100 x 100', using a dashed pen for
+negative contours and a solid pen for positive (and zero) contours:
+
+import contour;
+
+size(200);
+
+real f(real x, real y) {return x^2-y^2;}
+int n=10;
+real[] c=new real[n];
+for(int i=0; i < n; ++i) c[i]=(i-n/2)/n;
+
+pen[] p=sequence(new pen(int i) {
+ return (c[i] >= 0 ? solid : dashed)+fontsize(6);
+ },c.length);
+
+Label[] Labels=sequence(new Label(int i) {
+ return Label(c[i] != 0 ? (string) c[i] : "",Relative(unitrand()),(0,0),
+ UnFill(1bp));
+ },c.length);
+
+draw(Labels,contour(f,(-1,-1),(1,1),c),p);
+
+
+
+The next example illustrates how contour lines can be drawn on color
+density images:
+
+import graph;
+import palette;
+import contour;
+
+size(10cm,10cm,IgnoreAspect);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=200;
+int Divs=10;
+int divs=2;
+
+defaultpen(1bp);
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+scale(false);
+
+bounds range=image(f,Automatic,a,b,N,Palette);
+
+// Major contours
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+draw(contour(f,a,b,Cvals,N,operator --),Tickpen);
+
+// Minor contours
+real[] cvals;
+for(int i=0; i < Cvals.length-1; ++i)
+ cvals.append(uniform(Cvals[i],Cvals[i+1],divs)[1:divs]);
+draw(contour(f,a,b,cvals,N,operator --),tickpen);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,1),Top,Palette,
+ PaletteTicks(N=Divs,n=divs,Tickpen,tickpen));
+
+
+
+Finally, here is an example that illustrates the construction of
+contours from irregularly spaced data:
+
+import contour;
+
+size(200);
+
+int n=100;
+
+pair[] points=new pair[n];
+real[] values=new real[n];
+
+real f(real a, real b) {return a^2+b^2;}
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+for(int i=0; i < n; ++i) {
+ points[i]=(r(),r());
+ values[i]=f(points[i].x,points[i].y);
+}
+
+draw(contour(points,values,new real[]{0.25,0.5,1},operator ..),blue);
+
+
+
+In the above example, the contours of irregularly spaced data are
+constructed by first creating a triangular mesh from an array `z' of
+pairs:
+
+int[][] triangulate(pair[] z);
+
+size(200);
+int np=100;
+pair[] points;
+
+real r() {return 1.2*(rand()/randMax*2-1);}
+
+for(int i=0; i < np; ++i)
+ points.push((r(),r()));
+
+int[][] trn=triangulate(points);
+
+for(int i=0; i < trn.length; ++i) {
+ draw(points[trn[i][0]]--points[trn[i][1]]);
+ draw(points[trn[i][1]]--points[trn[i][2]]);
+ draw(points[trn[i][2]]--points[trn[i][0]]);
+}
+
+for(int i=0; i < np; ++i)
+ dot(points[i],red);
+
+
+
+The example `Gouraudcontour' illustrates how to produce color density
+images over such irregular triangular meshes. `Asymptote' uses a
+robust version of Paul Bourke's Delaunay triangulation algorithm based
+on the public-domain exact arithmetic predicates written by Jonathan
+Shewchuk.
+
+
+File: asymptote.info, Node: contour3, Next: slopefield, Prev: contour, Up: Base modules
+
+7.37 `contour3'
+===============
+
+This package draws surfaces described as the null space of real-valued
+functions of (x,y,z) or real[][][] matrices. Its usage is illustrated
+in the example file `magnetic.asy'.
+
+
+File: asymptote.info, Node: slopefield, Prev: contour3, Up: Base modules
+
+7.38 `slopefield'
+=================
+
+To draw a slope field for the differential equation dy/dx=f(x,y) (or
+dy/dx=f(x)), use:
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen,
+ arrowbar arrow=None);
+ Here, the points `a' and `b' are the lower left and upper right
+corners of the rectangle in which the slope field is to be drawn, `nx'
+and `ny' are the respective number of ticks in the x and y directions,
+`tickfactor' is the fraction of the minimum cell dimension to use for
+drawing ticks, and `p' is the pen to use for drawing the slope fields.
+The return value is a picture that can be added to `currentpicture' via
+the `add(picture)' command.
+
+ The function
+path curve(pair c, real f(real,real), pair a, pair b);
+ takes a point (`c') and a slope field-defining function `f' and
+returns, as a path, the curve passing through that point. The points
+`a' and `b' represent the rectangular boundaries over which the curve
+is interpolated.
+
+ Both `slopefield' and `curve' alternatively accept a function `real
+f(real)' that depends on x only, as seen in this example:
+
+import slopefield;
+
+size(200);
+
+real func(real x) {return 2x;}
+add(slopefield(func,(-3,-3),(3,3),20,Arrow));
+draw(curve((0,0),func,(-3,-3),(3,3)),red);
+
+
+
+
+File: asymptote.info, Node: Options, Next: Interactive mode, Prev: Base modules, Up: Top
+
+8 Options
+*********
+
+Type `asy -h' to see the full list of command-line options supported by
+`Asymptote':
+
+Usage: ../asy [options] [file ...]
+
+Options (negate by replacing - with -no):
+
+-V,-View View output; command-line only
+-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [Center]
+-antialias n Antialiasing width for rasterized output [2]
+-auto3D Automatically activate 3D scene [true]
+-autoimport string Module to automatically import
+-autoplain Enable automatic importing of plain [true]
+-autorotate Enable automatic PDF page rotation [false]
+-batchMask Mask fpu exceptions in batch mode [false]
+-batchView View output in batch mode [false]
+-bw Convert all colors to black and white [false]
+-cd directory Set current directory; command-line only
+-cmyk Convert rgb colors to cmyk [false]
+-c,-command string Command to autoexecute
+-compact Conserve memory at the expense of speed [false]
+-d,-debug Enable debugging messages [false]
+-divisor n Garbage collect using purge(divisor=n) [2]
+-embed Embed rendered preview image [true]
+-exitonEOF Exit interactive mode on EOF [true]
+-fitscreen Fit rendered image to screen [true]
+-globalwrite Allow write to other directory [false]
+-gray Convert all colors to grayscale [false]
+-h,-help Show summary of options; command-line only
+-historylines n Retain n lines of history [1000]
+-iconify Iconify rendering window [false]
+-inlineimage Generate inline embedded image [false]
+-inlinetex Generate inline TeX code [false]
+-interactiveMask Mask fpu exceptions in interactive mode [true]
+-interactiveView View output in interactive mode [true]
+-interactiveWrite Write expressions entered at the prompt to stdout [true]
+-k,-keep Keep intermediate files [false]
+-keepaux Keep intermediate LaTeX .aux files [false]
+-level n Postscript level [3]
+-l,-listvariables List available global functions and variables [false]
+-localhistory Use a local interactive history file [false]
+-m,-mask Mask fpu exceptions; command-line only
+-maxtile pair Maximum rendering tile size [(0,0)]
+-maxviewport pair Maximum viewport size [(2048,2048)]
+-multiline Input code over multiple lines at the prompt [false]
+-multipleView View output from multiple batch-mode files [false]
+-multisample n Multisampling width for screen images [4]
+-O,-offset pair PostScript offset [(0,0)]
+-f,-outformat format Convert each output file to specified format
+-o,-outname name Alternative output directory/filename
+-p,-parseonly Parse file [false]
+-pdfreload Automatically reload document in pdfviewer [false]
+-pdfreloaddelay usec Delay before attempting initial pdf reload [750000]
+-position pair Initial 3D rendering screen position [(0,0)]
+-prc Embed 3D PRC graphics in PDF output [true]
+-prompt string Prompt [> ]
+-prompt2 string Continuation prompt for multiline input [..]
+-q,-quiet Suppress welcome message [false]
+-render n Render 3D graphics using n pixels per bp (-1=auto) [-1]
+-rgb Convert cmyk colors to rgb [false]
+-safe Disable system call [true]
+-scroll n Scroll standard output n lines at a time [0]
+-tabcompletion Interactive prompt auto-completion [true]
+-tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex]
+-thick Render thick 3D lines [true]
+-thin Render thin 3D lines [true]
+-threads Use POSIX threads for 3D rendering [true]
+-toolbar Show 3D toolbar in PDF output [true]
+-s,-translate Show translated virtual machine code [false]
+-twice Run LaTeX twice (to resolve references) [false]
+-twosided Use two-sided 3D lighting model for rendering [true]
+-u,-user string General purpose user string
+-v,-verbose Increase verbosity level (can specify multiple times) [0]
+-version Show version; command-line only
+-wait Wait for child processes to finish before exiting [false]
+-where Show where listed variables are declared [false]
+-xformat format GUI deconstruction format [png]
+
+ All boolean options can be negated by prepending `no' to the option
+name.
+
+ If no arguments are given, `Asymptote' runs in interactive mode
+(*note Interactive mode::). In this case, the default output file is
+`out.eps'.
+
+ If `-' is given as the file argument, `Asymptote' reads from
+standard input.
+
+ If multiple files are specified, they are treated as separate
+`Asymptote' runs.
+
+ If the string `autoimport' is nonempty, a module with this name is
+automatically imported for each run as the final step in loading module
+`plain'.
+
+ Default option values may be entered as `Asymptote' code in a
+configuration file named `config.asy' (or the file specified by the
+environment variable `ASYMPTOTE_CONFIG' or `-config' option).
+`Asymptote' will look for this file in its usual search path.
+Typically the configuration file is placed in the `.asy' directory in
+the user's home directory (`%USERPROFILE%\.asy' under `MSDOS').
+Configuration variables are accessed using the long form of the option
+names:
+import settings;
+outformat="pdf";
+batchView=false;
+interactiveView=true;
+batchMask=false;
+interactiveMask=true;
+ Command-line options override these defaults. Most configuration
+variables may also be changed at runtime. The advanced configuration
+variables `dvipsOptions', `convertOptions', `gsOptions',
+`psviewerOptions', `pdfviewerOptions', and `glOptions' allow
+specialized options to be passed as a string to the respective
+applications or libraries.
+
+ If you insert
+import plain;
+settings.autoplain=true;
+ at the beginning of the configuration file, it can contain arbitrary
+`Asymptote' code.
+
+ The default output format is EPS for the (default) `latex' and `tex'
+tex engine and PDF for the `pdflatex', `xelatex', and `context' tex
+engines. Alternative output formats may be produced using the `-f'
+option (or `outformat' setting). The optional setting `-render n'
+requests an output resolution of `n' pixels per `bp'. Antialiasing is
+controlled by the parameter `antialias', which by default specifies a
+sampling width of 2 pixels. `Asymptote' can produce any output format
+supported by the `ImageMagick' `convert' program (version 6.3.5 or
+later recommended; an `Invalid Parameter' error message indicates that
+the `MSDOS' utility `convert' is being used instead of the one that
+comes with `ImageMagick'). To give specific options to `convert', use
+the `convertOptions' setting or call convert manually. This example
+emulates how `Asymptote' produces antialiased `tiff' output at one
+pixel per `bp':
+asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.tiff
+
+ If the option `-nosafe' is given, `Asymptote' runs in unsafe mode.
+This enables the `int system(string s)' call, allowing one to execute
+arbitrary shell commands. The default mode, `-safe', disables this call.
+
+ A `PostScript' offset may be specified as a pair (in `bp' units)
+with the `-O' option:
+asy -O 0,0 file
+ The default offset is zero. The default value of the page alignment
+setting `align' is `Center'.
+
+ The `-c' (`command') option may be used to execute arbitrary
+`Asymptote' code on the command line as a string. It is not necessary
+to terminate the string with a semicolon. Multiple `-c' options are
+executed in the order they are given. For example
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+ produces the output
+4
+0.841470984807897
+ and draws a unitsquare of size `100'.
+
+ The `-u' (`user') option may be used to specify arbitrary
+`Asymptote' settings on the command line as a string. It is not
+necessary to terminate the string with a semicolon. Multiple `-u'
+options are executed in the order they are given. Command-line code like
+`-u x=sqrt(2)' can be executed within a module like this:
+real x;
+usersetting();
+write(x);
+
+ When the `-l' (`listvariables') option is used with file arguments,
+only global functions and variables defined in the specified file(s)
+are listed.
+
+ Additional debugging output is produced with each additional `-v'
+option:
+`-v'
+ Display top-level module and final output file names.
+
+`-vv'
+ Also display imported and included module names and final `LaTeX'
+ and `dvips' processing information.
+
+`-vvv'
+ Also output `LaTeX' bidirectional pipe diagnostics.
+
+`-vvvv'
+ Also output knot guide solver diagnostics.
+
+`-vvvvv'
+ Also output `Asymptote' traceback diagnostics.
+
+
+File: asymptote.info, Node: Interactive mode, Next: GUI, Prev: Options, Up: Top
+
+9 Interactive mode
+******************
+
+Interactive mode is entered by executing the command `asy' with no file
+arguments. When the `-multiline' option is disabled (the default), each
+line must be a complete `Asymptote' statement (unless explicitly
+continued by a final backslash character `\'); it is not necessary to
+terminate input lines with a semicolon. If one assigns
+`settings.multiline=true', interactive code can be entered over
+multiple lines; in this mode, the automatic termination of interactive
+input lines by a semicolon is inhibited. Multiline mode is useful for
+cutting and pasting `Asymptote' code directly into the interactive
+input buffer.
+
+ Interactive mode can be conveniently used as a calculator:
+expressions entered at the interactive prompt (for which a
+corresponding `write' function exists) are automatically evaluated and
+written to `stdout'.
+
+ The following special commands are supported only in interactive mode
+and must be entered immediately after the prompt:
+
+`help'
+ view the manual;
+
+`reset'
+ reset the `Asymptote' environment to its initial state, except for
+ changes to the settings module (*note settings::), the current
+ directory (*note cd::), and breakpoints (*note Debugger::);
+
+`input FILE'
+ does an interactive reset, followed by the command `include FILE'.
+ If the file name `FILE' contains nonalphanumeric characters,
+ enclose it with quotation marks. A trailing semi-colon followed
+ by optional `Asymptote' commands may be entered on the same line.
+
+`quit'
+ exit interactive mode (`exit' is a synonym; the abbreviation `q'
+ is also accepted unless there exists a top-level variable named
+ `q'). A history of the most recent 1000 (this number can be
+ changed with the `historylines' configuration variable) previous
+ commands will be retained in the file `.asy/history' in the user's
+ home directory (unless the command-line option `-localhistory' was
+ specified, in which case the history will be stored in the file
+ `.asy_history' in the current directory).
+
+
+ Typing `ctrl-C' interrupts the execution of `Asymptote' code and
+returns control to the interactive prompt.
+
+ Interactive mode is implemented with the GNU `readline' library,
+with command history and auto-completion. To customize the key
+bindings, see:
+`http://cnswww.cns.cwru.edu/php/chet/readline/readline.html'
+
+ The file `asymptote.py' in the `Asymptote' system directory provides
+an alternative way of entering `Asymptote' commands interactively,
+coupled with the full power of `Python'. Copy this file to your `Python
+path' and then execute from within `Python' the commands
+from asymptote import *
+g=asy()
+g.size(200)
+g.draw("unitcircle")
+g.send("draw(unitsquare)")
+g.fill("unitsquare, blue")
+g.clip("unitcircle")
+g.label("\"$O$\", (0,0), SW")
+
+
+File: asymptote.info, Node: GUI, Next: PostScript to Asymptote, Prev: Interactive mode, Up: Top
+
+10 Graphical User Interface
+***************************
+
+In the event that adjustments to the final figure are required, the
+preliminary Graphical User Interface (GUI) `xasy' included with
+`Asymptote' allows you to move graphical objects and draw new ones.
+The modified figure can then be saved as a normal `Asymptote' file.
+
+* Menu:
+
+* GUI Installation:: Installing `xasy'
+* GUI Usage::
+
+
+File: asymptote.info, Node: GUI Installation, Next: GUI Usage, Up: GUI
+
+10.1 GUI Installation
+=====================
+
+As `xasy' is written in the interactive scripting language `Python/TK',
+it requires `Python' (`http://www.python.org'), the Python Imaging
+Library (`http://www.pythonware.com/products/pil/'), and the `tkinter'
+package (included with s`Python' under `Microsoft Windows') be
+installed. `Fedora Linux' users can either install `tkinter' with the
+commands
+yum install tkinter
+yum install tk-devel
+ or manually install the `tkinter', `tix', `tk', and `tk-devel'
+packages.
+
+ Pictures are deconstructed into the PNG image format, which supports
+full alpha channel transparency. Under `Microsoft Windows', this
+requires `Python 2.5 (or 2.5.1)' and the `Python Imaging Library':
+
+ `http://www.python.org/ftp/python/2.5.1/python-2.5.1.msi'
+
+ `http://effbot.org/downloads/PIL-1.1.6.win32-py2.5.exe'.
+ On `UNIX' systems, place
+`http://effbot.org/downloads/Imaging-1.1.6.tar.gz' in the `Asymptote'
+source directory, and type (as the root user):
+tar -zxf Imaging-1.1.6.tar.gz
+cd Imaging-1.1.6
+patch -p1 < ../patches/TkAlpha-Imaging-1.1.6.patch
+python setup.py install
+
+ Alternatively, `xasy' can deconstruct pictures into the GIF image
+format (not recommended as this is very slow), using white as the
+transparent color. This requires the lines
+import settings;
+xformat="gif";
+ in the `Asymptote' configuration file (*note configuration file::),
+along with the `ImageMagick' (*note convert::) program.
+
+
+File: asymptote.info, Node: GUI Usage, Prev: GUI Installation, Up: GUI
+
+10.2 GUI Usage
+==============
+
+A wheel mouse is convenient for raising and lowering objects within
+`xasy', to expose the object to be moved. If a wheel mouse is not
+available, mouse `Button-2' can be used to repeatedly lower an object
+instead. When run from the command line, `xasy' accepts a command line
+option `-x n', which sets the initial magnification to `n'.
+
+ Deconstruction of compound objects (such as arrows) can be prevented
+by enclosing them within the commands
+void begingroup(picture pic=currentpicture);
+void endgroup(picture pic=currentpicture);
+ By default, the elements of a picture or frame will be grouped
+together on adding them to a picture. However, the elements of a frame
+added to another frame are not grouped together by default: their
+elements will be individually deconstructed (*note add::).
+
+
+File: asymptote.info, Node: PostScript to Asymptote, Next: Help, Prev: GUI, Up: Top
+
+11 `PostScript' to `Asymptote'
+******************************
+
+The excellent `PostScript' editor `pstoedit' (version 3.45 or later;
+available from `http://pstoedit.net') includes an `Asymptote' backend.
+Unlike virtually all other `pstoedit' backends, this driver includes
+native clipping, even-odd fill rule, `PostScript' subpath, and full
+image support.
+
+ For full functionality, the patch `pstoedit-3.45asy.patch' in the
+`patches' directory should be applied. On `UNIX' systems, as the root
+user, place
+
+ `http://prdownloads.sourceforge.net/pstoedit/pstoedit-3.45.tar.gz'
+ in the `Asymptote' source directory, and type:
+
+tar -zxf pstoedit-3.45.tar.gz
+cd pstoedit-3.45
+patch -p1 < ../patches/pstoedit-3.45asy.patch
+autoconf
+./configure --prefix=/usr
+make install
+
+Then try:
+
+`asy -V /usr/local/share/doc/asymptote/examples/venn.asy'
+pstoedit -f asy venn.eps test.asy
+asy -V test
+
+If the line widths aren't quite correct, try giving `pstoedit' the
+`-dis' option. If the fonts aren't typeset correctly, try giving
+`pstoedit' the `-dt' option.
+
+
+File: asymptote.info, Node: Help, Next: Debugger, Prev: PostScript to Asymptote, Up: Top
+
+12 Help
+*******
+
+A list of frequently asked questions (FAQ) is maintained at
+
+ `http://asymptote.sourceforge.net/FAQ'
+ Questions on installing and using `Asymptote' that are not addressed
+in the FAQ should be sent to the `Asymptote' forum:
+
+ `http://sourceforge.net/forum/forum.php?forum_id=409349'
+ Including an example that illustrates what you are trying to do will
+help you get useful feedback. `LaTeX' problems can often be diagnosed
+with the `-vv' or `-vvv' command-line options. Contributions in the
+form of patches or `Asymptote' modules can be posted here:
+
+ `http://sourceforge.net/tracker/?atid=685685&group_id=120000'
+ To receive announcements of upcoming releases, please subscribe to
+`Asymptote' at
+
+ `http://freshmeat.net/projects/asy'
+ If you find a bug in `Asymptote', please check (if possible) whether
+the bug is still present in the latest Subversion developmental code
+(*note Subversion::) before submitting a bug report. New bugs can be
+submitted using the Bug Tracking System at
+
+ `http://sourceforge.net/projects/asymptote'
+ To see if the bug has already been fixed, check bugs with Status
+`Closed' and recent lines in
+
+ `http://asymptote.sourceforge.net/ChangeLog'
+ `Asymptote' can be configured with the optional GNU library
+`libsigsegv', available from `http://libsigsegv.sourceforge.net', which
+allows one to distinguish user-generated `Asymptote' stack overflows
+(*note stack overflow::) from true segmentation faults (due to internal
+C++ programming errors; please submit the `Asymptote' code that
+generates such segmentation faults along with your bug report).
+
+
+File: asymptote.info, Node: Debugger, Next: Credits, Prev: Help, Up: Top
+
+13 Debugger
+***********
+
+Asymptote now includes a line-based (as opposed to code-based) debugger
+that can assist the user in following flow control. To set a break
+point in file `file' at line `line', use the command
+
+void stop(string file, int line, code s=quote{});
+ The optional argument `s' may be used to conditionally set the variable
+`ignore' in `plain_debugger.asy' to `true'. For example, the first 10
+instances of this breakpoint will be ignored (the variable `int
+count=0' is defined in `plain_debugger.asy'):
+stop("test",2,quote{ignore=(++count <= 10);});
+
+ To set a break point in file `file' at the first line containing the
+string `text', use
+
+void stop(string file, string text, code s=quote{});
+ To list all breakpoints, use:
+void breakpoints();
+ To clear a breakpoint, use:
+void clear(string file, int line);
+ To clear all breakpoints, use:
+void clear();
+
+ The following commands may be entered at the debugging prompt:
+
+``h''
+ help;
+
+``c''
+ continue execution;
+
+``i''
+ step to the next instruction;
+
+``s''
+ step to the next executable line;
+
+``n''
+ step to the next executable line in the current file;
+
+``f''
+ step to the next file;
+
+``r''
+ return to the file associated with the most recent breakpoint;
+
+``t''
+ toggle tracing (`-vvvvv') mode;
+
+``q''
+ quit debugging and end execution;
+
+``x''
+ exit the debugger and run to completion.
+
+ Arbitrary `Asymptote' code may also be entered at the debugging
+prompt; however, since the debugger is implemented with `eval',
+currently only top-level (global) variables can be displayed or
+modified.
+
+ The debugging prompt may be entered manually with the call
+void breakpoint(code s=quote{});
+
+
+File: asymptote.info, Node: Credits, Next: Index, Prev: Debugger, Up: Top
+
+14 Acknowledgments
+******************
+
+Financial support for the development of `Asymptote' was generously
+provided by the Natural Sciences and Engineering Research Council of
+Canada, the Pacific Institute for Mathematical Sciences, and the
+University of Alberta Faculty of Science.
+
+ We also would like to acknowledge the previous work of John D. Hobby,
+author of the program `MetaPost' that inspired the development of
+`Asymptote', and Donald E. Knuth, author of TeX and `MetaFont' (on
+which `MetaPost' is based).
+
+ The authors of `Asymptote' are Andy Hammerlindl, John Bowman, and
+Tom Prince. Sean Healy designed the `Asymptote' logo. Other
+contributors include Radoslav Marinov, Orest Shardt, Chris Savage,
+Philippe Ivaldi, Olivier Guibe', Jacques Pienaar, Mark Henning, Steve
+Melenchuk, Martin Wiebusch, and Stefan Knorr.
+
+
+File: asymptote.info, Node: Index, Prev: Credits, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* !: Arithmetic & logical.
+ (line 68)
+* != <1>: Arithmetic & logical.
+ (line 38)
+* !=: Structures. (line 54)
+* %: Arithmetic & logical.
+ (line 23)
+* %=: Self & prefix operators.
+ (line 6)
+* & <1>: Arithmetic & logical.
+ (line 56)
+* &: Tutorial. (line 192)
+* &&: Arithmetic & logical.
+ (line 53)
+* * <1>: Arithmetic & logical.
+ (line 17)
+* *: Pens. (line 15)
+* **: Arithmetic & logical.
+ (line 31)
+* *=: Self & prefix operators.
+ (line 6)
+* + <1>: Arithmetic & logical.
+ (line 13)
+* +: Pens. (line 15)
+* ++: Self & prefix operators.
+ (line 6)
+* +=: Self & prefix operators.
+ (line 6)
+* -: Arithmetic & logical.
+ (line 14)
+* -- <1>: Self & prefix operators.
+ (line 6)
+* --: Tutorial. (line 109)
+* ---: Tutorial. (line 192)
+* -=: Self & prefix operators.
+ (line 6)
+* -c: Options. (line 155)
+* -l: Options. (line 174)
+* -u: Options. (line 165)
+* -V <1>: Tutorial. (line 41)
+* -V: Configuring. (line 6)
+* ..: Tutorial. (line 109)
+* .asy: Search paths. (line 13)
+* /: Arithmetic & logical.
+ (line 20)
+* /=: Self & prefix operators.
+ (line 6)
+* 2D graphs: graph. (line 6)
+* 3D graphs: graph3. (line 6)
+* 3D grids: grid3. (line 6)
+* 3D rendering: Compiling from UNIX source.
+ (line 16)
+* :: Arithmetic & logical.
+ (line 73)
+* ::: Tutorial. (line 176)
+* <: Arithmetic & logical.
+ (line 41)
+* <=: Arithmetic & logical.
+ (line 44)
+* == <1>: Arithmetic & logical.
+ (line 37)
+* ==: Structures. (line 54)
+* >: Arithmetic & logical.
+ (line 50)
+* >=: Arithmetic & logical.
+ (line 47)
+* ?: Arithmetic & logical.
+ (line 73)
+* ^: Arithmetic & logical.
+ (line 28)
+* ^=: Self & prefix operators.
+ (line 6)
+* ^^: Tutorial. (line 197)
+* a4: Configuring. (line 62)
+* abort: Data types. (line 320)
+* abs <1>: Mathematical functions.
+ (line 35)
+* abs: Data types. (line 60)
+* accel <1>: three. (line 433)
+* accel: Paths and guides. (line 110)
+* access: Import. (line 6)
+* acknowledgments: Credits. (line 6)
+* aCos: Mathematical functions.
+ (line 20)
+* acos: Mathematical functions.
+ (line 6)
+* acosh: Mathematical functions.
+ (line 6)
+* add: Frames and pictures. (line 190)
+* Ai: Mathematical functions.
+ (line 48)
+* Ai_deriv: Mathematical functions.
+ (line 48)
+* Airy: Mathematical functions.
+ (line 48)
+* alias <1>: Arrays. (line 187)
+* alias: Structures. (line 54)
+* align: Options. (line 149)
+* Align: label. (line 12)
+* all: Arrays. (line 331)
+* Allow: Pens. (line 323)
+* AND: Arithmetic & logical.
+ (line 80)
+* and: Tutorial. (line 165)
+* angle: Data types. (line 68)
+* animate <1>: animation. (line 12)
+* animate <2>: Files. (line 148)
+* animate: Configuring. (line 68)
+* animation: animation. (line 6)
+* annotate: annotate. (line 6)
+* antialias <1>: Options. (line 129)
+* antialias: three. (line 180)
+* antialiasing: Compiling from UNIX source.
+ (line 16)
+* append <1>: Arrays. (line 39)
+* append: Files. (line 36)
+* arc: three. (line 245)
+* Arc: Paths and guides. (line 32)
+* arc: Paths and guides. (line 22)
+* ArcArrow: draw. (line 26)
+* ArcArrow3: three. (line 476)
+* ArcArrows: draw. (line 26)
+* ArcArrows3: three. (line 476)
+* arclength <1>: three. (line 433)
+* arclength: Paths and guides. (line 137)
+* arctime <1>: three. (line 433)
+* arctime: Paths and guides. (line 141)
+* arguments: Default arguments. (line 6)
+* arithmetic operators: Arithmetic & logical.
+ (line 6)
+* array: Arrays. (line 125)
+* array iteration: Programming. (line 33)
+* arrays: Arrays. (line 6)
+* arrow: label. (line 72)
+* Arrow: draw. (line 26)
+* arrow: Drawing commands. (line 31)
+* arrow keys: Tutorial. (line 21)
+* Arrow3: three. (line 476)
+* Arrows: draw. (line 26)
+* Arrows3: three. (line 476)
+* as: Import. (line 70)
+* aSin: Mathematical functions.
+ (line 20)
+* asin: Mathematical functions.
+ (line 6)
+* asinh: Mathematical functions.
+ (line 6)
+* Aspect: Frames and pictures. (line 54)
+* assignment: Programming. (line 8)
+* asy: Import. (line 105)
+* asy-mode: Editing modes. (line 6)
+* asy.vim: Editing modes. (line 33)
+* asymptote.sty: LaTeX usage. (line 6)
+* ASYMPTOTE_CONFIG: Options. (line 102)
+* aTan: Mathematical functions.
+ (line 20)
+* atan: Mathematical functions.
+ (line 6)
+* atan2: Mathematical functions.
+ (line 6)
+* atanh: Mathematical functions.
+ (line 6)
+* atleast: Tutorial. (line 165)
+* attach <1>: graph. (line 405)
+* attach: LaTeX usage. (line 32)
+* autoadjust: three. (line 315)
+* autoimport: Options. (line 98)
+* automatic scaling: graph. (line 672)
+* axialshade: fill. (line 43)
+* axis <1>: graph3. (line 66)
+* axis: graph. (line 870)
+* azimuth: Data types. (line 124)
+* babel: babel. (line 6)
+* background color: Frames and pictures. (line 162)
+* BackView: three. (line 340)
+* Bar: draw. (line 19)
+* Bar3: three. (line 476)
+* Bars: draw. (line 19)
+* Bars3: three. (line 476)
+* barsize: draw. (line 19)
+* base modules: Base modules. (line 6)
+* basealign: Pens. (line 164)
+* baseline: label. (line 92)
+* batch mode: Tutorial. (line 30)
+* beep: Data types. (line 334)
+* BeginArcArrow: draw. (line 26)
+* BeginArcArrow3: three. (line 476)
+* BeginArrow: draw. (line 26)
+* BeginArrow3: three. (line 476)
+* BeginBar: draw. (line 19)
+* BeginBar3: three. (line 476)
+* BeginDotMargin: draw. (line 42)
+* BeginDotMargin3: three. (line 492)
+* BeginMargin: draw. (line 42)
+* BeginMargin3: three. (line 492)
+* BeginPenMargin: draw. (line 42)
+* BeginPenMargin2: three. (line 492)
+* BeginPenMargin3: three. (line 492)
+* BeginPoint: label. (line 57)
+* Bessel: Mathematical functions.
+ (line 48)
+* bevel: flowchart. (line 68)
+* beveljoin: Pens. (line 134)
+* bezulate: three. (line 98)
+* Bi: Mathematical functions.
+ (line 48)
+* Bi_deriv: Mathematical functions.
+ (line 48)
+* binary format: Files. (line 71)
+* binary operators: Arithmetic & logical.
+ (line 6)
+* binarytree: binarytree. (line 6)
+* binput: Files. (line 71)
+* Blank: draw. (line 26)
+* block.bottom: flowchart. (line 19)
+* block.bottomleft: flowchart. (line 19)
+* block.bottomright: flowchart. (line 19)
+* block.center: flowchart. (line 26)
+* block.draw: flowchart. (line 31)
+* block.left: flowchart. (line 19)
+* block.position: flowchart. (line 24)
+* block.right: flowchart. (line 19)
+* block.top: flowchart. (line 19)
+* block.topleft: flowchart. (line 19)
+* block.topright: flowchart. (line 19)
+* bool: Data types. (line 14)
+* bool3: Data types. (line 23)
+* boolean operators: Arithmetic & logical.
+ (line 6)
+* Bottom: graph. (line 128)
+* BottomTop: graph. (line 134)
+* BottomView: three. (line 340)
+* bounding box: Frames and pictures. (line 162)
+* Bounds: graph3. (line 20)
+* boutput: Files. (line 71)
+* box <1>: three. (line 267)
+* box: Frames and pictures. (line 22)
+* bp: Tutorial. (line 17)
+* break: Programming. (line 29)
+* breakpoints: Debugger. (line 21)
+* brick: Pens. (line 247)
+* broken axis: graph. (line 773)
+* bug reports: Help. (line 23)
+* buildcycle: Paths and guides. (line 251)
+* Button-1: GUI. (line 6)
+* Button-2: GUI. (line 6)
+* BWRainbow: palette. (line 15)
+* BWRainbow2: palette. (line 18)
+* C string: Data types. (line 189)
+* CAD: CAD. (line 6)
+* calculateTransform: Frames and pictures. (line 105)
+* casts: Casts. (line 6)
+* cbrt: Mathematical functions.
+ (line 6)
+* cd: Files. (line 24)
+* ceil: Mathematical functions.
+ (line 26)
+* center: three. (line 300)
+* Center: label. (line 62)
+* checker: Pens. (line 247)
+* Chinese: unicode. (line 12)
+* choose: Mathematical functions.
+ (line 39)
+* Ci: Mathematical functions.
+ (line 48)
+* circle <1>: flowchart. (line 57)
+* circle: three. (line 241)
+* Circle: Paths and guides. (line 17)
+* circle: Paths and guides. (line 10)
+* circlebarframe: markers. (line 18)
+* CJK: unicode. (line 12)
+* clear <1>: Debugger. (line 23)
+* clear: Files. (line 86)
+* clip: fill. (line 110)
+* cm: Tutorial. (line 63)
+* cmyk: Pens. (line 34)
+* colatitude: Data types. (line 129)
+* color: Pens. (line 23)
+* coloredNodes: tube. (line 25)
+* coloredpath: tube. (line 18)
+* coloredSegments: tube. (line 25)
+* colorless: Pens. (line 54)
+* colors: Pens. (line 51)
+* comma: Files. (line 59)
+* comma-separated-value mode: Arrays. (line 362)
+* command-line options <1>: Options. (line 7)
+* command-line options: Configuring. (line 82)
+* comment character: Files. (line 15)
+* compass directions: Tutorial. (line 94)
+* Compiling from UNIX source: Compiling from UNIX source.
+ (line 6)
+* complement: Arrays. (line 153)
+* concat: Arrays. (line 183)
+* conditional <1>: Arithmetic & logical.
+ (line 73)
+* conditional: Programming. (line 8)
+* config: Options. (line 102)
+* configuration file: Configuring. (line 21)
+* configuring: Configuring. (line 6)
+* conj: Data types. (line 57)
+* constructors: Structures. (line 95)
+* context: Options. (line 129)
+* continue <1>: Debugger. (line 31)
+* continue: Programming. (line 29)
+* contour: contour. (line 7)
+* contour3: contour3. (line 6)
+* controls <1>: three. (line 6)
+* controls: Tutorial. (line 154)
+* controlSpecifier: Paths and guides. (line 375)
+* convert <1>: Options. (line 129)
+* convert <2>: animation. (line 6)
+* convert <3>: Files. (line 148)
+* convert: Configuring. (line 68)
+* convertOptions: Options. (line 117)
+* Coons shading: fill. (line 74)
+* copy: Arrays. (line 174)
+* Cos: Mathematical functions.
+ (line 20)
+* cos: Mathematical functions.
+ (line 6)
+* cosh: Mathematical functions.
+ (line 6)
+* cputime: Structures. (line 177)
+* crop: graph. (line 626)
+* cropping graphs: graph. (line 626)
+* cross <1>: graph. (line 474)
+* cross: Data types. (line 167)
+* crossframe: markers. (line 23)
+* crosshatch: Pens. (line 263)
+* csv: Arrays. (line 362)
+* cubicroots: Arrays. (line 320)
+* curl <1>: three. (line 6)
+* curl: Tutorial. (line 172)
+* curlSpecifier: Paths and guides. (line 387)
+* currentpen: Pens. (line 6)
+* currentprojection: three. (line 337)
+* curve: slopefield. (line 20)
+* custom axis types: graph. (line 138)
+* custom mark routine: graph. (line 566)
+* custom tick locations: graph. (line 241)
+* cut: Paths and guides. (line 233)
+* cycle <1>: three. (line 6)
+* cycle: Tutorial. (line 46)
+* cyclic <1>: three. (line 433)
+* cyclic <2>: Arrays. (line 39)
+* cyclic: Paths and guides. (line 75)
+* cyclicflag: Arrays. (line 39)
+* Cyrillic: unicode. (line 7)
+* dashdotted: Pens. (line 92)
+* dashed: Pens. (line 92)
+* data types: Data types. (line 6)
+* date: Data types. (line 290)
+* Debian: UNIX binary distributions.
+ (line 19)
+* debugger: Debugger. (line 6)
+* declaration: Programming. (line 8)
+* deconstruct: GUI Usage. (line 6)
+* default arguments: Default arguments. (line 6)
+* defaultformat: graph. (line 169)
+* DefaultHead: draw. (line 26)
+* DefaultHead3: three. (line 476)
+* defaultpen: Pens. (line 46)
+* deferred drawing: simplex. (line 6)
+* Degrees: Mathematical functions.
+ (line 17)
+* degrees <1>: Mathematical functions.
+ (line 17)
+* degrees: Data types. (line 73)
+* delete <1>: Arrays. (line 39)
+* delete: Files. (line 143)
+* description: Description. (line 6)
+* diagonal: Arrays. (line 305)
+* diamond: flowchart. (line 50)
+* dimension: Arrays. (line 368)
+* dir <1>: three. (line 433)
+* dir <2>: Paths and guides. (line 99)
+* dir <3>: Data types. (line 85)
+* dir: Search paths. (line 10)
+* direction specifier: Tutorial. (line 115)
+* directory: Files. (line 24)
+* dirSpecifier: Paths and guides. (line 369)
+* dirtime: Paths and guides. (line 147)
+* display: Configuring. (line 68)
+* do: Programming. (line 29)
+* dot <1>: Data types. (line 98)
+* dot: draw. (line 83)
+* DotMargin: draw. (line 42)
+* DotMargin3: three. (line 492)
+* DotMargins: draw. (line 42)
+* DotMargins3: three. (line 492)
+* dotted: Pens. (line 92)
+* double: Files. (line 71)
+* double deferred drawing: three. (line 222)
+* Draw: Frames and pictures. (line 145)
+* draw: draw. (line 110)
+* Draw: draw. (line 26)
+* draw: Drawing commands. (line 31)
+* drawing commands: Drawing commands. (line 6)
+* drawline: math. (line 9)
+* drawtree: drawtree. (line 7)
+* dvips: Configuring. (line 68)
+* dvipsOptions: Options. (line 117)
+* E <1>: Mathematical functions.
+ (line 48)
+* E: Tutorial. (line 94)
+* Editing modes: Editing modes. (line 6)
+* Ei: Mathematical functions.
+ (line 48)
+* ellipse: Frames and pictures. (line 22)
+* elliptic functions: Mathematical functions.
+ (line 48)
+* else: Programming. (line 8)
+* emacs: Editing modes. (line 6)
+* embed: embed. (line 6)
+* empty: Frames and pictures. (line 7)
+* EndArcArrow: draw. (line 26)
+* EndArcArrow3: three. (line 476)
+* EndArrow: draw. (line 26)
+* EndArrow3: three. (line 476)
+* EndBar: draw. (line 19)
+* EndBar3: three. (line 476)
+* EndDotMargin: draw. (line 42)
+* EndDotMargin3: three. (line 492)
+* endl: Files. (line 59)
+* EndMargin: draw. (line 42)
+* EndMargin3: three. (line 492)
+* EndPenMargin: draw. (line 42)
+* EndPenMargin2: three. (line 492)
+* EndPenMargin3: three. (line 492)
+* EndPoint: label. (line 57)
+* envelope: Frames and pictures. (line 22)
+* environment variables: Configuring. (line 86)
+* eof <1>: Arrays. (line 346)
+* eof: Files. (line 86)
+* eol <1>: Arrays. (line 346)
+* eol: Files. (line 86)
+* EPS: label. (line 80)
+* erase <1>: Frames and pictures. (line 7)
+* erase: Data types. (line 239)
+* erf: Mathematical functions.
+ (line 6)
+* erfc: Mathematical functions.
+ (line 6)
+* error: Files. (line 15)
+* errorbars: graph. (line 474)
+* eval: Import. (line 101)
+* evenodd <1>: Pens. (line 148)
+* evenodd: Tutorial. (line 211)
+* exit <1>: Debugger. (line 57)
+* exit <2>: Interactive mode. (line 37)
+* exit: Data types. (line 325)
+* exp: Mathematical functions.
+ (line 6)
+* expi: Data types. (line 81)
+* explicit: Casts. (line 6)
+* explicit casts: Casts. (line 22)
+* expm1: Mathematical functions.
+ (line 6)
+* exponential integral: Mathematical functions.
+ (line 48)
+* extendcap: Pens. (line 125)
+* extension <1>: MetaPost. (line 10)
+* extension: Paths and guides. (line 228)
+* external: embed. (line 28)
+* extrude: three. (line 427)
+* F: Mathematical functions.
+ (line 48)
+* fabs: Mathematical functions.
+ (line 6)
+* face: three. (line 511)
+* factorial: Mathematical functions.
+ (line 39)
+* Fedora: UNIX binary distributions.
+ (line 15)
+* feynman: feynman. (line 6)
+* fft: Arrays. (line 252)
+* FFTW: Compiling from UNIX source.
+ (line 59)
+* file <1>: Debugger. (line 45)
+* file: Files. (line 6)
+* Fill: Frames and pictures. (line 131)
+* fill <1>: fill. (line 17)
+* fill: draw. (line 116)
+* Fill: draw. (line 26)
+* FillDraw: Frames and pictures. (line 121)
+* filldraw: fill. (line 11)
+* FillDraw: draw. (line 26)
+* filloutside: fill. (line 27)
+* fillrule: Pens. (line 148)
+* find <1>: Arrays. (line 162)
+* find: Data types. (line 224)
+* firstcut: Paths and guides. (line 243)
+* fit: Frames and pictures. (line 101)
+* fix-cm: Pens. (line 174)
+* fixedscaling: Frames and pictures. (line 74)
+* floor: Mathematical functions.
+ (line 26)
+* flowchart: flowchart. (line 6)
+* flush: Files. (line 59)
+* fmod: Mathematical functions.
+ (line 6)
+* font: Pens. (line 188)
+* font command: Pens. (line 188)
+* fontcommand: Pens. (line 203)
+* fontsize: Pens. (line 174)
+* for: Programming. (line 8)
+* format <1>: Options. (line 129)
+* format: Data types. (line 266)
+* forum: Help. (line 6)
+* frame: Frames and pictures. (line 7)
+* freeglut: Compiling from UNIX source.
+ (line 16)
+* from: Import. (line 17)
+* FrontView: three. (line 340)
+* function declarations: Functions. (line 67)
+* function shading: fill. (line 95)
+* Function shading: fill. (line 95)
+* functions <1>: Mathematical functions.
+ (line 6)
+* functions: Functions. (line 6)
+* functionshade: fill. (line 95)
+* gamma: Mathematical functions.
+ (line 6)
+* Gaussrand: Mathematical functions.
+ (line 39)
+* geometry: geometry. (line 6)
+* getc: Files. (line 30)
+* getpair: Files. (line 111)
+* getreal: Files. (line 111)
+* getstring: Files. (line 111)
+* gettriple: Files. (line 111)
+* glOptions <1>: Options. (line 117)
+* glOptions: three. (line 180)
+* GNU Scientific Library: Mathematical functions.
+ (line 48)
+* gouraudshade: fill. (line 58)
+* Gradient: palette. (line 25)
+* gradient shading: fill. (line 32)
+* graph: graph. (line 6)
+* graph3: graph3. (line 6)
+* graphic: label. (line 80)
+* graphical user interface: GUI. (line 6)
+* gray: Pens. (line 25)
+* Grayscale: palette. (line 9)
+* grayscale: Pens. (line 25)
+* grid <1>: graph. (line 724)
+* grid: Pens. (line 247)
+* grid3: grid3. (line 6)
+* gs: Configuring. (line 6)
+* gsl: Mathematical functions.
+ (line 48)
+* GSL: Compiling from UNIX source.
+ (line 59)
+* gsOptions: Options. (line 117)
+* GUI: GUI. (line 6)
+* GUI installation: GUI Installation. (line 6)
+* GUI usage: GUI Usage. (line 6)
+* guide: Paths and guides. (line 296)
+* guide3: three. (line 6)
+* hatch: Pens. (line 263)
+* height: LaTeX usage. (line 32)
+* help <1>: Debugger. (line 30)
+* help <2>: Help. (line 6)
+* help: Interactive mode. (line 25)
+* Hermite: graph. (line 37)
+* Hermite(splinetype splinetype: graph. (line 37)
+* hex: Data types. (line 278)
+* hexidecimal <1>: Pens. (line 59)
+* hexidecimal: Data types. (line 278)
+* hidden surface removal: three. (line 511)
+* histogram: Mathematical functions.
+ (line 39)
+* history: Files. (line 136)
+* historylines: Interactive mode. (line 42)
+* HookHead: draw. (line 26)
+* HookHead3: three. (line 476)
+* Horizontal: flowchart. (line 74)
+* hypot: Mathematical functions.
+ (line 6)
+* I: Mathematical functions.
+ (line 48)
+* i_scaled: Mathematical functions.
+ (line 48)
+* iconic: three. (line 180)
+* identity <1>: Arrays. (line 302)
+* identity <2>: Mathematical functions.
+ (line 6)
+* identity: Transforms. (line 24)
+* if: Programming. (line 8)
+* IgnoreAspect: Frames and pictures. (line 58)
+* image: palette. (line 34)
+* ImageMagick <1>: Options. (line 129)
+* ImageMagick <2>: animation. (line 6)
+* ImageMagick: Configuring. (line 68)
+* implicit casts: Casts. (line 6)
+* implicit linear solver: MetaPost. (line 10)
+* implicit scaling: Implicit scaling. (line 6)
+* import: Import. (line 48)
+* inches: Tutorial. (line 63)
+* including images: label. (line 80)
+* inheritance: Structures. (line 189)
+* initialized: Arrays. (line 39)
+* initializers: Variable initializers.
+ (line 6)
+* InOutTicks: graph3. (line 34)
+* input <1>: Interactive mode. (line 31)
+* input: Files. (line 11)
+* insert <1>: Arrays. (line 39)
+* insert: Data types. (line 235)
+* inside: Paths and guides. (line 275)
+* inst: Debugger. (line 36)
+* installation: Installation. (line 6)
+* int: Data types. (line 28)
+* integer division: Arithmetic & logical.
+ (line 6)
+* interactive mode: Interactive mode. (line 6)
+* interior: Paths and guides. (line 271)
+* international characters: unicode. (line 6)
+* interp: Arithmetic & logical.
+ (line 76)
+* interpolate: interpolate. (line 6)
+* intersect <1>: three. (line 433)
+* intersect <2>: math. (line 13)
+* intersect: Paths and guides. (line 176)
+* intersectionpoint <1>: three. (line 433)
+* intersectionpoint <2>: math. (line 17)
+* intersectionpoint: Paths and guides. (line 220)
+* intersectionpoints <1>: three. (line 433)
+* intersectionpoints: Paths and guides. (line 224)
+* intersections <1>: three. (line 433)
+* intersections: Paths and guides. (line 187)
+* InTicks: graph3. (line 34)
+* intMax: Data types. (line 28)
+* intMin: Data types. (line 28)
+* inverse <1>: Arrays. (line 308)
+* inverse: Transforms. (line 16)
+* invert: three. (line 366)
+* invisible: Pens. (line 39)
+* J: Mathematical functions.
+ (line 6)
+* Japanese: unicode. (line 12)
+* K: Mathematical functions.
+ (line 48)
+* k_scaled: Mathematical functions.
+ (line 48)
+* keyboard bindings:: three. (line 149)
+* keys: Arrays. (line 39)
+* keywords: Named arguments. (line 6)
+* Korean: unicode. (line 12)
+* Label: graph. (line 332)
+* label: clip. (line 16)
+* Label: draw. (line 98)
+* labelpath: labelpath. (line 6)
+* labelpath3: labelpath3. (line 6)
+* labelx: graph. (line 332)
+* labely: graph. (line 332)
+* Landscape: Frames and pictures. (line 93)
+* lastcut: Paths and guides. (line 247)
+* lasy-mode: Editing modes. (line 6)
+* latex: Options. (line 129)
+* LaTeX fonts: Pens. (line 188)
+* LaTeX usage: LaTeX usage. (line 6)
+* latin1: latin1. (line 6)
+* latitude: Data types. (line 134)
+* latticeshade: fill. (line 32)
+* layer: Drawing commands. (line 16)
+* leastsquares <1>: graph. (line 892)
+* leastsquares: stats. (line 6)
+* Left: graph. (line 274)
+* LeftRight: graph. (line 280)
+* LeftSide: label. (line 62)
+* LeftTicks: graph. (line 155)
+* LeftView: three. (line 340)
+* legend <1>: graph. (line 421)
+* legend <2>: draw. (line 64)
+* legend: Drawing commands. (line 31)
+* Legendre: Mathematical functions.
+ (line 48)
+* length <1>: three. (line 433)
+* length <2>: Arrays. (line 39)
+* length <3>: Paths and guides. (line 66)
+* length: Data types. (line 60)
+* letter: Configuring. (line 62)
+* libm routines: Mathematical functions.
+ (line 6)
+* libsigsegv <1>: Help. (line 33)
+* libsigsegv: Functions. (line 88)
+* limits: graph. (line 626)
+* line: Arrays. (line 346)
+* line mode: Arrays. (line 346)
+* Linear: graph. (line 672)
+* linecap: Pens. (line 125)
+* linejoin: Pens. (line 134)
+* lineskip: Pens. (line 174)
+* linewidth: Pens. (line 115)
+* locale: Data types. (line 285)
+* Log: graph. (line 672)
+* log: Mathematical functions.
+ (line 6)
+* log-log graph: graph. (line 703)
+* log10: Mathematical functions.
+ (line 6)
+* log1p: Mathematical functions.
+ (line 6)
+* log2 graph: graph. (line 753)
+* logarithmic graph: graph. (line 703)
+* logical operators: Arithmetic & logical.
+ (line 6)
+* longdashdotted: Pens. (line 92)
+* longdashed: Pens. (line 92)
+* longitude: Data types. (line 139)
+* loop: Programming. (line 8)
+* MacOS X binary distributions: MacOS X binary distributions.
+ (line 6)
+* makepen: Pens. (line 296)
+* map: Arrays. (line 144)
+* Margin: draw. (line 42)
+* Margin3: three. (line 492)
+* margins: three. (line 228)
+* Margins: draw. (line 42)
+* Margins3: three. (line 492)
+* mark: graph. (line 474)
+* markangle: markers. (line 38)
+* marker: graph. (line 474)
+* markers: markers. (line 6)
+* marknodes: graph. (line 474)
+* markuniform: graph. (line 474)
+* math: math. (line 6)
+* mathematical functions: Mathematical functions.
+ (line 6)
+* max <1>: three. (line 433)
+* max <2>: Arrays. (line 231)
+* max <3>: Frames and pictures. (line 7)
+* max: Paths and guides. (line 260)
+* maxbound: Data types. (line 104)
+* maxtile: three. (line 180)
+* maxtimes: Paths and guides. (line 215)
+* maxviewport: three. (line 180)
+* merge: animation. (line 6)
+* MetaPost: MetaPost. (line 6)
+* MetaPost ... : Tutorial. (line 176)
+* MetaPost cutafter: Paths and guides. (line 248)
+* MetaPost cutbefore: Paths and guides. (line 244)
+* MetaPost pickup: Pens. (line 6)
+* MetaPost whatever: MetaPost. (line 10)
+* Microsoft Windows: Microsoft Windows. (line 6)
+* MidArcArrow: draw. (line 26)
+* MidArcArrow3: three. (line 476)
+* MidArrow: draw. (line 26)
+* MidArrow3: three. (line 476)
+* midpoint: Paths and guides. (line 161)
+* MidPoint: label. (line 57)
+* min <1>: three. (line 433)
+* min <2>: Arrays. (line 224)
+* min <3>: Frames and pictures. (line 7)
+* min: Paths and guides. (line 256)
+* minbound: Data types. (line 101)
+* minipage: label. (line 119)
+* mintimes: Paths and guides. (line 210)
+* miterjoin: Pens. (line 134)
+* miterlimit: Pens. (line 143)
+* mm: Tutorial. (line 63)
+* mouse: GUI. (line 6)
+* mouse bindings: three. (line 129)
+* Move: Pens. (line 335)
+* MoveQuiet: Pens. (line 341)
+* multisample: three. (line 119)
+* multisampling: Compiling from UNIX source.
+ (line 16)
+* N: Tutorial. (line 94)
+* named arguments: Named arguments. (line 6)
+* new <1>: Arrays. (line 112)
+* new: Structures. (line 6)
+* newframe: Frames and pictures. (line 7)
+* newl: Files. (line 59)
+* newton: Mathematical functions.
+ (line 65)
+* next: Debugger. (line 42)
+* NFSS: Pens. (line 188)
+* nobasealign: Pens. (line 164)
+* NoFill <1>: Frames and pictures. (line 139)
+* NoFill: draw. (line 26)
+* NoMargin: draw. (line 42)
+* NoMargin3: three. (line 492)
+* none: Files. (line 59)
+* None: draw. (line 19)
+* normal: three. (line 419)
+* nosafe: Options. (line 145)
+* NOT: Arithmetic & logical.
+ (line 80)
+* NoTicks: graph. (line 155)
+* NoTicks3: graph3. (line 34)
+* null: Structures. (line 6)
+* nullpen <1>: Frames and pictures. (line 125)
+* nullpen: label. (line 14)
+* NURBS: three. (line 318)
+* O: three. (line 236)
+* obj: obj. (line 7)
+* oblique: three. (line 281)
+* obliqueX: three. (line 289)
+* obliqueY: three. (line 296)
+* obliqueZ: three. (line 281)
+* offset: Options. (line 149)
+* opacity: Pens. (line 218)
+* open: Files. (line 11)
+* OpenGL: three. (line 119)
+* operator: User-defined operators.
+ (line 6)
+* operator --: graph. (line 31)
+* operator ..: graph. (line 34)
+* operator cast: Casts. (line 31)
+* operator ecast: Casts. (line 58)
+* operator init <1>: Structures. (line 141)
+* operator init: Variable initializers.
+ (line 6)
+* operators: Operators. (line 6)
+* options: Options. (line 7)
+* OR: Arithmetic & logical.
+ (line 80)
+* orientation: Frames and pictures. (line 93)
+* orthographic: three. (line 300)
+* outformat: three. (line 119)
+* output <1>: Options. (line 129)
+* output: Files. (line 36)
+* OutTicks: graph3. (line 34)
+* overloading functions: Functions. (line 44)
+* overwrite: Pens. (line 320)
+* P: Mathematical functions.
+ (line 48)
+* pack: label. (line 102)
+* packing: Rest arguments. (line 30)
+* pair <1>: Data types. (line 41)
+* pair: Tutorial. (line 17)
+* pairs: Arrays. (line 248)
+* paperheight: Configuring. (line 62)
+* papertype: Configuring. (line 62)
+* paperwidth: Configuring. (line 62)
+* parametrized curve: graph. (line 626)
+* patch-dependent colors: three. (line 75)
+* path <1>: flowchart. (line 74)
+* path <2>: three. (line 43)
+* path: Paths and guides. (line 7)
+* path3: three. (line 6)
+* path[]: Tutorial. (line 197)
+* patterns <1>: patterns. (line 6)
+* patterns: Pens. (line 234)
+* pdflatex: Options. (line 129)
+* pdfviewer: Configuring. (line 6)
+* pdfviewerOptions: Options. (line 117)
+* pen: Pens. (line 6)
+* PenMargin: draw. (line 42)
+* PenMargin2: three. (line 492)
+* PenMargin3: three. (line 492)
+* PenMargins: draw. (line 42)
+* PenMargins2: three. (line 492)
+* PenMargins3: three. (line 492)
+* perpendicular: geometry. (line 6)
+* perspective: three. (line 318)
+* picture: Frames and pictures. (line 35)
+* picture alignment: Frames and pictures. (line 203)
+* piecewisestraight: Paths and guides. (line 82)
+* Pl: Mathematical functions.
+ (line 48)
+* plain: plain. (line 6)
+* planar: three. (line 83)
+* plane: three. (line 263)
+* planeproject: three. (line 416)
+* point <1>: three. (line 433)
+* point: Paths and guides. (line 85)
+* polar: Data types. (line 119)
+* polargraph: graph. (line 90)
+* polygon: graph. (line 474)
+* pop: Arrays. (line 39)
+* Portrait: Frames and pictures. (line 93)
+* postcontrol <1>: three. (line 433)
+* postcontrol: Paths and guides. (line 130)
+* postfix operators: Self & prefix operators.
+ (line 19)
+* postscript: Frames and pictures. (line 265)
+* PostScript fonts: Pens. (line 206)
+* PostScript subpath: Tutorial. (line 197)
+* pow10: Mathematical functions.
+ (line 6)
+* prc: three. (line 197)
+* precision: Files. (line 86)
+* precontrol <1>: three. (line 433)
+* precontrol: Paths and guides. (line 123)
+* prefix operators: Self & prefix operators.
+ (line 6)
+* private: Structures. (line 6)
+* programming: Programming. (line 6)
+* pstoedit: PostScript to Asymptote.
+ (line 6)
+* psviewer: Configuring. (line 6)
+* psviewerOptions: Options. (line 117)
+* pt: Tutorial. (line 63)
+* public: Structures. (line 6)
+* push: Arrays. (line 39)
+* python: Configuring. (line 27)
+* Python usage: Interactive mode. (line 58)
+* quadraticroots: Arrays. (line 311)
+* quarticroots: math. (line 22)
+* quit <1>: Debugger. (line 54)
+* quit: Interactive mode. (line 37)
+* quote: Import. (line 119)
+* quotient: Arithmetic & logical.
+ (line 6)
+* RadialShade: Frames and pictures. (line 157)
+* radialshade: fill. (line 49)
+* radians: Mathematical functions.
+ (line 17)
+* radius <1>: three. (line 433)
+* radius: Paths and guides. (line 119)
+* Rainbow: palette. (line 12)
+* rand: Mathematical functions.
+ (line 39)
+* randMax: Mathematical functions.
+ (line 39)
+* read1: Arrays. (line 386)
+* read2: Arrays. (line 386)
+* read3: Arrays. (line 386)
+* reading: Files. (line 11)
+* reading string arrays: Arrays. (line 353)
+* readline: Files. (line 128)
+* real: Data types. (line 33)
+* realDigits: Data types. (line 33)
+* realEpsilon: Data types. (line 33)
+* realMax: Data types. (line 33)
+* realMin: Data types. (line 33)
+* realmult: Data types. (line 95)
+* rectangle: flowchart. (line 37)
+* recursion: Functions. (line 88)
+* reflect: Transforms. (line 51)
+* Relative: label. (line 52)
+* relpoint: Paths and guides. (line 157)
+* reltime: Paths and guides. (line 153)
+* remainder: Mathematical functions.
+ (line 6)
+* rename: Files. (line 145)
+* render <1>: Options. (line 129)
+* render: three. (line 119)
+* replace: Data types. (line 252)
+* resetdefaultpen: Pens. (line 349)
+* rest arguments: Rest arguments. (line 6)
+* restore: Frames and pictures. (line 259)
+* restricted: Structures. (line 6)
+* return: Debugger. (line 48)
+* reverse <1>: three. (line 433)
+* reverse <2>: Arrays. (line 149)
+* reverse <3>: Paths and guides. (line 164)
+* reverse: Data types. (line 248)
+* rewind: Files. (line 86)
+* rfind: Data types. (line 229)
+* rgb: Pens. (line 30)
+* Riemann zeta function: Mathematical functions.
+ (line 48)
+* Right: graph. (line 277)
+* RightSide: label. (line 62)
+* RightTicks: graph. (line 155)
+* RightView: three. (line 340)
+* Rotate: label. (line 37)
+* Rotate(pair z): label. (line 40)
+* round: Mathematical functions.
+ (line 26)
+* roundcap: Pens. (line 125)
+* roundedpath: roundedpath. (line 6)
+* roundjoin: Pens. (line 134)
+* roundrectangle: flowchart. (line 62)
+* RPM: UNIX binary distributions.
+ (line 6)
+* runtime imports: Import. (line 101)
+* Russian: unicode. (line 7)
+* S: Tutorial. (line 94)
+* safe: Options. (line 145)
+* save: Frames and pictures. (line 256)
+* saveline: Files. (line 128)
+* scale: three. (line 395)
+* Scale: graph. (line 688)
+* scale <1>: graph. (line 672)
+* scale: Transforms. (line 39)
+* Scale: label. (line 46)
+* scale3: three. (line 392)
+* scaled graph: graph. (line 653)
+* scientific graph: graph. (line 386)
+* scroll: Files. (line 102)
+* search: Arrays. (line 167)
+* search paths: Search paths. (line 6)
+* Seascape: Frames and pictures. (line 98)
+* secondary axis: graph. (line 803)
+* secondaryX: graph. (line 803)
+* secondaryY: graph. (line 803)
+* seconds: Data types. (line 298)
+* seek: Files. (line 86)
+* seekeof: Files. (line 86)
+* segmentation fault: Help. (line 33)
+* self operators: Self & prefix operators.
+ (line 6)
+* sequence: Arrays. (line 131)
+* settings <1>: Options. (line 102)
+* settings: Configuring. (line 21)
+* sgn: Mathematical functions.
+ (line 26)
+* shading: fill. (line 32)
+* shift <1>: three. (line 380)
+* shift: Transforms. (line 27)
+* Shift: label. (line 34)
+* shiftless: Transforms. (line 53)
+* shipout: Frames and pictures. (line 83)
+* showtarget: three. (line 300)
+* Si: Mathematical functions.
+ (line 48)
+* SimpleHead: draw. (line 26)
+* simplex: simplex. (line 6)
+* simpson: Mathematical functions.
+ (line 81)
+* Sin: Mathematical functions.
+ (line 20)
+* sin: Mathematical functions.
+ (line 6)
+* single: Files. (line 71)
+* sinh: Mathematical functions.
+ (line 6)
+* size <1>: Options. (line 129)
+* size <2>: three. (line 433)
+* size <3>: Frames and pictures. (line 43)
+* size: Paths and guides. (line 71)
+* size3: three. (line 225)
+* slant: Transforms. (line 45)
+* Slant: label. (line 43)
+* sleep: Data types. (line 328)
+* slice: Paths and guides. (line 233)
+* slices: Slices. (line 6)
+* slide: slide. (line 6)
+* slopefield: slopefield. (line 6)
+* solid: Pens. (line 92)
+* solids: solids. (line 7)
+* solve: Arrays. (line 265)
+* sort: Arrays. (line 190)
+* Spline: graph. (line 34)
+* split: Data types. (line 261)
+* sqrt: Mathematical functions.
+ (line 6)
+* squarecap: Pens. (line 125)
+* srand: Mathematical functions.
+ (line 39)
+* stack overflow <1>: Help. (line 33)
+* stack overflow: Functions. (line 88)
+* static: Static. (line 6)
+* stats: stats. (line 6)
+* stdin: Files. (line 46)
+* stdout: Files. (line 46)
+* step: Debugger. (line 39)
+* stickframe: markers. (line 16)
+* stop: Debugger. (line 10)
+* straight: three. (line 433)
+* Straight: graph. (line 31)
+* straight: Paths and guides. (line 78)
+* strftime: Data types. (line 290)
+* string: Data types. (line 179)
+* stroke: fill. (line 36)
+* strokepath: Paths and guides. (line 290)
+* strptime: Data types. (line 298)
+* struct: Structures. (line 6)
+* structures: Structures. (line 6)
+* subpath <1>: three. (line 433)
+* subpath: Paths and guides. (line 167)
+* subpictures: Frames and pictures. (line 101)
+* substr: Data types. (line 244)
+* Subversion: Subversion. (line 6)
+* sum: Arrays. (line 219)
+* superpath: Tutorial. (line 197)
+* Suppress: Pens. (line 327)
+* SuppressQuiet: Pens. (line 331)
+* surface: three. (line 47)
+* SVN: Subversion. (line 6)
+* system <1>: Options. (line 145)
+* system: Files. (line 153)
+* syzygy: syzygy. (line 6)
+* tab: Files. (line 59)
+* tab completion: Tutorial. (line 21)
+* Tan: Mathematical functions.
+ (line 20)
+* tan: Mathematical functions.
+ (line 6)
+* tanh: Mathematical functions.
+ (line 6)
+* target: three. (line 300)
+* tell: Files. (line 86)
+* tension <1>: three. (line 6)
+* tension: Tutorial. (line 165)
+* tensionSpecifier: Paths and guides. (line 381)
+* tensor product shading: fill. (line 74)
+* tensorshade: fill. (line 74)
+* tex <1>: Options. (line 129)
+* tex: Frames and pictures. (line 272)
+* TeX fonts: Pens. (line 197)
+* TeX string: Data types. (line 179)
+* texcommand: Configuring. (line 68)
+* texdvicommand: Configuring. (line 68)
+* TeXHead: draw. (line 26)
+* TeXHead3: three. (line 476)
+* texpath <1>: label. (line 116)
+* texpath: Configuring. (line 68)
+* texpreamble: Frames and pictures. (line 280)
+* texreset: Frames and pictures. (line 283)
+* textbook graph: graph. (line 361)
+* tgz: UNIX binary distributions.
+ (line 6)
+* thick: three. (line 104)
+* thin: three. (line 104)
+* this: Structures. (line 6)
+* three: three. (line 6)
+* tick: graph. (line 332)
+* Ticks: graph. (line 155)
+* ticks: graph. (line 155)
+* tildeframe: markers. (line 26)
+* tile: Pens. (line 247)
+* tilings: Pens. (line 234)
+* time: Data types. (line 290)
+* times: Paths and guides. (line 202)
+* Top: graph. (line 131)
+* TopView: three. (line 340)
+* trace: Debugger. (line 51)
+* trailingzero: graph. (line 169)
+* transform <1>: three. (line 407)
+* transform: Transforms. (line 6)
+* transform3: three. (line 376)
+* transparency: Pens. (line 218)
+* transpose: Arrays. (line 211)
+* tree: tree. (line 7)
+* trembling: trembling. (line 6)
+* triangle: geometry. (line 6)
+* triangulate: contour. (line 154)
+* tridiagonal: Arrays. (line 268)
+* trigonometric integrals: Mathematical functions.
+ (line 48)
+* triple: Data types. (line 108)
+* TrueMargin: draw. (line 42)
+* TrueMargin3: three. (line 492)
+* tube <1>: tube. (line 6)
+* tube: three. (line 104)
+* tutorial: Tutorial. (line 6)
+* typedef <1>: Functions. (line 36)
+* typedef: Data types. (line 338)
+* undefined: Paths and guides. (line 264)
+* UnFill: Frames and pictures. (line 150)
+* unfill: fill. (line 105)
+* UnFill: draw. (line 26)
+* unicode: unicode. (line 6)
+* uniform: Arrays. (line 158)
+* Uninstall: Uninstall. (line 6)
+* unit: Data types. (line 78)
+* unitbox <1>: three. (line 269)
+* unitbox: Tutorial. (line 218)
+* unitcircle <1>: three. (line 236)
+* unitcircle: Tutorial. (line 110)
+* unitrand: Mathematical functions.
+ (line 39)
+* unitsize <1>: Frames and pictures. (line 64)
+* unitsize: Tutorial. (line 73)
+* UNIX binary distributions: UNIX binary distributions.
+ (line 6)
+* unpacking: Rest arguments. (line 39)
+* unravel: Import. (line 31)
+* up: three. (line 300)
+* update: Files. (line 36)
+* UpsideDown: Frames and pictures. (line 93)
+* usepackage: Frames and pictures. (line 285)
+* user coordinates: Tutorial. (line 73)
+* user-defined operators: User-defined operators.
+ (line 6)
+* usleep: Data types. (line 331)
+* variable initializers: Variable initializers.
+ (line 6)
+* vectorfield: graph. (line 965)
+* vectorfield3: graph3. (line 150)
+* vectorization: Arrays. (line 325)
+* verbatim: Frames and pictures. (line 265)
+* vertex-dependent colors: three. (line 75)
+* Vertical: flowchart. (line 74)
+* viewportheight: LaTeX usage. (line 32)
+* viewportmargin: three. (line 228)
+* viewportsize: three. (line 228)
+* viewportwidth: LaTeX usage. (line 32)
+* views: three. (line 197)
+* vim: Editing modes. (line 33)
+* virtual functions: Structures. (line 189)
+* void: Data types. (line 10)
+* W: Tutorial. (line 94)
+* whatever: Paths and guides. (line 228)
+* Wheel: palette. (line 22)
+* wheel mouse: GUI. (line 6)
+* while: Programming. (line 29)
+* white-space string delimiter mode: Arrays. (line 353)
+* width: LaTeX usage. (line 32)
+* windingnumber: Paths and guides. (line 264)
+* word: Arrays. (line 353)
+* write <1>: Arrays. (line 394)
+* write: Files. (line 51)
+* X: three. (line 236)
+* xasy <1>: GUI. (line 6)
+* xasy: Configuring. (line 68)
+* xaxis: graph3. (line 7)
+* xelatex <1>: Options. (line 129)
+* xelatex: embed. (line 10)
+* xequals: graph. (line 284)
+* XEquals: graph. (line 270)
+* xinput: Files. (line 71)
+* xlimits: graph. (line 626)
+* XOR: Arithmetic & logical.
+ (line 80)
+* xoutput: Files. (line 71)
+* xpart: Data types. (line 89)
+* xscale: Transforms. (line 33)
+* xscale3: three. (line 383)
+* xtick: graph. (line 332)
+* XYEquals: graph3. (line 20)
+* XYZero: graph3. (line 20)
+* XZEquals: graph3. (line 20)
+* XZero: graph. (line 265)
+* XZZero: graph3. (line 20)
+* Y <1>: three. (line 236)
+* Y: Mathematical functions.
+ (line 6)
+* yaxis: graph3. (line 7)
+* yequals: graph. (line 284)
+* YEquals: graph. (line 124)
+* ylimits: graph. (line 626)
+* ypart: Data types. (line 92)
+* yscale: Transforms. (line 36)
+* yscale3: three. (line 386)
+* ytick: graph. (line 332)
+* YZEquals: graph3. (line 20)
+* YZero: graph. (line 119)
+* YZZero: graph3. (line 20)
+* Z: three. (line 236)
+* zaxis: graph3. (line 7)
+* zero_Ai: Mathematical functions.
+ (line 48)
+* zero_Ai_deriv: Mathematical functions.
+ (line 48)
+* zero_Bi: Mathematical functions.
+ (line 48)
+* zero_Bi_deriv: Mathematical functions.
+ (line 48)
+* zero_J: Mathematical functions.
+ (line 48)
+* zerowinding: Pens. (line 148)
+* zeta: Mathematical functions.
+ (line 48)
+* zpart: Data types. (line 161)
+* zscale3: three. (line 389)
+* |: Arithmetic & logical.
+ (line 62)
+* ||: Arithmetic & logical.
+ (line 59)
+
+

Tag Table:
-(Indirect)
Node: Top578
-Node: Description6646
-Node: Installation10061
-Node: UNIX binary distributions11054
-Node: MacOS X binary distributions12160
-Node: Microsoft Windows13108
-Node: Configuring14278
-Node: Search paths18463
-Node: Compiling from UNIX source19143
-Ref: multisampling19732
-Node: Editing modes22158
-Node: Subversion24358
-Node: Uninstall24819
-Node: Tutorial25169
-Ref: unitcircle29177
-Ref: Bezier29386
-Node: Drawing commands34799
-Node: draw36508
-Ref: arrows37656
-Node: fill42881
-Ref: gradient shading43925
-Node: clip48118
-Node: label48710
-Ref: Label49409
-Node: Programming55205
-Ref: array iteration56022
-Node: Data types57104
-Ref: format66001
-Node: Paths and guides69398
-Ref: circle69652
-Ref: arctime75050
-Ref: extension78915
-Node: Pens85488
-Ref: fillrule92742
-Ref: basealign93639
-Ref: transparency96464
-Ref: makepen100013
-Ref: overwrite100905
-Node: Transforms102115
-Node: Frames and pictures103906
-Ref: envelope105047
-Ref: size106130
-Ref: unitsize107117
-Ref: shipout108177
-Ref: filltype110395
-Ref: add113378
-Ref: add about114324
-Ref: tex117325
-Node: Files118199
-Ref: cd119164
-Ref: scroll123545
-Node: Variable initializers126588
-Node: Structures128883
-Node: Operators136225
-Node: Arithmetic & logical136539
-Node: Self & prefix operators138436
-Node: User-defined operators139224
-Node: Implicit scaling140135
-Node: Functions140698
-Ref: stack overflow143451
-Node: Default arguments144015
-Node: Named arguments144754
-Node: Rest arguments146916
-Node: Mathematical functions149726
-Node: Arrays154331
-Ref: sort161512
-Ref: tridiagonal163803
-Ref: solve165031
-Node: Slices169158
-Node: Casts173052
-Node: Import175018
-Node: Static180248
-Node: LaTeX usage183144
-Node: Base modules188613
-Node: plain191049
-Node: simplex191701
-Node: math191974
-Node: interpolate193073
-Node: geometry193352
-Node: trembling193915
-Node: stats194276
-Node: patterns194536
-Node: markers194772
-Node: tree196661
-Node: binarytree196847
-Node: drawtree197493
-Node: syzygy197695
-Node: feynman197969
-Node: roundedpath198244
-Node: animation198527
-Ref: animate198946
-Node: embed200085
-Node: slide201887
-Node: MetaPost202227
-Node: unicode202943
-Node: latin1203831
-Node: babel204199
-Node: labelpath204428
-Node: labelpath3205248
-Node: annotate205559
-Node: CAD206030
-Node: graph206340
-Ref: ticks213178
-Ref: pathmarkers226599
-Ref: marker227064
-Ref: markuniform227415
-Ref: errorbars229206
-Ref: automatic scaling233543
-Node: palette244951
-Ref: images245069
-Ref: image249240
-Ref: logimage249769
-Ref: penimage250627
-Node: three251123
-Ref: PostScript3D272277
-Node: obj274022
-Node: graph3274272
-Ref: GaussianSurface279000
-Node: grid3280141
-Node: solids280935
-Node: tube281937
-Node: flowchart284168
-Node: contour288724
-Node: contour3294022
-Node: slopefield294329
-Node: Options295810
-Ref: configuration file300978
-Ref: settings300978
-Ref: convert302049
-Node: Interactive mode304808
-Ref: history306432
-Node: GUI307737
-Node: GUI Installation308240
-Node: GUI Usage309765
-Node: PostScript to Asymptote310668
-Node: Help311811
-Node: Debugger313538
-Node: Credits315323
-Node: Index316236
+Node: Description6701
+Node: Installation10116
+Node: UNIX binary distributions11164
+Node: MacOS X binary distributions12270
+Node: Microsoft Windows13218
+Node: Configuring14388
+Node: Search paths18573
+Node: Compiling from UNIX source19253
+Ref: multisampling19842
+Node: Editing modes22268
+Node: Subversion24468
+Node: Uninstall24929
+Node: Tutorial25279
+Ref: unitcircle29287
+Ref: Bezier29496
+Node: Drawing commands34909
+Node: draw36618
+Ref: arrows37766
+Node: fill42991
+Ref: gradient shading44035
+Node: clip48228
+Node: label48820
+Ref: Label49519
+Node: Programming55315
+Ref: array iteration56132
+Node: Data types57214
+Ref: format66111
+Node: Paths and guides69508
+Ref: circle69762
+Ref: arctime75160
+Ref: extension79025
+Node: Pens85764
+Ref: fillrule93018
+Ref: basealign93915
+Ref: transparency96740
+Ref: makepen100289
+Ref: overwrite101181
+Node: Transforms102391
+Node: Frames and pictures104182
+Ref: envelope105323
+Ref: size106406
+Ref: unitsize107393
+Ref: shipout108453
+Ref: filltype110671
+Ref: add113654
+Ref: add about114600
+Ref: tex117601
+Node: Files118475
+Ref: cd119440
+Ref: scroll123821
+Node: Variable initializers126864
+Node: Structures129159
+Node: Operators136501
+Node: Arithmetic & logical136815
+Node: Self & prefix operators138712
+Node: User-defined operators139500
+Node: Implicit scaling140411
+Node: Functions140974
+Ref: stack overflow143727
+Node: Default arguments144291
+Node: Named arguments145030
+Node: Rest arguments147192
+Node: Mathematical functions150002
+Node: Arrays154607
+Ref: sort161788
+Ref: tridiagonal164079
+Ref: solve165307
+Node: Slices169434
+Node: Casts173328
+Node: Import175294
+Node: Static180524
+Node: LaTeX usage183420
+Node: Base modules188889
+Node: plain191325
+Node: simplex191977
+Node: math192250
+Node: interpolate193349
+Node: geometry193628
+Node: trembling194191
+Node: stats194552
+Node: patterns194812
+Node: markers195048
+Node: tree196937
+Node: binarytree197123
+Node: drawtree197769
+Node: syzygy197971
+Node: feynman198245
+Node: roundedpath198520
+Node: animation198803
+Ref: animate199222
+Node: embed200361
+Node: slide202163
+Node: MetaPost202503
+Node: unicode203219
+Node: latin1204107
+Node: babel204475
+Node: labelpath204704
+Node: labelpath3205524
+Node: annotate205835
+Node: CAD206306
+Node: graph206616
+Ref: ticks213454
+Ref: pathmarkers226875
+Ref: marker227340
+Ref: markuniform227691
+Ref: errorbars229482
+Ref: automatic scaling233819
+Node: palette245227
+Ref: images245345
+Ref: image249516
+Ref: logimage250045
+Ref: penimage250903
+Node: three251399
+Ref: PostScript3D272916
+Node: obj274661
+Node: graph3274911
+Ref: GaussianSurface279639
+Node: grid3280780
+Node: solids281574
+Node: tube282576
+Node: flowchart284807
+Node: contour289363
+Node: contour3294661
+Node: slopefield294968
+Node: Options296449
+Ref: configuration file301617
+Ref: settings301617
+Ref: convert302688
+Node: Interactive mode305447
+Ref: history307071
+Node: GUI308376
+Node: GUI Installation308879
+Node: GUI Usage310404
+Node: PostScript to Asymptote311307
+Node: Help312450
+Node: Debugger314177
+Node: Credits315962
+Node: Index316875

End Tag Table
diff --git a/Build/source/utils/asymptote/drawclipend.h b/Build/source/utils/asymptote/drawclipend.h
index d6b2ef33199..098d4dac8eb 100644
--- a/Build/source/utils/asymptote/drawclipend.h
+++ b/Build/source/utils/asymptote/drawclipend.h
@@ -50,8 +50,7 @@ public:
out->verbatim("\\kern");
double width=bpath.right-bpath.left;
out->write(-width*ps2tex);
- out->verbatim(settings::texunits(out->texengine));
- out->verbatimline("%");
+ out->verbatimline("pt%");
if(grestore) out->grestore();
return true;
}
diff --git a/Build/source/utils/asymptote/drawfill.cc b/Build/source/utils/asymptote/drawfill.cc
index af32b95e475..4ebe07b4eb2 100644
--- a/Build/source/utils/asymptote/drawfill.cc
+++ b/Build/source/utils/asymptote/drawfill.cc
@@ -110,9 +110,6 @@ bool drawFunctionShade::write(texfile *out, const bbox& box)
{
if(empty()) return true;
- const char *units=
- settings::texunits(settings::getSetting<string>("tex"));
-
ColorSpace colorspace=pentype.colorspace();
size_t ncomponents=ColorComponents[colorspace];
@@ -130,12 +127,10 @@ bool drawFunctionShade::write(texfile *out, const bbox& box)
double Hoffset=out->hoffset();
double hoffset=(bpath.Max().getx()-Hoffset)*ps2tex;
out->write(hoffset);
- out->verbatim(units);
- out->verbatim(" {");
+ out->verbatim("pt {");
out->verbatim("\\vbox to ");
out->write((box.top-box.bottom)*ps2tex);
- out->verbatim(units);
- out->verbatimline(" {\\vfil%");
+ out->verbatimline("pt {\\vfil%");
out->gsave();
out->beginspecial();
out->beginraw();
@@ -161,8 +156,7 @@ bool drawFunctionShade::write(texfile *out, const bbox& box)
out->verbatimline("\\pdfrefxform\\the\\pdflastxform");
out->verbatim("\\kern");
out->write(-hoffset);
- out->verbatim(units);
- out->verbatimline("%");
+ out->verbatimline("pt%");
return true;
}
diff --git a/Build/source/utils/asymptote/drawlabel.cc b/Build/source/utils/asymptote/drawlabel.cc
index b6f0590ae1c..484ecf3cb89 100644
--- a/Build/source/utils/asymptote/drawlabel.cc
+++ b/Build/source/utils/asymptote/drawlabel.cc
@@ -25,8 +25,8 @@ void drawLabel::labelwarning(const char *action)
<< "\" " << action << " to avoid overwriting" << endl;
}
-int drawLabel::wait(iopipestream &tex, const char *s, const char **abort,
- bool ignore)
+int wait(iopipestream &tex, const char *s, const char **abort,
+ bool ignore=false)
{
int rc=tex.wait(s,abort);
if(rc > 0) {
@@ -49,12 +49,13 @@ int drawLabel::wait(iopipestream &tex, const char *s, const char **abort,
return rc;
}
-bool drawLabel::texbounds(iopipestream& tex, string& s, const char **abort,
- bool warn)
+bool texbounds(double& width, double& height, double& depth,
+ iopipestream& tex, string& s, const char **abort, bool warn,
+ bool Inline)
{
string texbuf;
tex << "\\setbox\\ASYbox=\\hbox{" << stripblanklines(s) << "}\n\n";
- int rc=wait(tex,texready.c_str(),abort,getSetting<bool>("inlinetex"));
+ int rc=wait(tex,texready.c_str(),abort,Inline);
if(rc) {
tex << "\\show 0\n";
tex.wait("\n*");
@@ -116,26 +117,33 @@ inline double urand()
return rand()*factor-1.0;
}
-void drawLabel::getbounds(iopipestream& tex, const string& texengine)
+void setpen(iopipestream& tex, const string& texengine, const pen& pentype)
{
- if(havebounds) return;
- havebounds=true;
-
const char **abort=texabort(texengine);
bool Latex=latex(texengine);
if(Latex) {
- if(setlatexfont(tex,pentype,lastpen))
+ if(setlatexfont(tex,pentype,drawElement::lastpen))
wait(tex,"\n*",abort);
}
- if(settexfont(tex,pentype,lastpen,Latex))
+ if(settexfont(tex,pentype,drawElement::lastpen,Latex))
wait(tex,"\n*",abort);
- lastpen=pentype;
-
+ drawElement::lastpen=pentype;
+}
+
+void drawLabel::getbounds(iopipestream& tex, const string& texengine)
+{
+ if(havebounds) return;
+ havebounds=true;
+
+ const char **abort=texabort(texengine);
+ setpen(tex,texengine,pentype);
+
bool nullsize=size.empty();
- if(!texbounds(tex,label,abort,nullsize) && !nullsize)
- texbounds(tex,size,abort,false);
+ if(!texbounds(width,height,depth,tex,label,abort,nullsize,
+ getSetting<bool>("inlinetex")) && !nullsize)
+ texbounds(width,height,depth,tex,size,abort,false);
enabled=true;
Align=inverse(T)*align;
diff --git a/Build/source/utils/asymptote/drawlabel.h b/Build/source/utils/asymptote/drawlabel.h
index 14c2122f676..100a544ea00 100644
--- a/Build/source/utils/asymptote/drawlabel.h
+++ b/Build/source/utils/asymptote/drawlabel.h
@@ -46,11 +46,6 @@ public:
void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&);
- bool texbounds(iopipestream& tex, string& s, const char **abort, bool warn);
-
- int wait(iopipestream &tex, const char *s, const char **abort,
- bool ignore=false);
-
bool islabel() {
return true;
}
@@ -81,6 +76,11 @@ public:
drawElement *transformed(const transform& t);
};
+void setpen(iopipestream& tex, const string& texengine, const pen& pentype);
+bool texbounds(double& width, double& height, double& depth,
+ iopipestream& tex, string& s, const char **abort,
+ bool warn, bool Inline=false);
+
}
#endif
diff --git a/Build/source/utils/asymptote/examples/BezierSurface.asy b/Build/source/utils/asymptote/examples/BezierSurface.asy
index 65410deebca..e87f785c761 100644
--- a/Build/source/utils/asymptote/examples/BezierSurface.asy
+++ b/Build/source/utils/asymptote/examples/BezierSurface.asy
@@ -5,7 +5,7 @@ string viewpoint="{-24.132780075073242 7.2992024421691895 7.695427417755127}{0.8
//viewpoint=getstring("viewpoint",viewpoint);
currentprojection=perspective(viewpoint);
-currentlight=adobe;
+currentlight=White;
triple[][][] P={{
{(-1.6,0,1.875),(-1.6,-0.3,1.875),(-1.5,-0.3,2.1),(-1.5,0,2.1)},
diff --git a/Build/source/utils/asymptote/examples/condor.asy b/Build/source/utils/asymptote/examples/condor.asy
index d109335e3bf..619b4bea12b 100644
--- a/Build/source/utils/asymptote/examples/condor.asy
+++ b/Build/source/utils/asymptote/examples/condor.asy
@@ -6,7 +6,7 @@ import graph3;
size(300,300,IgnoreAspect);
currentprojection=orthographic(0,-1,0,center=true);
-currentlight=adobe;
+currentlight=White;
real K=7;
triple condor(pair t)
diff --git a/Build/source/utils/asymptote/examples/layers.asy b/Build/source/utils/asymptote/examples/layers.asy
new file mode 100644
index 00000000000..4fe745f6a3c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/layers.asy
@@ -0,0 +1,44 @@
+usepackage("ocg");
+settings.tex="pdflatex";
+
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+
+begin("A");
+fill(c1,colour1);
+end();
+
+fill(c2,colour2);
+
+picture intersection;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+label("$A$",z1);
+
+begin("B");
+label("$B$",z2);
+end();
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
diff --git a/Build/source/utils/asymptote/examples/logo3.asy b/Build/source/utils/asymptote/examples/logo3.asy
index 6fc73dc9470..538838e02fa 100644
--- a/Build/source/utils/asymptote/examples/logo3.asy
+++ b/Build/source/utils/asymptote/examples/logo3.asy
@@ -3,7 +3,7 @@ import three;
size(560,320,IgnoreAspect);
size3(140,80,15);
currentprojection=perspective(-3,20,10,up=Y);
-currentlight=adobe;
+currentlight=White;
path[] outline;
diff --git a/Build/source/utils/asymptote/examples/pdb.asy b/Build/source/utils/asymptote/examples/pdb.asy
index bef21dc2277..e06b1241bce 100644
--- a/Build/source/utils/asymptote/examples/pdb.asy
+++ b/Build/source/utils/asymptote/examples/pdb.asy
@@ -6,7 +6,7 @@ import cpkcolors;
bool getviews=true;
-currentlight=adobe;
+currentlight=White;
//currentlight=nolight;
size(200);
diff --git a/Build/source/utils/asymptote/examples/pipeintersection.asy b/Build/source/utils/asymptote/examples/pipeintersection.asy
index b22574c13c2..7e42c17ee51 100644
--- a/Build/source/utils/asymptote/examples/pipeintersection.asy
+++ b/Build/source/utils/asymptote/examples/pipeintersection.asy
@@ -1,7 +1,7 @@
import graph3;
currentprojection=orthographic(5,4,2);
-currentlight=adobe;
+currentlight=White;
size(12cm,0);
diff --git a/Build/source/utils/asymptote/examples/teapot.asy b/Build/source/utils/asymptote/examples/teapot.asy
index e0ef51eb552..2fb6b9b0873 100644
--- a/Build/source/utils/asymptote/examples/teapot.asy
+++ b/Build/source/utils/asymptote/examples/teapot.asy
@@ -3,6 +3,7 @@ import three;
size(20cm);
currentprojection=perspective(250,-250,250);
+//currentlight=White;
triple[][][] Q={
{
diff --git a/Build/source/utils/asymptote/examples/trefoilknot.asy b/Build/source/utils/asymptote/examples/trefoilknot.asy
index fb10e3def0e..3c5e4aecc5a 100644
--- a/Build/source/utils/asymptote/examples/trefoilknot.asy
+++ b/Build/source/utils/asymptote/examples/trefoilknot.asy
@@ -1,7 +1,7 @@
import tube;
import graph3;
import palette;
-currentlight=adobe;
+currentlight=White;
size(0,8cm);
currentprojection=perspective(1,1,1,up=-Y);
diff --git a/Build/source/utils/asymptote/examples/wedge.asy b/Build/source/utils/asymptote/examples/wedge.asy
index 9e0f8355308..6cf6a58975f 100644
--- a/Build/source/utils/asymptote/examples/wedge.asy
+++ b/Build/source/utils/asymptote/examples/wedge.asy
@@ -2,7 +2,7 @@ import graph3;
import solids;
size(0,150);
currentprojection=perspective(8,10,2);
-currentlight=adobe;
+currentlight=White;
draw(circle(O,4,Z));
draw(shift(-4Z)*scale(4,4,8)*unitcylinder,green+opacity(0.2));
diff --git a/Build/source/utils/asymptote/pen.h b/Build/source/utils/asymptote/pen.h
index 6f4e6701fbe..164698b8b68 100644
--- a/Build/source/utils/asymptote/pen.h
+++ b/Build/source/utils/asymptote/pen.h
@@ -15,6 +15,9 @@
namespace camp {
+static const double tex2ps=72.0/72.27;
+static const double ps2tex=1.0/tex2ps;
+
static const string DEFPAT="<default>";
static const string DEFLATEXFONT="\\usefont{\\ASYencoding}{\\ASYfamily}{\\ASYseries}{\\ASYshape}";
static const string DEFCONTEXTFONT="modern";
@@ -399,11 +402,11 @@ public:
// Work around misalignment in ConTeXt switchtobodyfont if font is not found.
if(texengine == "context")
buf << "\\switchtobodyfont["
- << DEFCONTEXTFONT << "," << size()
+ << DEFCONTEXTFONT << "," << size()*ps2tex
<< "pt]\\removeunwantedspaces%" << newl;
else
buf << "\\font\\ASYfont=" << DEFTEXFONT
- << " at " << size() << "pt\\ASYfont";
+ << " at " << size()*ps2tex << "pt\\ASYfont";
return buf.str();
}
}
diff --git a/Build/source/utils/asymptote/picture.cc b/Build/source/utils/asymptote/picture.cc
index 827acc6ea70..cba4bbb0b6d 100644
--- a/Build/source/utils/asymptote/picture.cc
+++ b/Build/source/utils/asymptote/picture.cc
@@ -201,7 +201,7 @@ pair picture::bounds(double (*m)(double, double),
return b;
}
-void picture::texinit()
+void texinit()
{
drawElement::lastpen=pen(initialpen);
processDataStruct &pd=processData();
diff --git a/Build/source/utils/asymptote/picture.h b/Build/source/utils/asymptote/picture.h
index 561f0488bcd..de71f64964f 100644
--- a/Build/source/utils/asymptote/picture.h
+++ b/Build/source/utils/asymptote/picture.h
@@ -68,8 +68,6 @@ public:
double (*y)(const triple&, double*),
double *t=NULL);
- void texinit();
-
bool Transparency() {
return transparency;
}
@@ -121,6 +119,8 @@ inline picture *transformed(const vm::array& t, picture *p)
return p->transformed(t);
}
+void texinit();
+
const char *texpathmessage();
} //namespace camp
diff --git a/Build/source/utils/asymptote/runtime.cc b/Build/source/utils/asymptote/runtime.cc
index 67ee3ac3560..52e99541296 100644
--- a/Build/source/utils/asymptote/runtime.cc
+++ b/Build/source/utils/asymptote/runtime.cc
@@ -923,9 +923,25 @@ inline triple perp(triple v, triple u)
return v-dot(v,u)*u;
}
-string ASYo="/ASYo {( ) print 12 string cvs print} bind def";
-string pathforall="{(M) print ASYo ASYo} {(L) print ASYo ASYo} {(C) print ASYo ASYo ASYo ASYo ASYo ASYo} {(c) print} pathforall";
-string currentpoint="print currentpoint ASYo ASYo ";
+string ASYx="/ASYx {( ) print ASYX sub 12 string cvs print} bind def";
+string ASYy="/ASYy {( ) print ASYY sub 12 string cvs print} bind def";
+string pathforall="{(M) print ASYy ASYx} {(L) print ASYy ASYx} {(C) print ASYy ASYx ASYy ASYx ASYy ASYx} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYy ASYx ";
+string ASYinit="/ASYX currentpoint pop def /ASYY currentpoint exch pop def ";
+string ASY1="ASY1 {"+ASYinit+"/ASY1 false def} if ";
+
+void showpath(std::ofstream& ps)
+{
+ ps << ASYx << newl
+ << ASYy << newl
+ << "/ASY1 true def" << newl
+ << "/fill {" << ASY1
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << newl
+ << "/stroke {" << ASY1 << "strokepath "
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << endl;
+}
array *readpath(const string& psname, bool keep,
double hscale=1.0, double vscale=1.0)
@@ -956,7 +972,6 @@ array *readpath(const string& psname, bool keep,
bool cyclic=false;
bool active=false;
- pair offset;
while(!buf.eof()) {
char c;
buf >> c;
@@ -984,13 +999,13 @@ array *readpath(const string& psname, bool keep,
}
active=false;
cyclic=false;
- node.pre=node.point=readpair(buf,hscale,vscale)-offset;
+ node.pre=node.point=readpair(buf,hscale,vscale);
node.straight=false;
break;
}
case 'L':
{
- pair point=readpair(buf,hscale,vscale)-offset;
+ pair point=readpair(buf,hscale,vscale);
pair delta=(point-node.point)*third;
node.post=node.point+delta;
node.straight=true;
@@ -1002,9 +1017,9 @@ array *readpath(const string& psname, bool keep,
}
case 'C':
{
- pair point=readpair(buf,hscale,vscale)-offset;
- pair pre=readpair(buf,hscale,vscale)-offset;
- node.post=readpair(buf,hscale,vscale)-offset;
+ pair point=readpair(buf,hscale,vscale);
+ pair pre=readpair(buf,hscale,vscale);
+ node.post=readpair(buf,hscale,vscale);
node.straight=false;
nodes.push_back(node);
active=true;
@@ -1017,11 +1032,6 @@ array *readpath(const string& psname, bool keep,
cyclic=true;
break;
}
- case 'Z':
- {
- offset=readpair(buf,hscale,vscale);
- break;
- }
}
}
@@ -1079,45 +1089,45 @@ void cannotwrite(const string& s)
namespace run {
// Initializers
-#line 1119 "runtime.in"
+#line 1129 "runtime.in"
void IntZero(stack *Stack)
{
-#line 1120 "runtime.in"
+#line 1130 "runtime.in"
{Stack->push<Int>(0); return;}
}
-#line 1125 "runtime.in"
+#line 1135 "runtime.in"
void realZero(stack *Stack)
{
-#line 1126 "runtime.in"
+#line 1136 "runtime.in"
{Stack->push<real>(0.0); return;}
}
-#line 1130 "runtime.in"
+#line 1140 "runtime.in"
void boolFalse(stack *Stack)
{
-#line 1131 "runtime.in"
+#line 1141 "runtime.in"
{Stack->push<bool>(false); return;}
}
-#line 1135 "runtime.in"
+#line 1145 "runtime.in"
void pushNullArray(stack *Stack)
{
-#line 1136 "runtime.in"
+#line 1146 "runtime.in"
{Stack->push<array*>(0); return;}
}
-#line 1140 "runtime.in"
+#line 1150 "runtime.in"
void pushNullRecord(stack *Stack)
{
-#line 1141 "runtime.in"
+#line 1151 "runtime.in"
{Stack->push<frame*>(0); return;}
}
-#line 1145 "runtime.in"
+#line 1155 "runtime.in"
void pushNullFunction(stack *Stack)
{
-#line 1146 "runtime.in"
+#line 1156 "runtime.in"
{Stack->push(nullfunc::instance()); return;}
}
@@ -1126,183 +1136,183 @@ void pushNullFunction(stack *Stack)
// Put the default value token on the stack (in place of an argument when
// making a function call).
-#line 1155 "runtime.in"
+#line 1165 "runtime.in"
void pushDefault(stack *Stack)
{
-#line 1156 "runtime.in"
+#line 1166 "runtime.in"
{Stack->push(def); return;}
}
// Test if the value on the stack is the default value token.
-#line 1162 "runtime.in"
+#line 1172 "runtime.in"
void isDefault(stack *Stack)
{
item i=vm::pop(Stack);
-#line 1163 "runtime.in"
+#line 1173 "runtime.in"
{Stack->push<bool>(isdefault(i)); return;}
}
// Logical operations
-#line 1169 "runtime.in"
+#line 1179 "runtime.in"
// bool !(bool b);
void gen8(stack *Stack)
{
bool b=vm::pop<bool>(Stack);
-#line 1170 "runtime.in"
+#line 1180 "runtime.in"
{Stack->push<bool>(!b); return;}
}
-#line 1175 "runtime.in"
+#line 1185 "runtime.in"
void boolMemEq(stack *Stack)
{
frame * b=vm::pop<frame *>(Stack);
frame * a=vm::pop<frame *>(Stack);
-#line 1176 "runtime.in"
+#line 1186 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 1180 "runtime.in"
+#line 1190 "runtime.in"
void boolMemNeq(stack *Stack)
{
frame * b=vm::pop<frame *>(Stack);
frame * a=vm::pop<frame *>(Stack);
-#line 1181 "runtime.in"
+#line 1191 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 1185 "runtime.in"
+#line 1195 "runtime.in"
void boolFuncEq(stack *Stack)
{
callable * b=vm::pop<callable *>(Stack);
callable * a=vm::pop<callable *>(Stack);
-#line 1186 "runtime.in"
+#line 1196 "runtime.in"
{Stack->push<bool>(a->compare(b)); return;}
}
-#line 1190 "runtime.in"
+#line 1200 "runtime.in"
void boolFuncNeq(stack *Stack)
{
callable * b=vm::pop<callable *>(Stack);
callable * a=vm::pop<callable *>(Stack);
-#line 1191 "runtime.in"
+#line 1201 "runtime.in"
{Stack->push<bool>(!(a->compare(b))); return;}
}
// Bit operations
-#line 1197 "runtime.in"
+#line 1207 "runtime.in"
// Int AND(Int a, Int b);
void gen13(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 1198 "runtime.in"
+#line 1208 "runtime.in"
{Stack->push<Int>(a & b); return;}
}
-#line 1203 "runtime.in"
+#line 1213 "runtime.in"
// Int OR(Int a, Int b);
void gen14(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 1204 "runtime.in"
+#line 1214 "runtime.in"
{Stack->push<Int>(a | b); return;}
}
-#line 1208 "runtime.in"
+#line 1218 "runtime.in"
// Int XOR(Int a, Int b);
void gen15(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
-#line 1209 "runtime.in"
+#line 1219 "runtime.in"
{Stack->push<Int>(a ^ b); return;}
}
-#line 1213 "runtime.in"
+#line 1223 "runtime.in"
// Int NOT(Int a);
void gen16(stack *Stack)
{
Int a=vm::pop<Int>(Stack);
-#line 1214 "runtime.in"
+#line 1224 "runtime.in"
{Stack->push<Int>(~a); return;}
}
// Casts
-#line 1220 "runtime.in"
+#line 1230 "runtime.in"
void pairToGuide(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 1221 "runtime.in"
+#line 1231 "runtime.in"
{Stack->push<guide*>(new pairguide(z)); return;}
}
-#line 1226 "runtime.in"
+#line 1236 "runtime.in"
void pathToGuide(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 1227 "runtime.in"
+#line 1237 "runtime.in"
{Stack->push<guide*>(new pathguide(p)); return;}
}
-#line 1231 "runtime.in"
+#line 1241 "runtime.in"
void guideToPath(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 1232 "runtime.in"
+#line 1242 "runtime.in"
{Stack->push<path>(g->solve()); return;}
}
// Picture operations
-#line 1238 "runtime.in"
+#line 1248 "runtime.in"
void newPicture(stack *Stack)
{
-#line 1239 "runtime.in"
+#line 1249 "runtime.in"
{Stack->push<picture*>(new picture()); return;}
}
-#line 1244 "runtime.in"
+#line 1254 "runtime.in"
// bool empty(picture *f);
void gen21(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1245 "runtime.in"
+#line 1255 "runtime.in"
{Stack->push<bool>(f->null()); return;}
}
-#line 1249 "runtime.in"
+#line 1259 "runtime.in"
// void erase(picture *f);
void gen22(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1250 "runtime.in"
+#line 1260 "runtime.in"
f->nodes.clear();
}
-#line 1254 "runtime.in"
+#line 1264 "runtime.in"
// pair min(picture *f);
void gen23(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1255 "runtime.in"
+#line 1265 "runtime.in"
{Stack->push<pair>(f->bounds().Min()); return;}
}
-#line 1259 "runtime.in"
+#line 1269 "runtime.in"
// pair max(picture *f);
void gen24(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1260 "runtime.in"
+#line 1270 "runtime.in"
{Stack->push<pair>(f->bounds().Max()); return;}
}
-#line 1264 "runtime.in"
+#line 1274 "runtime.in"
// void label(picture *f, string *s, string *size, transform t, pair position, pair align, pen p);
void gen25(stack *Stack)
{
@@ -1313,26 +1323,51 @@ void gen25(stack *Stack)
string * size=vm::pop<string *>(Stack);
string * s=vm::pop<string *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1266 "runtime.in"
+#line 1276 "runtime.in"
f->append(new drawLabel(*s,*size,t,position,align,p));
}
-#line 1270 "runtime.in"
+#line 1280 "runtime.in"
// bool labels(picture *f);
void gen26(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1271 "runtime.in"
+#line 1281 "runtime.in"
{Stack->push<bool>(f->havelabels()); return;}
}
-#line 1275 "runtime.in"
-// patharray* _texpath(string *s, pen p=CURRENTPEN);
+#line 1285 "runtime.in"
+// realarray* texsize(string *s, pen p=CURRENTPEN);
void gen27(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
string * s=vm::pop<string *>(Stack);
-#line 1276 "runtime.in"
+#line 1286 "runtime.in"
+ texinit();
+ processDataStruct &pd=processData();
+
+ string texengine=getSetting<string>("tex");
+ const char **abort=texabort(texengine);
+ setpen(pd.tex,texengine,p);
+
+ double width,height,depth;
+ if(!texbounds(width,height,depth,pd.tex,*s,abort,false,true))
+ {Stack->push<realarray*>(new array(0)); return;}
+
+ array *t=new array(3);
+ (*t)[0]=width;
+ (*t)[1]=height;
+ (*t)[2]=depth;
+ {Stack->push<realarray*>(t); return;}
+}
+
+#line 1305 "runtime.in"
+// patharray* _texpath(string *s, pen p=CURRENTPEN);
+void gen28(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ string * s=vm::pop<string *>(Stack);
+#line 1306 "runtime.in"
array *P=new array(0);
if(s->empty()) {Stack->push<patharray*>(P); return;}
@@ -1349,18 +1384,19 @@ void gen27(stack *Stack)
if(!pdf) {
tex.verbatimline("\\special{ps:");
- tex.verbatimline(ASYo);
+ tex.verbatimline(ASYx);
+ tex.verbatimline(ASYy);
tex.verbatimline("/ASY1 true def");
- tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
- tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
- "/ASY1 false def} if currentpoint newpath moveto false charpath "+
+ tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYy ASYx (L) print ASYy add ASYx (L) print add ASYy add ASYx (L) print add ASYy ASYx (c) print} bind def");
+ tex.verbatimline("/show {"+ASY1+
+ "currentpoint newpath moveto false charpath "+
pathforall+"} bind def}");
}
tex.verbatimline(*s+"%");
tex.epilogue(true);
tex.close();
- // TODO: Put in common subproutine (cf. teprocess).
+ // TODO: Put in common subproutine (cf. texprocess).
string aux=auxname(prefix,"aux");
unlink(aux.c_str());
string program=texprogram();
@@ -1388,16 +1424,8 @@ void gen27(stack *Stack)
std::ofstream ps(psname.c_str());
if(!ps) cannotwrite(psname);
- ps << ASYo << newl
- << "/ASY1 true def" << newl
- << "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl
- << "/stroke {ASY1 {(Z) " << currentpoint
- << "/ASY1 false def} if strokepath "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl;
-
+ showpath(ps);
+
ostringstream cmd;
cmd << "'" << getSetting<string>("gs")
<< "' -q -dNOCACHE -dNOPAUSE -dBATCH";
@@ -1446,13 +1474,13 @@ void gen27(stack *Stack)
pdf ? twelvepercent : -twelvepercent)); return;}
}
-#line 1390 "runtime.in"
+#line 1413 "runtime.in"
// patharray* textpath(string *s, pen p=CURRENTPEN);
-void gen28(stack *Stack)
+void gen29(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
string * s=vm::pop<string *>(Stack);
-#line 1391 "runtime.in"
+#line 1414 "runtime.in"
array *P=new array(0);
if(s->empty()) {Stack->push<patharray*>(P); return;}
@@ -1475,15 +1503,7 @@ void gen28(stack *Stack)
std::ofstream ps(psname.c_str());
if(!ps) cannotwrite(psname);
- ps << ASYo << newl
- << "/ASY1 true def" << newl
- << "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl
- << "/stroke {ASY1 {(Z) " << currentpoint
- << "/ASY1 false def} if strokepath "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << endl;
+ showpath(ps);
ostringstream pipe;
pipe << getSetting<string>("textcommand") << " '" << textname << "'";
@@ -1523,13 +1543,13 @@ void gen28(stack *Stack)
{Stack->push<patharray*>(readpath(psname,keep,tenpercent,tenpercent)); return;}
}
-#line 1462 "runtime.in"
+#line 1477 "runtime.in"
// patharray* _strokepath(path g, pen p=CURRENTPEN);
-void gen29(stack *Stack)
+void gen30(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
path g=vm::pop<path>(Stack);
-#line 1463 "runtime.in"
+#line 1478 "runtime.in"
array *P=new array(0);
if(g.size() == 0) {Stack->push<patharray*>(P); return;}
@@ -1539,8 +1559,9 @@ void gen29(stack *Stack)
bbox b;
psfile ps(psname,false);
ps.prologue(b);
- ps.verbatimline(ASYo);
- ps.verbatimline("/stroke {(Z) "+currentpoint+pathforall+"} bind def");
+ ps.verbatimline(ASYx);
+ ps.verbatimline(ASYy);
+ ps.verbatimline("/stroke {"+ASYinit+pathforall+"} bind def");
ps.resetpen();
ps.setpen(p);
ps.write(g);
@@ -1552,33 +1573,33 @@ void gen29(stack *Stack)
{Stack->push<patharray*>(readpath(psname,getSetting<bool>("keep"))); return;}
}
-#line 1486 "runtime.in"
+#line 1502 "runtime.in"
// void _draw(picture *f, path g, pen p);
-void gen30(stack *Stack)
+void gen31(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
path g=vm::pop<path>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1487 "runtime.in"
+#line 1503 "runtime.in"
f->append(new drawPath(g,p));
}
-#line 1491 "runtime.in"
+#line 1507 "runtime.in"
// void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
-void gen31(stack *Stack)
+void gen32(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
pen p=vm::pop<pen>(Stack,CURRENTPEN);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1492 "runtime.in"
+#line 1508 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawFill(*copyarray(g),false,p));
}
-#line 1497 "runtime.in"
+#line 1513 "runtime.in"
// void latticeshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, bool copy=true);
-void gen32(stack *Stack)
+void gen33(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
penarray2 * p=vm::pop<penarray2 *>(Stack);
@@ -1586,14 +1607,14 @@ void gen32(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1499 "runtime.in"
+#line 1515 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p)));
}
-#line 1504 "runtime.in"
+#line 1520 "runtime.in"
// void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, pen penb, pair b, bool copy=true);
-void gen33(stack *Stack)
+void gen34(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
pair b=vm::pop<pair>(Stack);
@@ -1603,14 +1624,14 @@ void gen33(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1506 "runtime.in"
+#line 1522 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,penb,b));
}
-#line 1511 "runtime.in"
+#line 1527 "runtime.in"
// void radialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, real ra, pen penb, pair b, real rb, bool copy=true);
-void gen34(stack *Stack)
+void gen35(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
real rb=vm::pop<real>(Stack);
@@ -1622,14 +1643,14 @@ void gen34(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1513 "runtime.in"
+#line 1529 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,penb,b,rb));
}
-#line 1518 "runtime.in"
+#line 1534 "runtime.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, pairarray *z, Intarray *edges, bool copy=true);
-void gen35(stack *Stack)
+void gen36(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
Intarray * edges=vm::pop<Intarray *>(Stack);
@@ -1639,7 +1660,7 @@ void gen35(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1521 "runtime.in"
+#line 1537 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
checkArrays(p,z);
checkArrays(z,edges);
@@ -1647,9 +1668,9 @@ void gen35(stack *Stack)
*copyarray(z),*copyarray(edges)));
}
-#line 1529 "runtime.in"
+#line 1545 "runtime.in"
// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, Intarray *edges, bool copy=true);
-void gen36(stack *Stack)
+void gen37(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
Intarray * edges=vm::pop<Intarray *>(Stack);
@@ -1658,7 +1679,7 @@ void gen36(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1532 "runtime.in"
+#line 1548 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
size_t n=checkArrays(p,edges);
size_t m=checkArray(g);
@@ -1679,9 +1700,9 @@ void gen36(stack *Stack)
*z,*copyarray(edges)));
}
-#line 1553 "runtime.in"
+#line 1569 "runtime.in"
// void tensorshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL, pairarray2 *z=emptyarray, bool copy=true);
-void gen37(stack *Stack)
+void gen38(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
pairarray2 * z=vm::pop<pairarray2 *>(Stack,emptyarray);
@@ -1691,7 +1712,7 @@ void gen37(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1556 "runtime.in"
+#line 1572 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
if(b == NULL) b=g;
@@ -1703,9 +1724,9 @@ void gen37(stack *Stack)
*copyarray(b),*copyarray2(z)));
}
-#line 1568 "runtime.in"
+#line 1584 "runtime.in"
// void functionshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, string shader=emptystring, bool copy=true);
-void gen38(stack *Stack)
+void gen39(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
string shader=vm::pop<string>(Stack,emptystring);
@@ -1713,176 +1734,176 @@ void gen38(stack *Stack)
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1571 "runtime.in"
+#line 1587 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
}
// Clip a picture to a superpath using the given fill rule.
// Subsequent additions to the picture will not be affected by the clipping.
-#line 1578 "runtime.in"
+#line 1594 "runtime.in"
// void clip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
-void gen39(stack *Stack)
+void gen40(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1580 "runtime.in"
+#line 1596 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
f->enclose(begin,new drawClipEnd(true,begin));
}
-#line 1586 "runtime.in"
+#line 1602 "runtime.in"
// void beginclip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
-void gen40(stack *Stack)
+void gen41(stack *Stack)
{
bool copy=vm::pop<bool>(Stack,true);
pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
bool stroke=vm::pop<bool>(Stack,false);
patharray * g=vm::pop<patharray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1588 "runtime.in"
+#line 1604 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
}
-#line 1593 "runtime.in"
+#line 1609 "runtime.in"
// void endclip(picture *f);
-void gen41(stack *Stack)
+void gen42(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1594 "runtime.in"
+#line 1610 "runtime.in"
f->append(new drawClipEnd(false));
}
-#line 1598 "runtime.in"
+#line 1614 "runtime.in"
// void gsave(picture *f);
-void gen42(stack *Stack)
+void gen43(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1599 "runtime.in"
+#line 1615 "runtime.in"
f->append(new drawGsave());
}
-#line 1603 "runtime.in"
+#line 1619 "runtime.in"
// void grestore(picture *f);
-void gen43(stack *Stack)
+void gen44(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1604 "runtime.in"
+#line 1620 "runtime.in"
f->append(new drawGrestore());
}
-#line 1608 "runtime.in"
+#line 1624 "runtime.in"
// void begingroup(picture *f);
-void gen44(stack *Stack)
+void gen45(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1609 "runtime.in"
+#line 1625 "runtime.in"
f->append(new drawBegin());
}
-#line 1613 "runtime.in"
+#line 1629 "runtime.in"
// void endgroup(picture *f);
-void gen45(stack *Stack)
+void gen46(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1614 "runtime.in"
+#line 1630 "runtime.in"
f->append(new drawEnd());
}
-#line 1618 "runtime.in"
+#line 1634 "runtime.in"
// void add(picture *dest, picture *src);
-void gen46(stack *Stack)
+void gen47(stack *Stack)
{
picture * src=vm::pop<picture *>(Stack);
picture * dest=vm::pop<picture *>(Stack);
-#line 1619 "runtime.in"
+#line 1635 "runtime.in"
dest->add(*src);
}
-#line 1623 "runtime.in"
+#line 1639 "runtime.in"
// void prepend(picture *dest, picture *src);
-void gen47(stack *Stack)
+void gen48(stack *Stack)
{
picture * src=vm::pop<picture *>(Stack);
picture * dest=vm::pop<picture *>(Stack);
-#line 1624 "runtime.in"
+#line 1640 "runtime.in"
dest->prepend(*src);
}
-#line 1628 "runtime.in"
+#line 1644 "runtime.in"
// void postscript(picture *f, string s);
-void gen48(stack *Stack)
+void gen49(stack *Stack)
{
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1629 "runtime.in"
+#line 1645 "runtime.in"
f->append(new drawVerbatim(PostScript,s));
}
-#line 1633 "runtime.in"
+#line 1649 "runtime.in"
// void tex(picture *f, string s);
-void gen49(stack *Stack)
+void gen50(stack *Stack)
{
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1634 "runtime.in"
+#line 1650 "runtime.in"
f->append(new drawVerbatim(TeX,s));
}
-#line 1638 "runtime.in"
+#line 1654 "runtime.in"
// void postscript(picture *f, string s, pair min, pair max);
-void gen50(stack *Stack)
+void gen51(stack *Stack)
{
pair max=vm::pop<pair>(Stack);
pair min=vm::pop<pair>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1639 "runtime.in"
+#line 1655 "runtime.in"
f->append(new drawVerbatim(PostScript,s,min,max));
}
-#line 1643 "runtime.in"
+#line 1659 "runtime.in"
// void tex(picture *f, string s, pair min, pair max);
-void gen51(stack *Stack)
+void gen52(stack *Stack)
{
pair max=vm::pop<pair>(Stack);
pair min=vm::pop<pair>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1644 "runtime.in"
+#line 1660 "runtime.in"
f->append(new drawVerbatim(TeX,s,min,max));
}
-#line 1648 "runtime.in"
+#line 1664 "runtime.in"
// void texpreamble(string s);
-void gen52(stack *Stack)
+void gen53(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 1649 "runtime.in"
+#line 1665 "runtime.in"
string t=s+"\n";
processDataStruct &pd=processData();
pd.TeXpipepreamble.push_back(t);
pd.TeXpreamble.push_back(t);
}
-#line 1656 "runtime.in"
+#line 1672 "runtime.in"
// void deletepreamble();
-void gen53(stack *)
+void gen54(stack *)
{
-#line 1657 "runtime.in"
+#line 1673 "runtime.in"
if(getSetting<bool>("inlinetex")) {
unlink(auxname(outname(),"pre").c_str());
}
}
-#line 1663 "runtime.in"
+#line 1679 "runtime.in"
// void _labelpath(picture *f, string s, string size, path g, string justify, pair offset, pen p);
-void gen54(stack *Stack)
+void gen55(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
pair offset=vm::pop<pair>(Stack);
@@ -1891,42 +1912,42 @@ void gen54(stack *Stack)
string size=vm::pop<string>(Stack);
string s=vm::pop<string>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1665 "runtime.in"
+#line 1681 "runtime.in"
f->append(new drawLabelPath(s,size,g,justify,offset,p));
}
-#line 1669 "runtime.in"
+#line 1685 "runtime.in"
// void texreset();
-void gen55(stack *)
+void gen56(stack *)
{
-#line 1670 "runtime.in"
+#line 1686 "runtime.in"
processDataStruct &pd=processData();
pd.TeXpipepreamble.clear();
pd.TeXpreamble.clear();
pd.tex.pipeclose();
}
-#line 1677 "runtime.in"
+#line 1693 "runtime.in"
// void layer(picture *f);
-void gen56(stack *Stack)
+void gen57(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1678 "runtime.in"
+#line 1694 "runtime.in"
f->append(new drawLayer());
}
-#line 1682 "runtime.in"
+#line 1698 "runtime.in"
// void newpage(picture *f);
-void gen57(stack *Stack)
+void gen58(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 1683 "runtime.in"
+#line 1699 "runtime.in"
f->append(new drawNewPage());
}
-#line 1687 "runtime.in"
+#line 1703 "runtime.in"
// void _image(picture *f, realarray2 *data, pair initial, pair final, penarray *palette=NULL, transform t=identity, bool copy=true, bool antialias=false);
-void gen58(stack *Stack)
+void gen59(stack *Stack)
{
bool antialias=vm::pop<bool>(Stack,false);
bool copy=vm::pop<bool>(Stack,true);
@@ -1936,16 +1957,16 @@ void gen58(stack *Stack)
pair initial=vm::pop<pair>(Stack);
realarray2 * data=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1690 "runtime.in"
+#line 1706 "runtime.in"
array *(*copyarray)(array *a)=copy ? copyArray: nop;
array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
f->append(new drawImage(*copyarray2(data),*copyarray(palette),
t*matrix(initial,final),antialias));
}
-#line 1697 "runtime.in"
+#line 1713 "runtime.in"
// void _image(picture *f, penarray2 *data, pair initial, pair final, transform t=identity, bool copy=true, bool antialias=false);
-void gen59(stack *Stack)
+void gen60(stack *Stack)
{
bool antialias=vm::pop<bool>(Stack,false);
bool copy=vm::pop<bool>(Stack,true);
@@ -1954,38 +1975,38 @@ void gen59(stack *Stack)
pair initial=vm::pop<pair>(Stack);
penarray2 * data=vm::pop<penarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 1699 "runtime.in"
+#line 1715 "runtime.in"
array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
f->append(new drawImage(*copyarray2(data),t*matrix(initial,final),antialias));
}
-#line 1704 "runtime.in"
+#line 1720 "runtime.in"
// string nativeformat();
-void gen60(stack *Stack)
+void gen61(stack *Stack)
{
-#line 1705 "runtime.in"
+#line 1721 "runtime.in"
{Stack->push<string>(nativeformat()); return;}
}
-#line 1709 "runtime.in"
+#line 1725 "runtime.in"
// bool latex();
-void gen61(stack *Stack)
+void gen62(stack *Stack)
{
-#line 1710 "runtime.in"
+#line 1726 "runtime.in"
{Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
}
-#line 1714 "runtime.in"
+#line 1730 "runtime.in"
// bool pdf();
-void gen62(stack *Stack)
+void gen63(stack *Stack)
{
-#line 1715 "runtime.in"
+#line 1731 "runtime.in"
{Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
}
-#line 1719 "runtime.in"
+#line 1735 "runtime.in"
// void shipout(string prefix=emptystring, picture *f, picture *preamble=NULL, string format=emptystring, bool wait=false, bool view=true, callableTransform *xform);
-void gen63(stack *Stack)
+void gen64(stack *Stack)
{
callableTransform * xform=vm::pop<callableTransform *>(Stack);
bool view=vm::pop<bool>(Stack,true);
@@ -1994,7 +2015,7 @@ void gen63(stack *Stack)
picture * preamble=vm::pop<picture *>(Stack,NULL);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack,emptystring);
-#line 1722 "runtime.in"
+#line 1738 "runtime.in"
if(prefix.empty()) prefix=outname();
picture *result=new picture;
@@ -2037,9 +2058,9 @@ void gen63(stack *Stack)
result->shipout(preamble,prefix,format,0.0,wait,view);
}
-#line 1765 "runtime.in"
+#line 1781 "runtime.in"
// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, triple m, triple M, realarray2 *t, realarray *background, triplearray *lights, realarray2 *diffuse, realarray2 *ambient, realarray2 *specular, bool viewportlighting, bool view=true);
-void gen64(stack *Stack)
+void gen65(stack *Stack)
{
bool view=vm::pop<bool>(Stack,true);
bool viewportlighting=vm::pop<bool>(Stack);
@@ -2057,7 +2078,7 @@ void gen64(stack *Stack)
string format=vm::pop<string>(Stack,emptystring);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 1770 "runtime.in"
+#line 1786 "runtime.in"
size_t n=checkArrays(lights,diffuse);
checkEqual(n,checkArray(ambient));
checkEqual(n,checkArray(specular));
@@ -2068,25 +2089,25 @@ void gen64(stack *Stack)
copyArray2C(specular,false,4),viewportlighting,view);
}
-#line 1781 "runtime.in"
+#line 1797 "runtime.in"
// void shipout3(string prefix, picture *f);
-void gen65(stack *Stack)
+void gen66(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 1782 "runtime.in"
+#line 1798 "runtime.in"
f->shipout3(prefix);
}
-#line 1786 "runtime.in"
+#line 1802 "runtime.in"
// void deconstruct(picture *f, picture *preamble=NULL, real magnification=1, callableTransform *xform);
-void gen66(stack *Stack)
+void gen67(stack *Stack)
{
callableTransform * xform=vm::pop<callableTransform *>(Stack);
real magnification=vm::pop<real>(Stack,1);
picture * preamble=vm::pop<picture *>(Stack,NULL);
picture * f=vm::pop<picture *>(Stack);
-#line 1788 "runtime.in"
+#line 1804 "runtime.in"
unsigned level=0;
unsigned n=0;
@@ -2217,214 +2238,214 @@ void gen66(stack *Stack)
}
}
-#line 1919 "runtime.in"
+#line 1935 "runtime.in"
// void purge(Int divisor=0);
-void gen67(stack *Stack)
+void gen68(stack *Stack)
{
Int divisor=vm::pop<Int>(Stack,0);
-#line 1920 "runtime.in"
+#line 1936 "runtime.in"
purge(divisor);
}
// Pen operations
-#line 1926 "runtime.in"
+#line 1942 "runtime.in"
void newPen(stack *Stack)
{
-#line 1927 "runtime.in"
+#line 1943 "runtime.in"
{Stack->push<pen>(pen()); return;}
}
-#line 1932 "runtime.in"
+#line 1948 "runtime.in"
// bool ==(pen a, pen b);
-void gen69(stack *Stack)
+void gen70(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 1933 "runtime.in"
+#line 1949 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 1937 "runtime.in"
+#line 1953 "runtime.in"
// bool !=(pen a, pen b);
-void gen70(stack *Stack)
+void gen71(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 1938 "runtime.in"
+#line 1954 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 1942 "runtime.in"
+#line 1958 "runtime.in"
// pen +(pen a, pen b);
-void gen71(stack *Stack)
+void gen72(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 1943 "runtime.in"
+#line 1959 "runtime.in"
{Stack->push<pen>(a+b); return;}
}
-#line 1947 "runtime.in"
+#line 1963 "runtime.in"
// pen *(real a, pen b);
-void gen72(stack *Stack)
+void gen73(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
real a=vm::pop<real>(Stack);
-#line 1948 "runtime.in"
+#line 1964 "runtime.in"
{Stack->push<pen>(a*b); return;}
}
-#line 1952 "runtime.in"
+#line 1968 "runtime.in"
// pen *(pen a, real b);
-void gen73(stack *Stack)
+void gen74(stack *Stack)
{
real b=vm::pop<real>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 1953 "runtime.in"
+#line 1969 "runtime.in"
{Stack->push<pen>(b*a); return;}
}
-#line 1957 "runtime.in"
+#line 1973 "runtime.in"
// pair max(pen p);
-void gen74(stack *Stack)
+void gen75(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 1958 "runtime.in"
+#line 1974 "runtime.in"
{Stack->push<pair>(p.bounds().Max()); return;}
}
-#line 1962 "runtime.in"
+#line 1978 "runtime.in"
// pair min(pen p);
-void gen75(stack *Stack)
+void gen76(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 1963 "runtime.in"
+#line 1979 "runtime.in"
{Stack->push<pair>(p.bounds().Min()); return;}
}
// Reset the meaning of pen default attributes.
-#line 1968 "runtime.in"
+#line 1984 "runtime.in"
// void resetdefaultpen();
-void gen76(stack *)
+void gen77(stack *)
{
-#line 1969 "runtime.in"
+#line 1985 "runtime.in"
processData().defaultpen=camp::pen::initialpen();
}
-#line 1973 "runtime.in"
+#line 1989 "runtime.in"
// void defaultpen(pen p);
-void gen77(stack *Stack)
+void gen78(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 1974 "runtime.in"
+#line 1990 "runtime.in"
processData().defaultpen=pen(resolvepen,p);
}
-#line 1978 "runtime.in"
+#line 1994 "runtime.in"
// pen defaultpen();
-void gen78(stack *Stack)
+void gen79(stack *Stack)
{
-#line 1979 "runtime.in"
+#line 1995 "runtime.in"
{Stack->push<pen>(processData().defaultpen); return;}
}
-#line 1983 "runtime.in"
+#line 1999 "runtime.in"
// bool invisible(pen p);
-void gen79(stack *Stack)
+void gen80(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 1984 "runtime.in"
+#line 2000 "runtime.in"
{Stack->push<bool>(p.invisible()); return;}
}
-#line 1988 "runtime.in"
+#line 2004 "runtime.in"
// pen invisible();
-void gen80(stack *Stack)
+void gen81(stack *Stack)
{
-#line 1989 "runtime.in"
+#line 2005 "runtime.in"
{Stack->push<pen>(pen(invisiblepen)); return;}
}
-#line 1993 "runtime.in"
+#line 2009 "runtime.in"
// pen gray(pen p);
-void gen81(stack *Stack)
+void gen82(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 1994 "runtime.in"
+#line 2010 "runtime.in"
p.togrey();
{Stack->push<pen>(p); return;}
}
-#line 1999 "runtime.in"
+#line 2015 "runtime.in"
// pen rgb(pen p);
-void gen82(stack *Stack)
+void gen83(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2000 "runtime.in"
+#line 2016 "runtime.in"
p.torgb();
{Stack->push<pen>(p); return;}
}
-#line 2005 "runtime.in"
+#line 2021 "runtime.in"
// pen cmyk(pen p);
-void gen83(stack *Stack)
+void gen84(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2006 "runtime.in"
+#line 2022 "runtime.in"
p.tocmyk();
{Stack->push<pen>(p); return;}
}
-#line 2011 "runtime.in"
+#line 2027 "runtime.in"
// pen interp(pen a, pen b, real t);
-void gen84(stack *Stack)
+void gen85(stack *Stack)
{
real t=vm::pop<real>(Stack);
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 2012 "runtime.in"
+#line 2028 "runtime.in"
{Stack->push<pen>(interpolate(a,b,t)); return;}
}
-#line 2016 "runtime.in"
+#line 2032 "runtime.in"
// pen rgb(real r, real g, real b);
-void gen85(stack *Stack)
+void gen86(stack *Stack)
{
real b=vm::pop<real>(Stack);
real g=vm::pop<real>(Stack);
real r=vm::pop<real>(Stack);
-#line 2017 "runtime.in"
+#line 2033 "runtime.in"
{Stack->push<pen>(pen(r,g,b)); return;}
}
-#line 2021 "runtime.in"
+#line 2037 "runtime.in"
// pen cmyk(real c, real m, real y, real k);
-void gen86(stack *Stack)
+void gen87(stack *Stack)
{
real k=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
real m=vm::pop<real>(Stack);
real c=vm::pop<real>(Stack);
-#line 2022 "runtime.in"
+#line 2038 "runtime.in"
{Stack->push<pen>(pen(c,m,y,k)); return;}
}
-#line 2026 "runtime.in"
+#line 2042 "runtime.in"
// pen gray(real gray);
-void gen87(stack *Stack)
+void gen88(stack *Stack)
{
real gray=vm::pop<real>(Stack);
-#line 2027 "runtime.in"
+#line 2043 "runtime.in"
{Stack->push<pen>(pen(gray)); return;}
}
-#line 2031 "runtime.in"
+#line 2047 "runtime.in"
// realarray* colors(pen p);
-void gen88(stack *Stack)
+void gen89(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2032 "runtime.in"
+#line 2048 "runtime.in"
size_t n=ColorComponents[p.colorspace()];
array *a=new array(n);
@@ -2451,60 +2472,60 @@ void gen88(stack *Stack)
{Stack->push<realarray*>(a); return;}
}
-#line 2059 "runtime.in"
+#line 2075 "runtime.in"
// string colorspace(pen p);
-void gen89(stack *Stack)
+void gen90(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2060 "runtime.in"
+#line 2076 "runtime.in"
string s=ColorDeviceSuffix[p.colorspace()];
std::transform(s.begin(),s.end(),s.begin(),tolower);
{Stack->push<string>(s); return;}
}
-#line 2066 "runtime.in"
+#line 2082 "runtime.in"
// pen pattern(string *s);
-void gen90(stack *Stack)
+void gen91(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 2067 "runtime.in"
+#line 2083 "runtime.in"
{Stack->push<pen>(pen(setpattern,*s)); return;}
}
-#line 2071 "runtime.in"
+#line 2087 "runtime.in"
// string pattern(pen p);
-void gen91(stack *Stack)
+void gen92(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2072 "runtime.in"
+#line 2088 "runtime.in"
{Stack->push<string>(p.fillpattern()); return;}
}
-#line 2076 "runtime.in"
+#line 2092 "runtime.in"
// pen fillrule(Int n);
-void gen92(stack *Stack)
+void gen93(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 2077 "runtime.in"
+#line 2093 "runtime.in"
{Stack->push<pen>(pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL)); return;}
}
-#line 2081 "runtime.in"
+#line 2097 "runtime.in"
// Int fillrule(pen p);
-void gen93(stack *Stack)
+void gen94(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2082 "runtime.in"
+#line 2098 "runtime.in"
{Stack->push<Int>(p.Fillrule()); return;}
}
-#line 2086 "runtime.in"
+#line 2102 "runtime.in"
// pen opacity(real opacity=1.0, string blend=defaulttransparency);
-void gen94(stack *Stack)
+void gen95(stack *Stack)
{
string blend=vm::pop<string>(Stack,defaulttransparency);
real opacity=vm::pop<real>(Stack,1.0);
-#line 2087 "runtime.in"
+#line 2103 "runtime.in"
for(Int i=0; i < nBlendMode; ++i)
if(blend == BlendMode[i]) {Stack->push<pen>(pen(Transparency(blend,opacity))); return;}
@@ -2513,357 +2534,357 @@ void gen94(stack *Stack)
error(buf);
}
-#line 2096 "runtime.in"
+#line 2112 "runtime.in"
// real opacity(pen p);
-void gen95(stack *Stack)
+void gen96(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2097 "runtime.in"
+#line 2113 "runtime.in"
{Stack->push<real>(p.opacity()); return;}
}
-#line 2101 "runtime.in"
+#line 2117 "runtime.in"
// string blend(pen p);
-void gen96(stack *Stack)
+void gen97(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2102 "runtime.in"
+#line 2118 "runtime.in"
{Stack->push<string>(p.blend()); return;}
}
-#line 2106 "runtime.in"
+#line 2122 "runtime.in"
// pen linetype(string *s, real offset=0, bool scale=true, bool adjust=true);
-void gen97(stack *Stack)
+void gen98(stack *Stack)
{
bool adjust=vm::pop<bool>(Stack,true);
bool scale=vm::pop<bool>(Stack,true);
real offset=vm::pop<real>(Stack,0);
string * s=vm::pop<string *>(Stack);
-#line 2107 "runtime.in"
+#line 2123 "runtime.in"
{Stack->push<pen>(pen(LineType(*s,offset,scale,adjust))); return;}
}
-#line 2111 "runtime.in"
+#line 2127 "runtime.in"
// string linetype(pen p=CURRENTPEN);
-void gen98(stack *Stack)
+void gen99(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2112 "runtime.in"
+#line 2128 "runtime.in"
{Stack->push<string>(p.stroke()); return;}
}
-#line 2116 "runtime.in"
+#line 2132 "runtime.in"
// real offset(pen p);
-void gen99(stack *Stack)
+void gen100(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2117 "runtime.in"
+#line 2133 "runtime.in"
{Stack->push<real>(p.linetype().offset); return;}
}
-#line 2121 "runtime.in"
+#line 2137 "runtime.in"
// bool scale(pen p);
-void gen100(stack *Stack)
+void gen101(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2122 "runtime.in"
+#line 2138 "runtime.in"
{Stack->push<bool>(p.linetype().scale); return;}
}
-#line 2126 "runtime.in"
+#line 2142 "runtime.in"
// bool adjust(pen p);
-void gen101(stack *Stack)
+void gen102(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2127 "runtime.in"
+#line 2143 "runtime.in"
{Stack->push<bool>(p.linetype().adjust); return;}
}
-#line 2131 "runtime.in"
+#line 2147 "runtime.in"
// pen adjust(pen p, real arclength, bool cyclic);
-void gen102(stack *Stack)
+void gen103(stack *Stack)
{
bool cyclic=vm::pop<bool>(Stack);
real arclength=vm::pop<real>(Stack);
pen p=vm::pop<pen>(Stack);
-#line 2132 "runtime.in"
+#line 2148 "runtime.in"
{Stack->push<pen>(adjustdash(p,arclength,cyclic)); return;}
}
-#line 2136 "runtime.in"
+#line 2152 "runtime.in"
// pen linecap(Int n);
-void gen103(stack *Stack)
+void gen104(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 2137 "runtime.in"
+#line 2153 "runtime.in"
{Stack->push<pen>(pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP)); return;}
}
-#line 2141 "runtime.in"
+#line 2157 "runtime.in"
// Int linecap(pen p=CURRENTPEN);
-void gen104(stack *Stack)
+void gen105(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2142 "runtime.in"
+#line 2158 "runtime.in"
{Stack->push<Int>(p.cap()); return;}
}
-#line 2146 "runtime.in"
+#line 2162 "runtime.in"
// pen linejoin(Int n);
-void gen105(stack *Stack)
+void gen106(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 2147 "runtime.in"
+#line 2163 "runtime.in"
{Stack->push<pen>(pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN)); return;}
}
-#line 2151 "runtime.in"
+#line 2167 "runtime.in"
// Int linejoin(pen p=CURRENTPEN);
-void gen106(stack *Stack)
+void gen107(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2152 "runtime.in"
+#line 2168 "runtime.in"
{Stack->push<Int>(p.join()); return;}
}
-#line 2156 "runtime.in"
+#line 2172 "runtime.in"
// pen miterlimit(real x);
-void gen107(stack *Stack)
+void gen108(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 2157 "runtime.in"
+#line 2173 "runtime.in"
{Stack->push<pen>(pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN)); return;}
}
-#line 2161 "runtime.in"
+#line 2177 "runtime.in"
// real miterlimit(pen p=CURRENTPEN);
-void gen108(stack *Stack)
+void gen109(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2162 "runtime.in"
+#line 2178 "runtime.in"
{Stack->push<real>(p.miter()); return;}
}
-#line 2166 "runtime.in"
+#line 2182 "runtime.in"
// pen linewidth(real x);
-void gen109(stack *Stack)
+void gen110(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 2167 "runtime.in"
+#line 2183 "runtime.in"
{Stack->push<pen>(pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH)); return;}
}
-#line 2171 "runtime.in"
+#line 2187 "runtime.in"
// real linewidth(pen p=CURRENTPEN);
-void gen110(stack *Stack)
+void gen111(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2172 "runtime.in"
+#line 2188 "runtime.in"
{Stack->push<real>(p.width()); return;}
}
-#line 2176 "runtime.in"
+#line 2192 "runtime.in"
// pen fontcommand(string *s);
-void gen111(stack *Stack)
+void gen112(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 2177 "runtime.in"
+#line 2193 "runtime.in"
{Stack->push<pen>(pen(setfont,*s)); return;}
}
-#line 2181 "runtime.in"
+#line 2197 "runtime.in"
// string font(pen p=CURRENTPEN);
-void gen112(stack *Stack)
+void gen113(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2182 "runtime.in"
+#line 2198 "runtime.in"
{Stack->push<string>(p.Font()); return;}
}
-#line 2186 "runtime.in"
+#line 2202 "runtime.in"
// pen fontsize(real size, real lineskip);
-void gen113(stack *Stack)
+void gen114(stack *Stack)
{
real lineskip=vm::pop<real>(Stack);
real size=vm::pop<real>(Stack);
-#line 2187 "runtime.in"
+#line 2203 "runtime.in"
{Stack->push<pen>(pen(setfontsize,size > 0.0 ? size : 0.0,
lineskip > 0.0 ? lineskip : 0.0)); return;}
}
-#line 2192 "runtime.in"
+#line 2208 "runtime.in"
// real fontsize(pen p=CURRENTPEN);
-void gen114(stack *Stack)
+void gen115(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2193 "runtime.in"
+#line 2209 "runtime.in"
{Stack->push<real>(p.size()); return;}
}
-#line 2197 "runtime.in"
+#line 2213 "runtime.in"
// real lineskip(pen p=CURRENTPEN);
-void gen115(stack *Stack)
+void gen116(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2198 "runtime.in"
+#line 2214 "runtime.in"
{Stack->push<real>(p.Lineskip()); return;}
}
-#line 2202 "runtime.in"
+#line 2218 "runtime.in"
// pen overwrite(Int n);
-void gen116(stack *Stack)
+void gen117(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 2203 "runtime.in"
+#line 2219 "runtime.in"
{Stack->push<pen>(pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
DEFWRITE)); return;}
}
-#line 2208 "runtime.in"
+#line 2224 "runtime.in"
// Int overwrite(pen p=CURRENTPEN);
-void gen117(stack *Stack)
+void gen118(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2209 "runtime.in"
+#line 2225 "runtime.in"
{Stack->push<Int>(p.Overwrite()); return;}
}
-#line 2213 "runtime.in"
+#line 2229 "runtime.in"
// pen basealign(Int n);
-void gen118(stack *Stack)
+void gen119(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 2214 "runtime.in"
+#line 2230 "runtime.in"
{Stack->push<pen>(pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE)); return;}
}
-#line 2218 "runtime.in"
+#line 2234 "runtime.in"
// Int basealign(pen p=CURRENTPEN);
-void gen119(stack *Stack)
+void gen120(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 2219 "runtime.in"
+#line 2235 "runtime.in"
{Stack->push<Int>(p.Baseline()); return;}
}
-#line 2223 "runtime.in"
+#line 2239 "runtime.in"
// transform transform(pen p);
-void gen120(stack *Stack)
+void gen121(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2224 "runtime.in"
+#line 2240 "runtime.in"
{Stack->push<transform>(p.getTransform()); return;}
}
-#line 2228 "runtime.in"
+#line 2244 "runtime.in"
// path nib(pen p);
-void gen121(stack *Stack)
+void gen122(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2229 "runtime.in"
+#line 2245 "runtime.in"
{Stack->push<path>(p.Path()); return;}
}
-#line 2233 "runtime.in"
+#line 2249 "runtime.in"
// pen makepen(path p);
-void gen122(stack *Stack)
+void gen123(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2234 "runtime.in"
+#line 2250 "runtime.in"
{Stack->push<pen>(pen(p)); return;}
}
-#line 2238 "runtime.in"
+#line 2254 "runtime.in"
// pen colorless(pen p);
-void gen123(stack *Stack)
+void gen124(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 2239 "runtime.in"
+#line 2255 "runtime.in"
p.colorless();
{Stack->push<pen>(p); return;}
}
// Interactive mode
-#line 2245 "runtime.in"
+#line 2261 "runtime.in"
// bool interactive();
-void gen124(stack *Stack)
+void gen125(stack *Stack)
{
-#line 2246 "runtime.in"
+#line 2262 "runtime.in"
{Stack->push<bool>(interact::interactive); return;}
}
-#line 2251 "runtime.in"
+#line 2267 "runtime.in"
// bool uptodate();
-void gen125(stack *Stack)
+void gen126(stack *Stack)
{
-#line 2252 "runtime.in"
+#line 2268 "runtime.in"
{Stack->push<bool>(interact::uptodate); return;}
}
// System commands
-#line 2258 "runtime.in"
+#line 2274 "runtime.in"
// Int system(string s);
-void gen126(stack *Stack)
+void gen127(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 2259 "runtime.in"
+#line 2275 "runtime.in"
if(safe) error("system() call disabled; override with option -nosafe");
if(s.empty()) {Stack->push<Int>(0); return;}
else {Stack->push<Int>(System(s.c_str())); return;}
}
-#line 2266 "runtime.in"
+#line 2282 "runtime.in"
// bool view();
-void gen127(stack *Stack)
+void gen128(stack *Stack)
{
-#line 2267 "runtime.in"
+#line 2283 "runtime.in"
{Stack->push<bool>(view()); return;}
}
-#line 2271 "runtime.in"
+#line 2287 "runtime.in"
// string asydir();
-void gen128(stack *Stack)
+void gen129(stack *Stack)
{
-#line 2272 "runtime.in"
+#line 2288 "runtime.in"
{Stack->push<string>(systemDir); return;}
}
-#line 2276 "runtime.in"
+#line 2292 "runtime.in"
// string locale(string s=emptystring);
-void gen129(stack *Stack)
+void gen130(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 2277 "runtime.in"
+#line 2293 "runtime.in"
char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
{Stack->push<string>(L != NULL ? string(L) : ""); return;}
}
-#line 2282 "runtime.in"
+#line 2298 "runtime.in"
// void abort(string s=emptystring);
-void gen130(stack *Stack)
+void gen131(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 2283 "runtime.in"
+#line 2299 "runtime.in"
if(s.empty()) throw handled_error();
error(s.c_str());
}
-#line 2288 "runtime.in"
+#line 2304 "runtime.in"
// void exit();
-void gen131(stack *)
+void gen132(stack *)
{
-#line 2289 "runtime.in"
+#line 2305 "runtime.in"
throw quit();
}
-#line 2293 "runtime.in"
+#line 2309 "runtime.in"
// void assert(bool b, string s=emptystring);
-void gen132(stack *Stack)
+void gen133(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
bool b=vm::pop<bool>(Stack);
-#line 2294 "runtime.in"
+#line 2310 "runtime.in"
flush(cout);
if(!b) {
ostringstream buf;
@@ -2873,34 +2894,34 @@ void gen132(stack *Stack)
}
}
-#line 2304 "runtime.in"
+#line 2320 "runtime.in"
// void sleep(Int seconds);
-void gen133(stack *Stack)
+void gen134(stack *Stack)
{
Int seconds=vm::pop<Int>(Stack);
-#line 2305 "runtime.in"
+#line 2321 "runtime.in"
if(seconds <= 0) return;
sleep(seconds);
}
-#line 2310 "runtime.in"
+#line 2326 "runtime.in"
// void usleep(Int microseconds);
-void gen134(stack *Stack)
+void gen135(stack *Stack)
{
Int microseconds=vm::pop<Int>(Stack);
-#line 2311 "runtime.in"
+#line 2327 "runtime.in"
if(microseconds <= 0) return;
usleep((unsigned long) microseconds);
}
-#line 2316 "runtime.in"
+#line 2332 "runtime.in"
// void _eval(string *s, bool embedded, bool interactiveWrite=false);
-void gen135(stack *Stack)
+void gen136(stack *Stack)
{
bool interactiveWrite=vm::pop<bool>(Stack,false);
bool embedded=vm::pop<bool>(Stack);
string * s=vm::pop<string *>(Stack);
-#line 2317 "runtime.in"
+#line 2333 "runtime.in"
if (embedded) {
trans::coenv *e=Stack->getEnvironment();
vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
@@ -2914,13 +2935,13 @@ void gen135(stack *Stack)
}
}
-#line 2331 "runtime.in"
+#line 2347 "runtime.in"
// void _eval(runnable *s, bool embedded);
-void gen136(stack *Stack)
+void gen137(stack *Stack)
{
bool embedded=vm::pop<bool>(Stack);
runnable * s=vm::pop<runnable *>(Stack);
-#line 2332 "runtime.in"
+#line 2348 "runtime.in"
absyntax::block *ast=new absyntax::block(s->getPos(), false);
ast->add(s);
@@ -2937,42 +2958,42 @@ void gen136(stack *Stack)
}
}
-#line 2349 "runtime.in"
+#line 2365 "runtime.in"
// string location();
-void gen137(stack *Stack)
+void gen138(stack *Stack)
{
-#line 2350 "runtime.in"
+#line 2366 "runtime.in"
ostringstream buf;
buf << getPos();
{Stack->push<string>(buf.str()); return;}
}
// Wrapper for the stack::load() method.
-#line 2356 "runtime.in"
+#line 2372 "runtime.in"
void loadModule(stack *Stack)
{
string * index=vm::pop<string *>(Stack);
-#line 2357 "runtime.in"
+#line 2373 "runtime.in"
Stack->load(*index);
}
-#line 2361 "runtime.in"
+#line 2377 "runtime.in"
// string cd(string s=emptystring);
-void gen139(stack *Stack)
+void gen140(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 2362 "runtime.in"
+#line 2378 "runtime.in"
if(!s.empty() && !globalwrite()) writeDisabled();
{Stack->push<string>(setPath(s.c_str())); return;}
}
-#line 2367 "runtime.in"
+#line 2383 "runtime.in"
// void list(string *s, bool imports=false);
-void gen140(stack *Stack)
+void gen141(stack *Stack)
{
bool imports=vm::pop<bool>(Stack,false);
string * s=vm::pop<string *>(Stack);
-#line 2368 "runtime.in"
+#line 2384 "runtime.in"
if(*s == "-") return;
trans::genv ge;
symbol *name=symbol::trans(*s);
@@ -2982,144 +3003,144 @@ void gen140(stack *Stack)
// Path operations
-#line 2378 "runtime.in"
+#line 2394 "runtime.in"
void nullPath(stack *Stack)
{
-#line 2379 "runtime.in"
+#line 2395 "runtime.in"
{Stack->push<path>(nullpath); return;}
}
-#line 2384 "runtime.in"
+#line 2400 "runtime.in"
// bool ==(path a, path b);
-void gen142(stack *Stack)
+void gen143(stack *Stack)
{
path b=vm::pop<path>(Stack);
path a=vm::pop<path>(Stack);
-#line 2385 "runtime.in"
+#line 2401 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 2389 "runtime.in"
+#line 2405 "runtime.in"
// bool !=(path a, path b);
-void gen143(stack *Stack)
+void gen144(stack *Stack)
{
path b=vm::pop<path>(Stack);
path a=vm::pop<path>(Stack);
-#line 2390 "runtime.in"
+#line 2406 "runtime.in"
{Stack->push<bool>(!(a == b)); return;}
}
-#line 2394 "runtime.in"
+#line 2410 "runtime.in"
// pair point(path p, Int t);
-void gen144(stack *Stack)
+void gen145(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2395 "runtime.in"
+#line 2411 "runtime.in"
{Stack->push<pair>(p.point((Int) t)); return;}
}
-#line 2399 "runtime.in"
+#line 2415 "runtime.in"
// pair point(path p, real t);
-void gen145(stack *Stack)
+void gen146(stack *Stack)
{
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2400 "runtime.in"
+#line 2416 "runtime.in"
{Stack->push<pair>(p.point(t)); return;}
}
-#line 2404 "runtime.in"
+#line 2420 "runtime.in"
// pair precontrol(path p, Int t);
-void gen146(stack *Stack)
+void gen147(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2405 "runtime.in"
+#line 2421 "runtime.in"
{Stack->push<pair>(p.precontrol((Int) t)); return;}
}
-#line 2409 "runtime.in"
+#line 2425 "runtime.in"
// pair precontrol(path p, real t);
-void gen147(stack *Stack)
+void gen148(stack *Stack)
{
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2410 "runtime.in"
+#line 2426 "runtime.in"
{Stack->push<pair>(p.precontrol(t)); return;}
}
-#line 2414 "runtime.in"
+#line 2430 "runtime.in"
// pair postcontrol(path p, Int t);
-void gen148(stack *Stack)
+void gen149(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2415 "runtime.in"
+#line 2431 "runtime.in"
{Stack->push<pair>(p.postcontrol((Int) t)); return;}
}
-#line 2419 "runtime.in"
+#line 2435 "runtime.in"
// pair postcontrol(path p, real t);
-void gen149(stack *Stack)
+void gen150(stack *Stack)
{
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2420 "runtime.in"
+#line 2436 "runtime.in"
{Stack->push<pair>(p.postcontrol(t)); return;}
}
-#line 2424 "runtime.in"
+#line 2440 "runtime.in"
// pair dir(path p, Int t, Int sign=0, bool normalize=true);
-void gen150(stack *Stack)
+void gen151(stack *Stack)
{
bool normalize=vm::pop<bool>(Stack,true);
Int sign=vm::pop<Int>(Stack,0);
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2425 "runtime.in"
+#line 2441 "runtime.in"
{Stack->push<pair>(p.dir(t,sign,normalize)); return;}
}
-#line 2429 "runtime.in"
+#line 2445 "runtime.in"
// pair dir(path p, real t, bool normalize=true);
-void gen151(stack *Stack)
+void gen152(stack *Stack)
{
bool normalize=vm::pop<bool>(Stack,true);
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2430 "runtime.in"
+#line 2446 "runtime.in"
{Stack->push<pair>(p.dir(t,normalize)); return;}
}
-#line 2434 "runtime.in"
+#line 2450 "runtime.in"
// pair accel(path p, Int t, Int sign=0);
-void gen152(stack *Stack)
+void gen153(stack *Stack)
{
Int sign=vm::pop<Int>(Stack,0);
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2435 "runtime.in"
+#line 2451 "runtime.in"
{Stack->push<pair>(p.accel(t,sign)); return;}
}
-#line 2439 "runtime.in"
+#line 2455 "runtime.in"
// pair accel(path p, real t);
-void gen153(stack *Stack)
+void gen154(stack *Stack)
{
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2440 "runtime.in"
+#line 2456 "runtime.in"
{Stack->push<pair>(p.accel(t)); return;}
}
-#line 2444 "runtime.in"
+#line 2460 "runtime.in"
// real radius(path p, real t);
-void gen154(stack *Stack)
+void gen155(stack *Stack)
{
real t=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2445 "runtime.in"
+#line 2461 "runtime.in"
pair v=p.dir(t,false);
pair a=p.accel(t);
real d=dot(a,v);
@@ -3130,40 +3151,40 @@ void gen154(stack *Stack)
{Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
}
-#line 2456 "runtime.in"
+#line 2472 "runtime.in"
// path reverse(path p);
-void gen155(stack *Stack)
+void gen156(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2457 "runtime.in"
+#line 2473 "runtime.in"
{Stack->push<path>(p.reverse()); return;}
}
-#line 2461 "runtime.in"
+#line 2477 "runtime.in"
// path subpath(path p, Int a, Int b);
-void gen156(stack *Stack)
+void gen157(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2462 "runtime.in"
+#line 2478 "runtime.in"
{Stack->push<path>(p.subpath((Int) a, (Int) b)); return;}
}
-#line 2466 "runtime.in"
+#line 2482 "runtime.in"
// path subpath(path p, real a, real b);
-void gen157(stack *Stack)
+void gen158(stack *Stack)
{
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2467 "runtime.in"
+#line 2483 "runtime.in"
{Stack->push<path>(p.subpath(a,b)); return;}
}
-#line 2471 "runtime.in"
+#line 2487 "runtime.in"
// path nurb(pair z0, pair z1, pair z2, pair z3, real w0, real w1, real w2, real w3, Int m);
-void gen158(stack *Stack)
+void gen159(stack *Stack)
{
Int m=vm::pop<Int>(Stack);
real w3=vm::pop<real>(Stack);
@@ -3174,93 +3195,93 @@ void gen158(stack *Stack)
pair z2=vm::pop<pair>(Stack);
pair z1=vm::pop<pair>(Stack);
pair z0=vm::pop<pair>(Stack);
-#line 2473 "runtime.in"
+#line 2489 "runtime.in"
{Stack->push<path>(nurb(z0,z1,z2,z3,w0,w1,w2,w3,m)); return;}
}
-#line 2477 "runtime.in"
+#line 2493 "runtime.in"
// Int length(path p);
-void gen159(stack *Stack)
+void gen160(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2478 "runtime.in"
+#line 2494 "runtime.in"
{Stack->push<Int>(p.length()); return;}
}
-#line 2482 "runtime.in"
+#line 2498 "runtime.in"
// bool cyclic(path p);
-void gen160(stack *Stack)
+void gen161(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2483 "runtime.in"
+#line 2499 "runtime.in"
{Stack->push<bool>(p.cyclic()); return;}
}
-#line 2487 "runtime.in"
+#line 2503 "runtime.in"
// bool straight(path p, Int t);
-void gen161(stack *Stack)
+void gen162(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path p=vm::pop<path>(Stack);
-#line 2488 "runtime.in"
+#line 2504 "runtime.in"
{Stack->push<bool>(p.straight(t)); return;}
}
-#line 2492 "runtime.in"
+#line 2508 "runtime.in"
// path unstraighten(path p);
-void gen162(stack *Stack)
+void gen163(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2493 "runtime.in"
+#line 2509 "runtime.in"
{Stack->push<path>(p.unstraighten()); return;}
}
-#line 2497 "runtime.in"
+#line 2513 "runtime.in"
// bool piecewisestraight(path p);
-void gen163(stack *Stack)
+void gen164(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2498 "runtime.in"
+#line 2514 "runtime.in"
{Stack->push<bool>(p.piecewisestraight()); return;}
}
-#line 2502 "runtime.in"
+#line 2518 "runtime.in"
// real arclength(path p);
-void gen164(stack *Stack)
+void gen165(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2503 "runtime.in"
+#line 2519 "runtime.in"
{Stack->push<real>(p.arclength()); return;}
}
-#line 2507 "runtime.in"
+#line 2523 "runtime.in"
// real arctime(path p, real dval);
-void gen165(stack *Stack)
+void gen166(stack *Stack)
{
real dval=vm::pop<real>(Stack);
path p=vm::pop<path>(Stack);
-#line 2508 "runtime.in"
+#line 2524 "runtime.in"
{Stack->push<real>(p.arctime(dval)); return;}
}
-#line 2512 "runtime.in"
+#line 2528 "runtime.in"
// real dirtime(path p, pair z);
-void gen166(stack *Stack)
+void gen167(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
path p=vm::pop<path>(Stack);
-#line 2513 "runtime.in"
+#line 2529 "runtime.in"
{Stack->push<real>(p.directiontime(z)); return;}
}
-#line 2517 "runtime.in"
+#line 2533 "runtime.in"
// realarray* intersect(path p, path q, real fuzz=-1);
-void gen167(stack *Stack)
+void gen168(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
path q=vm::pop<path>(Stack);
path p=vm::pop<path>(Stack);
-#line 2518 "runtime.in"
+#line 2534 "runtime.in"
bool exact=fuzz <= 0.0;
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -3276,14 +3297,14 @@ void gen167(stack *Stack)
{Stack->push<realarray*>(new array(0)); return;}
}
-#line 2534 "runtime.in"
+#line 2550 "runtime.in"
// realarray2* intersections(path p, path q, real fuzz=-1);
-void gen168(stack *Stack)
+void gen169(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
path q=vm::pop<path>(Stack);
path p=vm::pop<path>(Stack);
-#line 2535 "runtime.in"
+#line 2551 "runtime.in"
bool exact=fuzz <= 0.0;
if(fuzz < 0.0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -3313,15 +3334,15 @@ void gen168(stack *Stack)
{Stack->push<realarray2*>(V); return;}
}
-#line 2565 "runtime.in"
+#line 2581 "runtime.in"
// realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);
-void gen169(stack *Stack)
+void gen170(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
path p=vm::pop<path>(Stack);
-#line 2566 "runtime.in"
+#line 2582 "runtime.in"
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
::max(length(a),length(b)));
@@ -3337,15 +3358,15 @@ void gen169(stack *Stack)
// Return the intersection point of the extensions of the line segments
// PQ and pq.
-#line 2582 "runtime.in"
+#line 2598 "runtime.in"
// pair extension(pair P, pair Q, pair p, pair q);
-void gen170(stack *Stack)
+void gen171(stack *Stack)
{
pair q=vm::pop<pair>(Stack);
pair p=vm::pop<pair>(Stack);
pair Q=vm::pop<pair>(Stack);
pair P=vm::pop<pair>(Stack);
-#line 2583 "runtime.in"
+#line 2599 "runtime.in"
pair ac=P-Q;
pair bd=q-p;
real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
@@ -3353,49 +3374,49 @@ void gen170(stack *Stack)
{Stack->push<pair>(P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det); return;}
}
-#line 2591 "runtime.in"
+#line 2607 "runtime.in"
// Int size(path p);
-void gen171(stack *Stack)
+void gen172(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2592 "runtime.in"
+#line 2608 "runtime.in"
{Stack->push<Int>(p.size()); return;}
}
-#line 2596 "runtime.in"
+#line 2612 "runtime.in"
// path &(path p, path q);
-void gen172(stack *Stack)
+void gen173(stack *Stack)
{
path q=vm::pop<path>(Stack);
path p=vm::pop<path>(Stack);
-#line 2597 "runtime.in"
+#line 2613 "runtime.in"
{Stack->push<path>(camp::concat(p,q)); return;}
}
-#line 2601 "runtime.in"
+#line 2617 "runtime.in"
// pair min(path p);
-void gen173(stack *Stack)
+void gen174(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2602 "runtime.in"
+#line 2618 "runtime.in"
{Stack->push<pair>(p.min()); return;}
}
-#line 2606 "runtime.in"
+#line 2622 "runtime.in"
// pair max(path p);
-void gen174(stack *Stack)
+void gen175(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2607 "runtime.in"
+#line 2623 "runtime.in"
{Stack->push<pair>(p.max()); return;}
}
-#line 2611 "runtime.in"
+#line 2627 "runtime.in"
// realarray* mintimes(path p);
-void gen175(stack *Stack)
+void gen176(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2612 "runtime.in"
+#line 2628 "runtime.in"
array *V=new array(2);
pair z=p.mintimes();
(*V)[0]=z.getx();
@@ -3403,12 +3424,12 @@ void gen175(stack *Stack)
{Stack->push<realarray*>(V); return;}
}
-#line 2620 "runtime.in"
+#line 2636 "runtime.in"
// realarray* maxtimes(path p);
-void gen176(stack *Stack)
+void gen177(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 2621 "runtime.in"
+#line 2637 "runtime.in"
array *V=new array(2);
pair z=p.maxtimes();
(*V)[0]=z.getx();
@@ -3416,90 +3437,90 @@ void gen176(stack *Stack)
{Stack->push<realarray*>(V); return;}
}
-#line 2629 "runtime.in"
+#line 2645 "runtime.in"
// real relativedistance(real theta, real phi, real t, bool atleast);
-void gen177(stack *Stack)
+void gen178(stack *Stack)
{
bool atleast=vm::pop<bool>(Stack);
real t=vm::pop<real>(Stack);
real phi=vm::pop<real>(Stack);
real theta=vm::pop<real>(Stack);
-#line 2630 "runtime.in"
+#line 2646 "runtime.in"
{Stack->push<real>(camp::velocity(theta,phi,tension(t,atleast))); return;}
}
-#line 2634 "runtime.in"
+#line 2650 "runtime.in"
// Int windingnumber(patharray *p, pair z);
-void gen178(stack *Stack)
+void gen179(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
patharray * p=vm::pop<patharray *>(Stack);
-#line 2635 "runtime.in"
+#line 2651 "runtime.in"
{Stack->push<Int>(windingnumber(p,z)); return;}
}
-#line 2639 "runtime.in"
+#line 2655 "runtime.in"
// bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN);
-void gen179(stack *Stack)
+void gen180(stack *Stack)
{
pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
pair z=vm::pop<pair>(Stack);
patharray * g=vm::pop<patharray *>(Stack);
-#line 2640 "runtime.in"
+#line 2656 "runtime.in"
{Stack->push<bool>(fillrule.inside(windingnumber(g,z))); return;}
}
-#line 2644 "runtime.in"
+#line 2660 "runtime.in"
// bool inside(path g, pair z, pen fillrule=CURRENTPEN);
-void gen180(stack *Stack)
+void gen181(stack *Stack)
{
pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
pair z=vm::pop<pair>(Stack);
path g=vm::pop<path>(Stack);
-#line 2645 "runtime.in"
+#line 2661 "runtime.in"
{Stack->push<bool>(fillrule.inside(g.windingnumber(z))); return;}
}
// Determine the side of a--b that c lies on
// (negative=left, zero=on line, positive=right).
-#line 2651 "runtime.in"
+#line 2667 "runtime.in"
// real side(pair a, pair b, pair c);
-void gen181(stack *Stack)
+void gen182(stack *Stack)
{
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 2652 "runtime.in"
+#line 2668 "runtime.in"
{Stack->push<real>(orient2d(a,b,c)); return;}
}
// Determine the side of the counterclockwise circle through a,b,c that d
// lies on (negative=inside, 0=on circle, positive=right).
-#line 2658 "runtime.in"
+#line 2674 "runtime.in"
// real incircle(pair a, pair b, pair c, pair d);
-void gen182(stack *Stack)
+void gen183(stack *Stack)
{
pair d=vm::pop<pair>(Stack);
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 2659 "runtime.in"
+#line 2675 "runtime.in"
{Stack->push<real>(incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
d.getx(),d.gety())); return;}
}
// Path3 operations
-#line 2666 "runtime.in"
+#line 2682 "runtime.in"
// path3 path3(triplearray *pre, triplearray *point, triplearray *post, boolarray *straight, bool cyclic);
-void gen183(stack *Stack)
+void gen184(stack *Stack)
{
bool cyclic=vm::pop<bool>(Stack);
boolarray * straight=vm::pop<boolarray *>(Stack);
triplearray * post=vm::pop<triplearray *>(Stack);
triplearray * point=vm::pop<triplearray *>(Stack);
triplearray * pre=vm::pop<triplearray *>(Stack);
-#line 2668 "runtime.in"
+#line 2684 "runtime.in"
size_t n=checkArrays(pre,point);
checkEqual(n,checkArray(post));
checkEqual(n,checkArray(straight));
@@ -3514,144 +3535,144 @@ void gen183(stack *Stack)
{Stack->push<path3>(path3(nodes,(Int) n,cyclic)); return;}
}
-#line 2684 "runtime.in"
+#line 2700 "runtime.in"
void nullPath3(stack *Stack)
{
-#line 2685 "runtime.in"
+#line 2701 "runtime.in"
{Stack->push<path3>(nullpath3); return;}
}
-#line 2689 "runtime.in"
+#line 2705 "runtime.in"
// bool ==(path3 a, path3 b);
-void gen185(stack *Stack)
+void gen186(stack *Stack)
{
path3 b=vm::pop<path3>(Stack);
path3 a=vm::pop<path3>(Stack);
-#line 2690 "runtime.in"
+#line 2706 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 2694 "runtime.in"
+#line 2710 "runtime.in"
// bool !=(path3 a, path3 b);
-void gen186(stack *Stack)
+void gen187(stack *Stack)
{
path3 b=vm::pop<path3>(Stack);
path3 a=vm::pop<path3>(Stack);
-#line 2695 "runtime.in"
+#line 2711 "runtime.in"
{Stack->push<bool>(!(a == b)); return;}
}
-#line 2699 "runtime.in"
+#line 2715 "runtime.in"
// triple point(path3 p, Int t);
-void gen187(stack *Stack)
+void gen188(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2700 "runtime.in"
+#line 2716 "runtime.in"
{Stack->push<triple>(p.point((Int) t)); return;}
}
-#line 2704 "runtime.in"
+#line 2720 "runtime.in"
// triple point(path3 p, real t);
-void gen188(stack *Stack)
+void gen189(stack *Stack)
{
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2705 "runtime.in"
+#line 2721 "runtime.in"
{Stack->push<triple>(p.point(t)); return;}
}
-#line 2709 "runtime.in"
+#line 2725 "runtime.in"
// triple precontrol(path3 p, Int t);
-void gen189(stack *Stack)
+void gen190(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2710 "runtime.in"
+#line 2726 "runtime.in"
{Stack->push<triple>(p.precontrol((Int) t)); return;}
}
-#line 2714 "runtime.in"
+#line 2730 "runtime.in"
// triple precontrol(path3 p, real t);
-void gen190(stack *Stack)
+void gen191(stack *Stack)
{
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2715 "runtime.in"
+#line 2731 "runtime.in"
{Stack->push<triple>(p.precontrol(t)); return;}
}
-#line 2719 "runtime.in"
+#line 2735 "runtime.in"
// triple postcontrol(path3 p, Int t);
-void gen191(stack *Stack)
+void gen192(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2720 "runtime.in"
+#line 2736 "runtime.in"
{Stack->push<triple>(p.postcontrol((Int) t)); return;}
}
-#line 2724 "runtime.in"
+#line 2740 "runtime.in"
// triple postcontrol(path3 p, real t);
-void gen192(stack *Stack)
+void gen193(stack *Stack)
{
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2725 "runtime.in"
+#line 2741 "runtime.in"
{Stack->push<triple>(p.postcontrol(t)); return;}
}
-#line 2729 "runtime.in"
+#line 2745 "runtime.in"
// triple dir(path3 p, Int t, Int sign=0, bool normalize=true);
-void gen193(stack *Stack)
+void gen194(stack *Stack)
{
bool normalize=vm::pop<bool>(Stack,true);
Int sign=vm::pop<Int>(Stack,0);
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2730 "runtime.in"
+#line 2746 "runtime.in"
{Stack->push<triple>(p.dir(t,sign,normalize)); return;}
}
-#line 2734 "runtime.in"
+#line 2750 "runtime.in"
// triple dir(path3 p, real t, bool normalize=true);
-void gen194(stack *Stack)
+void gen195(stack *Stack)
{
bool normalize=vm::pop<bool>(Stack,true);
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2735 "runtime.in"
+#line 2751 "runtime.in"
{Stack->push<triple>(p.dir(t,normalize)); return;}
}
-#line 2739 "runtime.in"
+#line 2755 "runtime.in"
// triple accel(path3 p, Int t, Int sign=0);
-void gen195(stack *Stack)
+void gen196(stack *Stack)
{
Int sign=vm::pop<Int>(Stack,0);
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2740 "runtime.in"
+#line 2756 "runtime.in"
{Stack->push<triple>(p.accel(t,sign)); return;}
}
-#line 2744 "runtime.in"
+#line 2760 "runtime.in"
// triple accel(path3 p, real t);
-void gen196(stack *Stack)
+void gen197(stack *Stack)
{
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2745 "runtime.in"
+#line 2761 "runtime.in"
{Stack->push<triple>(p.accel(t)); return;}
}
-#line 2749 "runtime.in"
+#line 2765 "runtime.in"
// real radius(path3 p, real t);
-void gen197(stack *Stack)
+void gen198(stack *Stack)
{
real t=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2750 "runtime.in"
+#line 2766 "runtime.in"
triple v=p.dir(t,false);
triple a=p.accel(t);
real d=dot(a,v);
@@ -3662,16 +3683,16 @@ void gen197(stack *Stack)
{Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
}
-#line 2761 "runtime.in"
+#line 2777 "runtime.in"
// real radius(triple z0, triple c0, triple c1, triple z1, real t);
-void gen198(stack *Stack)
+void gen199(stack *Stack)
{
real t=vm::pop<real>(Stack);
triple z1=vm::pop<triple>(Stack);
triple c1=vm::pop<triple>(Stack);
triple c0=vm::pop<triple>(Stack);
triple z0=vm::pop<triple>(Stack);
-#line 2762 "runtime.in"
+#line 2778 "runtime.in"
triple v=(3.0*(z1-z0)+9.0*(c0-c1))*t*t+(6.0*(z0+c1)-12.0*c0)*t+3.0*(c0-z0);
triple a=6.0*(z1-z0+3.0*(c0-c1))*t+6.0*(z0+c1)-12.0*c0;
real d=dot(a,v);
@@ -3682,85 +3703,85 @@ void gen198(stack *Stack)
{Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
}
-#line 2773 "runtime.in"
+#line 2789 "runtime.in"
// path3 reverse(path3 p);
-void gen199(stack *Stack)
+void gen200(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2774 "runtime.in"
+#line 2790 "runtime.in"
{Stack->push<path3>(p.reverse()); return;}
}
-#line 2778 "runtime.in"
+#line 2794 "runtime.in"
// path3 subpath(path3 p, Int a, Int b);
-void gen200(stack *Stack)
+void gen201(stack *Stack)
{
Int b=vm::pop<Int>(Stack);
Int a=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2779 "runtime.in"
+#line 2795 "runtime.in"
{Stack->push<path3>(p.subpath((Int) a, (Int) b)); return;}
}
-#line 2783 "runtime.in"
+#line 2799 "runtime.in"
// path3 subpath(path3 p, real a, real b);
-void gen201(stack *Stack)
+void gen202(stack *Stack)
{
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2784 "runtime.in"
+#line 2800 "runtime.in"
{Stack->push<path3>(p.subpath(a,b)); return;}
}
-#line 2788 "runtime.in"
+#line 2804 "runtime.in"
// Int length(path3 p);
-void gen202(stack *Stack)
+void gen203(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2789 "runtime.in"
+#line 2805 "runtime.in"
{Stack->push<Int>(p.length()); return;}
}
-#line 2793 "runtime.in"
+#line 2809 "runtime.in"
// bool cyclic(path3 p);
-void gen203(stack *Stack)
+void gen204(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2794 "runtime.in"
+#line 2810 "runtime.in"
{Stack->push<bool>(p.cyclic()); return;}
}
-#line 2798 "runtime.in"
+#line 2814 "runtime.in"
// bool straight(path3 p, Int t);
-void gen204(stack *Stack)
+void gen205(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2799 "runtime.in"
+#line 2815 "runtime.in"
{Stack->push<bool>(p.straight(t)); return;}
}
// Return the component of vector v perpendicular to a unit vector u.
-#line 2804 "runtime.in"
+#line 2820 "runtime.in"
// triple perp(triple v, triple u);
-void gen205(stack *Stack)
+void gen206(stack *Stack)
{
triple u=vm::pop<triple>(Stack);
triple v=vm::pop<triple>(Stack);
-#line 2805 "runtime.in"
+#line 2821 "runtime.in"
{Stack->push<triple>(v-dot(v,u)*u); return;}
}
// Return the maximum perpendicular deviation of segment i of path3 g
// from a straight line.
-#line 2811 "runtime.in"
+#line 2827 "runtime.in"
// real straightness(path3 p, Int t);
-void gen206(stack *Stack)
+void gen207(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2812 "runtime.in"
+#line 2828 "runtime.in"
if(p.straight(t)) {Stack->push<real>(0); return;}
triple z0=p.point(t);
triple u=unit(p.point(t+1)-z0);
@@ -3770,55 +3791,55 @@ void gen206(stack *Stack)
// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
// from a straight line.
-#line 2822 "runtime.in"
+#line 2838 "runtime.in"
// real straightness(triple z0, triple c0, triple c1, triple z1);
-void gen207(stack *Stack)
+void gen208(stack *Stack)
{
triple z1=vm::pop<triple>(Stack);
triple c1=vm::pop<triple>(Stack);
triple c0=vm::pop<triple>(Stack);
triple z0=vm::pop<triple>(Stack);
-#line 2823 "runtime.in"
+#line 2839 "runtime.in"
triple u=unit(z1-z0);
{Stack->push<real>(::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)))); return;}
}
-#line 2828 "runtime.in"
+#line 2844 "runtime.in"
// bool piecewisestraight(path3 p);
-void gen208(stack *Stack)
+void gen209(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2829 "runtime.in"
+#line 2845 "runtime.in"
{Stack->push<bool>(p.piecewisestraight()); return;}
}
-#line 2833 "runtime.in"
+#line 2849 "runtime.in"
// real arclength(path3 p);
-void gen209(stack *Stack)
+void gen210(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2834 "runtime.in"
+#line 2850 "runtime.in"
{Stack->push<real>(p.arclength()); return;}
}
-#line 2838 "runtime.in"
+#line 2854 "runtime.in"
// real arctime(path3 p, real dval);
-void gen210(stack *Stack)
+void gen211(stack *Stack)
{
real dval=vm::pop<real>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2839 "runtime.in"
+#line 2855 "runtime.in"
{Stack->push<real>(p.arctime(dval)); return;}
}
-#line 2843 "runtime.in"
+#line 2859 "runtime.in"
// realarray* intersect(path3 p, path3 q, real fuzz=-1);
-void gen211(stack *Stack)
+void gen212(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
path3 q=vm::pop<path3>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2844 "runtime.in"
+#line 2860 "runtime.in"
bool exact=fuzz <= 0.0;
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -3835,14 +3856,14 @@ void gen211(stack *Stack)
{Stack->push<realarray*>(new array(0)); return;}
}
-#line 2861 "runtime.in"
+#line 2877 "runtime.in"
// realarray2* intersections(path3 p, path3 q, real fuzz=-1);
-void gen212(stack *Stack)
+void gen213(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
path3 q=vm::pop<path3>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2862 "runtime.in"
+#line 2878 "runtime.in"
bool exact=fuzz <= 0.0;
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -3874,14 +3895,14 @@ void gen212(stack *Stack)
{Stack->push<realarray2*>(V); return;}
}
-#line 2894 "runtime.in"
+#line 2910 "runtime.in"
// realarray2* intersections(path3 p, triplearray2 *P, real fuzz=-1);
-void gen213(stack *Stack)
+void gen214(stack *Stack)
{
real fuzz=vm::pop<real>(Stack,-1);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2895 "runtime.in"
+#line 2911 "runtime.in"
triple *A=copyTripleArray2C(P,true,4);
if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
norm(A,16));
@@ -3900,49 +3921,49 @@ void gen213(stack *Stack)
{Stack->push<realarray2*>(W); return;} // Sorting will done in asy.
}
-#line 2914 "runtime.in"
+#line 2930 "runtime.in"
// Int size(path3 p);
-void gen214(stack *Stack)
+void gen215(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2915 "runtime.in"
+#line 2931 "runtime.in"
{Stack->push<Int>(p.size()); return;}
}
-#line 2919 "runtime.in"
+#line 2935 "runtime.in"
// path3 &(path3 p, path3 q);
-void gen215(stack *Stack)
+void gen216(stack *Stack)
{
path3 q=vm::pop<path3>(Stack);
path3 p=vm::pop<path3>(Stack);
-#line 2920 "runtime.in"
+#line 2936 "runtime.in"
{Stack->push<path3>(camp::concat(p,q)); return;}
}
-#line 2924 "runtime.in"
+#line 2940 "runtime.in"
// triple min(path3 p);
-void gen216(stack *Stack)
+void gen217(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2925 "runtime.in"
+#line 2941 "runtime.in"
{Stack->push<triple>(p.min()); return;}
}
-#line 2929 "runtime.in"
+#line 2945 "runtime.in"
// triple max(path3 p);
-void gen217(stack *Stack)
+void gen218(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2930 "runtime.in"
+#line 2946 "runtime.in"
{Stack->push<triple>(p.max()); return;}
}
-#line 2934 "runtime.in"
+#line 2950 "runtime.in"
// realarray* mintimes(path3 p);
-void gen218(stack *Stack)
+void gen219(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2935 "runtime.in"
+#line 2951 "runtime.in"
array *V=new array(3);
triple v=p.mintimes();
(*V)[0]=v.getx();
@@ -3951,12 +3972,12 @@ void gen218(stack *Stack)
{Stack->push<realarray*>(V); return;}
}
-#line 2944 "runtime.in"
+#line 2960 "runtime.in"
// realarray* maxtimes(path3 p);
-void gen219(stack *Stack)
+void gen220(stack *Stack)
{
path3 p=vm::pop<path3>(Stack);
-#line 2945 "runtime.in"
+#line 2961 "runtime.in"
array *V=new array(3);
triple v=p.maxtimes();
(*V)[0]=v.getx();
@@ -3965,30 +3986,30 @@ void gen219(stack *Stack)
{Stack->push<realarray*>(V); return;}
}
-#line 2954 "runtime.in"
+#line 2970 "runtime.in"
// path3 *(realarray2 *t, path3 g);
-void gen220(stack *Stack)
+void gen221(stack *Stack)
{
path3 g=vm::pop<path3>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 2955 "runtime.in"
+#line 2971 "runtime.in"
{Stack->push<path3>(transformed(*t,g)); return;}
}
// Guide operations
-#line 2961 "runtime.in"
+#line 2977 "runtime.in"
void nullGuide(stack *Stack)
{
-#line 2962 "runtime.in"
+#line 2978 "runtime.in"
{Stack->push<guide*>(new pathguide(path())); return;}
}
-#line 2967 "runtime.in"
+#line 2983 "runtime.in"
void dotsGuide(stack *Stack)
{
guidearray * a=vm::pop<guidearray *>(Stack);
-#line 2968 "runtime.in"
+#line 2984 "runtime.in"
guidevector v;
size_t size=checkArray(a);
for (size_t i=0; i < size; ++i)
@@ -3997,11 +4018,11 @@ void dotsGuide(stack *Stack)
{Stack->push<guide*>(new multiguide(v)); return;}
}
-#line 2977 "runtime.in"
+#line 2993 "runtime.in"
void dashesGuide(stack *Stack)
{
guidearray * a=vm::pop<guidearray *>(Stack);
-#line 2978 "runtime.in"
+#line 2994 "runtime.in"
static camp::curlSpec curly;
static specguide curlout(&curly, camp::OUT);
static specguide curlin(&curly, camp::IN);
@@ -4027,179 +4048,179 @@ void dashesGuide(stack *Stack)
{Stack->push<guide*>(new multiguide(v)); return;}
}
-#line 3004 "runtime.in"
+#line 3020 "runtime.in"
void newCycleToken(stack *Stack)
{
-#line 3005 "runtime.in"
+#line 3021 "runtime.in"
{Stack->push<cycleToken>(cycleToken()); return;}
}
-#line 3009 "runtime.in"
+#line 3025 "runtime.in"
// guide* operator cast(cycleToken tok);
-void gen225(stack *Stack)
+void gen226(stack *Stack)
{
cycleToken tok=vm::pop<cycleToken>(Stack);
-#line 3010 "runtime.in"
+#line 3026 "runtime.in"
// Avoid unused variable warning messages.
unused(&tok);
{Stack->push<guide*>(new cycletokguide()); return;}
}
-#line 3016 "runtime.in"
+#line 3032 "runtime.in"
// guide* operator spec(pair z, Int p);
-void gen226(stack *Stack)
+void gen227(stack *Stack)
{
Int p=vm::pop<Int>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 3017 "runtime.in"
+#line 3033 "runtime.in"
camp::side d=(camp::side) p;
camp::dirSpec *sp=new camp::dirSpec(z);
{Stack->push<guide*>(new specguide(sp,d)); return;}
}
-#line 3024 "runtime.in"
+#line 3040 "runtime.in"
// curlSpecifier operator curl(real gamma, Int p);
-void gen227(stack *Stack)
+void gen228(stack *Stack)
{
Int p=vm::pop<Int>(Stack);
real gamma=vm::pop<real>(Stack);
-#line 3025 "runtime.in"
+#line 3041 "runtime.in"
camp::side s=(camp::side) p;
{Stack->push<curlSpecifier>(curlSpecifier(gamma,s)); return;}
}
-#line 3030 "runtime.in"
+#line 3046 "runtime.in"
void curlSpecifierValuePart(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 3031 "runtime.in"
+#line 3047 "runtime.in"
{Stack->push<real>(spec.getValue()); return;}
}
-#line 3035 "runtime.in"
+#line 3051 "runtime.in"
void curlSpecifierSidePart(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 3036 "runtime.in"
+#line 3052 "runtime.in"
{Stack->push<Int>(spec.getSide()); return;}
}
-#line 3040 "runtime.in"
+#line 3056 "runtime.in"
// guide* operator cast(curlSpecifier spec);
-void gen230(stack *Stack)
+void gen231(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 3041 "runtime.in"
+#line 3057 "runtime.in"
{Stack->push<guide*>(new specguide(spec)); return;}
}
-#line 3045 "runtime.in"
+#line 3061 "runtime.in"
// tensionSpecifier operator tension(real tout, real tin, bool atleast);
-void gen231(stack *Stack)
+void gen232(stack *Stack)
{
bool atleast=vm::pop<bool>(Stack);
real tin=vm::pop<real>(Stack);
real tout=vm::pop<real>(Stack);
-#line 3046 "runtime.in"
+#line 3062 "runtime.in"
{Stack->push<tensionSpecifier>(tensionSpecifier(tout, tin, atleast)); return;}
}
-#line 3050 "runtime.in"
+#line 3066 "runtime.in"
void tensionSpecifierOutPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 3051 "runtime.in"
+#line 3067 "runtime.in"
{Stack->push<real>(t.getOut()); return;}
}
-#line 3055 "runtime.in"
+#line 3071 "runtime.in"
void tensionSpecifierInPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 3056 "runtime.in"
+#line 3072 "runtime.in"
{Stack->push<real>(t.getIn()); return;}
}
-#line 3060 "runtime.in"
+#line 3076 "runtime.in"
void tensionSpecifierAtleastPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 3061 "runtime.in"
+#line 3077 "runtime.in"
{Stack->push<bool>(t.getAtleast()); return;}
}
-#line 3065 "runtime.in"
+#line 3081 "runtime.in"
// guide* operator cast(tensionSpecifier t);
-void gen235(stack *Stack)
+void gen236(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 3066 "runtime.in"
+#line 3082 "runtime.in"
{Stack->push<guide*>(new tensionguide(t)); return;}
}
-#line 3070 "runtime.in"
+#line 3086 "runtime.in"
// guide* operator controls(pair zout, pair zin);
-void gen236(stack *Stack)
+void gen237(stack *Stack)
{
pair zin=vm::pop<pair>(Stack);
pair zout=vm::pop<pair>(Stack);
-#line 3071 "runtime.in"
+#line 3087 "runtime.in"
{Stack->push<guide*>(new controlguide(zout, zin)); return;}
}
-#line 3075 "runtime.in"
+#line 3091 "runtime.in"
// Int size(guide *g);
-void gen237(stack *Stack)
+void gen238(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 3076 "runtime.in"
+#line 3092 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<Int>(f.size()); return;}
}
-#line 3082 "runtime.in"
+#line 3098 "runtime.in"
// Int length(guide *g);
-void gen238(stack *Stack)
+void gen239(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 3083 "runtime.in"
+#line 3099 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<Int>(g->cyclic() ? f.size() : f.size()-1); return;}
}
-#line 3089 "runtime.in"
+#line 3105 "runtime.in"
// bool cyclic(guide *g);
-void gen239(stack *Stack)
+void gen240(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 3090 "runtime.in"
+#line 3106 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<bool>(g->cyclic()); return;}
}
-#line 3096 "runtime.in"
+#line 3112 "runtime.in"
// pair point(guide *g, Int t);
-void gen240(stack *Stack)
+void gen241(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 3097 "runtime.in"
+#line 3113 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<pair>(f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z); return;}
}
-#line 3103 "runtime.in"
+#line 3119 "runtime.in"
// pairarray* dirSpecifier(guide *g, Int t);
-void gen241(stack *Stack)
+void gen242(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 3104 "runtime.in"
+#line 3120 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -4210,13 +4231,13 @@ void gen241(stack *Stack)
{Stack->push<pairarray*>(c); return;}
}
-#line 3115 "runtime.in"
+#line 3131 "runtime.in"
// pairarray* controlSpecifier(guide *g, Int t);
-void gen242(stack *Stack)
+void gen243(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 3116 "runtime.in"
+#line 3132 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -4232,13 +4253,13 @@ void gen242(stack *Stack)
} else {Stack->push<pairarray*>(new array(0)); return;}
}
-#line 3132 "runtime.in"
+#line 3148 "runtime.in"
// tensionSpecifier tensionSpecifier(guide *g, Int t);
-void gen243(stack *Stack)
+void gen244(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 3133 "runtime.in"
+#line 3149 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -4247,13 +4268,13 @@ void gen243(stack *Stack)
{Stack->push<tensionSpecifier>(tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast)); return;}
}
-#line 3142 "runtime.in"
+#line 3158 "runtime.in"
// realarray* curlSpecifier(guide *g, Int t);
-void gen244(stack *Stack)
+void gen245(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 3143 "runtime.in"
+#line 3159 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -4266,12 +4287,12 @@ void gen244(stack *Stack)
{Stack->push<realarray*>(c); return;}
}
-#line 3156 "runtime.in"
+#line 3172 "runtime.in"
// guide* reverse(guide *g);
-void gen245(stack *Stack)
+void gen246(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 3157 "runtime.in"
+#line 3173 "runtime.in"
flatguide f;
g->flatten(f,false);
if(f.precyclic())
@@ -4326,21 +4347,21 @@ void gen245(stack *Stack)
// Three-dimensional picture and surface operations
-#line 3212 "runtime.in"
+#line 3228 "runtime.in"
// void _draw(picture *f, path3 g, pen p);
-void gen246(stack *Stack)
+void gen247(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
path3 g=vm::pop<path3>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 3213 "runtime.in"
+#line 3229 "runtime.in"
if(g.size() > 0)
f->append(new drawPath3(g,p));
}
-#line 3219 "runtime.in"
+#line 3235 "runtime.in"
// void draw(picture *f, triplearray2 *g, bool straight, penarray *p, real opacity, real shininess, real granularity, triple normal, bool lighton, penarray *colors);
-void gen247(stack *Stack)
+void gen248(stack *Stack)
{
penarray * colors=vm::pop<penarray *>(Stack);
bool lighton=vm::pop<bool>(Stack);
@@ -4352,80 +4373,80 @@ void gen247(stack *Stack)
bool straight=vm::pop<bool>(Stack);
triplearray2 * g=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 3222 "runtime.in"
+#line 3238 "runtime.in"
f->append(new drawSurface(*g,straight,*p,opacity,shininess,granularity,
normal,lighton,*colors));
}
-#line 3227 "runtime.in"
+#line 3243 "runtime.in"
// triple min3(picture *f);
-void gen248(stack *Stack)
+void gen249(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 3228 "runtime.in"
+#line 3244 "runtime.in"
{Stack->push<triple>(f->bounds3().Min()); return;}
}
-#line 3232 "runtime.in"
+#line 3248 "runtime.in"
// triple max3(picture *f);
-void gen249(stack *Stack)
+void gen250(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 3233 "runtime.in"
+#line 3249 "runtime.in"
{Stack->push<triple>(f->bounds3().Max()); return;}
}
-#line 3237 "runtime.in"
+#line 3253 "runtime.in"
// pair min(picture *f, realarray2 *t);
-void gen250(stack *Stack)
+void gen251(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 3238 "runtime.in"
+#line 3254 "runtime.in"
real *T=copyArray2C(t,4);
pair m=f->bounds(::min,xproject,yproject,T);
delete[] T;
{Stack->push<pair>(m); return;}
}
-#line 3245 "runtime.in"
+#line 3261 "runtime.in"
// pair max(picture *f, realarray2 *t);
-void gen251(stack *Stack)
+void gen252(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 3246 "runtime.in"
+#line 3262 "runtime.in"
real *T=copyArray2C(t,4);
pair M=f->bounds(::max,xproject,yproject,T);
delete[] T;
{Stack->push<pair>(M); return;}
}
-#line 3253 "runtime.in"
+#line 3269 "runtime.in"
// pair minratio(picture *f);
-void gen252(stack *Stack)
+void gen253(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 3254 "runtime.in"
+#line 3270 "runtime.in"
{Stack->push<pair>(f->bounds(::min,xratio,yratio)); return;}
}
-#line 3258 "runtime.in"
+#line 3274 "runtime.in"
// pair maxratio(picture *f);
-void gen253(stack *Stack)
+void gen254(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 3259 "runtime.in"
+#line 3275 "runtime.in"
{Stack->push<pair>(f->bounds(::max,xratio,yratio)); return;}
}
-#line 3263 "runtime.in"
+#line 3279 "runtime.in"
// triple minbound(triplearray2 *P, triple b);
-void gen254(stack *Stack)
+void gen255(stack *Stack)
{
triple b=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 3264 "runtime.in"
+#line 3280 "runtime.in"
real *A=copyTripleArray2Components(P,true,4);
b=triple(bound(A,::min,b.getx(),sqrtFuzz*norm(A,16)),
bound(A+16,::min,b.gety(),sqrtFuzz*norm(A+16,16)),
@@ -4434,13 +4455,13 @@ void gen254(stack *Stack)
{Stack->push<triple>(b); return;}
}
-#line 3273 "runtime.in"
+#line 3289 "runtime.in"
// triple maxbound(triplearray2 *P, triple b);
-void gen255(stack *Stack)
+void gen256(stack *Stack)
{
triple b=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 3274 "runtime.in"
+#line 3290 "runtime.in"
real *A=copyTripleArray2Components(P,true,4);
b=triple(bound(A,::max,b.getx(),sqrtFuzz*norm(A,16)),
bound(A+16,::max,b.gety(),sqrtFuzz*norm(A+16,16)),
@@ -4449,14 +4470,14 @@ void gen255(stack *Stack)
{Stack->push<triple>(b); return;}
}
-#line 3283 "runtime.in"
+#line 3299 "runtime.in"
// pair minbound(triplearray2 *P, realarray2 *t, pair b);
-void gen256(stack *Stack)
+void gen257(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 3284 "runtime.in"
+#line 3300 "runtime.in"
triple *A=copyTripleArray2C(P,true,4);
real *T=copyArray2C(t,4);
real fuzz=sqrtFuzz*norm(A,16);
@@ -4467,14 +4488,14 @@ void gen256(stack *Stack)
{Stack->push<pair>(b); return;}
}
-#line 3295 "runtime.in"
+#line 3311 "runtime.in"
// pair maxbound(triplearray2 *P, realarray2 *t, pair b);
-void gen257(stack *Stack)
+void gen258(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 3296 "runtime.in"
+#line 3312 "runtime.in"
triple *A=copyTripleArray2C(P,true,4);
real *T=copyArray2C(t,4);
real fuzz=sqrtFuzz*norm(A,16);
@@ -4485,38 +4506,38 @@ void gen257(stack *Stack)
{Stack->push<pair>(b); return;}
}
-#line 3307 "runtime.in"
+#line 3323 "runtime.in"
// pair max(path3 g, realarray2 *t);
-void gen258(stack *Stack)
+void gen259(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
path3 g=vm::pop<path3>(Stack);
-#line 3308 "runtime.in"
+#line 3324 "runtime.in"
real *T=copyArray2C(t,4);
pair b=g.bounds(::max,xproject,yproject,T);
delete[] T;
{Stack->push<pair>(b); return;}
}
-#line 3315 "runtime.in"
+#line 3331 "runtime.in"
// pair min(path3 g, realarray2 *t);
-void gen259(stack *Stack)
+void gen260(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
path3 g=vm::pop<path3>(Stack);
-#line 3316 "runtime.in"
+#line 3332 "runtime.in"
real *T=copyArray2C(t,4);
pair b=g.bounds(::min,xproject,yproject,T);
delete[] T;
{Stack->push<pair>(b); return;}
}
-#line 3323 "runtime.in"
+#line 3339 "runtime.in"
// real change2(triplearray2 *a);
-void gen260(stack *Stack)
+void gen261(stack *Stack)
{
triplearray2 * a=vm::pop<triplearray2 *>(Stack);
-#line 3324 "runtime.in"
+#line 3340 "runtime.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<real>(0.0); return;}
@@ -4537,241 +4558,241 @@ void gen260(stack *Stack)
{Stack->push<real>(M); return;}
}
-#line 3345 "runtime.in"
+#line 3361 "runtime.in"
// bool is3D(picture *f);
-void gen261(stack *Stack)
+void gen262(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 3346 "runtime.in"
+#line 3362 "runtime.in"
{Stack->push<bool>(f->have3D()); return;}
}
-#line 3350 "runtime.in"
+#line 3366 "runtime.in"
// pair bezier(pair a, pair b, pair c, pair d, real t);
-void gen262(stack *Stack)
+void gen263(stack *Stack)
{
real t=vm::pop<real>(Stack);
pair d=vm::pop<pair>(Stack);
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 3351 "runtime.in"
+#line 3367 "runtime.in"
real onemt=1-t;
real onemt2=onemt*onemt;
{Stack->push<pair>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
}
-#line 3357 "runtime.in"
+#line 3373 "runtime.in"
// pair bezierP(pair a, pair b, pair c, pair d, real t);
-void gen263(stack *Stack)
+void gen264(stack *Stack)
{
real t=vm::pop<real>(Stack);
pair d=vm::pop<pair>(Stack);
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 3358 "runtime.in"
+#line 3374 "runtime.in"
{Stack->push<pair>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
}
-#line 3362 "runtime.in"
+#line 3378 "runtime.in"
// pair bezierPP(pair a, pair b, pair c, pair d, real t);
-void gen264(stack *Stack)
+void gen265(stack *Stack)
{
real t=vm::pop<real>(Stack);
pair d=vm::pop<pair>(Stack);
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 3363 "runtime.in"
+#line 3379 "runtime.in"
{Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
}
-#line 3367 "runtime.in"
+#line 3383 "runtime.in"
// pair bezierPPP(pair a, pair b, pair c, pair d);
-void gen265(stack *Stack)
+void gen266(stack *Stack)
{
pair d=vm::pop<pair>(Stack);
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 3368 "runtime.in"
+#line 3384 "runtime.in"
{Stack->push<pair>(6.0*(d-a+3.0*(b-c))); return;}
}
-#line 3372 "runtime.in"
+#line 3388 "runtime.in"
// triple bezier(triple a, triple b, triple c, triple d, real t);
-void gen266(stack *Stack)
+void gen267(stack *Stack)
{
real t=vm::pop<real>(Stack);
triple d=vm::pop<triple>(Stack);
triple c=vm::pop<triple>(Stack);
triple b=vm::pop<triple>(Stack);
triple a=vm::pop<triple>(Stack);
-#line 3373 "runtime.in"
+#line 3389 "runtime.in"
real onemt=1-t;
real onemt2=onemt*onemt;
{Stack->push<triple>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
}
-#line 3379 "runtime.in"
+#line 3395 "runtime.in"
// triple bezierP(triple a, triple b, triple c, triple d, real t);
-void gen267(stack *Stack)
+void gen268(stack *Stack)
{
real t=vm::pop<real>(Stack);
triple d=vm::pop<triple>(Stack);
triple c=vm::pop<triple>(Stack);
triple b=vm::pop<triple>(Stack);
triple a=vm::pop<triple>(Stack);
-#line 3380 "runtime.in"
+#line 3396 "runtime.in"
{Stack->push<triple>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
}
-#line 3384 "runtime.in"
+#line 3400 "runtime.in"
// triple bezierPP(triple a, triple b, triple c, triple d, real t);
-void gen268(stack *Stack)
+void gen269(stack *Stack)
{
real t=vm::pop<real>(Stack);
triple d=vm::pop<triple>(Stack);
triple c=vm::pop<triple>(Stack);
triple b=vm::pop<triple>(Stack);
triple a=vm::pop<triple>(Stack);
-#line 3385 "runtime.in"
+#line 3401 "runtime.in"
{Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
}
-#line 3389 "runtime.in"
+#line 3405 "runtime.in"
// triple bezierPPP(triple a, triple b, triple c, triple d);
-void gen269(stack *Stack)
+void gen270(stack *Stack)
{
triple d=vm::pop<triple>(Stack);
triple c=vm::pop<triple>(Stack);
triple b=vm::pop<triple>(Stack);
triple a=vm::pop<triple>(Stack);
-#line 3390 "runtime.in"
+#line 3406 "runtime.in"
{Stack->push<triple>(6.0*(d-a+3.0*(b-c))); return;}
}
// String operations
-#line 3396 "runtime.in"
+#line 3412 "runtime.in"
void emptyString(stack *Stack)
{
-#line 3397 "runtime.in"
+#line 3413 "runtime.in"
{Stack->push<string>(emptystring); return;}
}
-#line 3402 "runtime.in"
+#line 3418 "runtime.in"
// Int length(string *s);
-void gen271(stack *Stack)
+void gen272(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 3403 "runtime.in"
+#line 3419 "runtime.in"
{Stack->push<Int>((Int) s->length()); return;}
}
-#line 3407 "runtime.in"
+#line 3423 "runtime.in"
// Int find(string *s, string t, Int pos=0);
-void gen272(stack *Stack)
+void gen273(stack *Stack)
{
Int pos=vm::pop<Int>(Stack,0);
string t=vm::pop<string>(Stack);
string * s=vm::pop<string *>(Stack);
-#line 3408 "runtime.in"
+#line 3424 "runtime.in"
size_t n=s->find(t,pos);
{Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
}
-#line 3413 "runtime.in"
+#line 3429 "runtime.in"
// Int rfind(string *s, string t, Int pos=-1);
-void gen273(stack *Stack)
+void gen274(stack *Stack)
{
Int pos=vm::pop<Int>(Stack,-1);
string t=vm::pop<string>(Stack);
string * s=vm::pop<string *>(Stack);
-#line 3414 "runtime.in"
+#line 3430 "runtime.in"
size_t n=s->rfind(t,pos);
{Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
}
-#line 3419 "runtime.in"
+#line 3435 "runtime.in"
// string reverse(string s);
-void gen274(stack *Stack)
+void gen275(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 3420 "runtime.in"
+#line 3436 "runtime.in"
reverse(s.begin(),s.end());
{Stack->push<string>(s); return;}
}
-#line 3425 "runtime.in"
+#line 3441 "runtime.in"
// string insert(string s, Int pos, string t);
-void gen275(stack *Stack)
+void gen276(stack *Stack)
{
string t=vm::pop<string>(Stack);
Int pos=vm::pop<Int>(Stack);
string s=vm::pop<string>(Stack);
-#line 3426 "runtime.in"
+#line 3442 "runtime.in"
if ((size_t) pos < s.length())
{Stack->push<string>(s.insert(pos,t)); return;}
{Stack->push<string>(s); return;}
}
-#line 3432 "runtime.in"
+#line 3448 "runtime.in"
// string substr(string* s, Int pos, Int n=-1);
-void gen276(stack *Stack)
+void gen277(stack *Stack)
{
Int n=vm::pop<Int>(Stack,-1);
Int pos=vm::pop<Int>(Stack);
string* s=vm::pop<string*>(Stack);
-#line 3433 "runtime.in"
+#line 3449 "runtime.in"
if ((size_t) pos < s->length())
{Stack->push<string>(s->substr(pos,n)); return;}
{Stack->push<string>(emptystring); return;}
}
-#line 3439 "runtime.in"
+#line 3455 "runtime.in"
// string erase(string s, Int pos, Int n);
-void gen277(stack *Stack)
+void gen278(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
Int pos=vm::pop<Int>(Stack);
string s=vm::pop<string>(Stack);
-#line 3440 "runtime.in"
+#line 3456 "runtime.in"
if ((size_t) pos < s.length())
{Stack->push<string>(s.erase(pos,n)); return;}
{Stack->push<string>(s); return;}
}
-#line 3446 "runtime.in"
+#line 3462 "runtime.in"
// string downcase(string s);
-void gen278(stack *Stack)
+void gen279(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 3447 "runtime.in"
+#line 3463 "runtime.in"
std::transform(s.begin(),s.end(),s.begin(),tolower);
{Stack->push<string>(s); return;}
}
-#line 3452 "runtime.in"
+#line 3468 "runtime.in"
// string upcase(string s);
-void gen279(stack *Stack)
+void gen280(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 3453 "runtime.in"
+#line 3469 "runtime.in"
std::transform(s.begin(),s.end(),s.begin(),toupper);
{Stack->push<string>(s); return;}
}
// returns a string constructed by translating all occurrences of the string
// from in an array of string pairs {from,to} to the string to in string s.
-#line 3460 "runtime.in"
+#line 3476 "runtime.in"
// string replace(string *S, stringarray2 *translate);
-void gen280(stack *Stack)
+void gen281(stack *Stack)
{
stringarray2 * translate=vm::pop<stringarray2 *>(Stack);
string * S=vm::pop<string *>(Stack);
-#line 3461 "runtime.in"
+#line 3477 "runtime.in"
size_t size=checkArray(translate);
for(size_t i=0; i < size; i++) {
array *a=read<array*>(translate,i);
@@ -4795,13 +4816,13 @@ void gen280(stack *Stack)
{Stack->push<string>(buf.str()); return;}
}
-#line 3485 "runtime.in"
+#line 3501 "runtime.in"
// string format(string *format, Int x);
-void gen281(stack *Stack)
+void gen282(stack *Stack)
{
Int x=vm::pop<Int>(Stack);
string * format=vm::pop<string *>(Stack);
-#line 3486 "runtime.in"
+#line 3502 "runtime.in"
const char *f=format->c_str();
checkformat(f,true);
@@ -4815,14 +4836,14 @@ void gen281(stack *Stack)
{Stack->push<string>(s); return;}
}
-#line 3500 "runtime.in"
+#line 3516 "runtime.in"
// string format(string *format, real x, string locale=emptystring);
-void gen282(stack *Stack)
+void gen283(stack *Stack)
{
string locale=vm::pop<string>(Stack,emptystring);
real x=vm::pop<real>(Stack);
string * format=vm::pop<string *>(Stack);
-#line 3501 "runtime.in"
+#line 3517 "runtime.in"
ostringstream out;
checkformat(format->c_str(),false);
@@ -4939,12 +4960,12 @@ void gen282(stack *Stack)
{Stack->push<string>(out.str()); return;}
}
-#line 3618 "runtime.in"
+#line 3634 "runtime.in"
// Int hex(string s);
-void gen283(stack *Stack)
+void gen284(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 3619 "runtime.in"
+#line 3635 "runtime.in"
istringstream is(s);
is.setf(std::ios::hex,std::ios::basefield);
Int value;
@@ -4954,36 +4975,36 @@ void gen283(stack *Stack)
error(buf);
}
-#line 3629 "runtime.in"
+#line 3645 "runtime.in"
// string string(Int x);
-void gen284(stack *Stack)
+void gen285(stack *Stack)
{
Int x=vm::pop<Int>(Stack);
-#line 3630 "runtime.in"
+#line 3646 "runtime.in"
ostringstream buf;
buf << x;
{Stack->push<string>(buf.str()); return;}
}
-#line 3636 "runtime.in"
+#line 3652 "runtime.in"
// string string(real x, Int digits=DBL_DIG);
-void gen285(stack *Stack)
+void gen286(stack *Stack)
{
Int digits=vm::pop<Int>(Stack,DBL_DIG);
real x=vm::pop<real>(Stack);
-#line 3637 "runtime.in"
+#line 3653 "runtime.in"
ostringstream buf;
buf.precision(digits);
buf << x;
{Stack->push<string>(buf.str()); return;}
}
-#line 3644 "runtime.in"
+#line 3660 "runtime.in"
// string time(string format=defaulttimeformat);
-void gen286(stack *Stack)
+void gen287(stack *Stack)
{
string format=vm::pop<string>(Stack,defaulttimeformat);
-#line 3645 "runtime.in"
+#line 3661 "runtime.in"
#ifdef HAVE_STRFTIME
const time_t bintime=time(NULL);
if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
@@ -4993,13 +5014,13 @@ void gen286(stack *Stack)
#endif
}
-#line 3655 "runtime.in"
+#line 3671 "runtime.in"
// string time(Int seconds, string format=defaulttimeformat);
-void gen287(stack *Stack)
+void gen288(stack *Stack)
{
string format=vm::pop<string>(Stack,defaulttimeformat);
Int seconds=vm::pop<Int>(Stack);
-#line 3656 "runtime.in"
+#line 3672 "runtime.in"
#ifdef HAVE_STRFTIME
const time_t bintime=seconds;
if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
@@ -5011,13 +5032,13 @@ void gen287(stack *Stack)
#endif
}
-#line 3668 "runtime.in"
+#line 3684 "runtime.in"
// Int seconds(string t=emptystring, string format=emptystring);
-void gen288(stack *Stack)
+void gen289(stack *Stack)
{
string format=vm::pop<string>(Stack,emptystring);
string t=vm::pop<string>(Stack,emptystring);
-#line 3669 "runtime.in"
+#line 3685 "runtime.in"
#if defined(HAVE_STRPTIME)
const time_t bintime=time(NULL);
tm tm=*localtime(&bintime);
@@ -5028,11 +5049,11 @@ void gen288(stack *Stack)
#endif
}
-#line 3680 "runtime.in"
+#line 3696 "runtime.in"
// realarray* _cputime();
-void gen289(stack *Stack)
+void gen290(stack *Stack)
{
-#line 3681 "runtime.in"
+#line 3697 "runtime.in"
static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
struct tms buf;
@@ -5047,234 +5068,234 @@ void gen289(stack *Stack)
// Math
-#line 3696 "runtime.in"
+#line 3712 "runtime.in"
// real ^(real x, Int y);
-void gen290(stack *Stack)
+void gen291(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
real x=vm::pop<real>(Stack);
-#line 3697 "runtime.in"
+#line 3713 "runtime.in"
{Stack->push<real>(pow(x,y)); return;}
}
-#line 3702 "runtime.in"
+#line 3718 "runtime.in"
// pair ^(pair z, Int y);
-void gen291(stack *Stack)
+void gen292(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 3703 "runtime.in"
+#line 3719 "runtime.in"
{Stack->push<pair>(pow(z,y)); return;}
}
-#line 3707 "runtime.in"
+#line 3723 "runtime.in"
// Int quotient(Int x, Int y);
-void gen292(stack *Stack)
+void gen293(stack *Stack)
{
Int y=vm::pop<Int>(Stack);
Int x=vm::pop<Int>(Stack);
-#line 3708 "runtime.in"
+#line 3724 "runtime.in"
if(y == 0) dividebyzero();
if(y == -1) {Stack->push<Int>(Negate(x)); return;}
// Implementation-independent definition of integer division: round down
{Stack->push<Int>((x-portableMod(x,y))/y); return;}
}
-#line 3715 "runtime.in"
+#line 3731 "runtime.in"
// Int abs(Int x);
-void gen293(stack *Stack)
+void gen294(stack *Stack)
{
Int x=vm::pop<Int>(Stack);
-#line 3716 "runtime.in"
+#line 3732 "runtime.in"
{Stack->push<Int>(Abs(x)); return;}
}
-#line 3720 "runtime.in"
+#line 3736 "runtime.in"
// Int sgn(real x);
-void gen294(stack *Stack)
+void gen295(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3721 "runtime.in"
+#line 3737 "runtime.in"
{Stack->push<Int>(sgn(x)); return;}
}
-#line 3725 "runtime.in"
+#line 3741 "runtime.in"
// Int rand();
-void gen295(stack *Stack)
+void gen296(stack *Stack)
{
-#line 3726 "runtime.in"
+#line 3742 "runtime.in"
{Stack->push<Int>(rand()); return;}
}
-#line 3730 "runtime.in"
+#line 3746 "runtime.in"
// void srand(Int seed);
-void gen296(stack *Stack)
+void gen297(stack *Stack)
{
Int seed=vm::pop<Int>(Stack);
-#line 3731 "runtime.in"
+#line 3747 "runtime.in"
srand(intcast(seed));
}
// a random number uniformly distributed in the interval [0,1]
-#line 3736 "runtime.in"
+#line 3752 "runtime.in"
// real unitrand();
-void gen297(stack *Stack)
+void gen298(stack *Stack)
{
-#line 3737 "runtime.in"
+#line 3753 "runtime.in"
{Stack->push<real>(((real) rand())/RAND_MAX); return;}
}
-#line 3741 "runtime.in"
+#line 3757 "runtime.in"
// Int ceil(real x);
-void gen298(stack *Stack)
+void gen299(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3742 "runtime.in"
+#line 3758 "runtime.in"
{Stack->push<Int>(Intcast(ceil(x))); return;}
}
-#line 3746 "runtime.in"
+#line 3762 "runtime.in"
// Int floor(real x);
-void gen299(stack *Stack)
+void gen300(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3747 "runtime.in"
+#line 3763 "runtime.in"
{Stack->push<Int>(Intcast(floor(x))); return;}
}
-#line 3751 "runtime.in"
+#line 3767 "runtime.in"
// Int round(real x);
-void gen300(stack *Stack)
+void gen301(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3752 "runtime.in"
+#line 3768 "runtime.in"
if(validInt(x)) {Stack->push<Int>(Round(x)); return;}
integeroverflow(0);
}
-#line 3757 "runtime.in"
+#line 3773 "runtime.in"
// Int Ceil(real x);
-void gen301(stack *Stack)
+void gen302(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3758 "runtime.in"
+#line 3774 "runtime.in"
{Stack->push<Int>(Ceil(x)); return;}
}
-#line 3762 "runtime.in"
+#line 3778 "runtime.in"
// Int Floor(real x);
-void gen302(stack *Stack)
+void gen303(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3763 "runtime.in"
+#line 3779 "runtime.in"
{Stack->push<Int>(Floor(x)); return;}
}
-#line 3767 "runtime.in"
+#line 3783 "runtime.in"
// Int Round(real x);
-void gen303(stack *Stack)
+void gen304(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3768 "runtime.in"
+#line 3784 "runtime.in"
{Stack->push<Int>(Round(Intcap(x))); return;}
}
-#line 3772 "runtime.in"
+#line 3788 "runtime.in"
// real fmod(real x, real y);
-void gen304(stack *Stack)
+void gen305(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 3773 "runtime.in"
+#line 3789 "runtime.in"
if (y == 0.0) dividebyzero();
{Stack->push<real>(fmod(x,y)); return;}
}
-#line 3778 "runtime.in"
+#line 3794 "runtime.in"
// real atan2(real y, real x);
-void gen305(stack *Stack)
+void gen306(stack *Stack)
{
real x=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
-#line 3779 "runtime.in"
+#line 3795 "runtime.in"
{Stack->push<real>(atan2(y,x)); return;}
}
-#line 3783 "runtime.in"
+#line 3799 "runtime.in"
// real hypot(real x, real y);
-void gen306(stack *Stack)
+void gen307(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 3784 "runtime.in"
+#line 3800 "runtime.in"
{Stack->push<real>(hypot(x,y)); return;}
}
-#line 3788 "runtime.in"
+#line 3804 "runtime.in"
// real remainder(real x, real y);
-void gen307(stack *Stack)
+void gen308(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 3789 "runtime.in"
+#line 3805 "runtime.in"
{Stack->push<real>(remainder(x,y)); return;}
}
-#line 3793 "runtime.in"
+#line 3809 "runtime.in"
// real J(Int n, real x);
-void gen308(stack *Stack)
+void gen309(stack *Stack)
{
real x=vm::pop<real>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 3794 "runtime.in"
+#line 3810 "runtime.in"
{Stack->push<real>(jn(n,x)); return;}
}
-#line 3798 "runtime.in"
+#line 3814 "runtime.in"
// real Y(Int n, real x);
-void gen309(stack *Stack)
+void gen310(stack *Stack)
{
real x=vm::pop<real>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 3799 "runtime.in"
+#line 3815 "runtime.in"
{Stack->push<real>(yn(n,x)); return;}
}
-#line 3803 "runtime.in"
+#line 3819 "runtime.in"
// real erf(real x);
-void gen310(stack *Stack)
+void gen311(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3804 "runtime.in"
+#line 3820 "runtime.in"
{Stack->push<real>(erf(x)); return;}
}
-#line 3808 "runtime.in"
+#line 3824 "runtime.in"
// real erfc(real x);
-void gen311(stack *Stack)
+void gen312(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3809 "runtime.in"
+#line 3825 "runtime.in"
{Stack->push<real>(erfc(x)); return;}
}
-#line 3813 "runtime.in"
+#line 3829 "runtime.in"
// Int factorial(Int n);
-void gen312(stack *Stack)
+void gen313(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 3814 "runtime.in"
+#line 3830 "runtime.in"
if(n < 0) error(invalidargument);
{Stack->push<Int>(factorial(n)); return;}
}
-#line 3818 "runtime.in"
+#line 3834 "runtime.in"
// Int choose(Int n, Int k);
-void gen313(stack *Stack)
+void gen314(stack *Stack)
{
Int k=vm::pop<Int>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 3819 "runtime.in"
+#line 3835 "runtime.in"
if(n < 0 || k < 0 || k > n) error(invalidargument);
Int f=1;
Int r=n-k;
@@ -5285,12 +5306,12 @@ void gen313(stack *Stack)
{Stack->push<Int>(f); return;}
}
-#line 3829 "runtime.in"
+#line 3845 "runtime.in"
// real gamma(real x);
-void gen314(stack *Stack)
+void gen315(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3830 "runtime.in"
+#line 3846 "runtime.in"
#ifdef HAVE_TGAMMA
{Stack->push<real>(tgamma(x)); return;}
#else
@@ -5300,23 +5321,23 @@ void gen314(stack *Stack)
}
// Complex Gamma function
-#line 3840 "runtime.in"
+#line 3856 "runtime.in"
// pair gamma(explicit pair z);
-void gen315(stack *Stack)
+void gen316(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 3841 "runtime.in"
+#line 3857 "runtime.in"
{Stack->push<pair>(gamma(z)); return;}
}
-#line 3845 "runtime.in"
+#line 3861 "runtime.in"
// realarray* quadraticroots(real a, real b, real c);
-void gen316(stack *Stack)
+void gen317(stack *Stack)
{
real c=vm::pop<real>(Stack);
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
-#line 3846 "runtime.in"
+#line 3862 "runtime.in"
quadraticroots q(a,b,c);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -5324,14 +5345,14 @@ void gen316(stack *Stack)
{Stack->push<realarray*>(roots); return;}
}
-#line 3854 "runtime.in"
+#line 3870 "runtime.in"
// pairarray* quadraticroots(explicit pair a, explicit pair b, explicit pair c);
-void gen317(stack *Stack)
+void gen318(stack *Stack)
{
pair c=vm::pop<pair>(Stack);
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 3855 "runtime.in"
+#line 3871 "runtime.in"
Quadraticroots q(a,b,c);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.z1;
@@ -5339,15 +5360,15 @@ void gen317(stack *Stack)
{Stack->push<pairarray*>(roots); return;}
}
-#line 3863 "runtime.in"
+#line 3879 "runtime.in"
// realarray* cubicroots(real a, real b, real c, real d);
-void gen318(stack *Stack)
+void gen319(stack *Stack)
{
real d=vm::pop<real>(Stack);
real c=vm::pop<real>(Stack);
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
-#line 3864 "runtime.in"
+#line 3880 "runtime.in"
cubicroots q(a,b,c,d);
array *roots=new array(q.roots);
if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -5358,103 +5379,103 @@ void gen318(stack *Stack)
// Transforms
-#line 3875 "runtime.in"
+#line 3891 "runtime.in"
// bool ==(transform a, transform b);
-void gen319(stack *Stack)
+void gen320(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 3876 "runtime.in"
+#line 3892 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 3881 "runtime.in"
+#line 3897 "runtime.in"
// bool !=(transform a, transform b);
-void gen320(stack *Stack)
+void gen321(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 3882 "runtime.in"
+#line 3898 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 3886 "runtime.in"
+#line 3902 "runtime.in"
// transform +(transform a, transform b);
-void gen321(stack *Stack)
+void gen322(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 3887 "runtime.in"
+#line 3903 "runtime.in"
{Stack->push<transform>(a+b); return;}
}
-#line 3891 "runtime.in"
+#line 3907 "runtime.in"
// transform *(transform a, transform b);
-void gen322(stack *Stack)
+void gen323(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 3892 "runtime.in"
+#line 3908 "runtime.in"
{Stack->push<transform>(a*b); return;}
}
-#line 3896 "runtime.in"
+#line 3912 "runtime.in"
// pair *(transform t, pair z);
-void gen323(stack *Stack)
+void gen324(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 3897 "runtime.in"
+#line 3913 "runtime.in"
{Stack->push<pair>(t*z); return;}
}
-#line 3901 "runtime.in"
+#line 3917 "runtime.in"
// path *(transform t, path g);
-void gen324(stack *Stack)
+void gen325(stack *Stack)
{
path g=vm::pop<path>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 3902 "runtime.in"
+#line 3918 "runtime.in"
{Stack->push<path>(transformed(t,g)); return;}
}
-#line 3906 "runtime.in"
+#line 3922 "runtime.in"
// pen *(transform t, pen p);
-void gen325(stack *Stack)
+void gen326(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 3907 "runtime.in"
+#line 3923 "runtime.in"
{Stack->push<pen>(transformed(t,p)); return;}
}
-#line 3911 "runtime.in"
+#line 3927 "runtime.in"
// picture* *(transform t, picture *f);
-void gen326(stack *Stack)
+void gen327(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 3912 "runtime.in"
+#line 3928 "runtime.in"
{Stack->push<picture*>(transformed(t,f)); return;}
}
-#line 3916 "runtime.in"
+#line 3932 "runtime.in"
// picture* *(realarray2 *t, picture *f);
-void gen327(stack *Stack)
+void gen328(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 3917 "runtime.in"
+#line 3933 "runtime.in"
{Stack->push<picture*>(transformed(*t,f)); return;}
}
-#line 3921 "runtime.in"
+#line 3937 "runtime.in"
// transform ^(transform t, Int n);
-void gen328(stack *Stack)
+void gen329(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 3922 "runtime.in"
+#line 3938 "runtime.in"
transform T;
if(n < 0) {
n=-n;
@@ -5464,55 +5485,55 @@ void gen328(stack *Stack)
{Stack->push<transform>(T); return;}
}
-#line 3932 "runtime.in"
+#line 3948 "runtime.in"
void transformXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3933 "runtime.in"
+#line 3949 "runtime.in"
{Stack->push<real>(t.getx()); return;}
}
-#line 3937 "runtime.in"
+#line 3953 "runtime.in"
void transformYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3938 "runtime.in"
+#line 3954 "runtime.in"
{Stack->push<real>(t.gety()); return;}
}
-#line 3942 "runtime.in"
+#line 3958 "runtime.in"
void transformXXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3943 "runtime.in"
+#line 3959 "runtime.in"
{Stack->push<real>(t.getxx()); return;}
}
-#line 3947 "runtime.in"
+#line 3963 "runtime.in"
void transformXYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3948 "runtime.in"
+#line 3964 "runtime.in"
{Stack->push<real>(t.getxy()); return;}
}
-#line 3952 "runtime.in"
+#line 3968 "runtime.in"
void transformYXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3953 "runtime.in"
+#line 3969 "runtime.in"
{Stack->push<real>(t.getyx()); return;}
}
-#line 3957 "runtime.in"
+#line 3973 "runtime.in"
void transformYYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3958 "runtime.in"
+#line 3974 "runtime.in"
{Stack->push<real>(t.getyy()); return;}
}
-#line 3962 "runtime.in"
+#line 3978 "runtime.in"
void real6ToTransform(stack *Stack)
{
real yy=vm::pop<real>(Stack);
@@ -5521,765 +5542,765 @@ void real6ToTransform(stack *Stack)
real xx=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 3964 "runtime.in"
+#line 3980 "runtime.in"
{Stack->push<transform>(transform(x,y,xx,xy,yx,yy)); return;}
}
-#line 3968 "runtime.in"
+#line 3984 "runtime.in"
// transform shift(transform t);
-void gen336(stack *Stack)
+void gen337(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3969 "runtime.in"
+#line 3985 "runtime.in"
{Stack->push<transform>(transform(t.getx(),t.gety(),0,0,0,0)); return;}
}
-#line 3973 "runtime.in"
+#line 3989 "runtime.in"
// transform shiftless(transform t);
-void gen337(stack *Stack)
+void gen338(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3974 "runtime.in"
+#line 3990 "runtime.in"
{Stack->push<transform>(transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy())); return;}
}
-#line 3978 "runtime.in"
+#line 3994 "runtime.in"
// transform identity();
void transformIdentity(stack *Stack)
{
-#line 3979 "runtime.in"
+#line 3995 "runtime.in"
{Stack->push<transform>(identity); return;}
}
-#line 3983 "runtime.in"
+#line 3999 "runtime.in"
// transform inverse(transform t);
-void gen339(stack *Stack)
+void gen340(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 3984 "runtime.in"
+#line 4000 "runtime.in"
{Stack->push<transform>(inverse(t)); return;}
}
-#line 3988 "runtime.in"
+#line 4004 "runtime.in"
// transform shift(pair z);
-void gen340(stack *Stack)
+void gen341(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 3989 "runtime.in"
+#line 4005 "runtime.in"
{Stack->push<transform>(shift(z)); return;}
}
-#line 3993 "runtime.in"
+#line 4009 "runtime.in"
// transform shift(real x, real y);
-void gen341(stack *Stack)
+void gen342(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 3994 "runtime.in"
+#line 4010 "runtime.in"
{Stack->push<transform>(shift(pair(x,y))); return;}
}
-#line 3998 "runtime.in"
+#line 4014 "runtime.in"
// transform xscale(real x);
-void gen342(stack *Stack)
+void gen343(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 3999 "runtime.in"
+#line 4015 "runtime.in"
{Stack->push<transform>(xscale(x)); return;}
}
-#line 4003 "runtime.in"
+#line 4019 "runtime.in"
// transform yscale(real y);
-void gen343(stack *Stack)
+void gen344(stack *Stack)
{
real y=vm::pop<real>(Stack);
-#line 4004 "runtime.in"
+#line 4020 "runtime.in"
{Stack->push<transform>(yscale(y)); return;}
}
-#line 4008 "runtime.in"
+#line 4024 "runtime.in"
// transform scale(real x);
-void gen344(stack *Stack)
+void gen345(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 4009 "runtime.in"
+#line 4025 "runtime.in"
{Stack->push<transform>(scale(x)); return;}
}
-#line 4013 "runtime.in"
+#line 4029 "runtime.in"
// transform scale(real x, real y);
-void gen345(stack *Stack)
+void gen346(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 4014 "runtime.in"
+#line 4030 "runtime.in"
{Stack->push<transform>(xscale(x)*yscale(y)); return;}
}
-#line 4018 "runtime.in"
+#line 4034 "runtime.in"
// transform slant(real s);
-void gen346(stack *Stack)
+void gen347(stack *Stack)
{
real s=vm::pop<real>(Stack);
-#line 4019 "runtime.in"
+#line 4035 "runtime.in"
{Stack->push<transform>(slant(s)); return;}
}
-#line 4023 "runtime.in"
+#line 4039 "runtime.in"
// transform rotate(real angle, pair z=0);
-void gen347(stack *Stack)
+void gen348(stack *Stack)
{
pair z=vm::pop<pair>(Stack,0);
real angle=vm::pop<real>(Stack);
-#line 4024 "runtime.in"
+#line 4040 "runtime.in"
{Stack->push<transform>(rotatearound(z,radians(angle))); return;}
}
-#line 4028 "runtime.in"
+#line 4044 "runtime.in"
// transform reflect(pair a, pair b);
-void gen348(stack *Stack)
+void gen349(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 4029 "runtime.in"
+#line 4045 "runtime.in"
{Stack->push<transform>(reflectabout(a,b)); return;}
}
// Pair operations
-#line 4035 "runtime.in"
+#line 4051 "runtime.in"
void pairZero(stack *Stack)
{
-#line 4036 "runtime.in"
+#line 4052 "runtime.in"
{Stack->push<pair>(zero); return;}
}
-#line 4041 "runtime.in"
+#line 4057 "runtime.in"
void realRealToPair(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 4042 "runtime.in"
+#line 4058 "runtime.in"
{Stack->push<pair>(pair(x,y)); return;}
}
-#line 4046 "runtime.in"
+#line 4062 "runtime.in"
void pairNegate(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4047 "runtime.in"
+#line 4063 "runtime.in"
{Stack->push<pair>(-z); return;}
}
-#line 4051 "runtime.in"
+#line 4067 "runtime.in"
// real xpart(pair z);
void pairXPart(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4052 "runtime.in"
+#line 4068 "runtime.in"
{Stack->push<real>(z.getx()); return;}
}
-#line 4056 "runtime.in"
+#line 4072 "runtime.in"
// real ypart(pair z);
void pairYPart(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4057 "runtime.in"
+#line 4073 "runtime.in"
{Stack->push<real>(z.gety()); return;}
}
-#line 4061 "runtime.in"
+#line 4077 "runtime.in"
// real length(pair z);
-void gen354(stack *Stack)
+void gen355(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4062 "runtime.in"
+#line 4078 "runtime.in"
{Stack->push<real>(z.length()); return;}
}
-#line 4066 "runtime.in"
+#line 4082 "runtime.in"
// real abs(pair z);
-void gen355(stack *Stack)
+void gen356(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4067 "runtime.in"
+#line 4083 "runtime.in"
{Stack->push<real>(z.length()); return;}
}
-#line 4071 "runtime.in"
+#line 4087 "runtime.in"
// pair sqrt(explicit pair z);
-void gen356(stack *Stack)
+void gen357(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4072 "runtime.in"
+#line 4088 "runtime.in"
{Stack->push<pair>(Sqrt(z)); return;}
}
// Return the angle of z in radians.
-#line 4077 "runtime.in"
+#line 4093 "runtime.in"
// real angle(pair z, bool warn=true);
-void gen357(stack *Stack)
+void gen358(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
pair z=vm::pop<pair>(Stack);
-#line 4078 "runtime.in"
+#line 4094 "runtime.in"
if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(z.angle()); return;}
}
// Return the angle of z in degrees in the interval [0,360).
-#line 4084 "runtime.in"
+#line 4100 "runtime.in"
// real degrees(pair z, bool warn=true);
-void gen358(stack *Stack)
+void gen359(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
pair z=vm::pop<pair>(Stack);
-#line 4085 "runtime.in"
+#line 4101 "runtime.in"
if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(principalBranch(degrees(z.angle()))); return;}
}
// Convert degrees to radians.
-#line 4091 "runtime.in"
+#line 4107 "runtime.in"
// real radians(real degrees);
-void gen359(stack *Stack)
+void gen360(stack *Stack)
{
real degrees=vm::pop<real>(Stack);
-#line 4092 "runtime.in"
+#line 4108 "runtime.in"
{Stack->push<real>(radians(degrees)); return;}
}
// Convert radians to degrees.
-#line 4097 "runtime.in"
+#line 4113 "runtime.in"
// real degrees(real radians);
-void gen360(stack *Stack)
+void gen361(stack *Stack)
{
real radians=vm::pop<real>(Stack);
-#line 4098 "runtime.in"
+#line 4114 "runtime.in"
{Stack->push<real>(degrees(radians)); return;}
}
// Convert radians to degrees in [0,360).
-#line 4103 "runtime.in"
+#line 4119 "runtime.in"
// real Degrees(real radians);
-void gen361(stack *Stack)
+void gen362(stack *Stack)
{
real radians=vm::pop<real>(Stack);
-#line 4104 "runtime.in"
+#line 4120 "runtime.in"
{Stack->push<real>(principalBranch(degrees(radians))); return;}
}
-#line 4108 "runtime.in"
+#line 4124 "runtime.in"
// real Sin(real deg);
-void gen362(stack *Stack)
+void gen363(stack *Stack)
{
real deg=vm::pop<real>(Stack);
-#line 4109 "runtime.in"
+#line 4125 "runtime.in"
{Stack->push<real>(sin(radians(deg))); return;}
}
-#line 4113 "runtime.in"
+#line 4129 "runtime.in"
// real Cos(real deg);
-void gen363(stack *Stack)
+void gen364(stack *Stack)
{
real deg=vm::pop<real>(Stack);
-#line 4114 "runtime.in"
+#line 4130 "runtime.in"
{Stack->push<real>(cos(radians(deg))); return;}
}
-#line 4118 "runtime.in"
+#line 4134 "runtime.in"
// real Tan(real deg);
-void gen364(stack *Stack)
+void gen365(stack *Stack)
{
real deg=vm::pop<real>(Stack);
-#line 4119 "runtime.in"
+#line 4135 "runtime.in"
{Stack->push<real>(tan(radians(deg))); return;}
}
-#line 4123 "runtime.in"
+#line 4139 "runtime.in"
// real aSin(real x);
-void gen365(stack *Stack)
+void gen366(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 4124 "runtime.in"
+#line 4140 "runtime.in"
{Stack->push<real>(degrees(asin(x))); return;}
}
-#line 4128 "runtime.in"
+#line 4144 "runtime.in"
// real aCos(real x);
-void gen366(stack *Stack)
+void gen367(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 4129 "runtime.in"
+#line 4145 "runtime.in"
{Stack->push<real>(degrees(acos(x))); return;}
}
-#line 4133 "runtime.in"
+#line 4149 "runtime.in"
// real aTan(real x);
-void gen367(stack *Stack)
+void gen368(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 4134 "runtime.in"
+#line 4150 "runtime.in"
{Stack->push<real>(degrees(atan(x))); return;}
}
-#line 4138 "runtime.in"
+#line 4154 "runtime.in"
// pair unit(pair z);
-void gen368(stack *Stack)
+void gen369(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4139 "runtime.in"
+#line 4155 "runtime.in"
{Stack->push<pair>(unit(z)); return;}
}
-#line 4143 "runtime.in"
+#line 4159 "runtime.in"
// pair dir(real degrees);
-void gen369(stack *Stack)
+void gen370(stack *Stack)
{
real degrees=vm::pop<real>(Stack);
-#line 4144 "runtime.in"
+#line 4160 "runtime.in"
{Stack->push<pair>(expi(radians(degrees))); return;}
}
-#line 4148 "runtime.in"
+#line 4164 "runtime.in"
// pair dir(explicit pair z);
-void gen370(stack *Stack)
+void gen371(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4149 "runtime.in"
+#line 4165 "runtime.in"
{Stack->push<pair>(unit(z)); return;}
}
-#line 4153 "runtime.in"
+#line 4169 "runtime.in"
// pair expi(real angle);
-void gen371(stack *Stack)
+void gen372(stack *Stack)
{
real angle=vm::pop<real>(Stack);
-#line 4154 "runtime.in"
+#line 4170 "runtime.in"
{Stack->push<pair>(expi(angle)); return;}
}
-#line 4158 "runtime.in"
+#line 4174 "runtime.in"
// pair exp(explicit pair z);
-void gen372(stack *Stack)
+void gen373(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4159 "runtime.in"
+#line 4175 "runtime.in"
{Stack->push<pair>(exp(z)); return;}
}
-#line 4163 "runtime.in"
+#line 4179 "runtime.in"
// pair log(explicit pair z);
-void gen373(stack *Stack)
+void gen374(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4164 "runtime.in"
+#line 4180 "runtime.in"
{Stack->push<pair>(pair(log(z.length()),z.angle())); return;}
}
-#line 4168 "runtime.in"
+#line 4184 "runtime.in"
// pair sin(explicit pair z);
-void gen374(stack *Stack)
+void gen375(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4169 "runtime.in"
+#line 4185 "runtime.in"
{Stack->push<pair>(sin(z)); return;}
}
-#line 4173 "runtime.in"
+#line 4189 "runtime.in"
// pair cos(explicit pair z);
-void gen375(stack *Stack)
+void gen376(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4174 "runtime.in"
+#line 4190 "runtime.in"
{Stack->push<pair>(pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()))); return;}
}
-#line 4178 "runtime.in"
+#line 4194 "runtime.in"
// pair conj(pair z);
-void gen376(stack *Stack)
+void gen377(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 4179 "runtime.in"
+#line 4195 "runtime.in"
{Stack->push<pair>(conj(z)); return;}
}
-#line 4183 "runtime.in"
+#line 4199 "runtime.in"
// pair realmult(pair z, pair w);
-void gen377(stack *Stack)
+void gen378(stack *Stack)
{
pair w=vm::pop<pair>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 4184 "runtime.in"
+#line 4200 "runtime.in"
{Stack->push<pair>(pair (z.getx()*w.getx(),z.gety()*w.gety())); return;}
}
-#line 4188 "runtime.in"
+#line 4204 "runtime.in"
// triple realmult(triple u, triple v);
-void gen378(stack *Stack)
+void gen379(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
triple u=vm::pop<triple>(Stack);
-#line 4189 "runtime.in"
+#line 4205 "runtime.in"
{Stack->push<triple>(triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz())); return;}
}
// To avoid confusion, a dot product requires explicit pair arguments.
-#line 4194 "runtime.in"
+#line 4210 "runtime.in"
// real dot(explicit pair z, explicit pair w);
-void gen379(stack *Stack)
+void gen380(stack *Stack)
{
pair w=vm::pop<pair>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 4195 "runtime.in"
+#line 4211 "runtime.in"
{Stack->push<real>(dot(z,w)); return;}
}
// Triple operations
-#line 4201 "runtime.in"
+#line 4217 "runtime.in"
void tripleZero(stack *Stack)
{
-#line 4202 "runtime.in"
+#line 4218 "runtime.in"
static triple zero;
{Stack->push<triple>(zero); return;}
}
-#line 4208 "runtime.in"
+#line 4224 "runtime.in"
void realRealRealToTriple(stack *Stack)
{
real z=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 4209 "runtime.in"
+#line 4225 "runtime.in"
{Stack->push<triple>(triple(x,y,z)); return;}
}
-#line 4213 "runtime.in"
+#line 4229 "runtime.in"
// real xpart(triple v);
void tripleXPart(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4214 "runtime.in"
+#line 4230 "runtime.in"
{Stack->push<real>(v.getx()); return;}
}
-#line 4218 "runtime.in"
+#line 4234 "runtime.in"
// real ypart(triple v);
void tripleYPart(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4219 "runtime.in"
+#line 4235 "runtime.in"
{Stack->push<real>(v.gety()); return;}
}
-#line 4223 "runtime.in"
+#line 4239 "runtime.in"
// real zpart(triple v);
void tripleZPart(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4224 "runtime.in"
+#line 4240 "runtime.in"
{Stack->push<real>(v.getz()); return;}
}
-#line 4228 "runtime.in"
+#line 4244 "runtime.in"
// triple *(real x, triple v);
-void gen385(stack *Stack)
+void gen386(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
real x=vm::pop<real>(Stack);
-#line 4229 "runtime.in"
+#line 4245 "runtime.in"
{Stack->push<triple>(x*v); return;}
}
-#line 4233 "runtime.in"
+#line 4249 "runtime.in"
// triple *(triple v, real x);
-void gen386(stack *Stack)
+void gen387(stack *Stack)
{
real x=vm::pop<real>(Stack);
triple v=vm::pop<triple>(Stack);
-#line 4234 "runtime.in"
+#line 4250 "runtime.in"
{Stack->push<triple>(v*x); return;}
}
-#line 4238 "runtime.in"
+#line 4254 "runtime.in"
// triple /(triple v, real x);
-void gen387(stack *Stack)
+void gen388(stack *Stack)
{
real x=vm::pop<real>(Stack);
triple v=vm::pop<triple>(Stack);
-#line 4239 "runtime.in"
+#line 4255 "runtime.in"
{Stack->push<triple>(v/x); return;}
}
-#line 4243 "runtime.in"
+#line 4259 "runtime.in"
// real length(triple v);
-void gen388(stack *Stack)
+void gen389(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4244 "runtime.in"
+#line 4260 "runtime.in"
{Stack->push<real>(v.length()); return;}
}
-#line 4248 "runtime.in"
+#line 4264 "runtime.in"
// real abs(triple v);
-void gen389(stack *Stack)
+void gen390(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4249 "runtime.in"
+#line 4265 "runtime.in"
{Stack->push<real>(v.length()); return;}
}
-#line 4253 "runtime.in"
+#line 4269 "runtime.in"
// real polar(triple v, bool warn=true);
-void gen390(stack *Stack)
+void gen391(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
triple v=vm::pop<triple>(Stack);
-#line 4254 "runtime.in"
+#line 4270 "runtime.in"
if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(v.polar()); return;}
}
-#line 4259 "runtime.in"
+#line 4275 "runtime.in"
// real azimuth(triple v, bool warn=true);
-void gen391(stack *Stack)
+void gen392(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
triple v=vm::pop<triple>(Stack);
-#line 4260 "runtime.in"
+#line 4276 "runtime.in"
if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(v.azimuth()); return;}
}
-#line 4265 "runtime.in"
+#line 4281 "runtime.in"
// real colatitude(triple v, bool warn=true);
-void gen392(stack *Stack)
+void gen393(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
triple v=vm::pop<triple>(Stack);
-#line 4266 "runtime.in"
+#line 4282 "runtime.in"
if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(degrees(v.polar())); return;}
}
-#line 4271 "runtime.in"
+#line 4287 "runtime.in"
// real latitude(triple v, bool warn=true);
-void gen393(stack *Stack)
+void gen394(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
triple v=vm::pop<triple>(Stack);
-#line 4272 "runtime.in"
+#line 4288 "runtime.in"
if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(90.0-degrees(v.polar())); return;}
}
// Return the longitude of v in [0,360).
-#line 4278 "runtime.in"
+#line 4294 "runtime.in"
// real longitude(triple v, bool warn=true);
-void gen394(stack *Stack)
+void gen395(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
triple v=vm::pop<triple>(Stack);
-#line 4279 "runtime.in"
+#line 4295 "runtime.in"
if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
{Stack->push<real>(principalBranch(degrees(v.azimuth()))); return;}
}
-#line 4284 "runtime.in"
+#line 4300 "runtime.in"
// triple unit(triple v);
-void gen395(stack *Stack)
+void gen396(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
-#line 4285 "runtime.in"
+#line 4301 "runtime.in"
{Stack->push<triple>(unit(v)); return;}
}
-#line 4289 "runtime.in"
+#line 4305 "runtime.in"
// real dot(triple u, triple v);
-void gen396(stack *Stack)
+void gen397(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
triple u=vm::pop<triple>(Stack);
-#line 4290 "runtime.in"
+#line 4306 "runtime.in"
{Stack->push<real>(dot(u,v)); return;}
}
-#line 4294 "runtime.in"
+#line 4310 "runtime.in"
// triple cross(triple u, triple v);
-void gen397(stack *Stack)
+void gen398(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
triple u=vm::pop<triple>(Stack);
-#line 4295 "runtime.in"
+#line 4311 "runtime.in"
{Stack->push<triple>(cross(u,v)); return;}
}
-#line 4299 "runtime.in"
+#line 4315 "runtime.in"
// triple expi(real polar, real azimuth);
-void gen398(stack *Stack)
+void gen399(stack *Stack)
{
real azimuth=vm::pop<real>(Stack);
real polar=vm::pop<real>(Stack);
-#line 4300 "runtime.in"
+#line 4316 "runtime.in"
{Stack->push<triple>(expi(polar,azimuth)); return;}
}
-#line 4304 "runtime.in"
+#line 4320 "runtime.in"
// triple dir(real colatitude, real longitude);
-void gen399(stack *Stack)
+void gen400(stack *Stack)
{
real longitude=vm::pop<real>(Stack);
real colatitude=vm::pop<real>(Stack);
-#line 4305 "runtime.in"
+#line 4321 "runtime.in"
{Stack->push<triple>(expi(radians(colatitude),radians(longitude))); return;}
}
// System routines
-#line 4311 "runtime.in"
+#line 4327 "runtime.in"
// void atupdate(callable *f);
-void gen400(stack *Stack)
+void gen401(stack *Stack)
{
callable * f=vm::pop<callable *>(Stack);
-#line 4312 "runtime.in"
+#line 4328 "runtime.in"
processData().atUpdateFunction=f;
}
-#line 4317 "runtime.in"
+#line 4333 "runtime.in"
// callable* atupdate();
-void gen401(stack *Stack)
+void gen402(stack *Stack)
{
-#line 4318 "runtime.in"
+#line 4334 "runtime.in"
{Stack->push<callable*>(processData().atUpdateFunction); return;}
}
-#line 4322 "runtime.in"
+#line 4338 "runtime.in"
// void atexit(callable *f);
-void gen402(stack *Stack)
+void gen403(stack *Stack)
{
callable * f=vm::pop<callable *>(Stack);
-#line 4323 "runtime.in"
+#line 4339 "runtime.in"
processData().atExitFunction=f;
}
-#line 4327 "runtime.in"
+#line 4343 "runtime.in"
// callable* atexit();
-void gen403(stack *Stack)
+void gen404(stack *Stack)
{
-#line 4328 "runtime.in"
+#line 4344 "runtime.in"
{Stack->push<callable*>(processData().atExitFunction); return;}
}
-#line 4332 "runtime.in"
+#line 4348 "runtime.in"
// void atbreakpoint(callableBp *f);
-void gen404(stack *Stack)
+void gen405(stack *Stack)
{
callableBp * f=vm::pop<callableBp *>(Stack);
-#line 4333 "runtime.in"
+#line 4349 "runtime.in"
processData().atBreakpointFunction=f;
}
-#line 4337 "runtime.in"
+#line 4353 "runtime.in"
// void breakpoint(runnable *s=NULL);
-void gen405(stack *Stack)
+void gen406(stack *Stack)
{
runnable * s=vm::pop<runnable *>(Stack,NULL);
-#line 4338 "runtime.in"
+#line 4354 "runtime.in"
breakpoint(Stack,s);
}
-#line 4342 "runtime.in"
+#line 4358 "runtime.in"
// string locatefile(string file);
-void gen406(stack *Stack)
+void gen407(stack *Stack)
{
string file=vm::pop<string>(Stack);
-#line 4343 "runtime.in"
+#line 4359 "runtime.in"
{Stack->push<string>(locateFile(file)); return;}
}
-#line 4347 "runtime.in"
+#line 4363 "runtime.in"
// void stop(string file, Int line, runnable *s=NULL);
-void gen407(stack *Stack)
+void gen408(stack *Stack)
{
runnable * s=vm::pop<runnable *>(Stack,NULL);
Int line=vm::pop<Int>(Stack);
string file=vm::pop<string>(Stack);
-#line 4348 "runtime.in"
+#line 4364 "runtime.in"
file=locateFile(file);
clear(file,line);
cout << "setting breakpoint at " << file << ": " << line << endl;
bplist.push_back(bpinfo(file,line,s));
}
-#line 4355 "runtime.in"
+#line 4371 "runtime.in"
// void breakpoints();
-void gen408(stack *)
+void gen409(stack *)
{
-#line 4356 "runtime.in"
+#line 4372 "runtime.in"
for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
cout << p->f.name() << ": " << p->f.line() << endl;
}
-#line 4361 "runtime.in"
+#line 4377 "runtime.in"
// void clear(string file, Int line);
-void gen409(stack *Stack)
+void gen410(stack *Stack)
{
Int line=vm::pop<Int>(Stack);
string file=vm::pop<string>(Stack);
-#line 4362 "runtime.in"
+#line 4378 "runtime.in"
file=locateFile(file);
clear(file,line,true);
}
-#line 4367 "runtime.in"
+#line 4383 "runtime.in"
// void clear();
-void gen410(stack *)
+void gen411(stack *)
{
-#line 4368 "runtime.in"
+#line 4384 "runtime.in"
bplist.clear();
}
// Strip directory from string
-#line 4373 "runtime.in"
+#line 4389 "runtime.in"
// string stripdirectory(string *s);
-void gen411(stack *Stack)
+void gen412(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 4374 "runtime.in"
+#line 4390 "runtime.in"
{Stack->push<string>(stripDir(*s)); return;}
}
// Strip directory from string
-#line 4379 "runtime.in"
+#line 4395 "runtime.in"
// string stripfile(string *s);
-void gen412(stack *Stack)
+void gen413(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 4380 "runtime.in"
+#line 4396 "runtime.in"
{Stack->push<string>(stripFile(*s)); return;}
}
// Strip file extension from string
-#line 4385 "runtime.in"
+#line 4401 "runtime.in"
// string stripextension(string *s);
-void gen413(stack *Stack)
+void gen414(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 4386 "runtime.in"
+#line 4402 "runtime.in"
{Stack->push<string>(stripExt(*s)); return;}
}
// Call ImageMagick convert.
-#line 4391 "runtime.in"
+#line 4407 "runtime.in"
// Int convert(string args=emptystring, string file=emptystring, string format=emptystring);
-void gen414(stack *Stack)
+void gen415(stack *Stack)
{
string format=vm::pop<string>(Stack,emptystring);
string file=vm::pop<string>(Stack,emptystring);
string args=vm::pop<string>(Stack,emptystring);
-#line 4393 "runtime.in"
+#line 4409 "runtime.in"
ostringstream cmd;
string name=convertname(file,format);
@@ -6295,14 +6316,14 @@ void gen414(stack *Stack)
}
// Call ImageMagick animate.
-#line 4409 "runtime.in"
+#line 4425 "runtime.in"
// Int animate(string args=emptystring, string file=emptystring, string format=emptystring);
-void gen415(stack *Stack)
+void gen416(stack *Stack)
{
string format=vm::pop<string>(Stack,emptystring);
string file=vm::pop<string>(Stack,emptystring);
string args=vm::pop<string>(Stack,emptystring);
-#line 4411 "runtime.in"
+#line 4427 "runtime.in"
#ifndef __CYGWIN__
string name=convertname(file,format,false);
if(view()) {
@@ -6316,12 +6337,12 @@ void gen415(stack *Stack)
}
// Delete file named s.
-#line 4425 "runtime.in"
+#line 4441 "runtime.in"
// Int delete(string *s);
-void gen416(stack *Stack)
+void gen417(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 4426 "runtime.in"
+#line 4442 "runtime.in"
checkLocal(*s);
Int rc=unlink(s->c_str());
if(rc == 0 && verbose > 0)
@@ -6330,13 +6351,13 @@ void gen416(stack *Stack)
}
// Rename file "from" to file "to".
-#line 4435 "runtime.in"
+#line 4451 "runtime.in"
// Int rename(string *from, string *to);
-void gen417(stack *Stack)
+void gen418(stack *Stack)
{
string * to=vm::pop<string *>(Stack);
string * from=vm::pop<string *>(Stack);
-#line 4436 "runtime.in"
+#line 4452 "runtime.in"
checkLocal(*from);
checkLocal(*to);
Int rc=rename(from->c_str(),to->c_str());
@@ -6349,10 +6370,10 @@ void gen417(stack *Stack)
// Array operations
// Create an empty array.
-#line 4449 "runtime.in"
+#line 4465 "runtime.in"
void emptyArray(stack *Stack)
{
-#line 4450 "runtime.in"
+#line 4466 "runtime.in"
{Stack->push<array*>(new array(0)); return;}
}
@@ -6361,11 +6382,11 @@ void emptyArray(stack *Stack)
// is popped off the stack, followed by each dimension in reverse order.
// The array itself is technically a one dimensional array of one
// dimension arrays and so on.
-#line 4459 "runtime.in"
+#line 4475 "runtime.in"
void newDeepArray(stack *Stack)
{
Int depth=vm::pop<Int>(Stack);
-#line 4460 "runtime.in"
+#line 4476 "runtime.in"
assert(depth > 0);
Int *dims = new Int[depth];
@@ -6384,11 +6405,11 @@ void newDeepArray(stack *Stack)
// Creates an array with elements already specified. First, the number
// of elements is popped off the stack, followed by each element in
// reverse order.
-#line 4479 "runtime.in"
+#line 4495 "runtime.in"
void newInitializedArray(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 4480 "runtime.in"
+#line 4496 "runtime.in"
assert(n >= 0);
array *a = new array(n);
@@ -6401,12 +6422,12 @@ void newInitializedArray(stack *Stack)
// Similar to newInitializedArray, but after the n elements, append another
// array to it.
-#line 4493 "runtime.in"
+#line 4509 "runtime.in"
void newAppendedArray(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array* tail=vm::pop<array*>(Stack);
-#line 4494 "runtime.in"
+#line 4510 "runtime.in"
assert(n >= 0);
array *a = new array(n);
@@ -6421,13 +6442,13 @@ void newAppendedArray(stack *Stack)
// The function T[] array(int n, T value, int depth=0) produces a array of n
// copies of x, where each copy is copied up to depth.
-#line 4509 "runtime.in"
+#line 4525 "runtime.in"
void newDuplicateArray(stack *Stack)
{
Int depth=vm::pop<Int>(Stack,Int_MAX);
item value=vm::pop(Stack);
Int n=vm::pop<Int>(Stack);
-#line 4510 "runtime.in"
+#line 4526 "runtime.in"
if(n < 0) error("cannot create a negative length array");
if(depth < 0) error("cannot copy to a negative depth");
@@ -6435,12 +6456,12 @@ void newDuplicateArray(stack *Stack)
}
// Read an element from an array. Checks for initialization & bounds.
-#line 4518 "runtime.in"
+#line 4534 "runtime.in"
void arrayRead(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4519 "runtime.in"
+#line 4535 "runtime.in"
item& i=arrayRead(a,n);
if (i.empty()) {
ostringstream buf;
@@ -6451,50 +6472,50 @@ void arrayRead(stack *Stack)
}
// Slice a substring from an array.
-#line 4530 "runtime.in"
+#line 4546 "runtime.in"
void arraySliceRead(stack *Stack)
{
Int right=vm::pop<Int>(Stack);
Int left=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4531 "runtime.in"
+#line 4547 "runtime.in"
checkArray(a);
{Stack->push(a->slice(left, right)); return;}
}
// Slice a substring from an array. This implements the cases a[i:] and a[:]
// where the endpoint is not given, and assumed to be the length of the array.
-#line 4538 "runtime.in"
+#line 4554 "runtime.in"
void arraySliceReadToEnd(stack *Stack)
{
Int left=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4539 "runtime.in"
+#line 4555 "runtime.in"
size_t len=checkArray(a);
{Stack->push(a->slice(left, (Int)len)); return;}
}
// Read an element from an array of arrays. Check bounds and initialize
// as necessary.
-#line 4546 "runtime.in"
+#line 4562 "runtime.in"
void arrayArrayRead(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4547 "runtime.in"
+#line 4563 "runtime.in"
item& i=arrayRead(a,n);
if (i.empty()) i=new array(0);
{Stack->push(i); return;}
}
// Write an element to an array. Increase size if necessary.
-#line 4554 "runtime.in"
+#line 4570 "runtime.in"
void arrayWrite(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
array * a=vm::pop<array *>(Stack);
item value=vm::pop(Stack);
-#line 4555 "runtime.in"
+#line 4571 "runtime.in"
size_t len=checkArray(a);
bool cyclic=a->cyclic();
if(cyclic && len > 0) n=imod(n,len);
@@ -6508,27 +6529,27 @@ void arrayWrite(stack *Stack)
{Stack->push(value); return;}
}
-#line 4569 "runtime.in"
+#line 4585 "runtime.in"
void arraySliceWrite(stack *Stack)
{
Int right=vm::pop<Int>(Stack);
Int left=vm::pop<Int>(Stack);
array * dest=vm::pop<array *>(Stack);
array * src=vm::pop<array *>(Stack);
-#line 4570 "runtime.in"
+#line 4586 "runtime.in"
checkArray(src);
checkArray(dest);
dest->setSlice(left, right, src);
{Stack->push<array*>(src); return;}
}
-#line 4577 "runtime.in"
+#line 4593 "runtime.in"
void arraySliceWriteToEnd(stack *Stack)
{
Int left=vm::pop<Int>(Stack);
array * dest=vm::pop<array *>(Stack);
array * src=vm::pop<array *>(Stack);
-#line 4578 "runtime.in"
+#line 4594 "runtime.in"
checkArray(src);
size_t len=checkArray(dest);
dest->setSlice(left, (Int) len, src);
@@ -6536,20 +6557,20 @@ void arraySliceWriteToEnd(stack *Stack)
}
// Returns the length of an array.
-#line 4586 "runtime.in"
+#line 4602 "runtime.in"
void arrayLength(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4587 "runtime.in"
+#line 4603 "runtime.in"
{Stack->push<Int>((Int) checkArray(a)); return;}
}
// Returns an array of integers representing the keys of the array.
-#line 4592 "runtime.in"
+#line 4608 "runtime.in"
void arrayKeys(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4593 "runtime.in"
+#line 4609 "runtime.in"
size_t size=checkArray(a);
array *keys=new array();
@@ -6563,22 +6584,22 @@ void arrayKeys(stack *Stack)
}
// Return the cyclic flag for an array.
-#line 4607 "runtime.in"
+#line 4623 "runtime.in"
void arrayCyclicFlag(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4608 "runtime.in"
+#line 4624 "runtime.in"
checkArray(a);
{Stack->push<bool>(a->cyclic()); return;}
}
// Check to see if an array element is initialized.
-#line 4614 "runtime.in"
+#line 4630 "runtime.in"
void arrayInitializedHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
Int n=vm::pop<Int>(Stack);
-#line 4615 "runtime.in"
+#line 4631 "runtime.in"
size_t len=checkArray(a);
bool cyclic=a->cyclic();
if(cyclic && len > 0) n=imod(n,len);
@@ -6588,62 +6609,62 @@ void arrayInitializedHelper(stack *Stack)
}
// Returns the initialize method for an array.
-#line 4625 "runtime.in"
+#line 4641 "runtime.in"
void arrayInitialized(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4626 "runtime.in"
+#line 4642 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayInitializedHelper),a)); return;}
}
// The helper function for the cyclic method that sets the cyclic flag.
-#line 4631 "runtime.in"
+#line 4647 "runtime.in"
void arrayCyclicHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
bool b=vm::pop<bool>(Stack);
-#line 4632 "runtime.in"
+#line 4648 "runtime.in"
checkArray(a);
a->cyclic(b);
}
// Set the cyclic flag for an array.
-#line 4638 "runtime.in"
+#line 4654 "runtime.in"
void arrayCyclic(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4639 "runtime.in"
+#line 4655 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayCyclicHelper),a)); return;}
}
// The helper function for the push method that does the actual operation.
-#line 4644 "runtime.in"
+#line 4660 "runtime.in"
void arrayPushHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
item x=vm::pop(Stack);
-#line 4645 "runtime.in"
+#line 4661 "runtime.in"
checkArray(a);
a->push(x);
{Stack->push(x); return;}
}
// Returns the push method for an array.
-#line 4652 "runtime.in"
+#line 4668 "runtime.in"
void arrayPush(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4653 "runtime.in"
+#line 4669 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayPushHelper),a)); return;}
}
// The helper function for the append method that appends b to a.
-#line 4658 "runtime.in"
+#line 4674 "runtime.in"
void arrayAppendHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
array * b=vm::pop<array *>(Stack);
-#line 4659 "runtime.in"
+#line 4675 "runtime.in"
checkArray(a);
size_t size=checkArray(b);
for(size_t i=0; i < size; i++)
@@ -6651,20 +6672,20 @@ void arrayAppendHelper(stack *Stack)
}
// Returns the append method for an array.
-#line 4667 "runtime.in"
+#line 4683 "runtime.in"
void arrayAppend(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4668 "runtime.in"
+#line 4684 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayAppendHelper),a)); return;}
}
// The helper function for the pop method.
-#line 4673 "runtime.in"
+#line 4689 "runtime.in"
void arrayPopHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4674 "runtime.in"
+#line 4690 "runtime.in"
size_t asize=checkArray(a);
if(asize == 0)
error("cannot pop element from empty array");
@@ -6672,22 +6693,22 @@ void arrayPopHelper(stack *Stack)
}
// Returns the pop method for an array.
-#line 4682 "runtime.in"
+#line 4698 "runtime.in"
void arrayPop(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4683 "runtime.in"
+#line 4699 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayPopHelper),a)); return;}
}
// The helper function for the insert method.
-#line 4688 "runtime.in"
+#line 4704 "runtime.in"
void arrayInsertHelper(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
array * x=vm::pop<array *>(Stack);
Int i=vm::pop<Int>(Stack);
-#line 4689 "runtime.in"
+#line 4705 "runtime.in"
size_t asize=checkArray(a);
checkArray(x);
if(a->cyclic() && asize > 0) i=imod(i,asize);
@@ -6697,39 +6718,39 @@ void arrayInsertHelper(stack *Stack)
}
// Returns the insert method for an array.
-#line 4699 "runtime.in"
+#line 4715 "runtime.in"
void arrayInsert(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4700 "runtime.in"
+#line 4716 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayInsertHelper),a)); return;}
}
// Returns the delete method for an array.
-#line 4705 "runtime.in"
+#line 4721 "runtime.in"
void arrayDelete(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4706 "runtime.in"
+#line 4722 "runtime.in"
{Stack->push<callable*>(new thunk(new bfunc(arrayDeleteHelper),a)); return;}
}
-#line 4710 "runtime.in"
+#line 4726 "runtime.in"
void arrayAlias(stack *Stack)
{
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4711 "runtime.in"
+#line 4727 "runtime.in"
{Stack->push<bool>(a==b); return;}
}
// Return array formed by indexing array a with elements of integer array b
-#line 4716 "runtime.in"
+#line 4732 "runtime.in"
void arrayIntArray(stack *Stack)
{
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4717 "runtime.in"
+#line 4733 "runtime.in"
size_t asize=checkArray(a);
size_t bsize=checkArray(b);
array *r=new array(bsize);
@@ -6747,13 +6768,13 @@ void arrayIntArray(stack *Stack)
// returns the complement of the integer array a in {0,2,...,n-1},
// so that b[complement(a,b.length)] yields the complement of b[a].
-#line 4735 "runtime.in"
+#line 4751 "runtime.in"
// Intarray* complement(Intarray *a, Int n);
-void gen448(stack *Stack)
+void gen449(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
Intarray * a=vm::pop<Intarray *>(Stack);
-#line 4736 "runtime.in"
+#line 4752 "runtime.in"
size_t asize=checkArray(a);
array *r=new array(0);
bool *keep=new bool[n];
@@ -6770,12 +6791,12 @@ void gen448(stack *Stack)
}
// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
-#line 4753 "runtime.in"
+#line 4769 "runtime.in"
void arraySequence(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
callable * f=vm::pop<callable *>(Stack);
-#line 4754 "runtime.in"
+#line 4770 "runtime.in"
if(n < 0) n=0;
array *a=new array(n);
for(Int i=0; i < n; ++i) {
@@ -6787,12 +6808,12 @@ void arraySequence(stack *Stack)
}
// Return the array {0,1,...n-1}
-#line 4766 "runtime.in"
+#line 4782 "runtime.in"
// Intarray* sequence(Int n);
-void gen450(stack *Stack)
+void gen451(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 4767 "runtime.in"
+#line 4783 "runtime.in"
if(n < 0) n=0;
array *a=new array(n);
for(Int i=0; i < n; ++i) {
@@ -6802,12 +6823,12 @@ void gen450(stack *Stack)
}
// Apply a function to each element of an array
-#line 4777 "runtime.in"
+#line 4793 "runtime.in"
void arrayFunction(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
callable * f=vm::pop<callable *>(Stack);
-#line 4778 "runtime.in"
+#line 4794 "runtime.in"
size_t size=checkArray(a);
array *b=new array(size);
for(size_t i=0; i < size; ++i) {
@@ -6818,12 +6839,12 @@ void arrayFunction(stack *Stack)
{Stack->push<array*>(b); return;}
}
-#line 4789 "runtime.in"
+#line 4805 "runtime.in"
void arraySort(stack *Stack)
{
callable * f=vm::pop<callable *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4790 "runtime.in"
+#line 4806 "runtime.in"
array *c=copyArray(a);
compareFunc=f;
FuncStack=Stack;
@@ -6831,12 +6852,12 @@ void arraySort(stack *Stack)
{Stack->push<array*>(c); return;}
}
-#line 4798 "runtime.in"
+#line 4814 "runtime.in"
// bool all(boolarray *a);
-void gen453(stack *Stack)
+void gen454(stack *Stack)
{
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 4799 "runtime.in"
+#line 4815 "runtime.in"
size_t size=checkArray(a);
bool c=true;
for(size_t i=0; i < size; i++)
@@ -6844,12 +6865,12 @@ void gen453(stack *Stack)
{Stack->push<bool>(c); return;}
}
-#line 4807 "runtime.in"
+#line 4823 "runtime.in"
// boolarray* !(boolarray* a);
-void gen454(stack *Stack)
+void gen455(stack *Stack)
{
boolarray* a=vm::pop<boolarray*>(Stack);
-#line 4808 "runtime.in"
+#line 4824 "runtime.in"
size_t size=checkArray(a);
array *c=new array(size);
for(size_t i=0; i < size; i++)
@@ -6857,12 +6878,12 @@ void gen454(stack *Stack)
{Stack->push<boolarray*>(c); return;}
}
-#line 4816 "runtime.in"
+#line 4832 "runtime.in"
// Int sum(boolarray *a);
-void gen455(stack *Stack)
+void gen456(stack *Stack)
{
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 4817 "runtime.in"
+#line 4833 "runtime.in"
size_t size=checkArray(a);
Int sum=0;
for(size_t i=0; i < size; i++)
@@ -6870,19 +6891,19 @@ void gen455(stack *Stack)
{Stack->push<Int>(sum); return;}
}
-#line 4825 "runtime.in"
+#line 4841 "runtime.in"
void arrayCopy(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4826 "runtime.in"
+#line 4842 "runtime.in"
{Stack->push<array*>(copyArray(a)); return;}
}
-#line 4830 "runtime.in"
+#line 4846 "runtime.in"
void arrayConcat(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4831 "runtime.in"
+#line 4847 "runtime.in"
// a is an array of arrays to be concatenated together.
// The signature is
// T[] concat(... T[][] a);
@@ -6909,27 +6930,27 @@ void arrayConcat(stack *Stack)
{Stack->push<array*>(result); return;}
}
-#line 4858 "runtime.in"
+#line 4874 "runtime.in"
void array2Copy(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4859 "runtime.in"
+#line 4875 "runtime.in"
{Stack->push<array*>(copyArray2(a)); return;}
}
-#line 4863 "runtime.in"
+#line 4879 "runtime.in"
void array3Copy(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4864 "runtime.in"
+#line 4880 "runtime.in"
{Stack->push<array*>(copyArray3(a)); return;}
}
-#line 4868 "runtime.in"
+#line 4884 "runtime.in"
void array2Transpose(stack *Stack)
{
array * a=vm::pop<array *>(Stack);
-#line 4869 "runtime.in"
+#line 4885 "runtime.in"
size_t asize=checkArray(a);
array *c=new array(0);
for(size_t i=0; i < asize; i++) {
@@ -6956,12 +6977,12 @@ void array2Transpose(stack *Stack)
// permutation (021 or 120, etc; original is 012).
// Transpose by sending respective members to the permutated locations:
// return the array obtained by putting a[i][j][k] into position perm{ijk}.
-#line 4896 "runtime.in"
+#line 4912 "runtime.in"
void array3Transpose(stack *Stack)
{
array * perm=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 4897 "runtime.in"
+#line 4913 "runtime.in"
const size_t DIM=3;
if(checkArray(perm) != DIM) {
@@ -7045,13 +7066,13 @@ void array3Transpose(stack *Stack)
// In a boolean array, find the index of the nth true value or -1 if not found
// If n is negative, search backwards.
-#line 4981 "runtime.in"
+#line 4997 "runtime.in"
// Int find(boolarray *a, Int n=1);
-void gen462(stack *Stack)
+void gen463(stack *Stack)
{
Int n=vm::pop<Int>(Stack,1);
boolarray * a=vm::pop<boolarray *>(Stack);
-#line 4982 "runtime.in"
+#line 4998 "runtime.in"
size_t size=checkArray(a);
Int j=-1;
@@ -7068,13 +7089,13 @@ void gen462(stack *Stack)
{Stack->push<Int>(j); return;}
}
-#line 4999 "runtime.in"
+#line 5015 "runtime.in"
// bool ==(realarray2 *a, realarray2 *b);
-void gen463(stack *Stack)
+void gen464(stack *Stack)
{
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5000 "runtime.in"
+#line 5016 "runtime.in"
size_t n=checkArray(a);
if(n != checkArray(b)) {Stack->push<bool>(false); return;}
@@ -7094,13 +7115,13 @@ void gen463(stack *Stack)
// construct vector obtained by replacing those elements of b for which the
// corresponding elements of a are false by the corresponding element of c.
-#line 5020 "runtime.in"
+#line 5036 "runtime.in"
void arrayConditional(stack *Stack)
{
array * c=vm::pop<array *>(Stack);
array * b=vm::pop<array *>(Stack);
array * a=vm::pop<array *>(Stack);
-#line 5021 "runtime.in"
+#line 5037 "runtime.in"
size_t size=checkArray(a);
array *r=new array(size);
if(b && c) {
@@ -7124,21 +7145,21 @@ void arrayConditional(stack *Stack)
}
// Return an n x n identity matrix.
-#line 5045 "runtime.in"
+#line 5061 "runtime.in"
// realarray2* identity(Int n);
-void gen465(stack *Stack)
+void gen466(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 5046 "runtime.in"
+#line 5062 "runtime.in"
{Stack->push<realarray2*>(Identity(n)); return;}
}
// Return the diagonal matrix with diagonal entries given by a.
-#line 5051 "runtime.in"
+#line 5067 "runtime.in"
void diagonal(stack *Stack)
{
realarray * a=vm::pop<realarray *>(Stack);
-#line 5052 "runtime.in"
+#line 5068 "runtime.in"
size_t n=checkArray(a);
array *c=new array(n);
for(size_t i=0; i < n; ++i) {
@@ -7154,12 +7175,12 @@ void diagonal(stack *Stack)
}
// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
-#line 5068 "runtime.in"
+#line 5084 "runtime.in"
// realarray2* inverse(realarray2 *a);
-void gen467(stack *Stack)
+void gen468(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5069 "runtime.in"
+#line 5085 "runtime.in"
a=copyArray2(a);
size_t n=checkArray(a);
checkSquare(a);
@@ -7252,14 +7273,14 @@ void gen467(stack *Stack)
// Solve the linear equation ax=b by LU decomposition, returning the
// solution x, where a is an n x n matrix and b is an array of length n.
// If no solution exists, return an empty array.
-#line 5162 "runtime.in"
+#line 5178 "runtime.in"
// realarray* solve(realarray2 *a, realarray *b, bool warn=true);
-void gen468(stack *Stack)
+void gen469(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
realarray * b=vm::pop<realarray *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5163 "runtime.in"
+#line 5179 "runtime.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<realarray*>(new array(0)); return;}
@@ -7309,14 +7330,14 @@ void gen468(stack *Stack)
// Solve the linear equation ax=b by LU decomposition, returning the
// solution x, where a is an n x n matrix and b is an n x m matrix.
// If no solution exists, return an empty array.
-#line 5213 "runtime.in"
+#line 5229 "runtime.in"
// realarray2* solve(realarray2 *a, realarray2 *b, bool warn=true);
-void gen469(stack *Stack)
+void gen470(stack *Stack)
{
bool warn=vm::pop<bool>(Stack,true);
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5214 "runtime.in"
+#line 5230 "runtime.in"
size_t n=checkArray(a);
if(n == 0) {Stack->push<realarray2*>(new array(0)); return;}
@@ -7377,12 +7398,12 @@ void gen469(stack *Stack)
}
// Compute the determinant of an n x n matrix.
-#line 5275 "runtime.in"
+#line 5291 "runtime.in"
// real determinant(realarray2 *a);
-void gen470(stack *Stack)
+void gen471(stack *Stack)
{
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5276 "runtime.in"
+#line 5292 "runtime.in"
real *A=copyArray2C(a);
size_t n=checkArray(a);
@@ -7396,13 +7417,13 @@ void gen470(stack *Stack)
{Stack->push<real>(det); return;}
}
-#line 5290 "runtime.in"
+#line 5306 "runtime.in"
// realarray* *(realarray2 *a, realarray *b);
-void gen471(stack *Stack)
+void gen472(stack *Stack)
{
realarray * b=vm::pop<realarray *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5291 "runtime.in"
+#line 5307 "runtime.in"
size_t n=checkArray(a);
size_t m=checkArray(b);
array *c=new array(n);
@@ -7419,13 +7440,13 @@ void gen471(stack *Stack)
{Stack->push<realarray*>(c); return;}
}
-#line 5308 "runtime.in"
+#line 5324 "runtime.in"
// realarray2* *(realarray2 *a, realarray2 *b);
-void gen472(stack *Stack)
+void gen473(stack *Stack)
{
realarray2 * b=vm::pop<realarray2 *>(Stack);
realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 5309 "runtime.in"
+#line 5325 "runtime.in"
size_t n=checkArray(a);
size_t nb=checkArray(b);
@@ -7459,23 +7480,23 @@ void gen472(stack *Stack)
{Stack->push<realarray2*>(c); return;}
}
-#line 5343 "runtime.in"
+#line 5359 "runtime.in"
// triple *(realarray2 *t, triple v);
-void gen473(stack *Stack)
+void gen474(stack *Stack)
{
triple v=vm::pop<triple>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 5344 "runtime.in"
+#line 5360 "runtime.in"
{Stack->push<triple>(*t*v); return;}
}
-#line 5348 "runtime.in"
+#line 5364 "runtime.in"
// pair project(triple v, realarray2 *t);
-void gen474(stack *Stack)
+void gen475(stack *Stack)
{
realarray2 * t=vm::pop<realarray2 *>(Stack);
triple v=vm::pop<triple>(Stack);
-#line 5349 "runtime.in"
+#line 5365 "runtime.in"
size_t n=checkArray(t);
if(n != 4) error(incommensurate);
array *t0=read<array*>(t,0);
@@ -7500,13 +7521,13 @@ void gen474(stack *Stack)
}
// Compute the dot product of vectors a and b.
-#line 5374 "runtime.in"
+#line 5390 "runtime.in"
// real dot(realarray *a, realarray *b);
-void gen475(stack *Stack)
+void gen476(stack *Stack)
{
realarray * b=vm::pop<realarray *>(Stack);
realarray * a=vm::pop<realarray *>(Stack);
-#line 5375 "runtime.in"
+#line 5391 "runtime.in"
size_t n=checkArrays(a,b);
real sum=0.0;
for(size_t i=0; i < n; ++i)
@@ -7521,15 +7542,15 @@ void gen475(stack *Stack)
// [ a[2] b[2] c[2] ]
// [ ... ]
// [ c[n-1] a[n-1] b[n-1] ]
-#line 5390 "runtime.in"
+#line 5406 "runtime.in"
// realarray* tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f);
-void gen476(stack *Stack)
+void gen477(stack *Stack)
{
realarray * f=vm::pop<realarray *>(Stack);
realarray * c=vm::pop<realarray *>(Stack);
realarray * b=vm::pop<realarray *>(Stack);
realarray * a=vm::pop<realarray *>(Stack);
-#line 5391 "runtime.in"
+#line 5407 "runtime.in"
size_t n=checkArrays(a,b);
checkEqual(n,checkArray(c));
checkEqual(n,checkArray(f));
@@ -7626,16 +7647,16 @@ void gen476(stack *Stack)
}
// Root solve by Newton-Raphson
-#line 5488 "runtime.in"
+#line 5504 "runtime.in"
// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x, bool verbose=false);
-void gen477(stack *Stack)
+void gen478(stack *Stack)
{
bool verbose=vm::pop<bool>(Stack,false);
real x=vm::pop<real>(Stack);
callableReal * fprime=vm::pop<callableReal *>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
Int iterations=vm::pop<Int>(Stack,100);
-#line 5490 "runtime.in"
+#line 5506 "runtime.in"
static const real fuzz=1000.0*DBL_EPSILON;
Int i=0;
size_t oldPrec=0;
@@ -7681,9 +7702,9 @@ void gen477(stack *Stack)
// Root solve by Newton-Raphson bisection
// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
-#line 5536 "runtime.in"
+#line 5552 "runtime.in"
// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1, real x2, bool verbose=false);
-void gen478(stack *Stack)
+void gen479(stack *Stack)
{
bool verbose=vm::pop<bool>(Stack,false);
real x2=vm::pop<real>(Stack);
@@ -7691,7 +7712,7 @@ void gen478(stack *Stack)
callableReal * fprime=vm::pop<callableReal *>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
Int iterations=vm::pop<Int>(Stack,100);
-#line 5538 "runtime.in"
+#line 5554 "runtime.in"
static const real fuzz=1000.0*DBL_EPSILON;
size_t oldPrec=0;
if(verbose)
@@ -7769,16 +7790,16 @@ void gen478(stack *Stack)
{Stack->push<real>((j == iterations) ? DBL_MAX : x); return;}
}
-#line 5616 "runtime.in"
+#line 5632 "runtime.in"
// real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON, real dxmax=0);
-void gen479(stack *Stack)
+void gen480(stack *Stack)
{
real dxmax=vm::pop<real>(Stack,0);
real acc=vm::pop<real>(Stack,DBL_EPSILON);
real b=vm::pop<real>(Stack);
real a=vm::pop<real>(Stack);
callableReal * f=vm::pop<callableReal *>(Stack);
-#line 5618 "runtime.in"
+#line 5634 "runtime.in"
real integral;
if(dxmax == 0) dxmax=b-a;
Func=f;
@@ -7789,12 +7810,12 @@ void gen479(stack *Stack)
}
// Compute the fast Fourier transform of a pair array
-#line 5629 "runtime.in"
+#line 5645 "runtime.in"
void pairArrayFFT(stack *Stack)
{
Int sign=vm::pop<Int>(Stack,1);
pairarray * a=vm::pop<pairarray *>(Stack);
-#line 5630 "runtime.in"
+#line 5646 "runtime.in"
unsigned n=(unsigned) checkArray(a);
#ifdef HAVE_LIBFFTW3
array *c=new array(n);
@@ -7822,12 +7843,12 @@ void pairArrayFFT(stack *Stack)
{Stack->push<pairarray*>(c); return;}
}
-#line 5658 "runtime.in"
+#line 5674 "runtime.in"
// Intarray2* triangulate(pairarray *z);
-void gen481(stack *Stack)
+void gen482(stack *Stack)
{
pairarray * z=vm::pop<pairarray *>(Stack);
-#line 5659 "runtime.in"
+#line 5675 "runtime.in"
size_t nv=checkArray(z);
// Call robust version of Gilles Dumoulin's port of Paul Bourke's
// triangulation code.
@@ -7863,55 +7884,55 @@ void gen481(stack *Stack)
// File operations
-#line 5695 "runtime.in"
+#line 5711 "runtime.in"
// bool ==(file *a, file *b);
-void gen482(stack *Stack)
+void gen483(stack *Stack)
{
file * b=vm::pop<file *>(Stack);
file * a=vm::pop<file *>(Stack);
-#line 5696 "runtime.in"
+#line 5712 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 5701 "runtime.in"
+#line 5717 "runtime.in"
// bool !=(file *a, file *b);
-void gen483(stack *Stack)
+void gen484(stack *Stack)
{
file * b=vm::pop<file *>(Stack);
file * a=vm::pop<file *>(Stack);
-#line 5702 "runtime.in"
+#line 5718 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 5706 "runtime.in"
+#line 5722 "runtime.in"
void nullFile(stack *Stack)
{
-#line 5707 "runtime.in"
+#line 5723 "runtime.in"
{Stack->push<file*>(&camp::nullfile); return;}
}
-#line 5711 "runtime.in"
+#line 5727 "runtime.in"
// file* input(string name, bool check=true, string comment=commentchar);
-void gen485(stack *Stack)
+void gen486(stack *Stack)
{
string comment=vm::pop<string>(Stack,commentchar);
bool check=vm::pop<bool>(Stack,true);
string name=vm::pop<string>(Stack);
-#line 5712 "runtime.in"
+#line 5728 "runtime.in"
char c=comment.empty() ? (char) 0 : comment[0];
file *f=new ifile(name,c,check);
f->open();
{Stack->push<file*>(f); return;}
}
-#line 5719 "runtime.in"
+#line 5735 "runtime.in"
// file* output(string name, bool update=false, string comment=commentchar);
-void gen486(stack *Stack)
+void gen487(stack *Stack)
{
string comment=vm::pop<string>(Stack,commentchar);
bool update=vm::pop<bool>(Stack,false);
string name=vm::pop<string>(Stack);
-#line 5720 "runtime.in"
+#line 5736 "runtime.in"
file *f;
if(update) {
char c=comment.empty() ? (char) 0 : comment[0];
@@ -7922,13 +7943,13 @@ void gen486(stack *Stack)
{Stack->push<file*>(f); return;}
}
-#line 5731 "runtime.in"
+#line 5747 "runtime.in"
// file* xinput(string name, bool check=true);
-void gen487(stack *Stack)
+void gen488(stack *Stack)
{
bool check=vm::pop<bool>(Stack,true);
string name=vm::pop<string>(Stack);
-#line 5732 "runtime.in"
+#line 5748 "runtime.in"
#ifdef HAVE_RPC_RPC_H
file *f=new ixfile(name,check);
f->open();
@@ -7941,13 +7962,13 @@ void gen487(stack *Stack)
#endif
}
-#line 5745 "runtime.in"
+#line 5761 "runtime.in"
// file* xoutput(string name, bool update=false);
-void gen488(stack *Stack)
+void gen489(stack *Stack)
{
bool update=vm::pop<bool>(Stack,false);
string name=vm::pop<string>(Stack);
-#line 5746 "runtime.in"
+#line 5762 "runtime.in"
#ifdef HAVE_RPC_RPC_H
file *f;
if(update)
@@ -7964,25 +7985,25 @@ void gen488(stack *Stack)
#endif
}
-#line 5763 "runtime.in"
+#line 5779 "runtime.in"
// file* binput(string name, bool check=true);
-void gen489(stack *Stack)
+void gen490(stack *Stack)
{
bool check=vm::pop<bool>(Stack,true);
string name=vm::pop<string>(Stack);
-#line 5764 "runtime.in"
+#line 5780 "runtime.in"
file *f=new ibfile(name,check);
f->open();
{Stack->push<file*>(f); return;}
}
-#line 5770 "runtime.in"
+#line 5786 "runtime.in"
// file* boutput(string name, bool update=false);
-void gen490(stack *Stack)
+void gen491(stack *Stack)
{
bool update=vm::pop<bool>(Stack,false);
string name=vm::pop<string>(Stack);
-#line 5771 "runtime.in"
+#line 5787 "runtime.in"
file *f;
if(update) f=new iobfile(name);
else f=new obfile(name);
@@ -7991,77 +8012,77 @@ void gen490(stack *Stack)
{Stack->push<file*>(f); return;}
}
-#line 5780 "runtime.in"
+#line 5796 "runtime.in"
// bool eof(file *File);
-void gen491(stack *Stack)
+void gen492(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5781 "runtime.in"
+#line 5797 "runtime.in"
{Stack->push<bool>(File->eof()); return;}
}
-#line 5785 "runtime.in"
+#line 5801 "runtime.in"
// bool eol(file *File);
-void gen492(stack *Stack)
+void gen493(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5786 "runtime.in"
+#line 5802 "runtime.in"
{Stack->push<bool>(File->eol()); return;}
}
-#line 5790 "runtime.in"
+#line 5806 "runtime.in"
// bool error(file *File);
-void gen493(stack *Stack)
+void gen494(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5791 "runtime.in"
+#line 5807 "runtime.in"
{Stack->push<bool>(File->error()); return;}
}
-#line 5795 "runtime.in"
+#line 5811 "runtime.in"
// void clear(file *File);
-void gen494(stack *Stack)
+void gen495(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5796 "runtime.in"
+#line 5812 "runtime.in"
File->clear();
}
-#line 5800 "runtime.in"
+#line 5816 "runtime.in"
// void close(file *File);
-void gen495(stack *Stack)
+void gen496(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5801 "runtime.in"
+#line 5817 "runtime.in"
File->close();
}
-#line 5805 "runtime.in"
+#line 5821 "runtime.in"
// Int precision(file *File=NULL, Int digits=0);
-void gen496(stack *Stack)
+void gen497(stack *Stack)
{
Int digits=vm::pop<Int>(Stack,0);
file * File=vm::pop<file *>(Stack,NULL);
-#line 5806 "runtime.in"
+#line 5822 "runtime.in"
if(File == 0) File=&camp::Stdout;
{Stack->push<Int>(File->precision(digits)); return;}
}
-#line 5811 "runtime.in"
+#line 5827 "runtime.in"
// void flush(file *File);
-void gen497(stack *Stack)
+void gen498(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5812 "runtime.in"
+#line 5828 "runtime.in"
File->flush();
}
-#line 5816 "runtime.in"
+#line 5832 "runtime.in"
// string getc(file *File);
-void gen498(stack *Stack)
+void gen499(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5817 "runtime.in"
+#line 5833 "runtime.in"
char c=0;
if(File->isOpen()) File->read(c);
static char str[1];
@@ -8069,189 +8090,189 @@ void gen498(stack *Stack)
{Stack->push<string>(string(str)); return;}
}
-#line 5825 "runtime.in"
+#line 5841 "runtime.in"
// Int tell(file *File);
-void gen499(stack *Stack)
+void gen500(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5826 "runtime.in"
+#line 5842 "runtime.in"
{Stack->push<Int>(File->tell()); return;}
}
-#line 5830 "runtime.in"
+#line 5846 "runtime.in"
// void seek(file *File, Int pos);
-void gen500(stack *Stack)
+void gen501(stack *Stack)
{
Int pos=vm::pop<Int>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5831 "runtime.in"
+#line 5847 "runtime.in"
File->seek(pos,pos >= 0);
}
-#line 5835 "runtime.in"
+#line 5851 "runtime.in"
// void seekeof(file *File);
-void gen501(stack *Stack)
+void gen502(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5836 "runtime.in"
+#line 5852 "runtime.in"
File->seek(0,false);
}
// Set file dimensions
-#line 5841 "runtime.in"
+#line 5857 "runtime.in"
// file* dimension(file *File, Int nx);
-void gen502(stack *Stack)
+void gen503(stack *Stack)
{
Int nx=vm::pop<Int>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5842 "runtime.in"
+#line 5858 "runtime.in"
File->dimension(nx);
{Stack->push<file*>(File); return;}
}
-#line 5847 "runtime.in"
+#line 5863 "runtime.in"
// file* dimension(file *File, Int nx, Int ny);
-void gen503(stack *Stack)
+void gen504(stack *Stack)
{
Int ny=vm::pop<Int>(Stack);
Int nx=vm::pop<Int>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5848 "runtime.in"
+#line 5864 "runtime.in"
File->dimension(nx,ny);
{Stack->push<file*>(File); return;}
}
-#line 5853 "runtime.in"
+#line 5869 "runtime.in"
// file* dimension(file *File, Int nx, Int ny, Int nz);
-void gen504(stack *Stack)
+void gen505(stack *Stack)
{
Int nz=vm::pop<Int>(Stack);
Int ny=vm::pop<Int>(Stack);
Int nx=vm::pop<Int>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5854 "runtime.in"
+#line 5870 "runtime.in"
File->dimension(nx,ny,nz);
{Stack->push<file*>(File); return;}
}
// Set file to read comma-separated values
-#line 5860 "runtime.in"
+#line 5876 "runtime.in"
// file* csv(file *File, bool b=true);
-void gen505(stack *Stack)
+void gen506(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
file * File=vm::pop<file *>(Stack);
-#line 5861 "runtime.in"
+#line 5877 "runtime.in"
File->CSVMode(b);
{Stack->push<file*>(File); return;}
}
// Set file to read whitespace-separated values
-#line 5867 "runtime.in"
+#line 5883 "runtime.in"
// file* word(file *File, bool b=true);
-void gen506(stack *Stack)
+void gen507(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
file * File=vm::pop<file *>(Stack);
-#line 5868 "runtime.in"
+#line 5884 "runtime.in"
File->WordMode(b);
{Stack->push<file*>(File); return;}
}
// Set file to read arrays in line-at-a-time mode
-#line 5874 "runtime.in"
+#line 5890 "runtime.in"
// file* line(file *File, bool b=true);
-void gen507(stack *Stack)
+void gen508(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
file * File=vm::pop<file *>(Stack);
-#line 5875 "runtime.in"
+#line 5891 "runtime.in"
File->LineMode(b);
{Stack->push<file*>(File); return;}
}
// Set file to read/write single-precision XDR values.
-#line 5881 "runtime.in"
+#line 5897 "runtime.in"
// file* single(file *File, bool b=true);
-void gen508(stack *Stack)
+void gen509(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
file * File=vm::pop<file *>(Stack);
-#line 5882 "runtime.in"
+#line 5898 "runtime.in"
File->SingleReal(b);
File->SingleInt(b);
{Stack->push<file*>(File); return;}
}
// Set file to read/write single-precision real XDR values.
-#line 5889 "runtime.in"
+#line 5905 "runtime.in"
// file* single(file *File, real x, bool b=true);
-void gen509(stack *Stack)
+void gen510(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
real x=vm::pop<real>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5890 "runtime.in"
+#line 5906 "runtime.in"
File->SingleReal(b);
unused(&x);
{Stack->push<file*>(File); return;}
}
// Set file to read/write single-precision int XDR values.
-#line 5897 "runtime.in"
+#line 5913 "runtime.in"
// file* single(file *File, Int x, bool b=true);
-void gen510(stack *Stack)
+void gen511(stack *Stack)
{
bool b=vm::pop<bool>(Stack,true);
Int x=vm::pop<Int>(Stack);
file * File=vm::pop<file *>(Stack);
-#line 5898 "runtime.in"
+#line 5914 "runtime.in"
File->SingleInt(b);
unused(&x);
{Stack->push<file*>(File); return;}
}
// Set file to read an array1 (1 Int size followed by a 1d array)
-#line 5905 "runtime.in"
+#line 5921 "runtime.in"
// file* read1(file *File);
-void gen511(stack *Stack)
+void gen512(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5906 "runtime.in"
+#line 5922 "runtime.in"
File->dimension(-2);
{Stack->push<file*>(File); return;}
}
// Set file to read an array2 (2 Int sizes followed by a 2d array)
-#line 5912 "runtime.in"
+#line 5928 "runtime.in"
// file* read2(file *File);
-void gen512(stack *Stack)
+void gen513(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5913 "runtime.in"
+#line 5929 "runtime.in"
File->dimension(-2,-2);
{Stack->push<file*>(File); return;}
}
// Set file to read an array3 (3 Int sizes followed by a 3d array)
-#line 5919 "runtime.in"
+#line 5935 "runtime.in"
// file* read3(file *File);
-void gen513(stack *Stack)
+void gen514(stack *Stack)
{
file * File=vm::pop<file *>(Stack);
-#line 5920 "runtime.in"
+#line 5936 "runtime.in"
File->dimension(-2,-2,-2);
{Stack->push<file*>(File); return;}
}
// Return the last n lines of the history named name.
-#line 5926 "runtime.in"
+#line 5942 "runtime.in"
// stringarray* history(string name, Int n=1);
-void gen514(stack *Stack)
+void gen515(stack *Stack)
{
Int n=vm::pop<Int>(Stack,1);
string name=vm::pop<string>(Stack);
-#line 5927 "runtime.in"
+#line 5943 "runtime.in"
#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
bool newhistory=historyMap.find(name) == historyMap.end();
@@ -8283,12 +8304,12 @@ void gen514(stack *Stack)
}
// Return the last n lines of the interactive history.
-#line 5959 "runtime.in"
+#line 5975 "runtime.in"
// stringarray* history(Int n=0);
-void gen515(stack *Stack)
+void gen516(stack *Stack)
{
Int n=vm::pop<Int>(Stack,0);
-#line 5960 "runtime.in"
+#line 5976 "runtime.in"
#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
{Stack->push<stringarray*>(get_history(n)); return;}
#else
@@ -8299,14 +8320,14 @@ void gen515(stack *Stack)
// Prompt for a string using prompt, the GNU readline library, and a
// local history named name.
-#line 5971 "runtime.in"
+#line 5987 "runtime.in"
// string readline(string prompt=emptystring, string name=emptystring, bool tabcompletion=false);
-void gen516(stack *Stack)
+void gen517(stack *Stack)
{
bool tabcompletion=vm::pop<bool>(Stack,false);
string name=vm::pop<string>(Stack,emptystring);
string prompt=vm::pop<string>(Stack,emptystring);
-#line 5973 "runtime.in"
+#line 5989 "runtime.in"
if(!isatty(STDIN_FILENO))
{Stack->push<string>(emptystring); return;}
#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
@@ -8348,14 +8369,14 @@ void gen516(stack *Stack)
// Save a string in a local history named name.
// If store=true, store the local history in the file historyfilename(name).
-#line 6015 "runtime.in"
+#line 6031 "runtime.in"
// void saveline(string name, string value, bool store=true);
-void gen517(stack *Stack)
+void gen518(stack *Stack)
{
bool store=vm::pop<bool>(Stack,true);
string value=vm::pop<string>(Stack);
string name=vm::pop<string>(Stack);
-#line 6016 "runtime.in"
+#line 6032 "runtime.in"
#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
store_history(&history_save);
bool newhistory=historyMap.find(name) == historyMap.end();
@@ -8382,11 +8403,11 @@ void gen517(stack *Stack)
#endif
}
-#line 6043 "runtime.in"
+#line 6059 "runtime.in"
// void generate_random_backtrace();
-void gen518(stack *)
+void gen519(stack *)
{
-#line 6044 "runtime.in"
+#line 6060 "runtime.in"
#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
GC_generate_random_backtrace();
#else
@@ -8394,12 +8415,12 @@ void gen518(stack *)
#endif
}
-#line 6052 "runtime.in"
+#line 6068 "runtime.in"
// void print_random_addresses(Int n=1);
-void gen519(stack *Stack)
+void gen520(stack *Stack)
{
Int n=vm::pop<Int>(Stack,1);
-#line 6053 "runtime.in"
+#line 6069 "runtime.in"
#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
GC_gcollect();
for (Int i=0; i < n; ++i)
@@ -8416,876 +8437,878 @@ namespace trans {
void gen_base_venv(venv &ve)
{
-#line 1167 "runtime.in"
+#line 1177 "runtime.in"
addFunc(ve, run::gen8, primBoolean(), "!", formal(primBoolean(), "b", false, false));
-#line 1195 "runtime.in"
+#line 1205 "runtime.in"
addFunc(ve, run::gen13, primInt(), "AND", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
-#line 1203 "runtime.in"
+#line 1213 "runtime.in"
addFunc(ve, run::gen14, primInt(), "OR", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
-#line 1208 "runtime.in"
+#line 1218 "runtime.in"
addFunc(ve, run::gen15, primInt(), "XOR", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
-#line 1213 "runtime.in"
+#line 1223 "runtime.in"
addFunc(ve, run::gen16, primInt(), "NOT", formal(primInt(), "a", false, false));
-#line 1244 "runtime.in"
+#line 1254 "runtime.in"
addFunc(ve, run::gen21, primBoolean(), "empty", formal(primPicture(), "f", false, false));
-#line 1249 "runtime.in"
+#line 1259 "runtime.in"
addFunc(ve, run::gen22, primVoid(), "erase", formal(primPicture(), "f", false, false));
-#line 1254 "runtime.in"
+#line 1264 "runtime.in"
addFunc(ve, run::gen23, primPair(), "min", formal(primPicture(), "f", false, false));
-#line 1259 "runtime.in"
+#line 1269 "runtime.in"
addFunc(ve, run::gen24, primPair(), "max", formal(primPicture(), "f", false, false));
-#line 1264 "runtime.in"
+#line 1274 "runtime.in"
addFunc(ve, run::gen25, primVoid(), "label", formal(primPicture(), "f", false, false), formal(primString(), "s", false, false), formal(primString(), "size", false, false), formal(primTransform(), "t", false, false), formal(primPair(), "position", false, false), formal(primPair(), "align", false, false), formal(primPen(), "p", false, false));
-#line 1270 "runtime.in"
+#line 1280 "runtime.in"
addFunc(ve, run::gen26, primBoolean(), "labels", formal(primPicture(), "f", false, false));
-#line 1275 "runtime.in"
- addFunc(ve, run::gen27, pathArray() , "_texpath", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
-#line 1390 "runtime.in"
- addFunc(ve, run::gen28, pathArray() , "textpath", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
-#line 1462 "runtime.in"
- addFunc(ve, run::gen29, pathArray() , "_strokepath", formal(primPath(), "g", false, false), formal(primPen(), "p", true, false));
-#line 1486 "runtime.in"
- addFunc(ve, run::gen30, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath(), "g", false, false), formal(primPen(), "p", false, false));
-#line 1491 "runtime.in"
- addFunc(ve, run::gen31, primVoid(), "fill", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primPen(), "p", true, false), formal(primBoolean(), "copy", true, false));
-#line 1497 "runtime.in"
- addFunc(ve, run::gen32, primVoid(), "latticeshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(primBoolean(), "copy", true, false));
-#line 1504 "runtime.in"
- addFunc(ve, run::gen33, primVoid(), "axialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primBoolean(), "copy", true, false));
-#line 1511 "runtime.in"
- addFunc(ve, run::gen34, primVoid(), "radialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primReal(), "ra", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primReal(), "rb", false, false), formal(primBoolean(), "copy", true, false));
-#line 1518 "runtime.in"
- addFunc(ve, run::gen35, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(pairArray(), "z", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
-#line 1529 "runtime.in"
- addFunc(ve, run::gen36, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
-#line 1553 "runtime.in"
- addFunc(ve, run::gen37, primVoid(), "tensorshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(pathArray() , "b", true, false), formal(pairArray2(), "z", true, false), formal(primBoolean(), "copy", true, false));
-#line 1568 "runtime.in"
- addFunc(ve, run::gen38, primVoid(), "functionshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primString() , "shader", true, false), formal(primBoolean(), "copy", true, false));
-#line 1576 "runtime.in"
- addFunc(ve, run::gen39, primVoid(), "clip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
-#line 1586 "runtime.in"
- addFunc(ve, run::gen40, primVoid(), "beginclip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
-#line 1593 "runtime.in"
- addFunc(ve, run::gen41, primVoid(), "endclip", formal(primPicture(), "f", false, false));
-#line 1598 "runtime.in"
- addFunc(ve, run::gen42, primVoid(), "gsave", formal(primPicture(), "f", false, false));
-#line 1603 "runtime.in"
- addFunc(ve, run::gen43, primVoid(), "grestore", formal(primPicture(), "f", false, false));
-#line 1608 "runtime.in"
- addFunc(ve, run::gen44, primVoid(), "begingroup", formal(primPicture(), "f", false, false));
-#line 1613 "runtime.in"
- addFunc(ve, run::gen45, primVoid(), "endgroup", formal(primPicture(), "f", false, false));
-#line 1618 "runtime.in"
- addFunc(ve, run::gen46, primVoid(), "add", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
-#line 1623 "runtime.in"
- addFunc(ve, run::gen47, primVoid(), "prepend", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
-#line 1628 "runtime.in"
- addFunc(ve, run::gen48, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
-#line 1633 "runtime.in"
- addFunc(ve, run::gen49, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
-#line 1638 "runtime.in"
- addFunc(ve, run::gen50, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
-#line 1643 "runtime.in"
- addFunc(ve, run::gen51, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
-#line 1648 "runtime.in"
- addFunc(ve, run::gen52, primVoid(), "texpreamble", formal(primString() , "s", false, false));
-#line 1656 "runtime.in"
- addFunc(ve, run::gen53, primVoid(), "deletepreamble");
-#line 1663 "runtime.in"
- addFunc(ve, run::gen54, primVoid(), "_labelpath", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primString() , "size", false, false), formal(primPath(), "g", false, false), formal(primString() , "justify", false, false), formal(primPair(), "offset", false, false), formal(primPen(), "p", false, false));
-#line 1669 "runtime.in"
- addFunc(ve, run::gen55, primVoid(), "texreset");
-#line 1677 "runtime.in"
- addFunc(ve, run::gen56, primVoid(), "layer", formal(primPicture(), "f", false, false));
-#line 1682 "runtime.in"
- addFunc(ve, run::gen57, primVoid(), "newpage", formal(primPicture(), "f", false, false));
-#line 1687 "runtime.in"
- addFunc(ve, run::gen58, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(realArray2(), "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(penArray() , "palette", true, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
-#line 1697 "runtime.in"
- addFunc(ve, run::gen59, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(penArray2() , "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
-#line 1704 "runtime.in"
- addFunc(ve, run::gen60, primString() , "nativeformat");
-#line 1709 "runtime.in"
- addFunc(ve, run::gen61, primBoolean(), "latex");
-#line 1714 "runtime.in"
- addFunc(ve, run::gen62, primBoolean(), "pdf");
-#line 1719 "runtime.in"
- addFunc(ve, run::gen63, primVoid(), "shipout", formal(primString() , "prefix", true, false), formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primString() , "format", true, false), formal(primBoolean(), "wait", true, false), formal(primBoolean(), "view", true, false), formal(transformFunction(), "xform", false, false));
-#line 1765 "runtime.in"
- addFunc(ve, run::gen64, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false), formal(primString() , "format", true, false), formal(primReal(), "width", false, false), formal(primReal(), "height", false, false), formal(primReal(), "angle", false, false), formal(primTriple(), "m", false, false), formal(primTriple(), "m", false, false), formal(realArray2(), "t", false, false), formal(realArray(), "background", false, false), formal(tripleArray(), "lights", false, false), formal(realArray2(), "diffuse", false, false), formal(realArray2(), "ambient", false, false), formal(realArray2(), "specular", false, false), formal(primBoolean(), "viewportlighting", false, false), formal(primBoolean(), "view", true, false));
+#line 1285 "runtime.in"
+ addFunc(ve, run::gen27, realArray(), "texsize", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
+#line 1305 "runtime.in"
+ addFunc(ve, run::gen28, pathArray() , "_texpath", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
+#line 1413 "runtime.in"
+ addFunc(ve, run::gen29, pathArray() , "textpath", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
+#line 1477 "runtime.in"
+ addFunc(ve, run::gen30, pathArray() , "_strokepath", formal(primPath(), "g", false, false), formal(primPen(), "p", true, false));
+#line 1502 "runtime.in"
+ addFunc(ve, run::gen31, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath(), "g", false, false), formal(primPen(), "p", false, false));
+#line 1507 "runtime.in"
+ addFunc(ve, run::gen32, primVoid(), "fill", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primPen(), "p", true, false), formal(primBoolean(), "copy", true, false));
+#line 1513 "runtime.in"
+ addFunc(ve, run::gen33, primVoid(), "latticeshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(primBoolean(), "copy", true, false));
+#line 1520 "runtime.in"
+ addFunc(ve, run::gen34, primVoid(), "axialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primBoolean(), "copy", true, false));
+#line 1527 "runtime.in"
+ addFunc(ve, run::gen35, primVoid(), "radialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primReal(), "ra", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primReal(), "rb", false, false), formal(primBoolean(), "copy", true, false));
+#line 1534 "runtime.in"
+ addFunc(ve, run::gen36, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(pairArray(), "z", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
+#line 1545 "runtime.in"
+ addFunc(ve, run::gen37, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
+#line 1569 "runtime.in"
+ addFunc(ve, run::gen38, primVoid(), "tensorshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(pathArray() , "b", true, false), formal(pairArray2(), "z", true, false), formal(primBoolean(), "copy", true, false));
+#line 1584 "runtime.in"
+ addFunc(ve, run::gen39, primVoid(), "functionshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primString() , "shader", true, false), formal(primBoolean(), "copy", true, false));
+#line 1592 "runtime.in"
+ addFunc(ve, run::gen40, primVoid(), "clip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
+#line 1602 "runtime.in"
+ addFunc(ve, run::gen41, primVoid(), "beginclip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
+#line 1609 "runtime.in"
+ addFunc(ve, run::gen42, primVoid(), "endclip", formal(primPicture(), "f", false, false));
+#line 1614 "runtime.in"
+ addFunc(ve, run::gen43, primVoid(), "gsave", formal(primPicture(), "f", false, false));
+#line 1619 "runtime.in"
+ addFunc(ve, run::gen44, primVoid(), "grestore", formal(primPicture(), "f", false, false));
+#line 1624 "runtime.in"
+ addFunc(ve, run::gen45, primVoid(), "begingroup", formal(primPicture(), "f", false, false));
+#line 1629 "runtime.in"
+ addFunc(ve, run::gen46, primVoid(), "endgroup", formal(primPicture(), "f", false, false));
+#line 1634 "runtime.in"
+ addFunc(ve, run::gen47, primVoid(), "add", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
+#line 1639 "runtime.in"
+ addFunc(ve, run::gen48, primVoid(), "prepend", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
+#line 1644 "runtime.in"
+ addFunc(ve, run::gen49, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
+#line 1649 "runtime.in"
+ addFunc(ve, run::gen50, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
+#line 1654 "runtime.in"
+ addFunc(ve, run::gen51, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
+#line 1659 "runtime.in"
+ addFunc(ve, run::gen52, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
+#line 1664 "runtime.in"
+ addFunc(ve, run::gen53, primVoid(), "texpreamble", formal(primString() , "s", false, false));
+#line 1672 "runtime.in"
+ addFunc(ve, run::gen54, primVoid(), "deletepreamble");
+#line 1679 "runtime.in"
+ addFunc(ve, run::gen55, primVoid(), "_labelpath", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primString() , "size", false, false), formal(primPath(), "g", false, false), formal(primString() , "justify", false, false), formal(primPair(), "offset", false, false), formal(primPen(), "p", false, false));
+#line 1685 "runtime.in"
+ addFunc(ve, run::gen56, primVoid(), "texreset");
+#line 1693 "runtime.in"
+ addFunc(ve, run::gen57, primVoid(), "layer", formal(primPicture(), "f", false, false));
+#line 1698 "runtime.in"
+ addFunc(ve, run::gen58, primVoid(), "newpage", formal(primPicture(), "f", false, false));
+#line 1703 "runtime.in"
+ addFunc(ve, run::gen59, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(realArray2(), "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(penArray() , "palette", true, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
+#line 1713 "runtime.in"
+ addFunc(ve, run::gen60, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(penArray2() , "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
+#line 1720 "runtime.in"
+ addFunc(ve, run::gen61, primString() , "nativeformat");
+#line 1725 "runtime.in"
+ addFunc(ve, run::gen62, primBoolean(), "latex");
+#line 1730 "runtime.in"
+ addFunc(ve, run::gen63, primBoolean(), "pdf");
+#line 1735 "runtime.in"
+ addFunc(ve, run::gen64, primVoid(), "shipout", formal(primString() , "prefix", true, false), formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primString() , "format", true, false), formal(primBoolean(), "wait", true, false), formal(primBoolean(), "view", true, false), formal(transformFunction(), "xform", false, false));
#line 1781 "runtime.in"
- addFunc(ve, run::gen65, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false));
-#line 1786 "runtime.in"
- addFunc(ve, run::gen66, primVoid(), "deconstruct", formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primReal(), "magnification", true, false), formal(transformFunction(), "xform", false, false));
-#line 1919 "runtime.in"
- addFunc(ve, run::gen67, primVoid(), "purge", formal(primInt(), "divisor", true, false));
-#line 1932 "runtime.in"
- addFunc(ve, run::gen69, primBoolean(), "==", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
-#line 1937 "runtime.in"
- addFunc(ve, run::gen70, primBoolean(), "!=", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
-#line 1942 "runtime.in"
- addFunc(ve, run::gen71, primPen(), "+", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
-#line 1947 "runtime.in"
- addFunc(ve, run::gen72, primPen(), "*", formal(primReal(), "a", false, false), formal(primPen(), "b", false, false));
-#line 1952 "runtime.in"
- addFunc(ve, run::gen73, primPen(), "*", formal(primPen(), "a", false, false), formal(primReal(), "b", false, false));
-#line 1957 "runtime.in"
- addFunc(ve, run::gen74, primPair(), "max", formal(primPen(), "p", false, false));
-#line 1962 "runtime.in"
- addFunc(ve, run::gen75, primPair(), "min", formal(primPen(), "p", false, false));
-#line 1967 "runtime.in"
- addFunc(ve, run::gen76, primVoid(), "resetdefaultpen");
+ addFunc(ve, run::gen65, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false), formal(primString() , "format", true, false), formal(primReal(), "width", false, false), formal(primReal(), "height", false, false), formal(primReal(), "angle", false, false), formal(primTriple(), "m", false, false), formal(primTriple(), "m", false, false), formal(realArray2(), "t", false, false), formal(realArray(), "background", false, false), formal(tripleArray(), "lights", false, false), formal(realArray2(), "diffuse", false, false), formal(realArray2(), "ambient", false, false), formal(realArray2(), "specular", false, false), formal(primBoolean(), "viewportlighting", false, false), formal(primBoolean(), "view", true, false));
+#line 1797 "runtime.in"
+ addFunc(ve, run::gen66, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false));
+#line 1802 "runtime.in"
+ addFunc(ve, run::gen67, primVoid(), "deconstruct", formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primReal(), "magnification", true, false), formal(transformFunction(), "xform", false, false));
+#line 1935 "runtime.in"
+ addFunc(ve, run::gen68, primVoid(), "purge", formal(primInt(), "divisor", true, false));
+#line 1948 "runtime.in"
+ addFunc(ve, run::gen70, primBoolean(), "==", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1953 "runtime.in"
+ addFunc(ve, run::gen71, primBoolean(), "!=", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1958 "runtime.in"
+ addFunc(ve, run::gen72, primPen(), "+", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1963 "runtime.in"
+ addFunc(ve, run::gen73, primPen(), "*", formal(primReal(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1968 "runtime.in"
+ addFunc(ve, run::gen74, primPen(), "*", formal(primPen(), "a", false, false), formal(primReal(), "b", false, false));
#line 1973 "runtime.in"
- addFunc(ve, run::gen77, primVoid(), "defaultpen", formal(primPen(), "p", false, false));
+ addFunc(ve, run::gen75, primPair(), "max", formal(primPen(), "p", false, false));
#line 1978 "runtime.in"
- addFunc(ve, run::gen78, primPen(), "defaultpen");
+ addFunc(ve, run::gen76, primPair(), "min", formal(primPen(), "p", false, false));
#line 1983 "runtime.in"
- addFunc(ve, run::gen79, primBoolean(), "invisible", formal(primPen(), "p", false, false));
-#line 1988 "runtime.in"
- addFunc(ve, run::gen80, primPen(), "invisible");
-#line 1993 "runtime.in"
- addFunc(ve, run::gen81, primPen(), "gray", formal(primPen(), "p", false, false));
+ addFunc(ve, run::gen77, primVoid(), "resetdefaultpen");
+#line 1989 "runtime.in"
+ addFunc(ve, run::gen78, primVoid(), "defaultpen", formal(primPen(), "p", false, false));
+#line 1994 "runtime.in"
+ addFunc(ve, run::gen79, primPen(), "defaultpen");
#line 1999 "runtime.in"
- addFunc(ve, run::gen82, primPen(), "rgb", formal(primPen(), "p", false, false));
-#line 2005 "runtime.in"
- addFunc(ve, run::gen83, primPen(), "cmyk", formal(primPen(), "p", false, false));
-#line 2011 "runtime.in"
- addFunc(ve, run::gen84, primPen(), "interp", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false), formal(primReal(), "t", false, false));
-#line 2016 "runtime.in"
- addFunc(ve, run::gen85, primPen(), "rgb", formal(primReal(), "r", false, false), formal(primReal(), "g", false, false), formal(primReal(), "b", false, false));
+ addFunc(ve, run::gen80, primBoolean(), "invisible", formal(primPen(), "p", false, false));
+#line 2004 "runtime.in"
+ addFunc(ve, run::gen81, primPen(), "invisible");
+#line 2009 "runtime.in"
+ addFunc(ve, run::gen82, primPen(), "gray", formal(primPen(), "p", false, false));
+#line 2015 "runtime.in"
+ addFunc(ve, run::gen83, primPen(), "rgb", formal(primPen(), "p", false, false));
#line 2021 "runtime.in"
- addFunc(ve, run::gen86, primPen(), "cmyk", formal(primReal(), "c", false, false), formal(primReal(), "m", false, false), formal(primReal(), "y", false, false), formal(primReal(), "k", false, false));
-#line 2026 "runtime.in"
- addFunc(ve, run::gen87, primPen(), "gray", formal(primReal(), "gray", false, false));
-#line 2031 "runtime.in"
- addFunc(ve, run::gen88, realArray(), "colors", formal(primPen(), "p", false, false));
-#line 2059 "runtime.in"
- addFunc(ve, run::gen89, primString() , "colorspace", formal(primPen(), "p", false, false));
-#line 2066 "runtime.in"
- addFunc(ve, run::gen90, primPen(), "pattern", formal(primString(), "s", false, false));
-#line 2071 "runtime.in"
- addFunc(ve, run::gen91, primString() , "pattern", formal(primPen(), "p", false, false));
-#line 2076 "runtime.in"
- addFunc(ve, run::gen92, primPen(), "fillrule", formal(primInt(), "n", false, false));
-#line 2081 "runtime.in"
- addFunc(ve, run::gen93, primInt(), "fillrule", formal(primPen(), "p", false, false));
-#line 2086 "runtime.in"
- addFunc(ve, run::gen94, primPen(), "opacity", formal(primReal(), "opacity", true, false), formal(primString() , "blend", true, false));
-#line 2096 "runtime.in"
- addFunc(ve, run::gen95, primReal(), "opacity", formal(primPen(), "p", false, false));
-#line 2101 "runtime.in"
- addFunc(ve, run::gen96, primString() , "blend", formal(primPen(), "p", false, false));
-#line 2106 "runtime.in"
- addFunc(ve, run::gen97, primPen(), "linetype", formal(primString(), "s", false, false), formal(primReal(), "offset", true, false), formal(primBoolean(), "scale", true, false), formal(primBoolean(), "adjust", true, false));
-#line 2111 "runtime.in"
- addFunc(ve, run::gen98, primString() , "linetype", formal(primPen(), "p", true, false));
-#line 2116 "runtime.in"
- addFunc(ve, run::gen99, primReal(), "offset", formal(primPen(), "p", false, false));
-#line 2121 "runtime.in"
- addFunc(ve, run::gen100, primBoolean(), "scale", formal(primPen(), "p", false, false));
-#line 2126 "runtime.in"
- addFunc(ve, run::gen101, primBoolean(), "adjust", formal(primPen(), "p", false, false));
-#line 2131 "runtime.in"
- addFunc(ve, run::gen102, primPen(), "adjust", formal(primPen(), "p", false, false), formal(primReal(), "arclength", false, false), formal(primBoolean(), "cyclic", false, false));
-#line 2136 "runtime.in"
- addFunc(ve, run::gen103, primPen(), "linecap", formal(primInt(), "n", false, false));
-#line 2141 "runtime.in"
- addFunc(ve, run::gen104, primInt(), "linecap", formal(primPen(), "p", true, false));
-#line 2146 "runtime.in"
- addFunc(ve, run::gen105, primPen(), "linejoin", formal(primInt(), "n", false, false));
-#line 2151 "runtime.in"
- addFunc(ve, run::gen106, primInt(), "linejoin", formal(primPen(), "p", true, false));
-#line 2156 "runtime.in"
- addFunc(ve, run::gen107, primPen(), "miterlimit", formal(primReal(), "x", false, false));
-#line 2161 "runtime.in"
- addFunc(ve, run::gen108, primReal(), "miterlimit", formal(primPen(), "p", true, false));
-#line 2166 "runtime.in"
- addFunc(ve, run::gen109, primPen(), "linewidth", formal(primReal(), "x", false, false));
-#line 2171 "runtime.in"
- addFunc(ve, run::gen110, primReal(), "linewidth", formal(primPen(), "p", true, false));
-#line 2176 "runtime.in"
- addFunc(ve, run::gen111, primPen(), "fontcommand", formal(primString(), "s", false, false));
-#line 2181 "runtime.in"
- addFunc(ve, run::gen112, primString() , "font", formal(primPen(), "p", true, false));
-#line 2186 "runtime.in"
- addFunc(ve, run::gen113, primPen(), "fontsize", formal(primReal(), "size", false, false), formal(primReal(), "lineskip", false, false));
+ addFunc(ve, run::gen84, primPen(), "cmyk", formal(primPen(), "p", false, false));
+#line 2027 "runtime.in"
+ addFunc(ve, run::gen85, primPen(), "interp", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false), formal(primReal(), "t", false, false));
+#line 2032 "runtime.in"
+ addFunc(ve, run::gen86, primPen(), "rgb", formal(primReal(), "r", false, false), formal(primReal(), "g", false, false), formal(primReal(), "b", false, false));
+#line 2037 "runtime.in"
+ addFunc(ve, run::gen87, primPen(), "cmyk", formal(primReal(), "c", false, false), formal(primReal(), "m", false, false), formal(primReal(), "y", false, false), formal(primReal(), "k", false, false));
+#line 2042 "runtime.in"
+ addFunc(ve, run::gen88, primPen(), "gray", formal(primReal(), "gray", false, false));
+#line 2047 "runtime.in"
+ addFunc(ve, run::gen89, realArray(), "colors", formal(primPen(), "p", false, false));
+#line 2075 "runtime.in"
+ addFunc(ve, run::gen90, primString() , "colorspace", formal(primPen(), "p", false, false));
+#line 2082 "runtime.in"
+ addFunc(ve, run::gen91, primPen(), "pattern", formal(primString(), "s", false, false));
+#line 2087 "runtime.in"
+ addFunc(ve, run::gen92, primString() , "pattern", formal(primPen(), "p", false, false));
+#line 2092 "runtime.in"
+ addFunc(ve, run::gen93, primPen(), "fillrule", formal(primInt(), "n", false, false));
+#line 2097 "runtime.in"
+ addFunc(ve, run::gen94, primInt(), "fillrule", formal(primPen(), "p", false, false));
+#line 2102 "runtime.in"
+ addFunc(ve, run::gen95, primPen(), "opacity", formal(primReal(), "opacity", true, false), formal(primString() , "blend", true, false));
+#line 2112 "runtime.in"
+ addFunc(ve, run::gen96, primReal(), "opacity", formal(primPen(), "p", false, false));
+#line 2117 "runtime.in"
+ addFunc(ve, run::gen97, primString() , "blend", formal(primPen(), "p", false, false));
+#line 2122 "runtime.in"
+ addFunc(ve, run::gen98, primPen(), "linetype", formal(primString(), "s", false, false), formal(primReal(), "offset", true, false), formal(primBoolean(), "scale", true, false), formal(primBoolean(), "adjust", true, false));
+#line 2127 "runtime.in"
+ addFunc(ve, run::gen99, primString() , "linetype", formal(primPen(), "p", true, false));
+#line 2132 "runtime.in"
+ addFunc(ve, run::gen100, primReal(), "offset", formal(primPen(), "p", false, false));
+#line 2137 "runtime.in"
+ addFunc(ve, run::gen101, primBoolean(), "scale", formal(primPen(), "p", false, false));
+#line 2142 "runtime.in"
+ addFunc(ve, run::gen102, primBoolean(), "adjust", formal(primPen(), "p", false, false));
+#line 2147 "runtime.in"
+ addFunc(ve, run::gen103, primPen(), "adjust", formal(primPen(), "p", false, false), formal(primReal(), "arclength", false, false), formal(primBoolean(), "cyclic", false, false));
+#line 2152 "runtime.in"
+ addFunc(ve, run::gen104, primPen(), "linecap", formal(primInt(), "n", false, false));
+#line 2157 "runtime.in"
+ addFunc(ve, run::gen105, primInt(), "linecap", formal(primPen(), "p", true, false));
+#line 2162 "runtime.in"
+ addFunc(ve, run::gen106, primPen(), "linejoin", formal(primInt(), "n", false, false));
+#line 2167 "runtime.in"
+ addFunc(ve, run::gen107, primInt(), "linejoin", formal(primPen(), "p", true, false));
+#line 2172 "runtime.in"
+ addFunc(ve, run::gen108, primPen(), "miterlimit", formal(primReal(), "x", false, false));
+#line 2177 "runtime.in"
+ addFunc(ve, run::gen109, primReal(), "miterlimit", formal(primPen(), "p", true, false));
+#line 2182 "runtime.in"
+ addFunc(ve, run::gen110, primPen(), "linewidth", formal(primReal(), "x", false, false));
+#line 2187 "runtime.in"
+ addFunc(ve, run::gen111, primReal(), "linewidth", formal(primPen(), "p", true, false));
#line 2192 "runtime.in"
- addFunc(ve, run::gen114, primReal(), "fontsize", formal(primPen(), "p", true, false));
+ addFunc(ve, run::gen112, primPen(), "fontcommand", formal(primString(), "s", false, false));
#line 2197 "runtime.in"
- addFunc(ve, run::gen115, primReal(), "lineskip", formal(primPen(), "p", true, false));
+ addFunc(ve, run::gen113, primString() , "font", formal(primPen(), "p", true, false));
#line 2202 "runtime.in"
- addFunc(ve, run::gen116, primPen(), "overwrite", formal(primInt(), "n", false, false));
+ addFunc(ve, run::gen114, primPen(), "fontsize", formal(primReal(), "size", false, false), formal(primReal(), "lineskip", false, false));
#line 2208 "runtime.in"
- addFunc(ve, run::gen117, primInt(), "overwrite", formal(primPen(), "p", true, false));
+ addFunc(ve, run::gen115, primReal(), "fontsize", formal(primPen(), "p", true, false));
#line 2213 "runtime.in"
- addFunc(ve, run::gen118, primPen(), "basealign", formal(primInt(), "n", false, false));
+ addFunc(ve, run::gen116, primReal(), "lineskip", formal(primPen(), "p", true, false));
#line 2218 "runtime.in"
- addFunc(ve, run::gen119, primInt(), "basealign", formal(primPen(), "p", true, false));
-#line 2223 "runtime.in"
- addFunc(ve, run::gen120, primTransform(), "transform", formal(primPen(), "p", false, false));
-#line 2228 "runtime.in"
- addFunc(ve, run::gen121, primPath(), "nib", formal(primPen(), "p", false, false));
-#line 2233 "runtime.in"
- addFunc(ve, run::gen122, primPen(), "makepen", formal(primPath(), "p", false, false));
-#line 2238 "runtime.in"
- addFunc(ve, run::gen123, primPen(), "colorless", formal(primPen(), "p", false, false));
+ addFunc(ve, run::gen117, primPen(), "overwrite", formal(primInt(), "n", false, false));
+#line 2224 "runtime.in"
+ addFunc(ve, run::gen118, primInt(), "overwrite", formal(primPen(), "p", true, false));
+#line 2229 "runtime.in"
+ addFunc(ve, run::gen119, primPen(), "basealign", formal(primInt(), "n", false, false));
+#line 2234 "runtime.in"
+ addFunc(ve, run::gen120, primInt(), "basealign", formal(primPen(), "p", true, false));
+#line 2239 "runtime.in"
+ addFunc(ve, run::gen121, primTransform(), "transform", formal(primPen(), "p", false, false));
#line 2244 "runtime.in"
- addFunc(ve, run::gen124, primBoolean(), "interactive");
-#line 2251 "runtime.in"
- addFunc(ve, run::gen125, primBoolean(), "uptodate");
-#line 2256 "runtime.in"
- addFunc(ve, run::gen126, primInt(), "system", formal(primString() , "s", false, false));
-#line 2266 "runtime.in"
- addFunc(ve, run::gen127, primBoolean(), "view");
-#line 2271 "runtime.in"
- addFunc(ve, run::gen128, primString() , "asydir");
-#line 2276 "runtime.in"
- addFunc(ve, run::gen129, primString() , "locale", formal(primString() , "s", true, false));
+ addFunc(ve, run::gen122, primPath(), "nib", formal(primPen(), "p", false, false));
+#line 2249 "runtime.in"
+ addFunc(ve, run::gen123, primPen(), "makepen", formal(primPath(), "p", false, false));
+#line 2254 "runtime.in"
+ addFunc(ve, run::gen124, primPen(), "colorless", formal(primPen(), "p", false, false));
+#line 2260 "runtime.in"
+ addFunc(ve, run::gen125, primBoolean(), "interactive");
+#line 2267 "runtime.in"
+ addFunc(ve, run::gen126, primBoolean(), "uptodate");
+#line 2272 "runtime.in"
+ addFunc(ve, run::gen127, primInt(), "system", formal(primString() , "s", false, false));
#line 2282 "runtime.in"
- addFunc(ve, run::gen130, primVoid(), "abort", formal(primString() , "s", true, false));
-#line 2288 "runtime.in"
- addFunc(ve, run::gen131, primVoid(), "exit");
-#line 2293 "runtime.in"
- addFunc(ve, run::gen132, primVoid(), "assert", formal(primBoolean(), "b", false, false), formal(primString() , "s", true, false));
+ addFunc(ve, run::gen128, primBoolean(), "view");
+#line 2287 "runtime.in"
+ addFunc(ve, run::gen129, primString() , "asydir");
+#line 2292 "runtime.in"
+ addFunc(ve, run::gen130, primString() , "locale", formal(primString() , "s", true, false));
+#line 2298 "runtime.in"
+ addFunc(ve, run::gen131, primVoid(), "abort", formal(primString() , "s", true, false));
#line 2304 "runtime.in"
- addFunc(ve, run::gen133, primVoid(), "sleep", formal(primInt(), "seconds", false, false));
-#line 2310 "runtime.in"
- addFunc(ve, run::gen134, primVoid(), "usleep", formal(primInt(), "microseconds", false, false));
-#line 2316 "runtime.in"
- addFunc(ve, run::gen135, primVoid(), "_eval", formal(primString(), "s", false, false), formal(primBoolean(), "embedded", false, false), formal(primBoolean(), "interactivewrite", true, false));
-#line 2331 "runtime.in"
- addFunc(ve, run::gen136, primVoid(), "_eval", formal(primCode(), "s", false, false), formal(primBoolean(), "embedded", false, false));
-#line 2349 "runtime.in"
- addFunc(ve, run::gen137, primString() , "location");
-#line 2361 "runtime.in"
- addFunc(ve, run::gen139, primString() , "cd", formal(primString() , "s", true, false));
-#line 2367 "runtime.in"
- addFunc(ve, run::gen140, primVoid(), "list", formal(primString(), "s", false, false), formal(primBoolean(), "imports", true, false));
-#line 2384 "runtime.in"
- addFunc(ve, run::gen142, primBoolean(), "==", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
-#line 2389 "runtime.in"
- addFunc(ve, run::gen143, primBoolean(), "!=", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
-#line 2394 "runtime.in"
- addFunc(ve, run::gen144, primPair(), "point", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2399 "runtime.in"
- addFunc(ve, run::gen145, primPair(), "point", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2404 "runtime.in"
- addFunc(ve, run::gen146, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2409 "runtime.in"
- addFunc(ve, run::gen147, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2414 "runtime.in"
- addFunc(ve, run::gen148, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2419 "runtime.in"
- addFunc(ve, run::gen149, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2424 "runtime.in"
- addFunc(ve, run::gen150, primPair(), "dir", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
-#line 2429 "runtime.in"
- addFunc(ve, run::gen151, primPair(), "dir", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
-#line 2434 "runtime.in"
- addFunc(ve, run::gen152, primPair(), "accel", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
-#line 2439 "runtime.in"
- addFunc(ve, run::gen153, primPair(), "accel", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2444 "runtime.in"
- addFunc(ve, run::gen154, primReal(), "radius", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2456 "runtime.in"
- addFunc(ve, run::gen155, primPath(), "reverse", formal(primPath(), "p", false, false));
-#line 2461 "runtime.in"
- addFunc(ve, run::gen156, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
-#line 2466 "runtime.in"
- addFunc(ve, run::gen157, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
-#line 2471 "runtime.in"
- addFunc(ve, run::gen158, primPath(), "nurb", formal(primPair(), "z0", false, false), formal(primPair(), "z1", false, false), formal(primPair(), "z2", false, false), formal(primPair(), "z3", false, false), formal(primReal(), "w0", false, false), formal(primReal(), "w1", false, false), formal(primReal(), "w2", false, false), formal(primReal(), "w3", false, false), formal(primInt(), "m", false, false));
+ addFunc(ve, run::gen132, primVoid(), "exit");
+#line 2309 "runtime.in"
+ addFunc(ve, run::gen133, primVoid(), "assert", formal(primBoolean(), "b", false, false), formal(primString() , "s", true, false));
+#line 2320 "runtime.in"
+ addFunc(ve, run::gen134, primVoid(), "sleep", formal(primInt(), "seconds", false, false));
+#line 2326 "runtime.in"
+ addFunc(ve, run::gen135, primVoid(), "usleep", formal(primInt(), "microseconds", false, false));
+#line 2332 "runtime.in"
+ addFunc(ve, run::gen136, primVoid(), "_eval", formal(primString(), "s", false, false), formal(primBoolean(), "embedded", false, false), formal(primBoolean(), "interactivewrite", true, false));
+#line 2347 "runtime.in"
+ addFunc(ve, run::gen137, primVoid(), "_eval", formal(primCode(), "s", false, false), formal(primBoolean(), "embedded", false, false));
+#line 2365 "runtime.in"
+ addFunc(ve, run::gen138, primString() , "location");
+#line 2377 "runtime.in"
+ addFunc(ve, run::gen140, primString() , "cd", formal(primString() , "s", true, false));
+#line 2383 "runtime.in"
+ addFunc(ve, run::gen141, primVoid(), "list", formal(primString(), "s", false, false), formal(primBoolean(), "imports", true, false));
+#line 2400 "runtime.in"
+ addFunc(ve, run::gen143, primBoolean(), "==", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
+#line 2405 "runtime.in"
+ addFunc(ve, run::gen144, primBoolean(), "!=", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
+#line 2410 "runtime.in"
+ addFunc(ve, run::gen145, primPair(), "point", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2415 "runtime.in"
+ addFunc(ve, run::gen146, primPair(), "point", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2420 "runtime.in"
+ addFunc(ve, run::gen147, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2425 "runtime.in"
+ addFunc(ve, run::gen148, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2430 "runtime.in"
+ addFunc(ve, run::gen149, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2435 "runtime.in"
+ addFunc(ve, run::gen150, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2440 "runtime.in"
+ addFunc(ve, run::gen151, primPair(), "dir", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
+#line 2445 "runtime.in"
+ addFunc(ve, run::gen152, primPair(), "dir", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
+#line 2450 "runtime.in"
+ addFunc(ve, run::gen153, primPair(), "accel", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
+#line 2455 "runtime.in"
+ addFunc(ve, run::gen154, primPair(), "accel", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2460 "runtime.in"
+ addFunc(ve, run::gen155, primReal(), "radius", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2472 "runtime.in"
+ addFunc(ve, run::gen156, primPath(), "reverse", formal(primPath(), "p", false, false));
#line 2477 "runtime.in"
- addFunc(ve, run::gen159, primInt(), "length", formal(primPath(), "p", false, false));
+ addFunc(ve, run::gen157, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
#line 2482 "runtime.in"
- addFunc(ve, run::gen160, primBoolean(), "cyclic", formal(primPath(), "p", false, false));
+ addFunc(ve, run::gen158, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
#line 2487 "runtime.in"
- addFunc(ve, run::gen161, primBoolean(), "straight", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2492 "runtime.in"
- addFunc(ve, run::gen162, primPath(), "unstraighten", formal(primPath(), "p", false, false));
-#line 2497 "runtime.in"
- addFunc(ve, run::gen163, primBoolean(), "piecewisestraight", formal(primPath(), "p", false, false));
-#line 2502 "runtime.in"
- addFunc(ve, run::gen164, primReal(), "arclength", formal(primPath(), "p", false, false));
-#line 2507 "runtime.in"
- addFunc(ve, run::gen165, primReal(), "arctime", formal(primPath(), "p", false, false), formal(primReal(), "dval", false, false));
-#line 2512 "runtime.in"
- addFunc(ve, run::gen166, primReal(), "dirtime", formal(primPath(), "p", false, false), formal(primPair(), "z", false, false));
-#line 2517 "runtime.in"
- addFunc(ve, run::gen167, realArray(), "intersect", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
-#line 2534 "runtime.in"
- addFunc(ve, run::gen168, realArray2(), "intersections", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
-#line 2565 "runtime.in"
- addFunc(ve, run::gen169, realArray(), "intersections", formal(primPath(), "p", false, false), formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primReal(), "fuzz", true, false));
-#line 2580 "runtime.in"
- addFunc(ve, run::gen170, primPair(), "extension", formal(primPair(), "p", false, false), formal(primPair(), "q", false, false), formal(primPair(), "p", false, false), formal(primPair(), "q", false, false));
-#line 2591 "runtime.in"
- addFunc(ve, run::gen171, primInt(), "size", formal(primPath(), "p", false, false));
+ addFunc(ve, run::gen159, primPath(), "nurb", formal(primPair(), "z0", false, false), formal(primPair(), "z1", false, false), formal(primPair(), "z2", false, false), formal(primPair(), "z3", false, false), formal(primReal(), "w0", false, false), formal(primReal(), "w1", false, false), formal(primReal(), "w2", false, false), formal(primReal(), "w3", false, false), formal(primInt(), "m", false, false));
+#line 2493 "runtime.in"
+ addFunc(ve, run::gen160, primInt(), "length", formal(primPath(), "p", false, false));
+#line 2498 "runtime.in"
+ addFunc(ve, run::gen161, primBoolean(), "cyclic", formal(primPath(), "p", false, false));
+#line 2503 "runtime.in"
+ addFunc(ve, run::gen162, primBoolean(), "straight", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2508 "runtime.in"
+ addFunc(ve, run::gen163, primPath(), "unstraighten", formal(primPath(), "p", false, false));
+#line 2513 "runtime.in"
+ addFunc(ve, run::gen164, primBoolean(), "piecewisestraight", formal(primPath(), "p", false, false));
+#line 2518 "runtime.in"
+ addFunc(ve, run::gen165, primReal(), "arclength", formal(primPath(), "p", false, false));
+#line 2523 "runtime.in"
+ addFunc(ve, run::gen166, primReal(), "arctime", formal(primPath(), "p", false, false), formal(primReal(), "dval", false, false));
+#line 2528 "runtime.in"
+ addFunc(ve, run::gen167, primReal(), "dirtime", formal(primPath(), "p", false, false), formal(primPair(), "z", false, false));
+#line 2533 "runtime.in"
+ addFunc(ve, run::gen168, realArray(), "intersect", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2550 "runtime.in"
+ addFunc(ve, run::gen169, realArray2(), "intersections", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2581 "runtime.in"
+ addFunc(ve, run::gen170, realArray(), "intersections", formal(primPath(), "p", false, false), formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primReal(), "fuzz", true, false));
#line 2596 "runtime.in"
- addFunc(ve, run::gen172, primPath(), "&", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false));
-#line 2601 "runtime.in"
- addFunc(ve, run::gen173, primPair(), "min", formal(primPath(), "p", false, false));
-#line 2606 "runtime.in"
- addFunc(ve, run::gen174, primPair(), "max", formal(primPath(), "p", false, false));
-#line 2611 "runtime.in"
- addFunc(ve, run::gen175, realArray(), "mintimes", formal(primPath(), "p", false, false));
-#line 2620 "runtime.in"
- addFunc(ve, run::gen176, realArray(), "maxtimes", formal(primPath(), "p", false, false));
-#line 2629 "runtime.in"
- addFunc(ve, run::gen177, primReal(), "relativedistance", formal(primReal(), "theta", false, false), formal(primReal(), "phi", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "atleast", false, false));
-#line 2634 "runtime.in"
- addFunc(ve, run::gen178, primInt(), "windingnumber", formal(pathArray() , "p", false, false), formal(primPair(), "z", false, false));
-#line 2639 "runtime.in"
- addFunc(ve, run::gen179, primBoolean(), "inside", formal(pathArray() , "g", false, true), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
-#line 2644 "runtime.in"
- addFunc(ve, run::gen180, primBoolean(), "inside", formal(primPath(), "g", false, false), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
-#line 2649 "runtime.in"
- addFunc(ve, run::gen181, primReal(), "side", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false));
-#line 2656 "runtime.in"
- addFunc(ve, run::gen182, primReal(), "incircle", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
-#line 2664 "runtime.in"
- addFunc(ve, run::gen183, primPath3(), "path3", formal(tripleArray(), "pre", false, false), formal(tripleArray(), "point", false, false), formal(tripleArray(), "post", false, false), formal(boolArray(), "straight", false, false), formal(primBoolean(), "cyclic", false, false));
-#line 2689 "runtime.in"
- addFunc(ve, run::gen185, primBoolean(), "==", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
-#line 2694 "runtime.in"
- addFunc(ve, run::gen186, primBoolean(), "!=", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
-#line 2699 "runtime.in"
- addFunc(ve, run::gen187, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2704 "runtime.in"
- addFunc(ve, run::gen188, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2709 "runtime.in"
- addFunc(ve, run::gen189, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2714 "runtime.in"
- addFunc(ve, run::gen190, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2719 "runtime.in"
- addFunc(ve, run::gen191, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2724 "runtime.in"
- addFunc(ve, run::gen192, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2729 "runtime.in"
- addFunc(ve, run::gen193, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
-#line 2734 "runtime.in"
- addFunc(ve, run::gen194, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
-#line 2739 "runtime.in"
- addFunc(ve, run::gen195, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
-#line 2744 "runtime.in"
- addFunc(ve, run::gen196, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2749 "runtime.in"
- addFunc(ve, run::gen197, primReal(), "radius", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
-#line 2761 "runtime.in"
- addFunc(ve, run::gen198, primReal(), "radius", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false), formal(primReal(), "t", false, false));
-#line 2773 "runtime.in"
- addFunc(ve, run::gen199, primPath3(), "reverse", formal(primPath3(), "p", false, false));
-#line 2778 "runtime.in"
- addFunc(ve, run::gen200, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
-#line 2783 "runtime.in"
- addFunc(ve, run::gen201, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
-#line 2788 "runtime.in"
- addFunc(ve, run::gen202, primInt(), "length", formal(primPath3(), "p", false, false));
-#line 2793 "runtime.in"
- addFunc(ve, run::gen203, primBoolean(), "cyclic", formal(primPath3(), "p", false, false));
-#line 2798 "runtime.in"
- addFunc(ve, run::gen204, primBoolean(), "straight", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2803 "runtime.in"
- addFunc(ve, run::gen205, primTriple(), "perp", formal(primTriple(), "v", false, false), formal(primTriple(), "u", false, false));
+ addFunc(ve, run::gen171, primPair(), "extension", formal(primPair(), "p", false, false), formal(primPair(), "q", false, false), formal(primPair(), "p", false, false), formal(primPair(), "q", false, false));
+#line 2607 "runtime.in"
+ addFunc(ve, run::gen172, primInt(), "size", formal(primPath(), "p", false, false));
+#line 2612 "runtime.in"
+ addFunc(ve, run::gen173, primPath(), "&", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false));
+#line 2617 "runtime.in"
+ addFunc(ve, run::gen174, primPair(), "min", formal(primPath(), "p", false, false));
+#line 2622 "runtime.in"
+ addFunc(ve, run::gen175, primPair(), "max", formal(primPath(), "p", false, false));
+#line 2627 "runtime.in"
+ addFunc(ve, run::gen176, realArray(), "mintimes", formal(primPath(), "p", false, false));
+#line 2636 "runtime.in"
+ addFunc(ve, run::gen177, realArray(), "maxtimes", formal(primPath(), "p", false, false));
+#line 2645 "runtime.in"
+ addFunc(ve, run::gen178, primReal(), "relativedistance", formal(primReal(), "theta", false, false), formal(primReal(), "phi", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "atleast", false, false));
+#line 2650 "runtime.in"
+ addFunc(ve, run::gen179, primInt(), "windingnumber", formal(pathArray() , "p", false, false), formal(primPair(), "z", false, false));
+#line 2655 "runtime.in"
+ addFunc(ve, run::gen180, primBoolean(), "inside", formal(pathArray() , "g", false, true), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
+#line 2660 "runtime.in"
+ addFunc(ve, run::gen181, primBoolean(), "inside", formal(primPath(), "g", false, false), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
+#line 2665 "runtime.in"
+ addFunc(ve, run::gen182, primReal(), "side", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false));
+#line 2672 "runtime.in"
+ addFunc(ve, run::gen183, primReal(), "incircle", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
+#line 2680 "runtime.in"
+ addFunc(ve, run::gen184, primPath3(), "path3", formal(tripleArray(), "pre", false, false), formal(tripleArray(), "point", false, false), formal(tripleArray(), "post", false, false), formal(boolArray(), "straight", false, false), formal(primBoolean(), "cyclic", false, false));
+#line 2705 "runtime.in"
+ addFunc(ve, run::gen186, primBoolean(), "==", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
+#line 2710 "runtime.in"
+ addFunc(ve, run::gen187, primBoolean(), "!=", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
+#line 2715 "runtime.in"
+ addFunc(ve, run::gen188, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2720 "runtime.in"
+ addFunc(ve, run::gen189, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2725 "runtime.in"
+ addFunc(ve, run::gen190, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2730 "runtime.in"
+ addFunc(ve, run::gen191, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2735 "runtime.in"
+ addFunc(ve, run::gen192, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2740 "runtime.in"
+ addFunc(ve, run::gen193, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2745 "runtime.in"
+ addFunc(ve, run::gen194, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
+#line 2750 "runtime.in"
+ addFunc(ve, run::gen195, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
+#line 2755 "runtime.in"
+ addFunc(ve, run::gen196, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
+#line 2760 "runtime.in"
+ addFunc(ve, run::gen197, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2765 "runtime.in"
+ addFunc(ve, run::gen198, primReal(), "radius", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2777 "runtime.in"
+ addFunc(ve, run::gen199, primReal(), "radius", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false), formal(primReal(), "t", false, false));
+#line 2789 "runtime.in"
+ addFunc(ve, run::gen200, primPath3(), "reverse", formal(primPath3(), "p", false, false));
+#line 2794 "runtime.in"
+ addFunc(ve, run::gen201, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 2799 "runtime.in"
+ addFunc(ve, run::gen202, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
+#line 2804 "runtime.in"
+ addFunc(ve, run::gen203, primInt(), "length", formal(primPath3(), "p", false, false));
#line 2809 "runtime.in"
- addFunc(ve, run::gen206, primReal(), "straightness", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
-#line 2820 "runtime.in"
- addFunc(ve, run::gen207, primReal(), "straightness", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false));
-#line 2828 "runtime.in"
- addFunc(ve, run::gen208, primBoolean(), "piecewisestraight", formal(primPath3(), "p", false, false));
-#line 2833 "runtime.in"
- addFunc(ve, run::gen209, primReal(), "arclength", formal(primPath3(), "p", false, false));
-#line 2838 "runtime.in"
- addFunc(ve, run::gen210, primReal(), "arctime", formal(primPath3(), "p", false, false), formal(primReal(), "dval", false, false));
-#line 2843 "runtime.in"
- addFunc(ve, run::gen211, realArray(), "intersect", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
-#line 2861 "runtime.in"
- addFunc(ve, run::gen212, realArray2(), "intersections", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
-#line 2894 "runtime.in"
- addFunc(ve, run::gen213, realArray2(), "intersections", formal(primPath3(), "p", false, false), formal(tripleArray2(), "p", false, false), formal(primReal(), "fuzz", true, false));
-#line 2914 "runtime.in"
- addFunc(ve, run::gen214, primInt(), "size", formal(primPath3(), "p", false, false));
-#line 2919 "runtime.in"
- addFunc(ve, run::gen215, primPath3(), "&", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false));
-#line 2924 "runtime.in"
- addFunc(ve, run::gen216, primTriple(), "min", formal(primPath3(), "p", false, false));
-#line 2929 "runtime.in"
- addFunc(ve, run::gen217, primTriple(), "max", formal(primPath3(), "p", false, false));
-#line 2934 "runtime.in"
- addFunc(ve, run::gen218, realArray(), "mintimes", formal(primPath3(), "p", false, false));
-#line 2944 "runtime.in"
- addFunc(ve, run::gen219, realArray(), "maxtimes", formal(primPath3(), "p", false, false));
-#line 2954 "runtime.in"
- addFunc(ve, run::gen220, primPath3(), "*", formal(realArray2(), "t", false, false), formal(primPath3(), "g", false, false));
-#line 3009 "runtime.in"
- addFunc(ve, run::gen225, primGuide(), "operator cast", formal(primCycleToken(), "tok", false, false));
-#line 3016 "runtime.in"
- addFunc(ve, run::gen226, primGuide(), "operator spec", formal(primPair(), "z", false, false), formal(primInt(), "p", false, false));
-#line 3024 "runtime.in"
- addFunc(ve, run::gen227, primCurlSpecifier(), "operator curl", formal(primReal(), "gamma", false, false), formal(primInt(), "p", false, false));
+ addFunc(ve, run::gen204, primBoolean(), "cyclic", formal(primPath3(), "p", false, false));
+#line 2814 "runtime.in"
+ addFunc(ve, run::gen205, primBoolean(), "straight", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2819 "runtime.in"
+ addFunc(ve, run::gen206, primTriple(), "perp", formal(primTriple(), "v", false, false), formal(primTriple(), "u", false, false));
+#line 2825 "runtime.in"
+ addFunc(ve, run::gen207, primReal(), "straightness", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2836 "runtime.in"
+ addFunc(ve, run::gen208, primReal(), "straightness", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false));
+#line 2844 "runtime.in"
+ addFunc(ve, run::gen209, primBoolean(), "piecewisestraight", formal(primPath3(), "p", false, false));
+#line 2849 "runtime.in"
+ addFunc(ve, run::gen210, primReal(), "arclength", formal(primPath3(), "p", false, false));
+#line 2854 "runtime.in"
+ addFunc(ve, run::gen211, primReal(), "arctime", formal(primPath3(), "p", false, false), formal(primReal(), "dval", false, false));
+#line 2859 "runtime.in"
+ addFunc(ve, run::gen212, realArray(), "intersect", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2877 "runtime.in"
+ addFunc(ve, run::gen213, realArray2(), "intersections", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2910 "runtime.in"
+ addFunc(ve, run::gen214, realArray2(), "intersections", formal(primPath3(), "p", false, false), formal(tripleArray2(), "p", false, false), formal(primReal(), "fuzz", true, false));
+#line 2930 "runtime.in"
+ addFunc(ve, run::gen215, primInt(), "size", formal(primPath3(), "p", false, false));
+#line 2935 "runtime.in"
+ addFunc(ve, run::gen216, primPath3(), "&", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false));
+#line 2940 "runtime.in"
+ addFunc(ve, run::gen217, primTriple(), "min", formal(primPath3(), "p", false, false));
+#line 2945 "runtime.in"
+ addFunc(ve, run::gen218, primTriple(), "max", formal(primPath3(), "p", false, false));
+#line 2950 "runtime.in"
+ addFunc(ve, run::gen219, realArray(), "mintimes", formal(primPath3(), "p", false, false));
+#line 2960 "runtime.in"
+ addFunc(ve, run::gen220, realArray(), "maxtimes", formal(primPath3(), "p", false, false));
+#line 2970 "runtime.in"
+ addFunc(ve, run::gen221, primPath3(), "*", formal(realArray2(), "t", false, false), formal(primPath3(), "g", false, false));
+#line 3025 "runtime.in"
+ addFunc(ve, run::gen226, primGuide(), "operator cast", formal(primCycleToken(), "tok", false, false));
+#line 3032 "runtime.in"
+ addFunc(ve, run::gen227, primGuide(), "operator spec", formal(primPair(), "z", false, false), formal(primInt(), "p", false, false));
#line 3040 "runtime.in"
- addFunc(ve, run::gen230, primGuide(), "operator cast", formal(primCurlSpecifier(), "spec", false, false));
-#line 3045 "runtime.in"
- addFunc(ve, run::gen231, primTensionSpecifier(), "operator tension", formal(primReal(), "tout", false, false), formal(primReal(), "tin", false, false), formal(primBoolean(), "atleast", false, false));
-#line 3065 "runtime.in"
- addFunc(ve, run::gen235, primGuide(), "operator cast", formal(primTensionSpecifier(), "t", false, false));
-#line 3070 "runtime.in"
- addFunc(ve, run::gen236, primGuide(), "operator controls", formal(primPair(), "zout", false, false), formal(primPair(), "zin", false, false));
-#line 3075 "runtime.in"
- addFunc(ve, run::gen237, primInt(), "size", formal(primGuide(), "g", false, false));
-#line 3082 "runtime.in"
- addFunc(ve, run::gen238, primInt(), "length", formal(primGuide(), "g", false, false));
-#line 3089 "runtime.in"
- addFunc(ve, run::gen239, primBoolean(), "cyclic", formal(primGuide(), "g", false, false));
-#line 3096 "runtime.in"
- addFunc(ve, run::gen240, primPair(), "point", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
-#line 3103 "runtime.in"
- addFunc(ve, run::gen241, pairArray(), "dirSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
-#line 3115 "runtime.in"
- addFunc(ve, run::gen242, pairArray(), "controlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
-#line 3132 "runtime.in"
- addFunc(ve, run::gen243, primTensionSpecifier(), "tensionSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
-#line 3142 "runtime.in"
- addFunc(ve, run::gen244, realArray(), "curlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
-#line 3156 "runtime.in"
- addFunc(ve, run::gen245, primGuide(), "reverse", formal(primGuide(), "g", false, false));
-#line 3210 "runtime.in"
- addFunc(ve, run::gen246, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath3(), "g", false, false), formal(primPen(), "p", false, false));
-#line 3219 "runtime.in"
- addFunc(ve, run::gen247, primVoid(), "draw", formal(primPicture(), "f", false, false), formal(tripleArray2(), "g", false, false), formal(primBoolean(), "straight", false, false), formal(penArray() , "p", false, false), formal(primReal(), "opacity", false, false), formal(primReal(), "shininess", false, false), formal(primReal(), "granularity", false, false), formal(primTriple(), "normal", false, false), formal(primBoolean(), "lighton", false, false), formal(penArray() , "colors", false, false));
-#line 3227 "runtime.in"
- addFunc(ve, run::gen248, primTriple(), "min3", formal(primPicture(), "f", false, false));
-#line 3232 "runtime.in"
- addFunc(ve, run::gen249, primTriple(), "max3", formal(primPicture(), "f", false, false));
-#line 3237 "runtime.in"
- addFunc(ve, run::gen250, primPair(), "min", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
-#line 3245 "runtime.in"
- addFunc(ve, run::gen251, primPair(), "max", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
+ addFunc(ve, run::gen228, primCurlSpecifier(), "operator curl", formal(primReal(), "gamma", false, false), formal(primInt(), "p", false, false));
+#line 3056 "runtime.in"
+ addFunc(ve, run::gen231, primGuide(), "operator cast", formal(primCurlSpecifier(), "spec", false, false));
+#line 3061 "runtime.in"
+ addFunc(ve, run::gen232, primTensionSpecifier(), "operator tension", formal(primReal(), "tout", false, false), formal(primReal(), "tin", false, false), formal(primBoolean(), "atleast", false, false));
+#line 3081 "runtime.in"
+ addFunc(ve, run::gen236, primGuide(), "operator cast", formal(primTensionSpecifier(), "t", false, false));
+#line 3086 "runtime.in"
+ addFunc(ve, run::gen237, primGuide(), "operator controls", formal(primPair(), "zout", false, false), formal(primPair(), "zin", false, false));
+#line 3091 "runtime.in"
+ addFunc(ve, run::gen238, primInt(), "size", formal(primGuide(), "g", false, false));
+#line 3098 "runtime.in"
+ addFunc(ve, run::gen239, primInt(), "length", formal(primGuide(), "g", false, false));
+#line 3105 "runtime.in"
+ addFunc(ve, run::gen240, primBoolean(), "cyclic", formal(primGuide(), "g", false, false));
+#line 3112 "runtime.in"
+ addFunc(ve, run::gen241, primPair(), "point", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 3119 "runtime.in"
+ addFunc(ve, run::gen242, pairArray(), "dirSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 3131 "runtime.in"
+ addFunc(ve, run::gen243, pairArray(), "controlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 3148 "runtime.in"
+ addFunc(ve, run::gen244, primTensionSpecifier(), "tensionSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 3158 "runtime.in"
+ addFunc(ve, run::gen245, realArray(), "curlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 3172 "runtime.in"
+ addFunc(ve, run::gen246, primGuide(), "reverse", formal(primGuide(), "g", false, false));
+#line 3226 "runtime.in"
+ addFunc(ve, run::gen247, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath3(), "g", false, false), formal(primPen(), "p", false, false));
+#line 3235 "runtime.in"
+ addFunc(ve, run::gen248, primVoid(), "draw", formal(primPicture(), "f", false, false), formal(tripleArray2(), "g", false, false), formal(primBoolean(), "straight", false, false), formal(penArray() , "p", false, false), formal(primReal(), "opacity", false, false), formal(primReal(), "shininess", false, false), formal(primReal(), "granularity", false, false), formal(primTriple(), "normal", false, false), formal(primBoolean(), "lighton", false, false), formal(penArray() , "colors", false, false));
+#line 3243 "runtime.in"
+ addFunc(ve, run::gen249, primTriple(), "min3", formal(primPicture(), "f", false, false));
+#line 3248 "runtime.in"
+ addFunc(ve, run::gen250, primTriple(), "max3", formal(primPicture(), "f", false, false));
#line 3253 "runtime.in"
- addFunc(ve, run::gen252, primPair(), "minratio", formal(primPicture(), "f", false, false));
-#line 3258 "runtime.in"
- addFunc(ve, run::gen253, primPair(), "maxratio", formal(primPicture(), "f", false, false));
-#line 3263 "runtime.in"
- addFunc(ve, run::gen254, primTriple(), "minbound", formal(tripleArray2(), "p", false, false), formal(primTriple(), "b", false, false));
-#line 3273 "runtime.in"
- addFunc(ve, run::gen255, primTriple(), "maxbound", formal(tripleArray2(), "p", false, false), formal(primTriple(), "b", false, false));
-#line 3283 "runtime.in"
- addFunc(ve, run::gen256, primPair(), "minbound", formal(tripleArray2(), "p", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
-#line 3295 "runtime.in"
- addFunc(ve, run::gen257, primPair(), "maxbound", formal(tripleArray2(), "p", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
-#line 3307 "runtime.in"
- addFunc(ve, run::gen258, primPair(), "max", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
-#line 3315 "runtime.in"
- addFunc(ve, run::gen259, primPair(), "min", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
+ addFunc(ve, run::gen251, primPair(), "min", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
+#line 3261 "runtime.in"
+ addFunc(ve, run::gen252, primPair(), "max", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
+#line 3269 "runtime.in"
+ addFunc(ve, run::gen253, primPair(), "minratio", formal(primPicture(), "f", false, false));
+#line 3274 "runtime.in"
+ addFunc(ve, run::gen254, primPair(), "maxratio", formal(primPicture(), "f", false, false));
+#line 3279 "runtime.in"
+ addFunc(ve, run::gen255, primTriple(), "minbound", formal(tripleArray2(), "p", false, false), formal(primTriple(), "b", false, false));
+#line 3289 "runtime.in"
+ addFunc(ve, run::gen256, primTriple(), "maxbound", formal(tripleArray2(), "p", false, false), formal(primTriple(), "b", false, false));
+#line 3299 "runtime.in"
+ addFunc(ve, run::gen257, primPair(), "minbound", formal(tripleArray2(), "p", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
+#line 3311 "runtime.in"
+ addFunc(ve, run::gen258, primPair(), "maxbound", formal(tripleArray2(), "p", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
#line 3323 "runtime.in"
- addFunc(ve, run::gen260, primReal(), "change2", formal(tripleArray2(), "a", false, false));
-#line 3345 "runtime.in"
- addFunc(ve, run::gen261, primBoolean(), "is3D", formal(primPicture(), "f", false, false));
-#line 3350 "runtime.in"
- addFunc(ve, run::gen262, primPair(), "bezier", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3357 "runtime.in"
- addFunc(ve, run::gen263, primPair(), "bezierP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3362 "runtime.in"
- addFunc(ve, run::gen264, primPair(), "bezierPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3367 "runtime.in"
- addFunc(ve, run::gen265, primPair(), "bezierPPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
-#line 3372 "runtime.in"
- addFunc(ve, run::gen266, primTriple(), "bezier", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3379 "runtime.in"
- addFunc(ve, run::gen267, primTriple(), "bezierP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3384 "runtime.in"
- addFunc(ve, run::gen268, primTriple(), "bezierPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
-#line 3389 "runtime.in"
- addFunc(ve, run::gen269, primTriple(), "bezierPPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false));
-#line 3402 "runtime.in"
- addFunc(ve, run::gen271, primInt(), "length", formal(primString(), "s", false, false));
-#line 3407 "runtime.in"
- addFunc(ve, run::gen272, primInt(), "find", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
-#line 3413 "runtime.in"
- addFunc(ve, run::gen273, primInt(), "rfind", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
-#line 3419 "runtime.in"
- addFunc(ve, run::gen274, primString() , "reverse", formal(primString() , "s", false, false));
-#line 3425 "runtime.in"
- addFunc(ve, run::gen275, primString() , "insert", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primString() , "t", false, false));
-#line 3432 "runtime.in"
- addFunc(ve, run::gen276, primString() , "substr", formal(primString(), "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", true, false));
-#line 3439 "runtime.in"
- addFunc(ve, run::gen277, primString() , "erase", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", false, false));
-#line 3446 "runtime.in"
- addFunc(ve, run::gen278, primString() , "downcase", formal(primString() , "s", false, false));
-#line 3452 "runtime.in"
- addFunc(ve, run::gen279, primString() , "upcase", formal(primString() , "s", false, false));
-#line 3458 "runtime.in"
- addFunc(ve, run::gen280, primString() , "replace", formal(primString(), "s", false, false), formal(stringArray2(), "translate", false, false));
-#line 3485 "runtime.in"
- addFunc(ve, run::gen281, primString() , "format", formal(primString(), "format", false, false), formal(primInt(), "x", false, false));
-#line 3500 "runtime.in"
- addFunc(ve, run::gen282, primString() , "format", formal(primString(), "format", false, false), formal(primReal(), "x", false, false), formal(primString() , "locale", true, false));
-#line 3618 "runtime.in"
- addFunc(ve, run::gen283, primInt(), "hex", formal(primString() , "s", false, false));
-#line 3629 "runtime.in"
- addFunc(ve, run::gen284, primString() , "string", formal(primInt(), "x", false, false));
-#line 3636 "runtime.in"
- addFunc(ve, run::gen285, primString() , "string", formal(primReal(), "x", false, false), formal(primInt(), "digits", true, false));
-#line 3644 "runtime.in"
- addFunc(ve, run::gen286, primString() , "time", formal(primString() , "format", true, false));
-#line 3655 "runtime.in"
- addFunc(ve, run::gen287, primString() , "time", formal(primInt(), "seconds", false, false), formal(primString() , "format", true, false));
-#line 3668 "runtime.in"
- addFunc(ve, run::gen288, primInt(), "seconds", formal(primString() , "t", true, false), formal(primString() , "format", true, false));
-#line 3680 "runtime.in"
- addFunc(ve, run::gen289, realArray(), "_cputime");
-#line 3694 "runtime.in"
- addFunc(ve, run::gen290, primReal(), "^", formal(primReal(), "x", false, false), formal(primInt(), "y", false, false));
-#line 3702 "runtime.in"
- addFunc(ve, run::gen291, primPair(), "^", formal(primPair(), "z", false, false), formal(primInt(), "y", false, false));
-#line 3707 "runtime.in"
- addFunc(ve, run::gen292, primInt(), "quotient", formal(primInt(), "x", false, false), formal(primInt(), "y", false, false));
-#line 3715 "runtime.in"
- addFunc(ve, run::gen293, primInt(), "abs", formal(primInt(), "x", false, false));
-#line 3720 "runtime.in"
- addFunc(ve, run::gen294, primInt(), "sgn", formal(primReal(), "x", false, false));
-#line 3725 "runtime.in"
- addFunc(ve, run::gen295, primInt(), "rand");
-#line 3730 "runtime.in"
- addFunc(ve, run::gen296, primVoid(), "srand", formal(primInt(), "seed", false, false));
-#line 3735 "runtime.in"
- addFunc(ve, run::gen297, primReal(), "unitrand");
+ addFunc(ve, run::gen259, primPair(), "max", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
+#line 3331 "runtime.in"
+ addFunc(ve, run::gen260, primPair(), "min", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
+#line 3339 "runtime.in"
+ addFunc(ve, run::gen261, primReal(), "change2", formal(tripleArray2(), "a", false, false));
+#line 3361 "runtime.in"
+ addFunc(ve, run::gen262, primBoolean(), "is3D", formal(primPicture(), "f", false, false));
+#line 3366 "runtime.in"
+ addFunc(ve, run::gen263, primPair(), "bezier", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3373 "runtime.in"
+ addFunc(ve, run::gen264, primPair(), "bezierP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3378 "runtime.in"
+ addFunc(ve, run::gen265, primPair(), "bezierPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3383 "runtime.in"
+ addFunc(ve, run::gen266, primPair(), "bezierPPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
+#line 3388 "runtime.in"
+ addFunc(ve, run::gen267, primTriple(), "bezier", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3395 "runtime.in"
+ addFunc(ve, run::gen268, primTriple(), "bezierP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3400 "runtime.in"
+ addFunc(ve, run::gen269, primTriple(), "bezierPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3405 "runtime.in"
+ addFunc(ve, run::gen270, primTriple(), "bezierPPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false));
+#line 3418 "runtime.in"
+ addFunc(ve, run::gen272, primInt(), "length", formal(primString(), "s", false, false));
+#line 3423 "runtime.in"
+ addFunc(ve, run::gen273, primInt(), "find", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
+#line 3429 "runtime.in"
+ addFunc(ve, run::gen274, primInt(), "rfind", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
+#line 3435 "runtime.in"
+ addFunc(ve, run::gen275, primString() , "reverse", formal(primString() , "s", false, false));
+#line 3441 "runtime.in"
+ addFunc(ve, run::gen276, primString() , "insert", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primString() , "t", false, false));
+#line 3448 "runtime.in"
+ addFunc(ve, run::gen277, primString() , "substr", formal(primString(), "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", true, false));
+#line 3455 "runtime.in"
+ addFunc(ve, run::gen278, primString() , "erase", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", false, false));
+#line 3462 "runtime.in"
+ addFunc(ve, run::gen279, primString() , "downcase", formal(primString() , "s", false, false));
+#line 3468 "runtime.in"
+ addFunc(ve, run::gen280, primString() , "upcase", formal(primString() , "s", false, false));
+#line 3474 "runtime.in"
+ addFunc(ve, run::gen281, primString() , "replace", formal(primString(), "s", false, false), formal(stringArray2(), "translate", false, false));
+#line 3501 "runtime.in"
+ addFunc(ve, run::gen282, primString() , "format", formal(primString(), "format", false, false), formal(primInt(), "x", false, false));
+#line 3516 "runtime.in"
+ addFunc(ve, run::gen283, primString() , "format", formal(primString(), "format", false, false), formal(primReal(), "x", false, false), formal(primString() , "locale", true, false));
+#line 3634 "runtime.in"
+ addFunc(ve, run::gen284, primInt(), "hex", formal(primString() , "s", false, false));
+#line 3645 "runtime.in"
+ addFunc(ve, run::gen285, primString() , "string", formal(primInt(), "x", false, false));
+#line 3652 "runtime.in"
+ addFunc(ve, run::gen286, primString() , "string", formal(primReal(), "x", false, false), formal(primInt(), "digits", true, false));
+#line 3660 "runtime.in"
+ addFunc(ve, run::gen287, primString() , "time", formal(primString() , "format", true, false));
+#line 3671 "runtime.in"
+ addFunc(ve, run::gen288, primString() , "time", formal(primInt(), "seconds", false, false), formal(primString() , "format", true, false));
+#line 3684 "runtime.in"
+ addFunc(ve, run::gen289, primInt(), "seconds", formal(primString() , "t", true, false), formal(primString() , "format", true, false));
+#line 3696 "runtime.in"
+ addFunc(ve, run::gen290, realArray(), "_cputime");
+#line 3710 "runtime.in"
+ addFunc(ve, run::gen291, primReal(), "^", formal(primReal(), "x", false, false), formal(primInt(), "y", false, false));
+#line 3718 "runtime.in"
+ addFunc(ve, run::gen292, primPair(), "^", formal(primPair(), "z", false, false), formal(primInt(), "y", false, false));
+#line 3723 "runtime.in"
+ addFunc(ve, run::gen293, primInt(), "quotient", formal(primInt(), "x", false, false), formal(primInt(), "y", false, false));
+#line 3731 "runtime.in"
+ addFunc(ve, run::gen294, primInt(), "abs", formal(primInt(), "x", false, false));
+#line 3736 "runtime.in"
+ addFunc(ve, run::gen295, primInt(), "sgn", formal(primReal(), "x", false, false));
#line 3741 "runtime.in"
- addFunc(ve, run::gen298, primInt(), "ceil", formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen296, primInt(), "rand");
#line 3746 "runtime.in"
- addFunc(ve, run::gen299, primInt(), "floor", formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen297, primVoid(), "srand", formal(primInt(), "seed", false, false));
#line 3751 "runtime.in"
- addFunc(ve, run::gen300, primInt(), "round", formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen298, primReal(), "unitrand");
#line 3757 "runtime.in"
- addFunc(ve, run::gen301, primInt(), "Ceil", formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen299, primInt(), "ceil", formal(primReal(), "x", false, false));
#line 3762 "runtime.in"
- addFunc(ve, run::gen302, primInt(), "Floor", formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen300, primInt(), "floor", formal(primReal(), "x", false, false));
#line 3767 "runtime.in"
- addFunc(ve, run::gen303, primInt(), "Round", formal(primReal(), "x", false, false));
-#line 3772 "runtime.in"
- addFunc(ve, run::gen304, primReal(), "fmod", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+ addFunc(ve, run::gen301, primInt(), "round", formal(primReal(), "x", false, false));
+#line 3773 "runtime.in"
+ addFunc(ve, run::gen302, primInt(), "Ceil", formal(primReal(), "x", false, false));
#line 3778 "runtime.in"
- addFunc(ve, run::gen305, primReal(), "atan2", formal(primReal(), "y", false, false), formal(primReal(), "x", false, false));
+ addFunc(ve, run::gen303, primInt(), "Floor", formal(primReal(), "x", false, false));
#line 3783 "runtime.in"
- addFunc(ve, run::gen306, primReal(), "hypot", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+ addFunc(ve, run::gen304, primInt(), "Round", formal(primReal(), "x", false, false));
#line 3788 "runtime.in"
- addFunc(ve, run::gen307, primReal(), "remainder", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
-#line 3793 "runtime.in"
- addFunc(ve, run::gen308, primReal(), "J", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
-#line 3798 "runtime.in"
- addFunc(ve, run::gen309, primReal(), "Y", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
-#line 3803 "runtime.in"
- addFunc(ve, run::gen310, primReal(), "erf", formal(primReal(), "x", false, false));
-#line 3808 "runtime.in"
- addFunc(ve, run::gen311, primReal(), "erfc", formal(primReal(), "x", false, false));
-#line 3813 "runtime.in"
- addFunc(ve, run::gen312, primInt(), "factorial", formal(primInt(), "n", false, false));
-#line 3818 "runtime.in"
- addFunc(ve, run::gen313, primInt(), "choose", formal(primInt(), "n", false, false), formal(primInt(), "k", false, false));
+ addFunc(ve, run::gen305, primReal(), "fmod", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3794 "runtime.in"
+ addFunc(ve, run::gen306, primReal(), "atan2", formal(primReal(), "y", false, false), formal(primReal(), "x", false, false));
+#line 3799 "runtime.in"
+ addFunc(ve, run::gen307, primReal(), "hypot", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3804 "runtime.in"
+ addFunc(ve, run::gen308, primReal(), "remainder", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3809 "runtime.in"
+ addFunc(ve, run::gen309, primReal(), "J", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
+#line 3814 "runtime.in"
+ addFunc(ve, run::gen310, primReal(), "Y", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
+#line 3819 "runtime.in"
+ addFunc(ve, run::gen311, primReal(), "erf", formal(primReal(), "x", false, false));
+#line 3824 "runtime.in"
+ addFunc(ve, run::gen312, primReal(), "erfc", formal(primReal(), "x", false, false));
#line 3829 "runtime.in"
- addFunc(ve, run::gen314, primReal(), "gamma", formal(primReal(), "x", false, false));
-#line 3839 "runtime.in"
- addFunc(ve, run::gen315, primPair(), "gamma", formal(primPair(), "z", false, true));
+ addFunc(ve, run::gen313, primInt(), "factorial", formal(primInt(), "n", false, false));
+#line 3834 "runtime.in"
+ addFunc(ve, run::gen314, primInt(), "choose", formal(primInt(), "n", false, false), formal(primInt(), "k", false, false));
#line 3845 "runtime.in"
- addFunc(ve, run::gen316, realArray(), "quadraticroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false));
-#line 3854 "runtime.in"
- addFunc(ve, run::gen317, pairArray(), "quadraticroots", formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primPair(), "c", false, true));
-#line 3863 "runtime.in"
- addFunc(ve, run::gen318, realArray(), "cubicroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false), formal(primReal(), "d", false, false));
-#line 3873 "runtime.in"
- addFunc(ve, run::gen319, primBoolean(), "==", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
-#line 3881 "runtime.in"
- addFunc(ve, run::gen320, primBoolean(), "!=", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
-#line 3886 "runtime.in"
- addFunc(ve, run::gen321, primTransform(), "+", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
-#line 3891 "runtime.in"
- addFunc(ve, run::gen322, primTransform(), "*", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
-#line 3896 "runtime.in"
- addFunc(ve, run::gen323, primPair(), "*", formal(primTransform(), "t", false, false), formal(primPair(), "z", false, false));
-#line 3901 "runtime.in"
- addFunc(ve, run::gen324, primPath(), "*", formal(primTransform(), "t", false, false), formal(primPath(), "g", false, false));
-#line 3906 "runtime.in"
- addFunc(ve, run::gen325, primPen(), "*", formal(primTransform(), "t", false, false), formal(primPen(), "p", false, false));
-#line 3911 "runtime.in"
- addFunc(ve, run::gen326, primPicture(), "*", formal(primTransform(), "t", false, false), formal(primPicture(), "f", false, false));
-#line 3916 "runtime.in"
- addFunc(ve, run::gen327, primPicture(), "*", formal(realArray2(), "t", false, false), formal(primPicture(), "f", false, false));
-#line 3921 "runtime.in"
- addFunc(ve, run::gen328, primTransform(), "^", formal(primTransform(), "t", false, false), formal(primInt(), "n", false, false));
-#line 3968 "runtime.in"
- addFunc(ve, run::gen336, primTransform(), "shift", formal(primTransform(), "t", false, false));
-#line 3973 "runtime.in"
- addFunc(ve, run::gen337, primTransform(), "shiftless", formal(primTransform(), "t", false, false));
-#line 3978 "runtime.in"
+ addFunc(ve, run::gen315, primReal(), "gamma", formal(primReal(), "x", false, false));
+#line 3855 "runtime.in"
+ addFunc(ve, run::gen316, primPair(), "gamma", formal(primPair(), "z", false, true));
+#line 3861 "runtime.in"
+ addFunc(ve, run::gen317, realArray(), "quadraticroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false));
+#line 3870 "runtime.in"
+ addFunc(ve, run::gen318, pairArray(), "quadraticroots", formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primPair(), "c", false, true));
+#line 3879 "runtime.in"
+ addFunc(ve, run::gen319, realArray(), "cubicroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false), formal(primReal(), "d", false, false));
+#line 3889 "runtime.in"
+ addFunc(ve, run::gen320, primBoolean(), "==", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3897 "runtime.in"
+ addFunc(ve, run::gen321, primBoolean(), "!=", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3902 "runtime.in"
+ addFunc(ve, run::gen322, primTransform(), "+", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3907 "runtime.in"
+ addFunc(ve, run::gen323, primTransform(), "*", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3912 "runtime.in"
+ addFunc(ve, run::gen324, primPair(), "*", formal(primTransform(), "t", false, false), formal(primPair(), "z", false, false));
+#line 3917 "runtime.in"
+ addFunc(ve, run::gen325, primPath(), "*", formal(primTransform(), "t", false, false), formal(primPath(), "g", false, false));
+#line 3922 "runtime.in"
+ addFunc(ve, run::gen326, primPen(), "*", formal(primTransform(), "t", false, false), formal(primPen(), "p", false, false));
+#line 3927 "runtime.in"
+ addFunc(ve, run::gen327, primPicture(), "*", formal(primTransform(), "t", false, false), formal(primPicture(), "f", false, false));
+#line 3932 "runtime.in"
+ addFunc(ve, run::gen328, primPicture(), "*", formal(realArray2(), "t", false, false), formal(primPicture(), "f", false, false));
+#line 3937 "runtime.in"
+ addFunc(ve, run::gen329, primTransform(), "^", formal(primTransform(), "t", false, false), formal(primInt(), "n", false, false));
+#line 3984 "runtime.in"
+ addFunc(ve, run::gen337, primTransform(), "shift", formal(primTransform(), "t", false, false));
+#line 3989 "runtime.in"
+ addFunc(ve, run::gen338, primTransform(), "shiftless", formal(primTransform(), "t", false, false));
+#line 3994 "runtime.in"
addFunc(ve, run::transformIdentity, primTransform(), "identity");
-#line 3983 "runtime.in"
- addFunc(ve, run::gen339, primTransform(), "inverse", formal(primTransform(), "t", false, false));
-#line 3988 "runtime.in"
- addFunc(ve, run::gen340, primTransform(), "shift", formal(primPair(), "z", false, false));
-#line 3993 "runtime.in"
- addFunc(ve, run::gen341, primTransform(), "shift", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
-#line 3998 "runtime.in"
- addFunc(ve, run::gen342, primTransform(), "xscale", formal(primReal(), "x", false, false));
-#line 4003 "runtime.in"
- addFunc(ve, run::gen343, primTransform(), "yscale", formal(primReal(), "y", false, false));
-#line 4008 "runtime.in"
- addFunc(ve, run::gen344, primTransform(), "scale", formal(primReal(), "x", false, false));
-#line 4013 "runtime.in"
- addFunc(ve, run::gen345, primTransform(), "scale", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
-#line 4018 "runtime.in"
- addFunc(ve, run::gen346, primTransform(), "slant", formal(primReal(), "s", false, false));
-#line 4023 "runtime.in"
- addFunc(ve, run::gen347, primTransform(), "rotate", formal(primReal(), "angle", false, false), formal(primPair(), "z", true, false));
-#line 4028 "runtime.in"
- addFunc(ve, run::gen348, primTransform(), "reflect", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false));
-#line 4051 "runtime.in"
+#line 3999 "runtime.in"
+ addFunc(ve, run::gen340, primTransform(), "inverse", formal(primTransform(), "t", false, false));
+#line 4004 "runtime.in"
+ addFunc(ve, run::gen341, primTransform(), "shift", formal(primPair(), "z", false, false));
+#line 4009 "runtime.in"
+ addFunc(ve, run::gen342, primTransform(), "shift", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 4014 "runtime.in"
+ addFunc(ve, run::gen343, primTransform(), "xscale", formal(primReal(), "x", false, false));
+#line 4019 "runtime.in"
+ addFunc(ve, run::gen344, primTransform(), "yscale", formal(primReal(), "y", false, false));
+#line 4024 "runtime.in"
+ addFunc(ve, run::gen345, primTransform(), "scale", formal(primReal(), "x", false, false));
+#line 4029 "runtime.in"
+ addFunc(ve, run::gen346, primTransform(), "scale", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 4034 "runtime.in"
+ addFunc(ve, run::gen347, primTransform(), "slant", formal(primReal(), "s", false, false));
+#line 4039 "runtime.in"
+ addFunc(ve, run::gen348, primTransform(), "rotate", formal(primReal(), "angle", false, false), formal(primPair(), "z", true, false));
+#line 4044 "runtime.in"
+ addFunc(ve, run::gen349, primTransform(), "reflect", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false));
+#line 4067 "runtime.in"
addFunc(ve, run::pairXPart, primReal(), "xpart", formal(primPair(), "z", false, false));
-#line 4056 "runtime.in"
+#line 4072 "runtime.in"
addFunc(ve, run::pairYPart, primReal(), "ypart", formal(primPair(), "z", false, false));
-#line 4061 "runtime.in"
- addFunc(ve, run::gen354, primReal(), "length", formal(primPair(), "z", false, false));
-#line 4066 "runtime.in"
- addFunc(ve, run::gen355, primReal(), "abs", formal(primPair(), "z", false, false));
-#line 4071 "runtime.in"
- addFunc(ve, run::gen356, primPair(), "sqrt", formal(primPair(), "z", false, true));
-#line 4076 "runtime.in"
- addFunc(ve, run::gen357, primReal(), "angle", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
-#line 4083 "runtime.in"
- addFunc(ve, run::gen358, primReal(), "degrees", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
-#line 4090 "runtime.in"
- addFunc(ve, run::gen359, primReal(), "radians", formal(primReal(), "degrees", false, false));
-#line 4096 "runtime.in"
- addFunc(ve, run::gen360, primReal(), "degrees", formal(primReal(), "radians", false, false));
-#line 4102 "runtime.in"
- addFunc(ve, run::gen361, primReal(), "Degrees", formal(primReal(), "radians", false, false));
-#line 4108 "runtime.in"
- addFunc(ve, run::gen362, primReal(), "Sin", formal(primReal(), "deg", false, false));
-#line 4113 "runtime.in"
- addFunc(ve, run::gen363, primReal(), "Cos", formal(primReal(), "deg", false, false));
+#line 4077 "runtime.in"
+ addFunc(ve, run::gen355, primReal(), "length", formal(primPair(), "z", false, false));
+#line 4082 "runtime.in"
+ addFunc(ve, run::gen356, primReal(), "abs", formal(primPair(), "z", false, false));
+#line 4087 "runtime.in"
+ addFunc(ve, run::gen357, primPair(), "sqrt", formal(primPair(), "z", false, true));
+#line 4092 "runtime.in"
+ addFunc(ve, run::gen358, primReal(), "angle", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
+#line 4099 "runtime.in"
+ addFunc(ve, run::gen359, primReal(), "degrees", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
+#line 4106 "runtime.in"
+ addFunc(ve, run::gen360, primReal(), "radians", formal(primReal(), "degrees", false, false));
+#line 4112 "runtime.in"
+ addFunc(ve, run::gen361, primReal(), "degrees", formal(primReal(), "radians", false, false));
#line 4118 "runtime.in"
- addFunc(ve, run::gen364, primReal(), "Tan", formal(primReal(), "deg", false, false));
-#line 4123 "runtime.in"
- addFunc(ve, run::gen365, primReal(), "aSin", formal(primReal(), "x", false, false));
-#line 4128 "runtime.in"
- addFunc(ve, run::gen366, primReal(), "aCos", formal(primReal(), "x", false, false));
-#line 4133 "runtime.in"
- addFunc(ve, run::gen367, primReal(), "aTan", formal(primReal(), "x", false, false));
-#line 4138 "runtime.in"
- addFunc(ve, run::gen368, primPair(), "unit", formal(primPair(), "z", false, false));
-#line 4143 "runtime.in"
- addFunc(ve, run::gen369, primPair(), "dir", formal(primReal(), "degrees", false, false));
-#line 4148 "runtime.in"
- addFunc(ve, run::gen370, primPair(), "dir", formal(primPair(), "z", false, true));
-#line 4153 "runtime.in"
- addFunc(ve, run::gen371, primPair(), "expi", formal(primReal(), "angle", false, false));
-#line 4158 "runtime.in"
- addFunc(ve, run::gen372, primPair(), "exp", formal(primPair(), "z", false, true));
-#line 4163 "runtime.in"
- addFunc(ve, run::gen373, primPair(), "log", formal(primPair(), "z", false, true));
-#line 4168 "runtime.in"
- addFunc(ve, run::gen374, primPair(), "sin", formal(primPair(), "z", false, true));
-#line 4173 "runtime.in"
- addFunc(ve, run::gen375, primPair(), "cos", formal(primPair(), "z", false, true));
-#line 4178 "runtime.in"
- addFunc(ve, run::gen376, primPair(), "conj", formal(primPair(), "z", false, false));
-#line 4183 "runtime.in"
- addFunc(ve, run::gen377, primPair(), "realmult", formal(primPair(), "z", false, false), formal(primPair(), "w", false, false));
-#line 4188 "runtime.in"
- addFunc(ve, run::gen378, primTriple(), "realmult", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
-#line 4193 "runtime.in"
- addFunc(ve, run::gen379, primReal(), "dot", formal(primPair(), "z", false, true), formal(primPair(), "w", false, true));
-#line 4213 "runtime.in"
+ addFunc(ve, run::gen362, primReal(), "Degrees", formal(primReal(), "radians", false, false));
+#line 4124 "runtime.in"
+ addFunc(ve, run::gen363, primReal(), "Sin", formal(primReal(), "deg", false, false));
+#line 4129 "runtime.in"
+ addFunc(ve, run::gen364, primReal(), "Cos", formal(primReal(), "deg", false, false));
+#line 4134 "runtime.in"
+ addFunc(ve, run::gen365, primReal(), "Tan", formal(primReal(), "deg", false, false));
+#line 4139 "runtime.in"
+ addFunc(ve, run::gen366, primReal(), "aSin", formal(primReal(), "x", false, false));
+#line 4144 "runtime.in"
+ addFunc(ve, run::gen367, primReal(), "aCos", formal(primReal(), "x", false, false));
+#line 4149 "runtime.in"
+ addFunc(ve, run::gen368, primReal(), "aTan", formal(primReal(), "x", false, false));
+#line 4154 "runtime.in"
+ addFunc(ve, run::gen369, primPair(), "unit", formal(primPair(), "z", false, false));
+#line 4159 "runtime.in"
+ addFunc(ve, run::gen370, primPair(), "dir", formal(primReal(), "degrees", false, false));
+#line 4164 "runtime.in"
+ addFunc(ve, run::gen371, primPair(), "dir", formal(primPair(), "z", false, true));
+#line 4169 "runtime.in"
+ addFunc(ve, run::gen372, primPair(), "expi", formal(primReal(), "angle", false, false));
+#line 4174 "runtime.in"
+ addFunc(ve, run::gen373, primPair(), "exp", formal(primPair(), "z", false, true));
+#line 4179 "runtime.in"
+ addFunc(ve, run::gen374, primPair(), "log", formal(primPair(), "z", false, true));
+#line 4184 "runtime.in"
+ addFunc(ve, run::gen375, primPair(), "sin", formal(primPair(), "z", false, true));
+#line 4189 "runtime.in"
+ addFunc(ve, run::gen376, primPair(), "cos", formal(primPair(), "z", false, true));
+#line 4194 "runtime.in"
+ addFunc(ve, run::gen377, primPair(), "conj", formal(primPair(), "z", false, false));
+#line 4199 "runtime.in"
+ addFunc(ve, run::gen378, primPair(), "realmult", formal(primPair(), "z", false, false), formal(primPair(), "w", false, false));
+#line 4204 "runtime.in"
+ addFunc(ve, run::gen379, primTriple(), "realmult", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 4209 "runtime.in"
+ addFunc(ve, run::gen380, primReal(), "dot", formal(primPair(), "z", false, true), formal(primPair(), "w", false, true));
+#line 4229 "runtime.in"
addFunc(ve, run::tripleXPart, primReal(), "xpart", formal(primTriple(), "v", false, false));
-#line 4218 "runtime.in"
+#line 4234 "runtime.in"
addFunc(ve, run::tripleYPart, primReal(), "ypart", formal(primTriple(), "v", false, false));
-#line 4223 "runtime.in"
+#line 4239 "runtime.in"
addFunc(ve, run::tripleZPart, primReal(), "zpart", formal(primTriple(), "v", false, false));
-#line 4228 "runtime.in"
- addFunc(ve, run::gen385, primTriple(), "*", formal(primReal(), "x", false, false), formal(primTriple(), "v", false, false));
-#line 4233 "runtime.in"
- addFunc(ve, run::gen386, primTriple(), "*", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
-#line 4238 "runtime.in"
- addFunc(ve, run::gen387, primTriple(), "/", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
-#line 4243 "runtime.in"
- addFunc(ve, run::gen388, primReal(), "length", formal(primTriple(), "v", false, false));
-#line 4248 "runtime.in"
- addFunc(ve, run::gen389, primReal(), "abs", formal(primTriple(), "v", false, false));
-#line 4253 "runtime.in"
- addFunc(ve, run::gen390, primReal(), "polar", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4244 "runtime.in"
+ addFunc(ve, run::gen386, primTriple(), "*", formal(primReal(), "x", false, false), formal(primTriple(), "v", false, false));
+#line 4249 "runtime.in"
+ addFunc(ve, run::gen387, primTriple(), "*", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
+#line 4254 "runtime.in"
+ addFunc(ve, run::gen388, primTriple(), "/", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
#line 4259 "runtime.in"
- addFunc(ve, run::gen391, primReal(), "azimuth", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
-#line 4265 "runtime.in"
- addFunc(ve, run::gen392, primReal(), "colatitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
-#line 4271 "runtime.in"
- addFunc(ve, run::gen393, primReal(), "latitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
-#line 4277 "runtime.in"
- addFunc(ve, run::gen394, primReal(), "longitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
-#line 4284 "runtime.in"
- addFunc(ve, run::gen395, primTriple(), "unit", formal(primTriple(), "v", false, false));
-#line 4289 "runtime.in"
- addFunc(ve, run::gen396, primReal(), "dot", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
-#line 4294 "runtime.in"
- addFunc(ve, run::gen397, primTriple(), "cross", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
-#line 4299 "runtime.in"
- addFunc(ve, run::gen398, primTriple(), "expi", formal(primReal(), "polar", false, false), formal(primReal(), "azimuth", false, false));
-#line 4304 "runtime.in"
- addFunc(ve, run::gen399, primTriple(), "dir", formal(primReal(), "colatitude", false, false), formal(primReal(), "longitude", false, false));
-#line 4309 "runtime.in"
- addFunc(ve, run::gen400, primVoid(), "atupdate", formal(voidFunction(), "f", false, false));
-#line 4317 "runtime.in"
- addFunc(ve, run::gen401, voidFunction(), "atupdate");
-#line 4322 "runtime.in"
- addFunc(ve, run::gen402, primVoid(), "atexit", formal(voidFunction(), "f", false, false));
-#line 4327 "runtime.in"
- addFunc(ve, run::gen403, voidFunction(), "atexit");
-#line 4332 "runtime.in"
- addFunc(ve, run::gen404, primVoid(), "atbreakpoint", formal(breakpointFunction(), "f", false, false));
-#line 4337 "runtime.in"
- addFunc(ve, run::gen405, primVoid(), "breakpoint", formal(primCode(), "s", true, false));
-#line 4342 "runtime.in"
- addFunc(ve, run::gen406, primString() , "locatefile", formal(primString() , "file", false, false));
-#line 4347 "runtime.in"
- addFunc(ve, run::gen407, primVoid(), "stop", formal(primString() , "file", false, false), formal(primInt(), "line", false, false), formal(primCode(), "s", true, false));
-#line 4355 "runtime.in"
- addFunc(ve, run::gen408, primVoid(), "breakpoints");
-#line 4361 "runtime.in"
- addFunc(ve, run::gen409, primVoid(), "clear", formal(primString() , "file", false, false), formal(primInt(), "line", false, false));
-#line 4367 "runtime.in"
- addFunc(ve, run::gen410, primVoid(), "clear");
-#line 4372 "runtime.in"
- addFunc(ve, run::gen411, primString() , "stripdirectory", formal(primString(), "s", false, false));
-#line 4378 "runtime.in"
- addFunc(ve, run::gen412, primString() , "stripfile", formal(primString(), "s", false, false));
-#line 4384 "runtime.in"
- addFunc(ve, run::gen413, primString() , "stripextension", formal(primString(), "s", false, false));
-#line 4390 "runtime.in"
- addFunc(ve, run::gen414, primInt(), "convert", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
-#line 4408 "runtime.in"
- addFunc(ve, run::gen415, primInt(), "animate", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
+ addFunc(ve, run::gen389, primReal(), "length", formal(primTriple(), "v", false, false));
+#line 4264 "runtime.in"
+ addFunc(ve, run::gen390, primReal(), "abs", formal(primTriple(), "v", false, false));
+#line 4269 "runtime.in"
+ addFunc(ve, run::gen391, primReal(), "polar", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4275 "runtime.in"
+ addFunc(ve, run::gen392, primReal(), "azimuth", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4281 "runtime.in"
+ addFunc(ve, run::gen393, primReal(), "colatitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4287 "runtime.in"
+ addFunc(ve, run::gen394, primReal(), "latitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4293 "runtime.in"
+ addFunc(ve, run::gen395, primReal(), "longitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4300 "runtime.in"
+ addFunc(ve, run::gen396, primTriple(), "unit", formal(primTriple(), "v", false, false));
+#line 4305 "runtime.in"
+ addFunc(ve, run::gen397, primReal(), "dot", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 4310 "runtime.in"
+ addFunc(ve, run::gen398, primTriple(), "cross", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 4315 "runtime.in"
+ addFunc(ve, run::gen399, primTriple(), "expi", formal(primReal(), "polar", false, false), formal(primReal(), "azimuth", false, false));
+#line 4320 "runtime.in"
+ addFunc(ve, run::gen400, primTriple(), "dir", formal(primReal(), "colatitude", false, false), formal(primReal(), "longitude", false, false));
+#line 4325 "runtime.in"
+ addFunc(ve, run::gen401, primVoid(), "atupdate", formal(voidFunction(), "f", false, false));
+#line 4333 "runtime.in"
+ addFunc(ve, run::gen402, voidFunction(), "atupdate");
+#line 4338 "runtime.in"
+ addFunc(ve, run::gen403, primVoid(), "atexit", formal(voidFunction(), "f", false, false));
+#line 4343 "runtime.in"
+ addFunc(ve, run::gen404, voidFunction(), "atexit");
+#line 4348 "runtime.in"
+ addFunc(ve, run::gen405, primVoid(), "atbreakpoint", formal(breakpointFunction(), "f", false, false));
+#line 4353 "runtime.in"
+ addFunc(ve, run::gen406, primVoid(), "breakpoint", formal(primCode(), "s", true, false));
+#line 4358 "runtime.in"
+ addFunc(ve, run::gen407, primString() , "locatefile", formal(primString() , "file", false, false));
+#line 4363 "runtime.in"
+ addFunc(ve, run::gen408, primVoid(), "stop", formal(primString() , "file", false, false), formal(primInt(), "line", false, false), formal(primCode(), "s", true, false));
+#line 4371 "runtime.in"
+ addFunc(ve, run::gen409, primVoid(), "breakpoints");
+#line 4377 "runtime.in"
+ addFunc(ve, run::gen410, primVoid(), "clear", formal(primString() , "file", false, false), formal(primInt(), "line", false, false));
+#line 4383 "runtime.in"
+ addFunc(ve, run::gen411, primVoid(), "clear");
+#line 4388 "runtime.in"
+ addFunc(ve, run::gen412, primString() , "stripdirectory", formal(primString(), "s", false, false));
+#line 4394 "runtime.in"
+ addFunc(ve, run::gen413, primString() , "stripfile", formal(primString(), "s", false, false));
+#line 4400 "runtime.in"
+ addFunc(ve, run::gen414, primString() , "stripextension", formal(primString(), "s", false, false));
+#line 4406 "runtime.in"
+ addFunc(ve, run::gen415, primInt(), "convert", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
#line 4424 "runtime.in"
- addFunc(ve, run::gen416, primInt(), "delete", formal(primString(), "s", false, false));
-#line 4434 "runtime.in"
- addFunc(ve, run::gen417, primInt(), "rename", formal(primString(), "from", false, false), formal(primString(), "to", false, false));
-#line 4733 "runtime.in"
- addFunc(ve, run::gen448, IntArray(), "complement", formal(IntArray(), "a", false, false), formal(primInt(), "n", false, false));
-#line 4765 "runtime.in"
- addFunc(ve, run::gen450, IntArray(), "sequence", formal(primInt(), "n", false, false));
-#line 4798 "runtime.in"
- addFunc(ve, run::gen453, primBoolean(), "all", formal(boolArray(), "a", false, false));
-#line 4807 "runtime.in"
- addFunc(ve, run::gen454, boolArray(), "!", formal(boolArray(), "a", false, false));
-#line 4816 "runtime.in"
- addFunc(ve, run::gen455, primInt(), "sum", formal(boolArray(), "a", false, false));
-#line 4979 "runtime.in"
- addFunc(ve, run::gen462, primInt(), "find", formal(boolArray(), "a", false, false), formal(primInt(), "n", true, false));
-#line 4999 "runtime.in"
- addFunc(ve, run::gen463, primBoolean(), "==", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
-#line 5044 "runtime.in"
- addFunc(ve, run::gen465, realArray2(), "identity", formal(primInt(), "n", false, false));
-#line 5067 "runtime.in"
- addFunc(ve, run::gen467, realArray2(), "inverse", formal(realArray2(), "a", false, false));
-#line 5159 "runtime.in"
- addFunc(ve, run::gen468, realArray(), "solve", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false), formal(primBoolean(), "warn", true, false));
-#line 5210 "runtime.in"
- addFunc(ve, run::gen469, realArray2(), "solve", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false), formal(primBoolean(), "warn", true, false));
-#line 5274 "runtime.in"
- addFunc(ve, run::gen470, primReal(), "determinant", formal(realArray2(), "a", false, false));
+ addFunc(ve, run::gen416, primInt(), "animate", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
+#line 4440 "runtime.in"
+ addFunc(ve, run::gen417, primInt(), "delete", formal(primString(), "s", false, false));
+#line 4450 "runtime.in"
+ addFunc(ve, run::gen418, primInt(), "rename", formal(primString(), "from", false, false), formal(primString(), "to", false, false));
+#line 4749 "runtime.in"
+ addFunc(ve, run::gen449, IntArray(), "complement", formal(IntArray(), "a", false, false), formal(primInt(), "n", false, false));
+#line 4781 "runtime.in"
+ addFunc(ve, run::gen451, IntArray(), "sequence", formal(primInt(), "n", false, false));
+#line 4814 "runtime.in"
+ addFunc(ve, run::gen454, primBoolean(), "all", formal(boolArray(), "a", false, false));
+#line 4823 "runtime.in"
+ addFunc(ve, run::gen455, boolArray(), "!", formal(boolArray(), "a", false, false));
+#line 4832 "runtime.in"
+ addFunc(ve, run::gen456, primInt(), "sum", formal(boolArray(), "a", false, false));
+#line 4995 "runtime.in"
+ addFunc(ve, run::gen463, primInt(), "find", formal(boolArray(), "a", false, false), formal(primInt(), "n", true, false));
+#line 5015 "runtime.in"
+ addFunc(ve, run::gen464, primBoolean(), "==", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
+#line 5060 "runtime.in"
+ addFunc(ve, run::gen466, realArray2(), "identity", formal(primInt(), "n", false, false));
+#line 5083 "runtime.in"
+ addFunc(ve, run::gen468, realArray2(), "inverse", formal(realArray2(), "a", false, false));
+#line 5175 "runtime.in"
+ addFunc(ve, run::gen469, realArray(), "solve", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false), formal(primBoolean(), "warn", true, false));
+#line 5226 "runtime.in"
+ addFunc(ve, run::gen470, realArray2(), "solve", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false), formal(primBoolean(), "warn", true, false));
#line 5290 "runtime.in"
- addFunc(ve, run::gen471, realArray(), "*", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false));
-#line 5308 "runtime.in"
- addFunc(ve, run::gen472, realArray2(), "*", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
-#line 5343 "runtime.in"
- addFunc(ve, run::gen473, primTriple(), "*", formal(realArray2(), "t", false, false), formal(primTriple(), "v", false, false));
-#line 5348 "runtime.in"
- addFunc(ve, run::gen474, primPair(), "project", formal(primTriple(), "v", false, false), formal(realArray2(), "t", false, false));
-#line 5373 "runtime.in"
- addFunc(ve, run::gen475, primReal(), "dot", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false));
-#line 5383 "runtime.in"
- addFunc(ve, run::gen476, realArray(), "tridiagonal", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false), formal(realArray(), "c", false, false), formal(realArray(), "f", false, false));
-#line 5487 "runtime.in"
- addFunc(ve, run::gen477, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "verbose", true, false));
-#line 5534 "runtime.in"
- addFunc(ve, run::gen478, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x1", false, false), formal(primReal(), "x2", false, false), formal(primBoolean(), "verbose", true, false));
-#line 5616 "runtime.in"
- addFunc(ve, run::gen479, primReal(), "simpson", formal(realRealFunction(), "f", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "acc", true, false), formal(primReal(), "dxmax", true, false));
-#line 5658 "runtime.in"
- addFunc(ve, run::gen481, IntArray2(), "triangulate", formal(pairArray(), "z", false, false));
-#line 5693 "runtime.in"
- addFunc(ve, run::gen482, primBoolean(), "==", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
-#line 5701 "runtime.in"
- addFunc(ve, run::gen483, primBoolean(), "!=", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
-#line 5711 "runtime.in"
- addFunc(ve, run::gen485, primFile(), "input", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false), formal(primString() , "comment", true, false));
-#line 5719 "runtime.in"
- addFunc(ve, run::gen486, primFile(), "output", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false), formal(primString() , "comment", true, false));
-#line 5731 "runtime.in"
- addFunc(ve, run::gen487, primFile(), "xinput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
-#line 5745 "runtime.in"
- addFunc(ve, run::gen488, primFile(), "xoutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
-#line 5763 "runtime.in"
- addFunc(ve, run::gen489, primFile(), "binput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
-#line 5770 "runtime.in"
- addFunc(ve, run::gen490, primFile(), "boutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
-#line 5780 "runtime.in"
- addFunc(ve, run::gen491, primBoolean(), "eof", formal(primFile(), "file", false, false));
-#line 5785 "runtime.in"
- addFunc(ve, run::gen492, primBoolean(), "eol", formal(primFile(), "file", false, false));
-#line 5790 "runtime.in"
- addFunc(ve, run::gen493, primBoolean(), "error", formal(primFile(), "file", false, false));
-#line 5795 "runtime.in"
- addFunc(ve, run::gen494, primVoid(), "clear", formal(primFile(), "file", false, false));
-#line 5800 "runtime.in"
- addFunc(ve, run::gen495, primVoid(), "close", formal(primFile(), "file", false, false));
-#line 5805 "runtime.in"
- addFunc(ve, run::gen496, primInt(), "precision", formal(primFile(), "file", true, false), formal(primInt(), "digits", true, false));
+ addFunc(ve, run::gen471, primReal(), "determinant", formal(realArray2(), "a", false, false));
+#line 5306 "runtime.in"
+ addFunc(ve, run::gen472, realArray(), "*", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false));
+#line 5324 "runtime.in"
+ addFunc(ve, run::gen473, realArray2(), "*", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
+#line 5359 "runtime.in"
+ addFunc(ve, run::gen474, primTriple(), "*", formal(realArray2(), "t", false, false), formal(primTriple(), "v", false, false));
+#line 5364 "runtime.in"
+ addFunc(ve, run::gen475, primPair(), "project", formal(primTriple(), "v", false, false), formal(realArray2(), "t", false, false));
+#line 5389 "runtime.in"
+ addFunc(ve, run::gen476, primReal(), "dot", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false));
+#line 5399 "runtime.in"
+ addFunc(ve, run::gen477, realArray(), "tridiagonal", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false), formal(realArray(), "c", false, false), formal(realArray(), "f", false, false));
+#line 5503 "runtime.in"
+ addFunc(ve, run::gen478, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "verbose", true, false));
+#line 5550 "runtime.in"
+ addFunc(ve, run::gen479, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x1", false, false), formal(primReal(), "x2", false, false), formal(primBoolean(), "verbose", true, false));
+#line 5632 "runtime.in"
+ addFunc(ve, run::gen480, primReal(), "simpson", formal(realRealFunction(), "f", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "acc", true, false), formal(primReal(), "dxmax", true, false));
+#line 5674 "runtime.in"
+ addFunc(ve, run::gen482, IntArray2(), "triangulate", formal(pairArray(), "z", false, false));
+#line 5709 "runtime.in"
+ addFunc(ve, run::gen483, primBoolean(), "==", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
+#line 5717 "runtime.in"
+ addFunc(ve, run::gen484, primBoolean(), "!=", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
+#line 5727 "runtime.in"
+ addFunc(ve, run::gen486, primFile(), "input", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false), formal(primString() , "comment", true, false));
+#line 5735 "runtime.in"
+ addFunc(ve, run::gen487, primFile(), "output", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false), formal(primString() , "comment", true, false));
+#line 5747 "runtime.in"
+ addFunc(ve, run::gen488, primFile(), "xinput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
+#line 5761 "runtime.in"
+ addFunc(ve, run::gen489, primFile(), "xoutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
+#line 5779 "runtime.in"
+ addFunc(ve, run::gen490, primFile(), "binput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
+#line 5786 "runtime.in"
+ addFunc(ve, run::gen491, primFile(), "boutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
+#line 5796 "runtime.in"
+ addFunc(ve, run::gen492, primBoolean(), "eof", formal(primFile(), "file", false, false));
+#line 5801 "runtime.in"
+ addFunc(ve, run::gen493, primBoolean(), "eol", formal(primFile(), "file", false, false));
+#line 5806 "runtime.in"
+ addFunc(ve, run::gen494, primBoolean(), "error", formal(primFile(), "file", false, false));
#line 5811 "runtime.in"
- addFunc(ve, run::gen497, primVoid(), "flush", formal(primFile(), "file", false, false));
+ addFunc(ve, run::gen495, primVoid(), "clear", formal(primFile(), "file", false, false));
#line 5816 "runtime.in"
- addFunc(ve, run::gen498, primString() , "getc", formal(primFile(), "file", false, false));
-#line 5825 "runtime.in"
- addFunc(ve, run::gen499, primInt(), "tell", formal(primFile(), "file", false, false));
-#line 5830 "runtime.in"
- addFunc(ve, run::gen500, primVoid(), "seek", formal(primFile(), "file", false, false), formal(primInt(), "pos", false, false));
-#line 5835 "runtime.in"
- addFunc(ve, run::gen501, primVoid(), "seekeof", formal(primFile(), "file", false, false));
-#line 5840 "runtime.in"
- addFunc(ve, run::gen502, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false));
-#line 5847 "runtime.in"
- addFunc(ve, run::gen503, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false));
-#line 5853 "runtime.in"
- addFunc(ve, run::gen504, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false), formal(primInt(), "nz", false, false));
-#line 5859 "runtime.in"
- addFunc(ve, run::gen505, primFile(), "csv", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
-#line 5866 "runtime.in"
- addFunc(ve, run::gen506, primFile(), "word", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
-#line 5873 "runtime.in"
- addFunc(ve, run::gen507, primFile(), "line", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
-#line 5880 "runtime.in"
- addFunc(ve, run::gen508, primFile(), "single", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
-#line 5888 "runtime.in"
- addFunc(ve, run::gen509, primFile(), "single", formal(primFile(), "file", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "b", true, false));
+ addFunc(ve, run::gen496, primVoid(), "close", formal(primFile(), "file", false, false));
+#line 5821 "runtime.in"
+ addFunc(ve, run::gen497, primInt(), "precision", formal(primFile(), "file", true, false), formal(primInt(), "digits", true, false));
+#line 5827 "runtime.in"
+ addFunc(ve, run::gen498, primVoid(), "flush", formal(primFile(), "file", false, false));
+#line 5832 "runtime.in"
+ addFunc(ve, run::gen499, primString() , "getc", formal(primFile(), "file", false, false));
+#line 5841 "runtime.in"
+ addFunc(ve, run::gen500, primInt(), "tell", formal(primFile(), "file", false, false));
+#line 5846 "runtime.in"
+ addFunc(ve, run::gen501, primVoid(), "seek", formal(primFile(), "file", false, false), formal(primInt(), "pos", false, false));
+#line 5851 "runtime.in"
+ addFunc(ve, run::gen502, primVoid(), "seekeof", formal(primFile(), "file", false, false));
+#line 5856 "runtime.in"
+ addFunc(ve, run::gen503, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false));
+#line 5863 "runtime.in"
+ addFunc(ve, run::gen504, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false));
+#line 5869 "runtime.in"
+ addFunc(ve, run::gen505, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false), formal(primInt(), "nz", false, false));
+#line 5875 "runtime.in"
+ addFunc(ve, run::gen506, primFile(), "csv", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5882 "runtime.in"
+ addFunc(ve, run::gen507, primFile(), "word", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5889 "runtime.in"
+ addFunc(ve, run::gen508, primFile(), "line", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
#line 5896 "runtime.in"
- addFunc(ve, run::gen510, primFile(), "single", formal(primFile(), "file", false, false), formal(primInt(), "x", false, false), formal(primBoolean(), "b", true, false));
+ addFunc(ve, run::gen509, primFile(), "single", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
#line 5904 "runtime.in"
- addFunc(ve, run::gen511, primFile(), "read1", formal(primFile(), "file", false, false));
-#line 5911 "runtime.in"
- addFunc(ve, run::gen512, primFile(), "read2", formal(primFile(), "file", false, false));
-#line 5918 "runtime.in"
- addFunc(ve, run::gen513, primFile(), "read3", formal(primFile(), "file", false, false));
-#line 5925 "runtime.in"
- addFunc(ve, run::gen514, stringArray(), "history", formal(primString() , "name", false, false), formal(primInt(), "n", true, false));
-#line 5958 "runtime.in"
- addFunc(ve, run::gen515, stringArray(), "history", formal(primInt(), "n", true, false));
-#line 5969 "runtime.in"
- addFunc(ve, run::gen516, primString() , "readline", formal(primString() , "prompt", true, false), formal(primString() , "name", true, false), formal(primBoolean(), "tabcompletion", true, false));
-#line 6013 "runtime.in"
- addFunc(ve, run::gen517, primVoid(), "saveline", formal(primString() , "name", false, false), formal(primString() , "value", false, false), formal(primBoolean(), "store", true, false));
-#line 6043 "runtime.in"
- addFunc(ve, run::gen518, primVoid(), "generate_random_backtrace");
-#line 6052 "runtime.in"
- addFunc(ve, run::gen519, primVoid(), "print_random_addresses", formal(primInt(), "n", true, false));
+ addFunc(ve, run::gen510, primFile(), "single", formal(primFile(), "file", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "b", true, false));
+#line 5912 "runtime.in"
+ addFunc(ve, run::gen511, primFile(), "single", formal(primFile(), "file", false, false), formal(primInt(), "x", false, false), formal(primBoolean(), "b", true, false));
+#line 5920 "runtime.in"
+ addFunc(ve, run::gen512, primFile(), "read1", formal(primFile(), "file", false, false));
+#line 5927 "runtime.in"
+ addFunc(ve, run::gen513, primFile(), "read2", formal(primFile(), "file", false, false));
+#line 5934 "runtime.in"
+ addFunc(ve, run::gen514, primFile(), "read3", formal(primFile(), "file", false, false));
+#line 5941 "runtime.in"
+ addFunc(ve, run::gen515, stringArray(), "history", formal(primString() , "name", false, false), formal(primInt(), "n", true, false));
+#line 5974 "runtime.in"
+ addFunc(ve, run::gen516, stringArray(), "history", formal(primInt(), "n", true, false));
+#line 5985 "runtime.in"
+ addFunc(ve, run::gen517, primString() , "readline", formal(primString() , "prompt", true, false), formal(primString() , "name", true, false), formal(primBoolean(), "tabcompletion", true, false));
+#line 6029 "runtime.in"
+ addFunc(ve, run::gen518, primVoid(), "saveline", formal(primString() , "name", false, false), formal(primString() , "value", false, false), formal(primBoolean(), "store", true, false));
+#line 6059 "runtime.in"
+ addFunc(ve, run::gen519, primVoid(), "generate_random_backtrace");
+#line 6068 "runtime.in"
+ addFunc(ve, run::gen520, primVoid(), "print_random_addresses", formal(primInt(), "n", true, false));
}
} // namespace trans
diff --git a/Build/source/utils/asymptote/runtime.in b/Build/source/utils/asymptote/runtime.in
index b921b6217e2..ecaf3d61d31 100644
--- a/Build/source/utils/asymptote/runtime.in
+++ b/Build/source/utils/asymptote/runtime.in
@@ -962,9 +962,25 @@ inline triple perp(triple v, triple u)
return v-dot(v,u)*u;
}
-string ASYo="/ASYo {( ) print 12 string cvs print} bind def";
-string pathforall="{(M) print ASYo ASYo} {(L) print ASYo ASYo} {(C) print ASYo ASYo ASYo ASYo ASYo ASYo} {(c) print} pathforall";
-string currentpoint="print currentpoint ASYo ASYo ";
+string ASYx="/ASYx {( ) print ASYX sub 12 string cvs print} bind def";
+string ASYy="/ASYy {( ) print ASYY sub 12 string cvs print} bind def";
+string pathforall="{(M) print ASYy ASYx} {(L) print ASYy ASYx} {(C) print ASYy ASYx ASYy ASYx ASYy ASYx} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYy ASYx ";
+string ASYinit="/ASYX currentpoint pop def /ASYY currentpoint exch pop def ";
+string ASY1="ASY1 {"+ASYinit+"/ASY1 false def} if ";
+
+void showpath(std::ofstream& ps)
+{
+ ps << ASYx << newl
+ << ASYy << newl
+ << "/ASY1 true def" << newl
+ << "/fill {" << ASY1
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << newl
+ << "/stroke {" << ASY1 << "strokepath "
+ << pathforall << " (M) " << currentpoint
+ << "currentpoint newpath moveto } bind def" << endl;
+}
array *readpath(const string& psname, bool keep,
double hscale=1.0, double vscale=1.0)
@@ -995,7 +1011,6 @@ array *readpath(const string& psname, bool keep,
bool cyclic=false;
bool active=false;
- pair offset;
while(!buf.eof()) {
char c;
buf >> c;
@@ -1023,13 +1038,13 @@ array *readpath(const string& psname, bool keep,
}
active=false;
cyclic=false;
- node.pre=node.point=readpair(buf,hscale,vscale)-offset;
+ node.pre=node.point=readpair(buf,hscale,vscale);
node.straight=false;
break;
}
case 'L':
{
- pair point=readpair(buf,hscale,vscale)-offset;
+ pair point=readpair(buf,hscale,vscale);
pair delta=(point-node.point)*third;
node.post=node.point+delta;
node.straight=true;
@@ -1041,9 +1056,9 @@ array *readpath(const string& psname, bool keep,
}
case 'C':
{
- pair point=readpair(buf,hscale,vscale)-offset;
- pair pre=readpair(buf,hscale,vscale)-offset;
- node.post=readpair(buf,hscale,vscale)-offset;
+ pair point=readpair(buf,hscale,vscale);
+ pair pre=readpair(buf,hscale,vscale);
+ node.post=readpair(buf,hscale,vscale);
node.straight=false;
nodes.push_back(node);
active=true;
@@ -1056,11 +1071,6 @@ array *readpath(const string& psname, bool keep,
cyclic=true;
break;
}
- case 'Z':
- {
- offset=readpair(buf,hscale,vscale);
- break;
- }
}
}
@@ -1272,6 +1282,26 @@ bool labels(picture *f)
return f->havelabels();
}
+realarray *texsize(string *s, pen p=CURRENTPEN)
+{
+ texinit();
+ processDataStruct &pd=processData();
+
+ string texengine=getSetting<string>("tex");
+ const char **abort=texabort(texengine);
+ setpen(pd.tex,texengine,p);
+
+ double width,height,depth;
+ if(!texbounds(width,height,depth,pd.tex,*s,abort,false,true))
+ return new array(0);
+
+ array *t=new array(3);
+ (*t)[0]=width;
+ (*t)[1]=height;
+ (*t)[2]=depth;
+ return t;
+}
+
patharray *_texpath(string *s, pen p=CURRENTPEN)
{
array *P=new array(0);
@@ -1290,18 +1320,19 @@ patharray *_texpath(string *s, pen p=CURRENTPEN)
if(!pdf) {
tex.verbatimline("\\special{ps:");
- tex.verbatimline(ASYo);
+ tex.verbatimline(ASYx);
+ tex.verbatimline(ASYy);
tex.verbatimline("/ASY1 true def");
- tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
- tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
- "/ASY1 false def} if currentpoint newpath moveto false charpath "+
+ tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYy ASYx (L) print ASYy add ASYx (L) print add ASYy add ASYx (L) print add ASYy ASYx (c) print} bind def");
+ tex.verbatimline("/show {"+ASY1+
+ "currentpoint newpath moveto false charpath "+
pathforall+"} bind def}");
}
tex.verbatimline(*s+"%");
tex.epilogue(true);
tex.close();
- // TODO: Put in common subproutine (cf. teprocess).
+ // TODO: Put in common subproutine (cf. texprocess).
string aux=auxname(prefix,"aux");
unlink(aux.c_str());
string program=texprogram();
@@ -1329,16 +1360,8 @@ patharray *_texpath(string *s, pen p=CURRENTPEN)
std::ofstream ps(psname.c_str());
if(!ps) cannotwrite(psname);
- ps << ASYo << newl
- << "/ASY1 true def" << newl
- << "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl
- << "/stroke {ASY1 {(Z) " << currentpoint
- << "/ASY1 false def} if strokepath "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl;
-
+ showpath(ps);
+
ostringstream cmd;
cmd << "'" << getSetting<string>("gs")
<< "' -q -dNOCACHE -dNOPAUSE -dBATCH";
@@ -1411,15 +1434,7 @@ patharray *textpath(string *s, pen p=CURRENTPEN)
std::ofstream ps(psname.c_str());
if(!ps) cannotwrite(psname);
- ps << ASYo << newl
- << "/ASY1 true def" << newl
- << "/fill {ASY1 {(Z) " << currentpoint << "/ASY1 false def} if "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << newl
- << "/stroke {ASY1 {(Z) " << currentpoint
- << "/ASY1 false def} if strokepath "
- << pathforall << " (M) " << currentpoint
- << "currentpoint newpath moveto } bind def" << endl;
+ showpath(ps);
ostringstream pipe;
pipe << getSetting<string>("textcommand") << " '" << textname << "'";
@@ -1470,8 +1485,9 @@ patharray *_strokepath(path g, pen p=CURRENTPEN)
bbox b;
psfile ps(psname,false);
ps.prologue(b);
- ps.verbatimline(ASYo);
- ps.verbatimline("/stroke {(Z) "+currentpoint+pathforall+"} bind def");
+ ps.verbatimline(ASYx);
+ ps.verbatimline(ASYy);
+ ps.verbatimline("/stroke {"+ASYinit+pathforall+"} bind def");
ps.resetpen();
ps.setpen(p);
ps.write(g);
diff --git a/Build/source/utils/asymptote/settings.cc b/Build/source/utils/asymptote/settings.cc
index 3af58073c3a..5c24dba4e93 100644
--- a/Build/source/utils/asymptote/settings.cc
+++ b/Build/source/utils/asymptote/settings.cc
@@ -1339,13 +1339,6 @@ const char *endspecial() {
return "}%";
}
-// Default TeX units.
-const char *texunits(const string& texengine)
-{
- return xe(texengine) ? "bp" : "pt";
-}
-
-
bool fataltex[]={false,true};
const char *pdftexerrors[]={"! "," ==> Fatal error",NULL};
const char *texerrors[]={"! ",NULL};
diff --git a/Build/source/utils/asymptote/settings.h b/Build/source/utils/asymptote/settings.h
index 7261313a1fd..e7b3a6301ce 100644
--- a/Build/source/utils/asymptote/settings.h
+++ b/Build/source/utils/asymptote/settings.h
@@ -107,7 +107,6 @@ const char *beginpicture(const string& texengine);
const char *endpicture(const string& texengine);
const char *beginspecial(const string& texengine);
const char *endspecial();
-const char *texunits(const string& texengine);
extern bool fataltex[];
const char **texabort(const string& texengine);
diff --git a/Build/source/utils/asymptote/texfile.cc b/Build/source/utils/asymptote/texfile.cc
index ef81e38d816..eb6a2c33c57 100644
--- a/Build/source/utils/asymptote/texfile.cc
+++ b/Build/source/utils/asymptote/texfile.cc
@@ -14,7 +14,6 @@
using std::ofstream;
using settings::getSetting;
-
namespace camp {
texfile::texfile(const string& texname, const bbox& box, bool pipe)
@@ -137,7 +136,6 @@ void texfile::prologue()
void texfile::beginlayer(const string& psname, bool postscript)
{
- const char *units=settings::texunits(texengine);
if(box.right > box.left && box.top > box.bottom) {
if(postscript) {
if(settings::context(texengine))
@@ -150,14 +148,12 @@ void texfile::beginlayer(const string& psname, bool postscript)
*out << "{" << psname << "}%" << newl;
}
if(!inlinetex)
- *out << "\\kern " << (box.left-box.right)*ps2tex << units
- << "%" << newl;
+ *out << "\\kern " << (box.left-box.right)*ps2tex << "pt%" << newl;
} else {
*out << "\\leavevmode\\vbox to " << (box.top-box.bottom)*ps2tex
- << units << "{}%" << newl;
+ << "pt{}%" << newl;
if(inlinetex)
- *out << "\\kern " << (box.right-box.left)*ps2tex << units
- << "%" << newl;
+ *out << "\\kern " << (box.right-box.left)*ps2tex << "pt%" << newl;
}
}
}
@@ -165,8 +161,7 @@ void texfile::beginlayer(const string& psname, bool postscript)
void texfile::endlayer()
{
if(inlinetex && (box.right > box.left && box.top > box.bottom))
- *out << "\\kern " << (box.left-box.right)*ps2tex
- << settings::texunits(texengine) << "%" << newl;
+ *out << "\\kern " << (box.left-box.right)*ps2tex << "pt%" << newl;
}
void texfile::writeshifted(path p, bool newPath)
diff --git a/Build/source/utils/asymptote/texfile.h b/Build/source/utils/asymptote/texfile.h
index f2a5d22dccd..32862613b51 100644
--- a/Build/source/utils/asymptote/texfile.h
+++ b/Build/source/utils/asymptote/texfile.h
@@ -26,9 +26,6 @@
namespace camp {
-const double tex2ps=72.0/72.27;
-const double ps2tex=1.0/tex2ps;
-
template<class T>
void texdocumentclass(T& out, bool pipe=false)
{