From 9e32dd6aee7faf4e59888cfbd7a927d497b563ad Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 8 Jun 2009 00:57:31 +0000 Subject: asymptote 1.76 git-svn-id: svn://tug.org/texlive/trunk@13664 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/utils/README | 6 +- Build/source/utils/asymptote/ChangeLog | 232 + Build/source/utils/asymptote/Makefile.in | 2 +- Build/source/utils/asymptote/ReleaseNotes | 15 +- Build/source/utils/asymptote/asymptote.spec | 2 +- Build/source/utils/asymptote/base/bezulate.asy | 37 +- Build/source/utils/asymptote/base/fontsize.asy | 2 +- Build/source/utils/asymptote/base/labelpath3.asy | 27 +- Build/source/utils/asymptote/base/plain_Label.asy | 20 +- Build/source/utils/asymptote/base/plain_paths.asy | 10 +- Build/source/utils/asymptote/base/plain_pens.asy | 6 +- .../source/utils/asymptote/base/plain_strings.asy | 19 + Build/source/utils/asymptote/base/three.asy | 106 +- Build/source/utils/asymptote/base/three_light.asy | 47 +- .../source/utils/asymptote/base/three_surface.asy | 16 + Build/source/utils/asymptote/configure | 18 +- Build/source/utils/asymptote/configure.ac | 2 +- Build/source/utils/asymptote/doc/CAD.pdf | Bin 67399 -> 67399 bytes Build/source/utils/asymptote/doc/FAQ/asy-faq.info | 2 +- Build/source/utils/asymptote/doc/asymptote.pdf | Bin 1558385 -> 1559735 bytes Build/source/utils/asymptote/doc/asymptote.sty | 10 +- Build/source/utils/asymptote/doc/asymptote.texi | 31 +- Build/source/utils/asymptote/doc/ocg.sty | 127 + Build/source/utils/asymptote/doc/png/Makefile.in | 3 +- .../source/utils/asymptote/doc/png/asymptote.info | 9643 +++++++++++++++++++- Build/source/utils/asymptote/drawclipend.h | 3 +- Build/source/utils/asymptote/drawfill.cc | 12 +- Build/source/utils/asymptote/drawlabel.cc | 38 +- Build/source/utils/asymptote/drawlabel.h | 10 +- .../utils/asymptote/examples/BezierSurface.asy | 2 +- Build/source/utils/asymptote/examples/condor.asy | 2 +- Build/source/utils/asymptote/examples/layers.asy | 44 + Build/source/utils/asymptote/examples/logo3.asy | 2 +- Build/source/utils/asymptote/examples/pdb.asy | 2 +- .../utils/asymptote/examples/pipeintersection.asy | 2 +- Build/source/utils/asymptote/examples/teapot.asy | 1 + .../utils/asymptote/examples/trefoilknot.asy | 2 +- Build/source/utils/asymptote/examples/wedge.asy | 2 +- Build/source/utils/asymptote/pen.h | 7 +- Build/source/utils/asymptote/picture.cc | 2 +- Build/source/utils/asymptote/picture.h | 4 +- Build/source/utils/asymptote/runtime.cc | 4641 +++++----- Build/source/utils/asymptote/runtime.in | 96 +- Build/source/utils/asymptote/settings.cc | 7 - Build/source/utils/asymptote/settings.h | 1 - Build/source/utils/asymptote/texfile.cc | 13 +- Build/source/utils/asymptote/texfile.h | 3 - 47 files changed, 12592 insertions(+), 2687 deletions(-) create mode 100644 Build/source/utils/asymptote/doc/ocg.sty create mode 100644 Build/source/utils/asymptote/examples/layers.asy (limited to 'Build/source/utils') 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 . # @@ -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 ." _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 Binary files a/Build/source/utils/asymptote/doc/CAD.pdf and b/Build/source/utils/asymptote/doc/CAD.pdf 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 Binary files a/Build/source/utils/asymptote/doc/asymptote.pdf and b/Build/source/utils/asymptote/doc/asymptote.pdf 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 +%% 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 '. 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 '. + + 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)); + + [image src="diagonal.png"] + +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); + + [image src="square.png"] + +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); + + [image src="bigsquare.png"] + +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); + + [image src="labelsquare.png"] + +`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)); + + [image src="quartercircle.png"] + +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 + +[image src="bezier.png" alt="(1-t)^3*z_0+3t(1-t)^2*c_0+3t^2(1-t)*c_1+t^3*z_1 for 0 <=t <= 1."] + +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: + + [image src="bezier2.png"] + +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}); + + [image src="dots.png"] +with + +draw((0,0){up}::(100,25){right}::(200,0){down}); + + [image src="colons.png"] + +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); + + [image src="superpath.png"] + +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); + + [image src="cube.png"] + +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: + + [image src="CDlabel.png"] +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); + + [image src="join.png"] + + 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); + + [image src="mexicanhat.png"] + + 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': + + [image src="colors.png"] + + 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);} + + [image src="linetype.png"] + + 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")); + + [image src="tile.png"] + + 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")); + + [image src="hatch.png"] + + 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); + + [image src="makepen.png"] + + 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); + + [image src="subpictures.png"] + + 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} + [image src="latexusage.png"] + + +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: + + + [image src="markers1.png"] + +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'. + + + [image src="markers2.png"] + + +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); + + [image src="binarytreetest.png"] + + +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); + + [image src="exp.png"] + + 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); + + [image src="lineargraph0.png"] + + 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); + + [image src="legend.png"] + + 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})); + + [image src="datagraph.png"] + + 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); + + [image src="filegraph.png"] + + 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); + + [image src="errorbars.png"] + + 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); + + [image src="graphmarkers.png"] + + 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)); + + [image src="monthaxis.png"] + + 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)); + + [image src="parametricgraph.png"] + + 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)); + + [image src="scaledgraph.png"] + + 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); + + [image src="loggraph.png"] + + 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)); + + [image src="loggrid.png"] + + 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)); + + [image src="logticks.png"] + + 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); + + [image src="log2graph.png"] + + 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))); + + [image src="brokenaxis.png"] + + 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); + + [image src="Bode.png"] + + 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); + + [image src="secondaryaxis.png"] + + 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)); + + [image src="histogram.png"] + + 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); + + [image src="leastsquares.png"] + + 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];})); + + [image src="generalaxis.png"] + + 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)); + + [image src="flow.png"] + + 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)); + + [image src="vectorfield.png"] + + 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'. + + + [image src="diatom.png"] + + [image src="westnile.png"] + + +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); + + [image src="image.png"] + +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()))); + + [image src="logimage.png"] + +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)); + + [image src="penimage.png"] + +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); + + [image src="unitcircle3.png"] +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); + + [image src="saddle.png"] +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); + + [image src="join3.png"] + +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); + + [image src="planes.png"] + + +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); + + [image src="helix.png"] + +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)); + + [image src="axis3.png"] + +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);})); + + [image src="generalaxis3.png"] + +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); + + [image src="GaussianSurface.png"] +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)); + + [image src="grid3xyz.png"] + + +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); + + [image src="cylinderskeleton.png"] + +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); + }); + + [image src="flowchartdemo.png"] + + +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})); + + [image src="onecontour.png"] + +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); + + [image src="multicontour.png"] + +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)); + + [image src="imagecontour.png"] + +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); + + [image src="irregularcontour.png"] + +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); + + [image src="triangulate.png"] + +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); + + [image src="slopefield1.png"] + + +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 +***** + +[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("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("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("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=""; 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(0); return;} } -#line 1125 "runtime.in" +#line 1135 "runtime.in" void realZero(stack *Stack) { -#line 1126 "runtime.in" +#line 1136 "runtime.in" {Stack->push(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(false); return;} } -#line 1135 "runtime.in" +#line 1145 "runtime.in" void pushNullArray(stack *Stack) { -#line 1136 "runtime.in" +#line 1146 "runtime.in" {Stack->push(0); return;} } -#line 1140 "runtime.in" +#line 1150 "runtime.in" void pushNullRecord(stack *Stack) { -#line 1141 "runtime.in" +#line 1151 "runtime.in" {Stack->push(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(isdefault(i)); return;} } // Logical operations -#line 1169 "runtime.in" +#line 1179 "runtime.in" // bool !(bool b); void gen8(stack *Stack) { bool b=vm::pop(Stack); -#line 1170 "runtime.in" +#line 1180 "runtime.in" {Stack->push(!b); return;} } -#line 1175 "runtime.in" +#line 1185 "runtime.in" void boolMemEq(stack *Stack) { frame * b=vm::pop(Stack); frame * a=vm::pop(Stack); -#line 1176 "runtime.in" +#line 1186 "runtime.in" {Stack->push(a == b); return;} } -#line 1180 "runtime.in" +#line 1190 "runtime.in" void boolMemNeq(stack *Stack) { frame * b=vm::pop(Stack); frame * a=vm::pop(Stack); -#line 1181 "runtime.in" +#line 1191 "runtime.in" {Stack->push(a != b); return;} } -#line 1185 "runtime.in" +#line 1195 "runtime.in" void boolFuncEq(stack *Stack) { callable * b=vm::pop(Stack); callable * a=vm::pop(Stack); -#line 1186 "runtime.in" +#line 1196 "runtime.in" {Stack->push(a->compare(b)); return;} } -#line 1190 "runtime.in" +#line 1200 "runtime.in" void boolFuncNeq(stack *Stack) { callable * b=vm::pop(Stack); callable * a=vm::pop(Stack); -#line 1191 "runtime.in" +#line 1201 "runtime.in" {Stack->push(!(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(Stack); Int a=vm::pop(Stack); -#line 1198 "runtime.in" +#line 1208 "runtime.in" {Stack->push(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(Stack); Int a=vm::pop(Stack); -#line 1204 "runtime.in" +#line 1214 "runtime.in" {Stack->push(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(Stack); Int a=vm::pop(Stack); -#line 1209 "runtime.in" +#line 1219 "runtime.in" {Stack->push(a ^ b); return;} } -#line 1213 "runtime.in" +#line 1223 "runtime.in" // Int NOT(Int a); void gen16(stack *Stack) { Int a=vm::pop(Stack); -#line 1214 "runtime.in" +#line 1224 "runtime.in" {Stack->push(~a); return;} } // Casts -#line 1220 "runtime.in" +#line 1230 "runtime.in" void pairToGuide(stack *Stack) { pair z=vm::pop(Stack); -#line 1221 "runtime.in" +#line 1231 "runtime.in" {Stack->push(new pairguide(z)); return;} } -#line 1226 "runtime.in" +#line 1236 "runtime.in" void pathToGuide(stack *Stack) { path p=vm::pop(Stack); -#line 1227 "runtime.in" +#line 1237 "runtime.in" {Stack->push(new pathguide(p)); return;} } -#line 1231 "runtime.in" +#line 1241 "runtime.in" void guideToPath(stack *Stack) { guide * g=vm::pop(Stack); -#line 1232 "runtime.in" +#line 1242 "runtime.in" {Stack->push(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(new picture()); return;} } -#line 1244 "runtime.in" +#line 1254 "runtime.in" // bool empty(picture *f); void gen21(stack *Stack) { picture * f=vm::pop(Stack); -#line 1245 "runtime.in" +#line 1255 "runtime.in" {Stack->push(f->null()); return;} } -#line 1249 "runtime.in" +#line 1259 "runtime.in" // void erase(picture *f); void gen22(stack *Stack) { picture * f=vm::pop(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(Stack); -#line 1255 "runtime.in" +#line 1265 "runtime.in" {Stack->push(f->bounds().Min()); return;} } -#line 1259 "runtime.in" +#line 1269 "runtime.in" // pair max(picture *f); void gen24(stack *Stack) { picture * f=vm::pop(Stack); -#line 1260 "runtime.in" +#line 1270 "runtime.in" {Stack->push(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(Stack); string * s=vm::pop(Stack); picture * f=vm::pop(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(Stack); -#line 1271 "runtime.in" +#line 1281 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); string * s=vm::pop(Stack); -#line 1276 "runtime.in" +#line 1286 "runtime.in" + texinit(); + processDataStruct &pd=processData(); + + string texengine=getSetting("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(new array(0)); return;} + + array *t=new array(3); + (*t)[0]=width; + (*t)[1]=height; + (*t)[2]=depth; + {Stack->push(t); return;} +} + +#line 1305 "runtime.in" +// patharray* _texpath(string *s, pen p=CURRENTPEN); +void gen28(stack *Stack) +{ + pen p=vm::pop(Stack,CURRENTPEN); + string * s=vm::pop(Stack); +#line 1306 "runtime.in" array *P=new array(0); if(s->empty()) {Stack->push(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("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(Stack,CURRENTPEN); string * s=vm::pop(Stack); -#line 1391 "runtime.in" +#line 1414 "runtime.in" array *P=new array(0); if(s->empty()) {Stack->push(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("textcommand") << " '" << textname << "'"; @@ -1523,13 +1543,13 @@ void gen28(stack *Stack) {Stack->push(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(Stack,CURRENTPEN); path g=vm::pop(Stack); -#line 1463 "runtime.in" +#line 1478 "runtime.in" array *P=new array(0); if(g.size() == 0) {Stack->push(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(readpath(psname,getSetting("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(Stack); path g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); pen p=vm::pop(Stack,CURRENTPEN); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); penarray2 * p=vm::pop(Stack); @@ -1586,14 +1607,14 @@ void gen32(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); pair b=vm::pop(Stack); @@ -1603,14 +1624,14 @@ void gen33(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); real rb=vm::pop(Stack); @@ -1622,14 +1643,14 @@ void gen34(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); Intarray * edges=vm::pop(Stack); @@ -1639,7 +1660,7 @@ void gen35(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); Intarray * edges=vm::pop(Stack); @@ -1658,7 +1679,7 @@ void gen36(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); pairarray2 * z=vm::pop(Stack,emptyarray); @@ -1691,7 +1712,7 @@ void gen37(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); string shader=vm::pop(Stack,emptystring); @@ -1713,176 +1734,176 @@ void gen38(stack *Stack) bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); pen fillrule=vm::pop(Stack,CURRENTPEN); bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(Stack,true); pen fillrule=vm::pop(Stack,CURRENTPEN); bool stroke=vm::pop(Stack,false); patharray * g=vm::pop(Stack); picture * f=vm::pop(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(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(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(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(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(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(Stack); picture * dest=vm::pop(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(Stack); picture * dest=vm::pop(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(Stack); picture * f=vm::pop(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(Stack); picture * f=vm::pop(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(Stack); pair min=vm::pop(Stack); string s=vm::pop(Stack); picture * f=vm::pop(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(Stack); pair min=vm::pop(Stack); string s=vm::pop(Stack); picture * f=vm::pop(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(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("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(Stack); pair offset=vm::pop(Stack); @@ -1891,42 +1912,42 @@ void gen54(stack *Stack) string size=vm::pop(Stack); string s=vm::pop(Stack); picture * f=vm::pop(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(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(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(Stack,false); bool copy=vm::pop(Stack,true); @@ -1936,16 +1957,16 @@ void gen58(stack *Stack) pair initial=vm::pop(Stack); realarray2 * data=vm::pop(Stack); picture * f=vm::pop(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(Stack,false); bool copy=vm::pop(Stack,true); @@ -1954,38 +1975,38 @@ void gen59(stack *Stack) pair initial=vm::pop(Stack); penarray2 * data=vm::pop(Stack); picture * f=vm::pop(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(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(latex(getSetting("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(pdf(getSetting("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(Stack); bool view=vm::pop(Stack,true); @@ -1994,7 +2015,7 @@ void gen63(stack *Stack) picture * preamble=vm::pop(Stack,NULL); picture * f=vm::pop(Stack); string prefix=vm::pop(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(Stack,true); bool viewportlighting=vm::pop(Stack); @@ -2057,7 +2078,7 @@ void gen64(stack *Stack) string format=vm::pop(Stack,emptystring); picture * f=vm::pop(Stack); string prefix=vm::pop(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(Stack); string prefix=vm::pop(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(Stack); real magnification=vm::pop(Stack,1); picture * preamble=vm::pop(Stack,NULL); picture * f=vm::pop(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(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()); 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(Stack); pen a=vm::pop(Stack); -#line 1933 "runtime.in" +#line 1949 "runtime.in" {Stack->push(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(Stack); pen a=vm::pop(Stack); -#line 1938 "runtime.in" +#line 1954 "runtime.in" {Stack->push(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(Stack); pen a=vm::pop(Stack); -#line 1943 "runtime.in" +#line 1959 "runtime.in" {Stack->push(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(Stack); real a=vm::pop(Stack); -#line 1948 "runtime.in" +#line 1964 "runtime.in" {Stack->push(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(Stack); pen a=vm::pop(Stack); -#line 1953 "runtime.in" +#line 1969 "runtime.in" {Stack->push(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(Stack); -#line 1958 "runtime.in" +#line 1974 "runtime.in" {Stack->push(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(Stack); -#line 1963 "runtime.in" +#line 1979 "runtime.in" {Stack->push(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(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(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(Stack); -#line 1984 "runtime.in" +#line 2000 "runtime.in" {Stack->push(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(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(Stack); -#line 1994 "runtime.in" +#line 2010 "runtime.in" p.togrey(); {Stack->push(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(Stack); -#line 2000 "runtime.in" +#line 2016 "runtime.in" p.torgb(); {Stack->push(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(Stack); -#line 2006 "runtime.in" +#line 2022 "runtime.in" p.tocmyk(); {Stack->push(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(Stack); pen b=vm::pop(Stack); pen a=vm::pop(Stack); -#line 2012 "runtime.in" +#line 2028 "runtime.in" {Stack->push(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(Stack); real g=vm::pop(Stack); real r=vm::pop(Stack); -#line 2017 "runtime.in" +#line 2033 "runtime.in" {Stack->push(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(Stack); real y=vm::pop(Stack); real m=vm::pop(Stack); real c=vm::pop(Stack); -#line 2022 "runtime.in" +#line 2038 "runtime.in" {Stack->push(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(Stack); -#line 2027 "runtime.in" +#line 2043 "runtime.in" {Stack->push(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(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(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(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(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(Stack); -#line 2067 "runtime.in" +#line 2083 "runtime.in" {Stack->push(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(Stack); -#line 2072 "runtime.in" +#line 2088 "runtime.in" {Stack->push(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(Stack); -#line 2077 "runtime.in" +#line 2093 "runtime.in" {Stack->push(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(Stack); -#line 2082 "runtime.in" +#line 2098 "runtime.in" {Stack->push(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(Stack,defaulttransparency); real opacity=vm::pop(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(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(Stack); -#line 2097 "runtime.in" +#line 2113 "runtime.in" {Stack->push(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(Stack); -#line 2102 "runtime.in" +#line 2118 "runtime.in" {Stack->push(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(Stack,true); bool scale=vm::pop(Stack,true); real offset=vm::pop(Stack,0); string * s=vm::pop(Stack); -#line 2107 "runtime.in" +#line 2123 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2112 "runtime.in" +#line 2128 "runtime.in" {Stack->push(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(Stack); -#line 2117 "runtime.in" +#line 2133 "runtime.in" {Stack->push(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(Stack); -#line 2122 "runtime.in" +#line 2138 "runtime.in" {Stack->push(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(Stack); -#line 2127 "runtime.in" +#line 2143 "runtime.in" {Stack->push(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(Stack); real arclength=vm::pop(Stack); pen p=vm::pop(Stack); -#line 2132 "runtime.in" +#line 2148 "runtime.in" {Stack->push(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(Stack); -#line 2137 "runtime.in" +#line 2153 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2142 "runtime.in" +#line 2158 "runtime.in" {Stack->push(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(Stack); -#line 2147 "runtime.in" +#line 2163 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2152 "runtime.in" +#line 2168 "runtime.in" {Stack->push(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(Stack); -#line 2157 "runtime.in" +#line 2173 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2162 "runtime.in" +#line 2178 "runtime.in" {Stack->push(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(Stack); -#line 2167 "runtime.in" +#line 2183 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2172 "runtime.in" +#line 2188 "runtime.in" {Stack->push(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(Stack); -#line 2177 "runtime.in" +#line 2193 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2182 "runtime.in" +#line 2198 "runtime.in" {Stack->push(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(Stack); real size=vm::pop(Stack); -#line 2187 "runtime.in" +#line 2203 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2193 "runtime.in" +#line 2209 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2198 "runtime.in" +#line 2214 "runtime.in" {Stack->push(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(Stack); -#line 2203 "runtime.in" +#line 2219 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2209 "runtime.in" +#line 2225 "runtime.in" {Stack->push(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(Stack); -#line 2214 "runtime.in" +#line 2230 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); -#line 2219 "runtime.in" +#line 2235 "runtime.in" {Stack->push(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(Stack); -#line 2224 "runtime.in" +#line 2240 "runtime.in" {Stack->push(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(Stack); -#line 2229 "runtime.in" +#line 2245 "runtime.in" {Stack->push(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(Stack); -#line 2234 "runtime.in" +#line 2250 "runtime.in" {Stack->push(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(Stack); -#line 2239 "runtime.in" +#line 2255 "runtime.in" p.colorless(); {Stack->push(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(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(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(Stack); -#line 2259 "runtime.in" +#line 2275 "runtime.in" if(safe) error("system() call disabled; override with option -nosafe"); if(s.empty()) {Stack->push(0); return;} else {Stack->push(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(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(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(Stack,emptystring); -#line 2277 "runtime.in" +#line 2293 "runtime.in" char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str()); {Stack->push(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(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(Stack,emptystring); bool b=vm::pop(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(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(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(Stack,false); bool embedded=vm::pop(Stack); string * s=vm::pop(Stack); -#line 2317 "runtime.in" +#line 2333 "runtime.in" if (embedded) { trans::coenv *e=Stack->getEnvironment(); vm::interactiveStack *is=dynamic_cast(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(Stack); runnable * s=vm::pop(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(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(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(Stack,emptystring); -#line 2362 "runtime.in" +#line 2378 "runtime.in" if(!s.empty() && !globalwrite()) writeDisabled(); {Stack->push(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(Stack,false); string * s=vm::pop(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(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(Stack); path a=vm::pop(Stack); -#line 2385 "runtime.in" +#line 2401 "runtime.in" {Stack->push(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(Stack); path a=vm::pop(Stack); -#line 2390 "runtime.in" +#line 2406 "runtime.in" {Stack->push(!(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(Stack); path p=vm::pop(Stack); -#line 2395 "runtime.in" +#line 2411 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2400 "runtime.in" +#line 2416 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2405 "runtime.in" +#line 2421 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2410 "runtime.in" +#line 2426 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2415 "runtime.in" +#line 2431 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2420 "runtime.in" +#line 2436 "runtime.in" {Stack->push(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(Stack,true); Int sign=vm::pop(Stack,0); Int t=vm::pop(Stack); path p=vm::pop(Stack); -#line 2425 "runtime.in" +#line 2441 "runtime.in" {Stack->push(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(Stack,true); real t=vm::pop(Stack); path p=vm::pop(Stack); -#line 2430 "runtime.in" +#line 2446 "runtime.in" {Stack->push(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(Stack,0); Int t=vm::pop(Stack); path p=vm::pop(Stack); -#line 2435 "runtime.in" +#line 2451 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2440 "runtime.in" +#line 2456 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(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(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(Stack); -#line 2457 "runtime.in" +#line 2473 "runtime.in" {Stack->push(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(Stack); Int a=vm::pop(Stack); path p=vm::pop(Stack); -#line 2462 "runtime.in" +#line 2478 "runtime.in" {Stack->push(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(Stack); real a=vm::pop(Stack); path p=vm::pop(Stack); -#line 2467 "runtime.in" +#line 2483 "runtime.in" {Stack->push(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(Stack); real w3=vm::pop(Stack); @@ -3174,93 +3195,93 @@ void gen158(stack *Stack) pair z2=vm::pop(Stack); pair z1=vm::pop(Stack); pair z0=vm::pop(Stack); -#line 2473 "runtime.in" +#line 2489 "runtime.in" {Stack->push(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(Stack); -#line 2478 "runtime.in" +#line 2494 "runtime.in" {Stack->push(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(Stack); -#line 2483 "runtime.in" +#line 2499 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2488 "runtime.in" +#line 2504 "runtime.in" {Stack->push(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(Stack); -#line 2493 "runtime.in" +#line 2509 "runtime.in" {Stack->push(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(Stack); -#line 2498 "runtime.in" +#line 2514 "runtime.in" {Stack->push(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(Stack); -#line 2503 "runtime.in" +#line 2519 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2508 "runtime.in" +#line 2524 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2513 "runtime.in" +#line 2529 "runtime.in" {Stack->push(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(Stack,-1); path q=vm::pop(Stack); path p=vm::pop(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(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(Stack,-1); path q=vm::pop(Stack); path p=vm::pop(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(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(Stack,-1); pair b=vm::pop(Stack); pair a=vm::pop(Stack); path p=vm::pop(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(Stack); pair p=vm::pop(Stack); pair Q=vm::pop(Stack); pair P=vm::pop(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(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(Stack); -#line 2592 "runtime.in" +#line 2608 "runtime.in" {Stack->push(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(Stack); path p=vm::pop(Stack); -#line 2597 "runtime.in" +#line 2613 "runtime.in" {Stack->push(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(Stack); -#line 2602 "runtime.in" +#line 2618 "runtime.in" {Stack->push(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(Stack); -#line 2607 "runtime.in" +#line 2623 "runtime.in" {Stack->push(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(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(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(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(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(Stack); real t=vm::pop(Stack); real phi=vm::pop(Stack); real theta=vm::pop(Stack); -#line 2630 "runtime.in" +#line 2646 "runtime.in" {Stack->push(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(Stack); patharray * p=vm::pop(Stack); -#line 2635 "runtime.in" +#line 2651 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); pair z=vm::pop(Stack); patharray * g=vm::pop(Stack); -#line 2640 "runtime.in" +#line 2656 "runtime.in" {Stack->push(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(Stack,CURRENTPEN); pair z=vm::pop(Stack); path g=vm::pop(Stack); -#line 2645 "runtime.in" +#line 2661 "runtime.in" {Stack->push(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(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 2652 "runtime.in" +#line 2668 "runtime.in" {Stack->push(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(Stack); pair c=vm::pop(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 2659 "runtime.in" +#line 2675 "runtime.in" {Stack->push(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(Stack); boolarray * straight=vm::pop(Stack); triplearray * post=vm::pop(Stack); triplearray * point=vm::pop(Stack); triplearray * pre=vm::pop(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(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(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(Stack); path3 a=vm::pop(Stack); -#line 2690 "runtime.in" +#line 2706 "runtime.in" {Stack->push(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(Stack); path3 a=vm::pop(Stack); -#line 2695 "runtime.in" +#line 2711 "runtime.in" {Stack->push(!(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(Stack); path3 p=vm::pop(Stack); -#line 2700 "runtime.in" +#line 2716 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2705 "runtime.in" +#line 2721 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2710 "runtime.in" +#line 2726 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2715 "runtime.in" +#line 2731 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2720 "runtime.in" +#line 2736 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2725 "runtime.in" +#line 2741 "runtime.in" {Stack->push(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(Stack,true); Int sign=vm::pop(Stack,0); Int t=vm::pop(Stack); path3 p=vm::pop(Stack); -#line 2730 "runtime.in" +#line 2746 "runtime.in" {Stack->push(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(Stack,true); real t=vm::pop(Stack); path3 p=vm::pop(Stack); -#line 2735 "runtime.in" +#line 2751 "runtime.in" {Stack->push(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(Stack,0); Int t=vm::pop(Stack); path3 p=vm::pop(Stack); -#line 2740 "runtime.in" +#line 2756 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2745 "runtime.in" +#line 2761 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(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(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(Stack); triple z1=vm::pop(Stack); triple c1=vm::pop(Stack); triple c0=vm::pop(Stack); triple z0=vm::pop(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(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(Stack); -#line 2774 "runtime.in" +#line 2790 "runtime.in" {Stack->push(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(Stack); Int a=vm::pop(Stack); path3 p=vm::pop(Stack); -#line 2779 "runtime.in" +#line 2795 "runtime.in" {Stack->push(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(Stack); real a=vm::pop(Stack); path3 p=vm::pop(Stack); -#line 2784 "runtime.in" +#line 2800 "runtime.in" {Stack->push(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(Stack); -#line 2789 "runtime.in" +#line 2805 "runtime.in" {Stack->push(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(Stack); -#line 2794 "runtime.in" +#line 2810 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2799 "runtime.in" +#line 2815 "runtime.in" {Stack->push(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(Stack); triple v=vm::pop(Stack); -#line 2805 "runtime.in" +#line 2821 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2812 "runtime.in" +#line 2828 "runtime.in" if(p.straight(t)) {Stack->push(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(Stack); triple c1=vm::pop(Stack); triple c0=vm::pop(Stack); triple z0=vm::pop(Stack); -#line 2823 "runtime.in" +#line 2839 "runtime.in" triple u=unit(z1-z0); {Stack->push(::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(Stack); -#line 2829 "runtime.in" +#line 2845 "runtime.in" {Stack->push(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(Stack); -#line 2834 "runtime.in" +#line 2850 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2839 "runtime.in" +#line 2855 "runtime.in" {Stack->push(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(Stack,-1); path3 q=vm::pop(Stack); path3 p=vm::pop(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(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(Stack,-1); path3 q=vm::pop(Stack); path3 p=vm::pop(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(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(Stack,-1); triplearray2 * P=vm::pop(Stack); path3 p=vm::pop(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(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(Stack); -#line 2915 "runtime.in" +#line 2931 "runtime.in" {Stack->push(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(Stack); path3 p=vm::pop(Stack); -#line 2920 "runtime.in" +#line 2936 "runtime.in" {Stack->push(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(Stack); -#line 2925 "runtime.in" +#line 2941 "runtime.in" {Stack->push(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(Stack); -#line 2930 "runtime.in" +#line 2946 "runtime.in" {Stack->push(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(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(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(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(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(Stack); realarray2 * t=vm::pop(Stack); -#line 2955 "runtime.in" +#line 2971 "runtime.in" {Stack->push(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(new pathguide(path())); return;} } -#line 2967 "runtime.in" +#line 2983 "runtime.in" void dotsGuide(stack *Stack) { guidearray * a=vm::pop(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(new multiguide(v)); return;} } -#line 2977 "runtime.in" +#line 2993 "runtime.in" void dashesGuide(stack *Stack) { guidearray * a=vm::pop(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(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()); 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(Stack); -#line 3010 "runtime.in" +#line 3026 "runtime.in" // Avoid unused variable warning messages. unused(&tok); {Stack->push(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(Stack); pair z=vm::pop(Stack); -#line 3017 "runtime.in" +#line 3033 "runtime.in" camp::side d=(camp::side) p; camp::dirSpec *sp=new camp::dirSpec(z); {Stack->push(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(Stack); real gamma=vm::pop(Stack); -#line 3025 "runtime.in" +#line 3041 "runtime.in" camp::side s=(camp::side) p; {Stack->push(curlSpecifier(gamma,s)); return;} } -#line 3030 "runtime.in" +#line 3046 "runtime.in" void curlSpecifierValuePart(stack *Stack) { curlSpecifier spec=vm::pop(Stack); -#line 3031 "runtime.in" +#line 3047 "runtime.in" {Stack->push(spec.getValue()); return;} } -#line 3035 "runtime.in" +#line 3051 "runtime.in" void curlSpecifierSidePart(stack *Stack) { curlSpecifier spec=vm::pop(Stack); -#line 3036 "runtime.in" +#line 3052 "runtime.in" {Stack->push(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(Stack); -#line 3041 "runtime.in" +#line 3057 "runtime.in" {Stack->push(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(Stack); real tin=vm::pop(Stack); real tout=vm::pop(Stack); -#line 3046 "runtime.in" +#line 3062 "runtime.in" {Stack->push(tensionSpecifier(tout, tin, atleast)); return;} } -#line 3050 "runtime.in" +#line 3066 "runtime.in" void tensionSpecifierOutPart(stack *Stack) { tensionSpecifier t=vm::pop(Stack); -#line 3051 "runtime.in" +#line 3067 "runtime.in" {Stack->push(t.getOut()); return;} } -#line 3055 "runtime.in" +#line 3071 "runtime.in" void tensionSpecifierInPart(stack *Stack) { tensionSpecifier t=vm::pop(Stack); -#line 3056 "runtime.in" +#line 3072 "runtime.in" {Stack->push(t.getIn()); return;} } -#line 3060 "runtime.in" +#line 3076 "runtime.in" void tensionSpecifierAtleastPart(stack *Stack) { tensionSpecifier t=vm::pop(Stack); -#line 3061 "runtime.in" +#line 3077 "runtime.in" {Stack->push(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(Stack); -#line 3066 "runtime.in" +#line 3082 "runtime.in" {Stack->push(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(Stack); pair zout=vm::pop(Stack); -#line 3071 "runtime.in" +#line 3087 "runtime.in" {Stack->push(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(Stack); -#line 3076 "runtime.in" +#line 3092 "runtime.in" flatguide f; g->flatten(f,false); {Stack->push(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(Stack); -#line 3083 "runtime.in" +#line 3099 "runtime.in" flatguide f; g->flatten(f,false); {Stack->push(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(Stack); -#line 3090 "runtime.in" +#line 3106 "runtime.in" flatguide f; g->flatten(f,false); {Stack->push(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(Stack); guide * g=vm::pop(Stack); -#line 3097 "runtime.in" +#line 3113 "runtime.in" flatguide f; g->flatten(f,false); {Stack->push(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(Stack); guide * g=vm::pop(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(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(Stack); guide * g=vm::pop(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(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(Stack); guide * g=vm::pop(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(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(Stack); guide * g=vm::pop(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(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(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(Stack); path3 g=vm::pop(Stack); picture * f=vm::pop(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(Stack); bool lighton=vm::pop(Stack); @@ -4352,80 +4373,80 @@ void gen247(stack *Stack) bool straight=vm::pop(Stack); triplearray2 * g=vm::pop(Stack); picture * f=vm::pop(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(Stack); -#line 3228 "runtime.in" +#line 3244 "runtime.in" {Stack->push(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(Stack); -#line 3233 "runtime.in" +#line 3249 "runtime.in" {Stack->push(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(Stack); picture * f=vm::pop(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(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(Stack); picture * f=vm::pop(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(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(Stack); -#line 3254 "runtime.in" +#line 3270 "runtime.in" {Stack->push(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(Stack); -#line 3259 "runtime.in" +#line 3275 "runtime.in" {Stack->push(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(Stack); triplearray2 * P=vm::pop(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(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(Stack); triplearray2 * P=vm::pop(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(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(Stack); realarray2 * t=vm::pop(Stack); triplearray2 * P=vm::pop(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(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(Stack); realarray2 * t=vm::pop(Stack); triplearray2 * P=vm::pop(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(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(Stack); path3 g=vm::pop(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(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(Stack); path3 g=vm::pop(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(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(Stack); -#line 3324 "runtime.in" +#line 3340 "runtime.in" size_t n=checkArray(a); if(n == 0) {Stack->push(0.0); return;} @@ -4537,241 +4558,241 @@ void gen260(stack *Stack) {Stack->push(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(Stack); -#line 3346 "runtime.in" +#line 3362 "runtime.in" {Stack->push(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(Stack); pair d=vm::pop(Stack); pair c=vm::pop(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 3351 "runtime.in" +#line 3367 "runtime.in" real onemt=1-t; real onemt2=onemt*onemt; {Stack->push(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(Stack); pair d=vm::pop(Stack); pair c=vm::pop(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 3358 "runtime.in" +#line 3374 "runtime.in" {Stack->push(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(Stack); pair d=vm::pop(Stack); pair c=vm::pop(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 3363 "runtime.in" +#line 3379 "runtime.in" {Stack->push(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(Stack); pair c=vm::pop(Stack); pair b=vm::pop(Stack); pair a=vm::pop(Stack); -#line 3368 "runtime.in" +#line 3384 "runtime.in" {Stack->push(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(Stack); triple d=vm::pop(Stack); triple c=vm::pop(Stack); triple b=vm::pop(Stack); triple a=vm::pop(Stack); -#line 3373 "runtime.in" +#line 3389 "runtime.in" real onemt=1-t; real onemt2=onemt*onemt; {Stack->push(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(Stack); triple d=vm::pop(Stack); triple c=vm::pop(Stack); triple b=vm::pop(Stack); triple a=vm::pop(Stack); -#line 3380 "runtime.in" +#line 3396 "runtime.in" {Stack->push(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(Stack); triple d=vm::pop(Stack); triple c=vm::pop(Stack); triple b=vm::pop(Stack); triple a=vm::pop(Stack); -#line 3385 "runtime.in" +#line 3401 "runtime.in" {Stack->push(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(Stack); triple c=vm::pop(Stack); triple b=vm::pop(Stack); triple a=vm::pop(Stack); -#line 3390 "runtime.in" +#line 3406 "runtime.in" {Stack->push(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(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(Stack); -#line 3403 "runtime.in" +#line 3419 "runtime.in" {Stack->push((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(Stack,0); string t=vm::pop(Stack); string * s=vm::pop(Stack); -#line 3408 "runtime.in" +#line 3424 "runtime.in" size_t n=s->find(t,pos); {Stack->push(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(Stack,-1); string t=vm::pop(Stack); string * s=vm::pop(Stack); -#line 3414 "runtime.in" +#line 3430 "runtime.in" size_t n=s->rfind(t,pos); {Stack->push(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(Stack); -#line 3420 "runtime.in" +#line 3436 "runtime.in" reverse(s.begin(),s.end()); {Stack->push(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(Stack); Int pos=vm::pop(Stack); string s=vm::pop(Stack); -#line 3426 "runtime.in" +#line 3442 "runtime.in" if ((size_t) pos < s.length()) {Stack->push(s.insert(pos,t)); return;} {Stack->push(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(Stack,-1); Int pos=vm::pop(Stack); string* s=vm::pop(Stack); -#line 3433 "runtime.in" +#line 3449 "runtime.in" if ((size_t) pos < s->length()) {Stack->push(s->substr(pos,n)); return;} {Stack->push(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(Stack); Int pos=vm::pop(Stack); string s=vm::pop(Stack); -#line 3440 "runtime.in" +#line 3456 "runtime.in" if ((size_t) pos < s.length()) {Stack->push(s.erase(pos,n)); return;} {Stack->push(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(Stack); -#line 3447 "runtime.in" +#line 3463 "runtime.in" std::transform(s.begin(),s.end(),s.begin(),tolower); {Stack->push(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(Stack); -#line 3453 "runtime.in" +#line 3469 "runtime.in" std::transform(s.begin(),s.end(),s.begin(),toupper); {Stack->push(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(Stack); string * S=vm::pop(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(translate,i); @@ -4795,13 +4816,13 @@ void gen280(stack *Stack) {Stack->push(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(Stack); string * format=vm::pop(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(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(Stack,emptystring); real x=vm::pop(Stack); string * format=vm::pop(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(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(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(Stack); -#line 3630 "runtime.in" +#line 3646 "runtime.in" ostringstream buf; buf << x; {Stack->push(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(Stack,DBL_DIG); real x=vm::pop(Stack); -#line 3637 "runtime.in" +#line 3653 "runtime.in" ostringstream buf; buf.precision(digits); buf << x; {Stack->push(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(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(""); 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(Stack,defaulttimeformat); Int seconds=vm::pop(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(""); 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(Stack,emptystring); string t=vm::pop(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(Stack); real x=vm::pop(Stack); -#line 3697 "runtime.in" +#line 3713 "runtime.in" {Stack->push(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(Stack); pair z=vm::pop(Stack); -#line 3703 "runtime.in" +#line 3719 "runtime.in" {Stack->push(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(Stack); Int x=vm::pop(Stack); -#line 3708 "runtime.in" +#line 3724 "runtime.in" if(y == 0) dividebyzero(); if(y == -1) {Stack->push(Negate(x)); return;} // Implementation-independent definition of integer division: round down {Stack->push((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(Stack); -#line 3716 "runtime.in" +#line 3732 "runtime.in" {Stack->push(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(Stack); -#line 3721 "runtime.in" +#line 3737 "runtime.in" {Stack->push(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(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(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) 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(Stack); -#line 3742 "runtime.in" +#line 3758 "runtime.in" {Stack->push(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(Stack); -#line 3747 "runtime.in" +#line 3763 "runtime.in" {Stack->push(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(Stack); -#line 3752 "runtime.in" +#line 3768 "runtime.in" if(validInt(x)) {Stack->push(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(Stack); -#line 3758 "runtime.in" +#line 3774 "runtime.in" {Stack->push(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(Stack); -#line 3763 "runtime.in" +#line 3779 "runtime.in" {Stack->push(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(Stack); -#line 3768 "runtime.in" +#line 3784 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 3773 "runtime.in" +#line 3789 "runtime.in" if (y == 0.0) dividebyzero(); {Stack->push(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(Stack); real y=vm::pop(Stack); -#line 3779 "runtime.in" +#line 3795 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 3784 "runtime.in" +#line 3800 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 3789 "runtime.in" +#line 3805 "runtime.in" {Stack->push(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(Stack); Int n=vm::pop(Stack); -#line 3794 "runtime.in" +#line 3810 "runtime.in" {Stack->push(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(Stack); Int n=vm::pop(Stack); -#line 3799 "runtime.in" +#line 3815 "runtime.in" {Stack->push(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(Stack); -#line 3804 "runtime.in" +#line 3820 "runtime.in" {Stack->push(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(Stack); -#line 3809 "runtime.in" +#line 3825 "runtime.in" {Stack->push(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(Stack); -#line 3814 "runtime.in" +#line 3830 "runtime.in" if(n < 0) error(invalidargument); {Stack->push(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(Stack); Int n=vm::pop(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(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(Stack); -#line 3830 "runtime.in" +#line 3846 "runtime.in" #ifdef HAVE_TGAMMA {Stack->push(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(Stack); -#line 3841 "runtime.in" +#line 3857 "runtime.in" {Stack->push(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(Stack); real b=vm::pop(Stack); real a=vm::pop(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(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(Stack); pair b=vm::pop(Stack); pair a=vm::pop(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(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(Stack); real c=vm::pop(Stack); real b=vm::pop(Stack); real a=vm::pop(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(Stack); transform a=vm::pop(Stack); -#line 3876 "runtime.in" +#line 3892 "runtime.in" {Stack->push(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(Stack); transform a=vm::pop(Stack); -#line 3882 "runtime.in" +#line 3898 "runtime.in" {Stack->push(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(Stack); transform a=vm::pop(Stack); -#line 3887 "runtime.in" +#line 3903 "runtime.in" {Stack->push(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(Stack); transform a=vm::pop(Stack); -#line 3892 "runtime.in" +#line 3908 "runtime.in" {Stack->push(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(Stack); transform t=vm::pop(Stack); -#line 3897 "runtime.in" +#line 3913 "runtime.in" {Stack->push(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(Stack); transform t=vm::pop(Stack); -#line 3902 "runtime.in" +#line 3918 "runtime.in" {Stack->push(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(Stack); transform t=vm::pop(Stack); -#line 3907 "runtime.in" +#line 3923 "runtime.in" {Stack->push(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(Stack); transform t=vm::pop(Stack); -#line 3912 "runtime.in" +#line 3928 "runtime.in" {Stack->push(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(Stack); realarray2 * t=vm::pop(Stack); -#line 3917 "runtime.in" +#line 3933 "runtime.in" {Stack->push(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(Stack); transform t=vm::pop(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(T); return;} } -#line 3932 "runtime.in" +#line 3948 "runtime.in" void transformXPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3933 "runtime.in" +#line 3949 "runtime.in" {Stack->push(t.getx()); return;} } -#line 3937 "runtime.in" +#line 3953 "runtime.in" void transformYPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3938 "runtime.in" +#line 3954 "runtime.in" {Stack->push(t.gety()); return;} } -#line 3942 "runtime.in" +#line 3958 "runtime.in" void transformXXPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3943 "runtime.in" +#line 3959 "runtime.in" {Stack->push(t.getxx()); return;} } -#line 3947 "runtime.in" +#line 3963 "runtime.in" void transformXYPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3948 "runtime.in" +#line 3964 "runtime.in" {Stack->push(t.getxy()); return;} } -#line 3952 "runtime.in" +#line 3968 "runtime.in" void transformYXPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3953 "runtime.in" +#line 3969 "runtime.in" {Stack->push(t.getyx()); return;} } -#line 3957 "runtime.in" +#line 3973 "runtime.in" void transformYYPart(stack *Stack) { transform t=vm::pop(Stack); -#line 3958 "runtime.in" +#line 3974 "runtime.in" {Stack->push(t.getyy()); return;} } -#line 3962 "runtime.in" +#line 3978 "runtime.in" void real6ToTransform(stack *Stack) { real yy=vm::pop(Stack); @@ -5521,765 +5542,765 @@ void real6ToTransform(stack *Stack) real xx=vm::pop(Stack); real y=vm::pop(Stack); real x=vm::pop(Stack); -#line 3964 "runtime.in" +#line 3980 "runtime.in" {Stack->push(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(Stack); -#line 3969 "runtime.in" +#line 3985 "runtime.in" {Stack->push(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(Stack); -#line 3974 "runtime.in" +#line 3990 "runtime.in" {Stack->push(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(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(Stack); -#line 3984 "runtime.in" +#line 4000 "runtime.in" {Stack->push(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(Stack); -#line 3989 "runtime.in" +#line 4005 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 3994 "runtime.in" +#line 4010 "runtime.in" {Stack->push(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(Stack); -#line 3999 "runtime.in" +#line 4015 "runtime.in" {Stack->push(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(Stack); -#line 4004 "runtime.in" +#line 4020 "runtime.in" {Stack->push(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(Stack); -#line 4009 "runtime.in" +#line 4025 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 4014 "runtime.in" +#line 4030 "runtime.in" {Stack->push(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(Stack); -#line 4019 "runtime.in" +#line 4035 "runtime.in" {Stack->push(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(Stack,0); real angle=vm::pop(Stack); -#line 4024 "runtime.in" +#line 4040 "runtime.in" {Stack->push(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(Stack); pair a=vm::pop(Stack); -#line 4029 "runtime.in" +#line 4045 "runtime.in" {Stack->push(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(zero); return;} } -#line 4041 "runtime.in" +#line 4057 "runtime.in" void realRealToPair(stack *Stack) { real y=vm::pop(Stack); real x=vm::pop(Stack); -#line 4042 "runtime.in" +#line 4058 "runtime.in" {Stack->push(pair(x,y)); return;} } -#line 4046 "runtime.in" +#line 4062 "runtime.in" void pairNegate(stack *Stack) { pair z=vm::pop(Stack); -#line 4047 "runtime.in" +#line 4063 "runtime.in" {Stack->push(-z); return;} } -#line 4051 "runtime.in" +#line 4067 "runtime.in" // real xpart(pair z); void pairXPart(stack *Stack) { pair z=vm::pop(Stack); -#line 4052 "runtime.in" +#line 4068 "runtime.in" {Stack->push(z.getx()); return;} } -#line 4056 "runtime.in" +#line 4072 "runtime.in" // real ypart(pair z); void pairYPart(stack *Stack) { pair z=vm::pop(Stack); -#line 4057 "runtime.in" +#line 4073 "runtime.in" {Stack->push(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(Stack); -#line 4062 "runtime.in" +#line 4078 "runtime.in" {Stack->push(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(Stack); -#line 4067 "runtime.in" +#line 4083 "runtime.in" {Stack->push(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(Stack); -#line 4072 "runtime.in" +#line 4088 "runtime.in" {Stack->push(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(Stack,true); pair z=vm::pop(Stack); -#line 4078 "runtime.in" +#line 4094 "runtime.in" if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push(0.0); return;} {Stack->push(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(Stack,true); pair z=vm::pop(Stack); -#line 4085 "runtime.in" +#line 4101 "runtime.in" if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push(0.0); return;} {Stack->push(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(Stack); -#line 4092 "runtime.in" +#line 4108 "runtime.in" {Stack->push(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(Stack); -#line 4098 "runtime.in" +#line 4114 "runtime.in" {Stack->push(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(Stack); -#line 4104 "runtime.in" +#line 4120 "runtime.in" {Stack->push(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(Stack); -#line 4109 "runtime.in" +#line 4125 "runtime.in" {Stack->push(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(Stack); -#line 4114 "runtime.in" +#line 4130 "runtime.in" {Stack->push(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(Stack); -#line 4119 "runtime.in" +#line 4135 "runtime.in" {Stack->push(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(Stack); -#line 4124 "runtime.in" +#line 4140 "runtime.in" {Stack->push(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(Stack); -#line 4129 "runtime.in" +#line 4145 "runtime.in" {Stack->push(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(Stack); -#line 4134 "runtime.in" +#line 4150 "runtime.in" {Stack->push(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(Stack); -#line 4139 "runtime.in" +#line 4155 "runtime.in" {Stack->push(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(Stack); -#line 4144 "runtime.in" +#line 4160 "runtime.in" {Stack->push(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(Stack); -#line 4149 "runtime.in" +#line 4165 "runtime.in" {Stack->push(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(Stack); -#line 4154 "runtime.in" +#line 4170 "runtime.in" {Stack->push(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(Stack); -#line 4159 "runtime.in" +#line 4175 "runtime.in" {Stack->push(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(Stack); -#line 4164 "runtime.in" +#line 4180 "runtime.in" {Stack->push(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(Stack); -#line 4169 "runtime.in" +#line 4185 "runtime.in" {Stack->push(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(Stack); -#line 4174 "runtime.in" +#line 4190 "runtime.in" {Stack->push(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(Stack); -#line 4179 "runtime.in" +#line 4195 "runtime.in" {Stack->push(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(Stack); pair z=vm::pop(Stack); -#line 4184 "runtime.in" +#line 4200 "runtime.in" {Stack->push(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(Stack); triple u=vm::pop(Stack); -#line 4189 "runtime.in" +#line 4205 "runtime.in" {Stack->push(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(Stack); pair z=vm::pop(Stack); -#line 4195 "runtime.in" +#line 4211 "runtime.in" {Stack->push(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(zero); return;} } -#line 4208 "runtime.in" +#line 4224 "runtime.in" void realRealRealToTriple(stack *Stack) { real z=vm::pop(Stack); real y=vm::pop(Stack); real x=vm::pop(Stack); -#line 4209 "runtime.in" +#line 4225 "runtime.in" {Stack->push(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(Stack); -#line 4214 "runtime.in" +#line 4230 "runtime.in" {Stack->push(v.getx()); return;} } -#line 4218 "runtime.in" +#line 4234 "runtime.in" // real ypart(triple v); void tripleYPart(stack *Stack) { triple v=vm::pop(Stack); -#line 4219 "runtime.in" +#line 4235 "runtime.in" {Stack->push(v.gety()); return;} } -#line 4223 "runtime.in" +#line 4239 "runtime.in" // real zpart(triple v); void tripleZPart(stack *Stack) { triple v=vm::pop(Stack); -#line 4224 "runtime.in" +#line 4240 "runtime.in" {Stack->push(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(Stack); real x=vm::pop(Stack); -#line 4229 "runtime.in" +#line 4245 "runtime.in" {Stack->push(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(Stack); triple v=vm::pop(Stack); -#line 4234 "runtime.in" +#line 4250 "runtime.in" {Stack->push(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(Stack); triple v=vm::pop(Stack); -#line 4239 "runtime.in" +#line 4255 "runtime.in" {Stack->push(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(Stack); -#line 4244 "runtime.in" +#line 4260 "runtime.in" {Stack->push(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(Stack); -#line 4249 "runtime.in" +#line 4265 "runtime.in" {Stack->push(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(Stack,true); triple v=vm::pop(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(0.0); return;} {Stack->push(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(Stack,true); triple v=vm::pop(Stack); -#line 4260 "runtime.in" +#line 4276 "runtime.in" if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push(0.0); return;} {Stack->push(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(Stack,true); triple v=vm::pop(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(0.0); return;} {Stack->push(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(Stack,true); triple v=vm::pop(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(0.0); return;} {Stack->push(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(Stack,true); triple v=vm::pop(Stack); -#line 4279 "runtime.in" +#line 4295 "runtime.in" if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push(0.0); return;} {Stack->push(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(Stack); -#line 4285 "runtime.in" +#line 4301 "runtime.in" {Stack->push(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(Stack); triple u=vm::pop(Stack); -#line 4290 "runtime.in" +#line 4306 "runtime.in" {Stack->push(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(Stack); triple u=vm::pop(Stack); -#line 4295 "runtime.in" +#line 4311 "runtime.in" {Stack->push(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(Stack); real polar=vm::pop(Stack); -#line 4300 "runtime.in" +#line 4316 "runtime.in" {Stack->push(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(Stack); real colatitude=vm::pop(Stack); -#line 4305 "runtime.in" +#line 4321 "runtime.in" {Stack->push(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(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(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(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(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(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(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(Stack); -#line 4343 "runtime.in" +#line 4359 "runtime.in" {Stack->push(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(Stack,NULL); Int line=vm::pop(Stack); string file=vm::pop(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::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(Stack); string file=vm::pop(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(Stack); -#line 4374 "runtime.in" +#line 4390 "runtime.in" {Stack->push(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(Stack); -#line 4380 "runtime.in" +#line 4396 "runtime.in" {Stack->push(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(Stack); -#line 4386 "runtime.in" +#line 4402 "runtime.in" {Stack->push(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(Stack,emptystring); string file=vm::pop(Stack,emptystring); string args=vm::pop(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(Stack,emptystring); string file=vm::pop(Stack,emptystring); string args=vm::pop(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(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(Stack); string * from=vm::pop(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(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(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(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(Stack); array* tail=vm::pop(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(Stack,Int_MAX); item value=vm::pop(Stack); Int n=vm::pop(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(Stack); array * a=vm::pop(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(Stack); Int left=vm::pop(Stack); array * a=vm::pop(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(Stack); array * a=vm::pop(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(Stack); array * a=vm::pop(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(Stack); array * a=vm::pop(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(Stack); Int left=vm::pop(Stack); array * dest=vm::pop(Stack); array * src=vm::pop(Stack); -#line 4570 "runtime.in" +#line 4586 "runtime.in" checkArray(src); checkArray(dest); dest->setSlice(left, right, src); {Stack->push(src); return;} } -#line 4577 "runtime.in" +#line 4593 "runtime.in" void arraySliceWriteToEnd(stack *Stack) { Int left=vm::pop(Stack); array * dest=vm::pop(Stack); array * src=vm::pop(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(Stack); -#line 4587 "runtime.in" +#line 4603 "runtime.in" {Stack->push((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(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(Stack); -#line 4608 "runtime.in" +#line 4624 "runtime.in" checkArray(a); {Stack->push(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(Stack); Int n=vm::pop(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(Stack); -#line 4626 "runtime.in" +#line 4642 "runtime.in" {Stack->push(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(Stack); bool b=vm::pop(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(Stack); -#line 4639 "runtime.in" +#line 4655 "runtime.in" {Stack->push(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(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(Stack); -#line 4653 "runtime.in" +#line 4669 "runtime.in" {Stack->push(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(Stack); array * b=vm::pop(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(Stack); -#line 4668 "runtime.in" +#line 4684 "runtime.in" {Stack->push(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(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(Stack); -#line 4683 "runtime.in" +#line 4699 "runtime.in" {Stack->push(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(Stack); array * x=vm::pop(Stack); Int i=vm::pop(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(Stack); -#line 4700 "runtime.in" +#line 4716 "runtime.in" {Stack->push(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(Stack); -#line 4706 "runtime.in" +#line 4722 "runtime.in" {Stack->push(new thunk(new bfunc(arrayDeleteHelper),a)); return;} } -#line 4710 "runtime.in" +#line 4726 "runtime.in" void arrayAlias(stack *Stack) { array * b=vm::pop(Stack); array * a=vm::pop(Stack); -#line 4711 "runtime.in" +#line 4727 "runtime.in" {Stack->push(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(Stack); array * a=vm::pop(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(Stack); Intarray * a=vm::pop(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(Stack); callable * f=vm::pop(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(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(Stack); callable * f=vm::pop(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(b); return;} } -#line 4789 "runtime.in" +#line 4805 "runtime.in" void arraySort(stack *Stack) { callable * f=vm::pop(Stack); array * a=vm::pop(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(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(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(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(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(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(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(sum); return;} } -#line 4825 "runtime.in" +#line 4841 "runtime.in" void arrayCopy(stack *Stack) { array * a=vm::pop(Stack); -#line 4826 "runtime.in" +#line 4842 "runtime.in" {Stack->push(copyArray(a)); return;} } -#line 4830 "runtime.in" +#line 4846 "runtime.in" void arrayConcat(stack *Stack) { array * a=vm::pop(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(result); return;} } -#line 4858 "runtime.in" +#line 4874 "runtime.in" void array2Copy(stack *Stack) { array * a=vm::pop(Stack); -#line 4859 "runtime.in" +#line 4875 "runtime.in" {Stack->push(copyArray2(a)); return;} } -#line 4863 "runtime.in" +#line 4879 "runtime.in" void array3Copy(stack *Stack) { array * a=vm::pop(Stack); -#line 4864 "runtime.in" +#line 4880 "runtime.in" {Stack->push(copyArray3(a)); return;} } -#line 4868 "runtime.in" +#line 4884 "runtime.in" void array2Transpose(stack *Stack) { array * a=vm::pop(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(Stack); array * a=vm::pop(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(Stack,1); boolarray * a=vm::pop(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(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(Stack); realarray2 * a=vm::pop(Stack); -#line 5000 "runtime.in" +#line 5016 "runtime.in" size_t n=checkArray(a); if(n != checkArray(b)) {Stack->push(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(Stack); array * b=vm::pop(Stack); array * a=vm::pop(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(Stack); -#line 5046 "runtime.in" +#line 5062 "runtime.in" {Stack->push(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(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(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(Stack,true); realarray * b=vm::pop(Stack); realarray2 * a=vm::pop(Stack); -#line 5163 "runtime.in" +#line 5179 "runtime.in" size_t n=checkArray(a); if(n == 0) {Stack->push(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(Stack,true); realarray2 * b=vm::pop(Stack); realarray2 * a=vm::pop(Stack); -#line 5214 "runtime.in" +#line 5230 "runtime.in" size_t n=checkArray(a); if(n == 0) {Stack->push(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(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(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(Stack); realarray2 * a=vm::pop(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(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(Stack); realarray2 * a=vm::pop(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(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(Stack); realarray2 * t=vm::pop(Stack); -#line 5344 "runtime.in" +#line 5360 "runtime.in" {Stack->push(*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(Stack); triple v=vm::pop(Stack); -#line 5349 "runtime.in" +#line 5365 "runtime.in" size_t n=checkArray(t); if(n != 4) error(incommensurate); array *t0=read(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(Stack); realarray * a=vm::pop(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(Stack); realarray * c=vm::pop(Stack); realarray * b=vm::pop(Stack); realarray * a=vm::pop(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(Stack,false); real x=vm::pop(Stack); callableReal * fprime=vm::pop(Stack); callableReal * f=vm::pop(Stack); Int iterations=vm::pop(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(Stack,false); real x2=vm::pop(Stack); @@ -7691,7 +7712,7 @@ void gen478(stack *Stack) callableReal * fprime=vm::pop(Stack); callableReal * f=vm::pop(Stack); Int iterations=vm::pop(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((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(Stack,0); real acc=vm::pop(Stack,DBL_EPSILON); real b=vm::pop(Stack); real a=vm::pop(Stack); callableReal * f=vm::pop(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(Stack,1); pairarray * a=vm::pop(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(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(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(Stack); file * a=vm::pop(Stack); -#line 5696 "runtime.in" +#line 5712 "runtime.in" {Stack->push(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(Stack); file * a=vm::pop(Stack); -#line 5702 "runtime.in" +#line 5718 "runtime.in" {Stack->push(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(&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(Stack,commentchar); bool check=vm::pop(Stack,true); string name=vm::pop(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(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(Stack,commentchar); bool update=vm::pop(Stack,false); string name=vm::pop(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(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(Stack,true); string name=vm::pop(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(Stack,false); string name=vm::pop(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(Stack,true); string name=vm::pop(Stack); -#line 5764 "runtime.in" +#line 5780 "runtime.in" file *f=new ibfile(name,check); f->open(); {Stack->push(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(Stack,false); string name=vm::pop(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(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(Stack); -#line 5781 "runtime.in" +#line 5797 "runtime.in" {Stack->push(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(Stack); -#line 5786 "runtime.in" +#line 5802 "runtime.in" {Stack->push(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(Stack); -#line 5791 "runtime.in" +#line 5807 "runtime.in" {Stack->push(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(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(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(Stack,0); file * File=vm::pop(Stack,NULL); -#line 5806 "runtime.in" +#line 5822 "runtime.in" if(File == 0) File=&camp::Stdout; {Stack->push(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(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(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(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(Stack); -#line 5826 "runtime.in" +#line 5842 "runtime.in" {Stack->push(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(Stack); file * File=vm::pop(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(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(Stack); file * File=vm::pop(Stack); -#line 5842 "runtime.in" +#line 5858 "runtime.in" File->dimension(nx); {Stack->push(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(Stack); Int nx=vm::pop(Stack); file * File=vm::pop(Stack); -#line 5848 "runtime.in" +#line 5864 "runtime.in" File->dimension(nx,ny); {Stack->push(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(Stack); Int ny=vm::pop(Stack); Int nx=vm::pop(Stack); file * File=vm::pop(Stack); -#line 5854 "runtime.in" +#line 5870 "runtime.in" File->dimension(nx,ny,nz); {Stack->push(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(Stack,true); file * File=vm::pop(Stack); -#line 5861 "runtime.in" +#line 5877 "runtime.in" File->CSVMode(b); {Stack->push(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(Stack,true); file * File=vm::pop(Stack); -#line 5868 "runtime.in" +#line 5884 "runtime.in" File->WordMode(b); {Stack->push(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(Stack,true); file * File=vm::pop(Stack); -#line 5875 "runtime.in" +#line 5891 "runtime.in" File->LineMode(b); {Stack->push(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(Stack,true); file * File=vm::pop(Stack); -#line 5882 "runtime.in" +#line 5898 "runtime.in" File->SingleReal(b); File->SingleInt(b); {Stack->push(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(Stack,true); real x=vm::pop(Stack); file * File=vm::pop(Stack); -#line 5890 "runtime.in" +#line 5906 "runtime.in" File->SingleReal(b); unused(&x); {Stack->push(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(Stack,true); Int x=vm::pop(Stack); file * File=vm::pop(Stack); -#line 5898 "runtime.in" +#line 5914 "runtime.in" File->SingleInt(b); unused(&x); {Stack->push(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(Stack); -#line 5906 "runtime.in" +#line 5922 "runtime.in" File->dimension(-2); {Stack->push(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(Stack); -#line 5913 "runtime.in" +#line 5929 "runtime.in" File->dimension(-2,-2); {Stack->push(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(Stack); -#line 5920 "runtime.in" +#line 5936 "runtime.in" File->dimension(-2,-2,-2); {Stack->push(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(Stack,1); string name=vm::pop(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(Stack,0); -#line 5960 "runtime.in" +#line 5976 "runtime.in" #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) {Stack->push(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(Stack,false); string name=vm::pop(Stack,emptystring); string prompt=vm::pop(Stack,emptystring); -#line 5973 "runtime.in" +#line 5989 "runtime.in" if(!isatty(STDIN_FILENO)) {Stack->push(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(Stack,true); string value=vm::pop(Stack); string name=vm::pop(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(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("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("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("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 void texdocumentclass(T& out, bool pipe=false) { -- cgit v1.2.3