diff options
Diffstat (limited to 'Build/source/utils/asymptote/doc/asymptote.texi')
-rw-r--r-- | Build/source/utils/asymptote/doc/asymptote.texi | 9131 |
1 files changed, 9131 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/doc/asymptote.texi b/Build/source/utils/asymptote/doc/asymptote.texi new file mode 100644 index 00000000000..46043c85867 --- /dev/null +++ b/Build/source/utils/asymptote/doc/asymptote.texi @@ -0,0 +1,9131 @@ +\input texinfo @c -*-texinfo-*- +@setfilename asymptote.info +@settitle Asymptote: the Vector Graphics Language +@include version.texi +@finalout + +@copying +This file documents @code{Asymptote}, version @value{VERSION}. + +@url{http://asymptote.sourceforge.net} + +Copyright @copyright{} 2004-9 Andy Hammerlindl, John Bowman, and Tom Prince. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the @acronym{GNU} Lesser General Public License (see the +file LICENSE in the top-level source directory). + +@end quotation +@end copying + +@dircategory Languages +@direntry +* asymptote: (asymptote). Vector graphics language. +@end direntry + +@titlepage +@title Asymptote: the Vector Graphics Language +@subtitle For version @value{VERSION} +@sp 1 +@center @image{logo} + +@page +@vskip 0pt plus 1filll +@insertcopying + +@end titlepage + +@c So the toc is printed at the start. +@contents + +@ifnottex +@node Top +@top Asymptote + +@insertcopying +@end ifnottex + +@menu +* Description:: What is @code{Asymptote}? +* Installation:: Downloading and installing +* Tutorial:: Getting started +* Drawing commands:: Four primitive graphics commands +* Programming:: The @code{Asymptote} vector graphics language +* LaTeX usage:: Embedding @code{Asymptote} commands within @code{LaTeX} +* Base modules:: Base modules shipped with @code{Asymptote} +* Options:: Command-line options +* Interactive mode:: Typing @code{Asymptote} commands interactively +* GUI:: Graphical user interface +* PostScript to Asymptote:: @code{Asymptote} backend to @code{pstoedit} +* Help:: Where to get help and submit bug reports +* Debugger:: Squish those bugs! +* Credits:: Contributions and acknowledgments +* Index:: General index + +@detailmenu + --- The Detailed Node Listing --- + +Installation + +* UNIX binary distributions:: Prebuilt @code{UNIX} binaries +* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries +* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary +* Configuring:: Configuring @code{Asymptote} for your system +* 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:: +* Uninstall:: Goodbye, @code{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 @code{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 @code{Asymptote} base file +* simplex:: Linear programming: simplex method +* math:: Extend @code{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 @acronym{PDF} and @acronym{MPEG} movies +* embed:: Embedding movies, sounds, and 3D objects +* slide:: Making presentations with @code{Asymptote} +* MetaPost:: @code{MetaPost} compatibility routines +* unicode:: Accept @code{unicode} (UTF-8) characters +* latin1:: Accept @code{ISO 8859-1} characters +* babel:: Interface to @code{LaTeX} @code{babel} package +* labelpath:: Drawing curved labels +* labelpath3:: Drawing curved labels in 3D +* annotate:: Annotate your @acronym{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 @code{xasy} +* GUI Usage:: + +@end detailmenu +@end menu + +@node Description +@chapter Description +@cindex description + +@code{Asymptote} is a powerful descriptive vector graphics language that +provides a mathematical coordinate-based framework for technical drawings. +Labels and equations are typeset with @code{LaTeX}, for overall document +consistency, yielding the same high-quality level of typesetting that +@code{LaTeX} provides for scientific text. By default it produces +@code{PostScript} output, but it can also generate any format that the +@code{ImageMagick} package can produce. + +A major advantage of @code{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 (@acronym{GUI}) methods for +producing figures. The rudimentary @acronym{GUI} @code{xasy} included with the +package allows one to move script-generated objects +around. To make @code{Asymptote} accessible to the average user, this +@acronym{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 @code{Asymptote} graphics commands (@pxref{Drawing commands}). + +@code{Asymptote} is mathematically oriented (e.g.@ one can +use complex multiplication to rotate a vector) and uses +@code{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 @code{MetaPost}. + +The @code{Asymptote} vector graphics language provides: + +@itemize @bullet +@item a standard for typesetting mathematical figures, just +as @TeX{}/@code{LaTeX} is the de-facto standard for typesetting equations. + +@item @code{LaTeX} typesetting of labels, for overall document consistency; + +@item a natural coordinate-based framework for technical drawings, +inspired by @code{MetaPost}, with a much cleaner, powerful C++-like programming +syntax; + +@item compilation of figures into virtual machine code for speed, without +sacrificing portability; + +@item the power of a script-based language coupled to the convenience of +a @acronym{GUI}; + +@item customization using its own C++-like graphics programming language; + +@item sensible defaults for graphical features, with the ability to override; + +@item a high-level mathematically oriented interface to the +@code{PostScript} language for vector graphics, including affine transforms +and complex variables; + +@item functions that can create new (anonymous) functions; + +@item 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; + +@end itemize + +Many of the features of @code{Asymptote} are written in the +@code{Asymptote} language itself. While the stock version of +@code{Asymptote} is designed for mathematics typesetting needs, one can +write @code{Asymptote} modules that tailor it to specific +applications. A scientific graphing module has already been written +(@pxref{graph}). Examples of @code{Asymptote} code and output, +including animations, are available at +@quotation +@url{http://asymptote.sourceforge.net/gallery/}. +@end quotation +@noindent +Links to many external resources, including an excellent user-written +@code{Asymptote} tutorial can be found at +@quotation +@url{http://asymptote.sourceforge.net/links.html}. +@end quotation + +@node Installation +@chapter Installation +@cindex installation + +@menu +* UNIX binary distributions:: Prebuilt @code{UNIX} binaries +* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries +* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary +* Configuring:: Configuring @code{Asymptote} for your system +* 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:: +* Uninstall:: Goodbye, @code{Asymptote}! +@end menu + +After following the instructions for your specific distribution, +please see also @ref{Configuring}. + +@noindent +We recommend subscribing to new release announcements at +@quotation +@url{http://freshmeat.net/projects/asy} +@end quotation +@noindent +Users may also wish to monitor the @code{Asymptote} forum: +@quotation +@url{http://sourceforge.net/forum/monitor.php?forum_id=409349} +@end quotation +@noindent + +@node UNIX binary distributions +@section UNIX binary distributions +@cindex UNIX binary distributions + +@cindex @acronym{RPM} +@cindex @code{tgz} +We release both @code{tgz} and @acronym{RPM} binary distributions of +@code{Asymptote}. The root user can install the @code{Linux i386} @code{tgz} +distribution of version @code{x.xx} of @code{Asymptote} with the commands: +@verbatim +tar -C / -zxf asymptote-x.xx.i386.tgz +texhash +@end verbatim +@noindent +The @code{texhash} command, which installs LaTeX style files, is optional. +The executable file will be @code{/usr/local/bin/asy}) and example code +will be installed by default in @code{@value{Datadir}/doc/asymptote/examples}. + +@noindent +@cindex Fedora +Fedora users can easily install the most recent version of @code{Asymptote} +with the command +@verbatim +yum --enablerepo=rawhide install asymptote +@end verbatim + +@cindex Debian +@noindent +To install the latest version of @code{Asymptote} on a Debian-based distribution +(e.g.@ Ubuntu, Mepis, Linspire) follow the instructions for compiling +from @code{UNIX} source (@pxref{Compiling from UNIX source}). +Alternatively, Debian users can install one of Hubert Chan's +prebuilt @code{Asymptote} binaries from +@quotation +@url{http://ftp.debian.org/debian/pool/main/a/asymptote} +@end quotation + +@node MacOS X binary distributions +@section MacOS X binary distributions +@cindex @code{MacOS X} binary distributions +@code{MacOS X} users can either compile the @code{UNIX} source code +(@pxref{Compiling from UNIX source}) +or install the contributed @code{Asymptote} binary available at + +@url{http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote/} + +@noindent +Because these preconfigured binary distributions have +strict architecture and library dependencies that many installations do +not satisfy, we recommend installing @code{Asymptote} directly from the +official source: + +@url{http://sourceforge.net/project/showfiles.php?group_id=120000} + +@noindent +Note that many @code{MacOS X} (and FreeBSD) systems inexplicably ship +with an extremely old @acronym{GNU} @code{readline} version (4.1, +dated 21 March 2000). For full interactive functionality, +@code{readline} version 4.2 or later (16 April 2001) is required. + +@node Microsoft Windows +@section Microsoft Windows +@cindex Microsoft Windows +Users of the @code{Microsoft Windows} operating system can install the +self-extracting @code{Asymptote} executable @code{asymptote-x.xx-setup.exe}, +where @code{x.xx} denotes the latest version. + +A working @TeX{} implementation (such as the one available at +@url{http://www.miktex.org}) will be required to typeset labels. +You will also need to install @code{GPL Ghostscript} from +@url{http://sourceforge.net/projects/ghostscript/}. +To view the default @code{PostScript} output, you can install the +program @code{gsview} available from +@url{http://www.cs.wisc.edu/~ghost/gsview/}. + +The @code{ImageMagick} package from + +@url{http://www.imagemagick.org/script/binary-releases.php} + +@noindent +is required to support output formats other than @acronym{EPS} and +@acronym{PDF} (@pxref{convert}). +The @code{Python} interpreter from @url{http://www.python.org} is only required +if you wish to try out the graphical user interface (@pxref{GUI}). + +@noindent +Example code will be installed by default in the @code{examples} +subdirectory of the installation directory (by default, +@code{C:\Program Files\Asymptote}). + +@node Configuring +@section Configuring +@cindex configuring +@cindex @code{-V} +@cindex @code{psviewer} +@cindex @code{pdfviewer} +@cindex @code{gs} +In interactive mode, or when given the @code{-V} option (the default +when running @code{Asymptote} on a single file under @code{MSDOS}), +@code{Asymptote} will automatically invoke the @code{PostScript} +viewer @code{gv} (under @code{UNIX}) or @code{gsview} (under +@code{MSDOS} to display graphical output. These defaults may be +overridden with the configuration variable @code{psviewer}. +The @code{PostScript} viewer should be capable of automatically +redrawing whenever the output file is updated. The default @code{UNIX} +@code{PostScript} viewer @code{gv} supports this (via a @code{SIGHUP} +signal). Version @code{gv-3.6.3} or later (from +@url{http://ftp.gnu.org/gnu/gv/}) is required for interactive mode to +work properly. +Users of @code{ggv} will need to enable @code{Watch file} under +@code{Edit/Postscript Viewer Preferences}. +Users of @code{gsview} will need to enable @code{Options/Auto Redisplay} +(however, under @code{MSDOS} it is still necessary to click on the +@code{gsview} window; under @code{UNIX} one must manually redisplay by +pressing the @code{r} key). + +@cindex @code{settings} +@cindex configuration file +Configuration variables are most easily set as @code{Asymptote} +variables in the configuration file (by default, @code{.asy/config.asy} in the +user's home directory or @code{%USERPROFILE%\.asy\config.asy} under +@code{MSDOS}); @pxref{configuration file}. Here are the default values +of several important configuration variables under @code{UNIX}: + +@cindex @code{python} +@noindent +@verbatim +import settings; +psviewer="gv"; +pdfviewer="acroread"; +gs="gs"; +python=""; +@end verbatim + +@noindent +The (installation-dependent) default values of these configuration +variables under @code{MSDOS} are determined automatically from the +@code{Microsoft Windows} registry. + +For @acronym{PDF} format output, the @code{gs} setting specifies the +location of the @code{PostScript}-to-@acronym{PDF} processor @code{Ghostscript}, +available from @url{http://sourceforge.net/projects/ghostscript/}. + +The setting @code{pdfviewer} specifies the location of the @acronym{PDF} +viewer. On @code{UNIX} systems, to support automatic document +reloading in @code{Adobe Reader}, we recommend copying the file +@code{reload.js} from the @code{Asymptote} system directory (by default, +@code{@value{Datadir}/asymptote} under @code{UNIX} to +@code{~/.adobe/Acrobat/x.x/JavaScripts/}, +where @code{x.x} represents the appropriate @code{Adobe Reader} +version number. The automatic document reload feature must then be +explicitly enabled by putting +@verbatim +import settings; +pdfreload=true; +pdfreloadOptions="-tempFile"; +@end verbatim +@noindent +in the @code{Asymptote} configuration file. This reload feature is not +useful under @code{MSDOS} since the document cannot be updated anyway on +that operating system until it is first closed by @code{Adobe Reader}. + +The graphical user interface may also require setting the variable +@code{python} if @code{Python} is installed in a nonstandard location. + +The configuration variable @code{dir} can be used to adjust the +search path (@pxref{Search paths}). + +@cindex @code{papertype} +@cindex @code{paperwidth} +@cindex @code{paperheight} +@cindex @code{letter} +@cindex @code{a4} +By default, @code{Asymptote} attempts to center the figure on the +page, assuming that the paper type is @code{letter}. The default paper +type may be changed to @code{a4} with the configuration variable +@code{papertype}. Alignment to other paper sizes can be obtained by setting the +configuration variables @code{paperwidth} and @code{paperheight}. + +@cindex @code{texpath} +@cindex @code{texcommand} +@cindex @code{texdvicommand} +@cindex @code{dvips} +@cindex @code{convert} +@cindex @code{display} +@cindex @code{animate} +@cindex @code{xasy} +@cindex @code{ImageMagick} +The following configuration variables normally do not require adjustment: +@verbatim +texpath +texcommand +texdvicommand +dvips +convert +display +animate +xasy +@end verbatim +@noindent +The @code{texdvicommand} is used for @code{3D} label typesetting, which +requires @code{dvips} output. An empty string indicates the default setting +of @code{latex}/@code{tex}, depending on the setting of @code{texengine}. + +@cindex command-line options +Configuration variables may also be set or overwritten with a +command-line option: +@verbatim +asy -psviewer=gsview -V venn +@end verbatim + +@cindex environment variables +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 @code{ASYMPTOTE_}: +for example, to set the environment variable +@verbatim +ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe"; +@end verbatim +@noindent +under @code{Microsoft Windows XP}: +@enumerate +@item Click on the @code{Start} button; +@item Right-click on @code{My Computer}; +@item Choose @code{Properties} from the popup menu; +@item Click the @code{Advanced} tab; +@item Click the @code{Environment Variables} button. +@end enumerate + +@node Search paths +@section Search paths +@cindex search paths + +In looking for @code{Asymptote} system +files, @code{asy} will search the following paths, in the order listed: +@enumerate +@item +The current directory; +@item +@cindex @code{dir} +A list of one or more directories specified by the configuration +variable @code{dir} (separated by @code{:} under UNIX and +@code{;} under @code{MSDOS}); +@item +@cindex @code{.asy} +The directory @code{.asy} in the user's home directory +(@code{%USERPROFILE%\.asy} under @code{MSDOS}); +@item +The @code{Asymptote} system directory (by default, +@code{@value{Datadir}/asymptote} under @code{UNIX} and +@code{C:\Program Files\Asymptote} under @code{MSDOS}). +@end enumerate + +@node Compiling from UNIX source +@section Compiling from UNIX source +@cindex Compiling from UNIX source + +To compile and install a @code{UNIX} executable from +a source release +@code{x.xx}, first execute the commands: +@verbatim +gunzip asymptote-x.xx.src.tgz +tar -xf asymptote-x.xx.src.tar +cd asymptote-x.xx +@end verbatim +By default the system version of the Boehm garbage collector will be +used; if it is old we recommend first putting +@url{http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.1.tar.gz} +in the @code{Asymptote} source directory. + +@cindex @code{freeglut} +@cindex 3D rendering +@cindex antialiasing +@cindex multisampling +@anchor{multisampling} +@noindent +If your graphics card supports multisampling, we recommend using SVN +revision 761 (or later) of @code{freeglut} to support antialiasing in +@code{Asymptote}'s adaptive @code{OpenGL} 3D renderer +(@code{MacOS X} users can skip this step since @code{Asymptote} is configured +to use the native glut library on that platform). Download +@quotation +@url{http://freeglut.svn.sourceforge.net/viewvc/freeglut/trunk/freeglut/freeglut.tar.gz} +@end quotation +@noindent +and type (as the root user): +@verbatim +tar -zxf freeglut.tar.gz +cd freeglut +sh autogen.sh +./configure --prefix=/usr +make install +cd .. +@end verbatim +@noindent +Then compile @code{Asymptote} with the commands +@verbatim +./configure +make all +make install +@end verbatim +@noindent +Be sure to use @acronym{GNU} @code{make} (on non-@acronym{GNU} systems +this command may be called @code{gmake}). +To build the documentation, you may need to install the +@code{texinfo-tex} package. If you get errors from a broken @code{texinfo} +or @code{pdftex} installation, simply put +@quotation +@url{http://asymptote.sourceforge.net/asymptote.pdf} +@end quotation +@noindent +in the directory @code{doc} and repeat the command @code{make all}. + +@noindent +For a (default) system-wide installation, the last command should be +done as the root user. To install without root privileges, change the +@code{./configure} command to +@verbatim +./configure --prefix=$HOME/asymptote +@end verbatim +One can disable use of the Boehm garbage collector by configuring +with @code{./configure --disable-gc}. For a list of other configuration +options, say @code{./configure --help}. For example, one can tell +configure to look for header files and libraries in nonstandard locations: +@verbatim +./configure CFLAGS=-I/opt/usr/include LDFLAGS=-L/opt/usr/lib +@end verbatim + +If you are compiling @code{Asymptote} with @code{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 @acronym{GNU} +@code{readline} library. +The file @code{gcc3.3.2curses.patch} in the @code{patches} directory can +be used to patch the broken curses.h header file (or a local copy thereof +in the current directory) on some @code{AIX} and @code{IRIX} systems. + +@cindex @code{FFTW} +@cindex @code{GSL} +The @code{FFTW} library is only required if you want @code{Asymptote} +to be able to take Fourier transforms of data (say, to compute an +audio power spectrum). The @code{GSL} library is only required if you +require the special functions that it supports. + +If you don't want to install @code{Asymptote} system wide, just make +sure the compiled binary @code{asy} and @acronym{GUI} script @code{xasy} are in +your path and set the configuration variable @code{dir} to point +to the directory @code{base} (in the top level directory of the +@code{Asymptote} source code). + +@node Editing modes +@section Editing modes +@cindex Editing modes +@cindex @code{emacs} +@cindex @code{asy-mode} +@cindex @code{lasy-mode} +Users of @code{emacs} can edit @code{Asymptote} code with the mode +@code{asy-mode}, after enabling it by putting the following lines in their +@code{.emacs} initialization file, replacing @code{ASYDIR} with the +location of the @code{Asymptote} system directory (by default, +@code{@value{Datadir}/asymptote} or @code{C:\Program Files\Asymptote} +under @code{MSDOS}): +@verbatim +(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)) + +@end verbatim +@noindent +Particularly useful key bindings in this mode are @code{C-c C-c}, which compiles +and displays the current buffer, and the key binding @code{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 @code{two-mode-mode}: +@quotation +@url{http://www.dedasys.com/freesoftware/files/two-mode-mode.el} +@end quotation +@noindent +Once installed, you can use the hybrid mode @code{lasy-mode} to edit a +LaTeX file containing embedded @code{Asymptote} code (@pxref{LaTeX usage}). +This mode can be enabled within @code{latex-mode} +with the key sequence @code{M-x lasy-mode <RET>}. +On @code{UNIX} systems, additional keywords will be generated from +all @code{asy} files in the space-separated list of directories +specified by the environment variable @code{ASYMPTOTE_SITEDIR}. +Further documentation of @code{asy-mode} is available within +@code{emacs} by pressing the sequence keys @code{C-h f asy-mode <RET>}. + +@cindex @code{vim} +@cindex @code{asy.vim} +Fans of @code{vim} can customize @code{vim} for @code{Asymptote} with + +@noindent +@code{cp @value{Datadir}/asymptote/asy.vim ~/.vim/syntax/asy.vim} + +@noindent +and add the following to their @code{~/.vimrc} file: +@verbatim +augroup filetypedetect +au BufNewFile,BufRead *.asy setf asy +augroup END +filetype plugin on +@end verbatim + +If any of these directories or files don't exist, just create them. +To set @code{vim} up to run the current asymptote script using @code{:make} +just add to @code{~/.vim/ftplugin/asy.vim}: +@verbatim +setlocal makeprg=asy\ % +setlocal errorformat=%f:\ %l.%c:\ %m + +@end verbatim + +@node Subversion +@section Subversion (SVN) +@cindex Subversion +@cindex SVN + +The following commands are needed to install the latest development version of +@code{Asymptote} using @acronym{Subversion}: +@verbatim +svn co http://asymptote.svn.sourceforge.net/svnroot/asymptote/trunk/asymptote +cd asymptote +./autogen.sh +./configure +make all +make install +@end verbatim + +@noindent +To compile without optimization, use the command @code{make CFLAGS=-g}. + +@node Uninstall +@section Uninstall +@cindex Uninstall + +To uninstall an @code{Linux i386} binary distribution, use the commands +@verbatim +tar -zxvf asymptote-x.xx.i386.tgz | xargs --replace=% rm /% +texhash +@end verbatim + +@noindent +To uninstall all @code{Asymptote} files installed from a source +distribution, use the command +@verbatim +make uninstall +@end verbatim + +@node Tutorial +@chapter Tutorial +@cindex tutorial +@emph{An excellent user-written @code{Asymptote} tutorial is also available +from} + +@url{http://www.artofproblemsolving.com/Wiki/index.php/Asymptote:_Basics} + +@noindent +To draw a line from coordinate (0,0) to coordinate (100,100) using +@code{Asymptote}'s interactive mode, type at the command prompt: +@verbatim +asy +draw((0,0)--(100,100)); +@end verbatim +@sp 1 +@center @image{diagonal} + +@cindex @code{bp} +@cindex @code{pair} +The units here are @code{PostScript} "big points" +(1 @code{bp} = 1/72 @code{inch}); @code{--} means join with a linear segment. +In @code{Asymptote} coordinates like @code{(0,0)} and +@code{(1000,100)} are called @emph{pairs}. + +@cindex tab completion +@cindex arrow keys +At this point you can type in further draw commands, which will be added +to the displayed figure, or type @code{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 @acronym{GNU} @code{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 @ref{Interactive mode}. + +@cindex batch mode +In batch mode, @code{Asymptote} reads commands directly from a +file. To try this out, type +@verbatiminclude diagonal.asy + +@noindent +into a file, say test.asy. Then execute this file with the +@code{MSDOS} or @code{UNIX} command +@verbatim +asy -V test +@end verbatim +@noindent +@code{MSDOS} users can drag and drop the file onto the +Desktop @code{asy} icon or make @code{Asymptote} the +default application for files with the extension @code{asy}. + +@noindent +@cindex @code{-V} +The @code{-V} option opens up a @code{PostScript} +viewer window so you can immediately view the encapsulated +@code{PostScript} output. By default the output will be written to the +file @code{test.eps}; the prefix of the output file may be changed with +the @code{-o} command-line option. + +@cindex @code{cycle} +One can draw a line with more than two points and create a cyclic path +like this square: +@verbatiminclude square.asy +@sp 1 +@center @image{square} + +It is often inconvenient to work directly with @code{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. +@verbatim +size(101,101); +draw((0,0)--(1,0)--(1,1)--(0,1)--cycle); +@end verbatim + +For convenience, the path @code{(0,0)--(1,0)--(1,1)--(0,1)--cycle} +may be replaced with the predefined variable +@code{unitsquare}, or equivalently, @code{box((0,0),(1,1))}. + +@cindex @code{inches} +@cindex @code{cm} +@cindex @code{mm} +@cindex @code{pt} +One can also specify the size in @code{pt} (1 @code{pt} = 1/72.27 @code{inch}), +@code{cm}, @code{mm}, or @code{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 +(@pxref{size}): +@verbatiminclude bigsquare.asy +@sp 1 +@center @image{bigsquare} + +@cindex user coordinates +@cindex @code{unitsize} +To make the user coordinates represent multiples of exactly @code{1cm}: +@verbatim +unitsize(1cm); +draw(unitsquare); +@end verbatim + +One can also specify different @math{x} and @math{y} unit sizes: +@verbatim +unitsize(1cm,2cm); +draw(unitsquare); +@end verbatim + +Adding labels is easy in @code{Asymptote}; one specifies the +label as a double-quoted @code{LaTeX} string, a +coordinate, and an optional alignment direction: +@verbatiminclude labelsquare.asy +@sp 1 +@center @image{labelsquare} + +@cindex compass directions +@cindex @code{N} +@cindex @code{E} +@cindex @code{W} +@cindex @code{S} +@code{Asymptote} uses the standard compass directions @code{E=(1,0)}, +@code{N=(0,1)}, @code{NE=unit(N+E)}, and @code{ENE=unit(E+NE)}, etc., +which along with the directions @code{up}, @code{down}, @code{right}, +and @code{left} are defined as pairs in the @code{Asymptote} base +module @code{plain}. A user who has a local variable named @code{E} +may access the compass direction @code{E} by prefixing it with the name +of the module where it is defined: @code{plain.E}. + +This example draws a path that approximates a quarter circle: +@verbatiminclude quartercircle.asy +@sp 1 +@center @image{quartercircle} + +In general, a path is specified as a list of pairs (or other paths) +interconnected with +@cindex @code{cycle} +@cindex @code{--} +@cindex @code{..} +@code{--}, which denotes a straight line segment, or @code{..}, which +denotes a cubic spline. +@anchor{unitcircle} +@cindex @code{unitcircle} +Specifying a final node @code{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: +@verbatim +path unitcircle=E..N..W..S..cycle; +@end verbatim + +@anchor{Bezier} +@cindex direction specifier +Each interior node of a cubic spline may be given a +direction prefix or suffix @code{@{dir@}}: the direction of the pair +@code{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 @math{z_0}, with postcontrol point +@math{c_0}, and the node @math{z_1}, with precontrol point @math{c_1}, +is computed as the Bezier curve +@sp 1 +@center @image{bezier,,,(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 (@math{m_5}) +constructed from two endpoints @math{z_0} and @math{z_1} and two control points +@math{c_0} and @math{c_1}, is the point corresponding to @math{t=1/2} on +the Bezier curve formed by the quadruple (@math{z_0}, @math{c_0}, +@math{c_1}, @math{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: +@sp 1 +@center @image{bezier2} + +Here @math{m_0}, @math{m_1} and @math{m_2} are the first-order +midpoints, @math{m_3} and @math{m_4} are the second-order midpoints, and +@math{m_5} is the third-order midpoint. +The curve is then constructed by recursively applying the algorithm to +(@math{z_0}, @math{m_0}, @math{m_3}, @math{m_5}) and +(@math{m_5}, @math{m_4}, @math{m_2}, @math{z_1}). + +In fact, an analogous property holds for points located at any +fraction @math{t} in @math{[0,1]} of each segment, not just for +midpoints (@math{t=1/2}). + +The Bezier curve constructed in this manner has the following properties: +@itemize @bullet + +@item It is entirely contained in the convex hull of the given four points. + +@item It starts heading from the first endpoint to the first control point +and finishes heading from the second control point to the second endpoint. + +@end itemize + +@cindex @code{controls} +The user can specify explicit control points between two nodes like this: +@verbatim +draw((0,0)..controls (0,100) and (100,100)..(100,0)); +@end verbatim + +However, it is usually more convenient to just use the +@code{..} operator, which tells @code{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. +@cindex @code{tension} +@cindex @code{and} +@cindex @code{atleast} +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): +@verbatim +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)); +@end verbatim + +@cindex @code{curl} +The curl parameter specifies the curvature at the endpoints of a path +(0 means straight; the default value of 1 means approximately circular): +@verbatim +draw((100,0){curl 0}..(100,100)..{curl 0}(0,100)); +@end verbatim + +@cindex @code{MetaPost ...@ } +@cindex @code{::} +The @code{MetaPost ...} path connector, which requests, when possible, an +inflection-free curve confined to a triangle defined by the +endpoints and directions, is implemented in @code{Asymptote} as the +convenient abbreviation @code{::} for @code{..tension atleast 1 ..} +(the ellipsis @code{...} is used in @code{Asymptote} to indicate a +variable number of arguments; @pxref{Rest arguments}). For example, +compare +@verbatiminclude dots.asy +@sp 1 +@center @image{dots} +@noindent +with +@verbatiminclude colons.asy +@sp 1 +@center @image{colons} + +@cindex @code{---} +@cindex @code{&} +The @code{---} connector is an abbreviation for @code{..tension atleast +infinity..} and the @code{&} 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). + +@cindex @code{PostScript} subpath +@cindex @code{^^} +@cindex @code{path[]} +@cindex superpath +An @code{Asymptote} path, being connected, is equivalent to a +@code{Postscript subpath}. The @code{^^} 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 +@code{Asymptote} paths into a @code{path[]} array (equivalent to a +@code{PostScript} path): +@verbatiminclude superpath.asy +@sp 1 +@center @image{superpath} + +@cindex evenodd +The @code{PostScript} even-odd fill rule here specifies that only the +region bounded between the two unit circles is filled (@pxref{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: +@verbatim +filldraw(unitcircle^^reverse(g),yellow,black); +@end verbatim + +@cindex @code{unitbox} +The @code{^^} operator is used by the @code{box(triple, triple)} function in +@code{three.asy} to construct the edges of a cube @code{unitbox} +without retracing steps: +@verbatiminclude cube.asy +@sp 1 +@center @image{cube} + +See section @ref{graph} (or the online @code{Asymptote} gallery and +external links posted at @url{http://asymptote.sourceforge.net}) for +further examples, including two and three-dimensional scientific +graphs. Additional examples have been posted by Philippe Ivaldi at +@url{http://piprim.tuxfamily.org/asymptote/}. + +@node Drawing commands +@chapter Drawing commands +@cindex drawing commands + +All of @code{Asymptote}'s graphical capabilities are based on four primitive +commands. The three @code{PostScript} drawing commands @code{draw}, +@code{fill}, and @code{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 @code{label} can be used to add text +labels and external @acronym{EPS} images, which will appear on top of the +@code{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 +@code{shipout} function (@pxref{shipout}). + +@cindex @code{layer} +If you wish to draw @code{PostScript} objects on top of labels (or verbatim +@code{tex} commands; @pxref{tex}), the @code{layer} command may be +used to start a +new @code{PostScript/LaTeX} layer: +@verbatim +void layer(picture pic=currentpicture); +@end verbatim + +The @code{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 @code{tex} commands are always drawn after the +@code{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). + +@cindex legend +@cindex @code{draw} +@cindex @code{arrow} +@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 +@end menu + +@node draw +@section draw +@verbatim +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); +@end verbatim + +Draw the path @code{g} on the picture @code{pic} using pen @code{p} +for drawing, with optional drawing attributes (Label @code{L}, +explicit label alignment @code{align}, +arrows and bars @code{arrow} and @code{bar}, margins @code{margin}, +legend, and markers @code{marker}). Only one parameter, the path, is +required. For convenience, the arguments @code{arrow} and @code{bar} may be +specified in either order. The argument @code{legend} is a Label to +use in constructing an optional legend entry. + +@cindex @code{None} +@cindex @code{BeginBar} +@cindex @code{EndBar} +@cindex @code{Bar} +@cindex @code{Bars} +@cindex @code{barsize} +Bars are useful for indicating dimensions. The possible values of +@code{bar} are @code{None}, @code{BeginBar}, @code{EndBar} (or +equivalently @code{Bar}), and @code{Bars} (which draws a bar at both +ends of the path). Each of these bar specifiers (except for +@code{None}) will accept an optional real argument that denotes the +length of the bar in @code{PostScript} coordinates. The default +bar length is @code{barsize(pen)}. + +@anchor{arrows} +@cindex @code{None} +@cindex @code{Blank} +@cindex @code{BeginArrow} +@cindex @code{MidArrow} +@cindex @code{EndArrow} +@cindex @code{Arrow} +@cindex @code{Arrows} +@cindex @code{FillDraw} +@cindex @code{Fill} +@cindex @code{Draw} +@cindex @code{NoFill} +@cindex @code{UnFill} +@cindex @code{BeginArcArrow} +@cindex @code{MidArcArrow} +@cindex @code{EndArcArrow} +@cindex @code{ArcArrow} +@cindex @code{ArcArrows} + +@cindex @code{DefaultHead} +@cindex @code{SimpleHead} +@cindex @code{HookHead} +@cindex @code{TeXHead} +The possible values of @code{arrow} are @code{None}, @code{Blank} +(which draws no arrows or path), @code{BeginArrow}, @code{MidArrow}, +@code{EndArrow} (or equivalently @code{Arrow}), +and @code{Arrows} (which draws an arrow at both ends of the path). +All of the arrow specifiers except for @code{None} and @code{Blank} +may be given the optional arguments arrowhead @code{arrowhead} (one of +the predefined arrowhead styles @code{DefaultHead}, @code{SimpleHead}, +@code{HookHead}, @code{TeXHead}), +real @code{size} (arrowhead size in @code{PostScript} coordinates), +real @code{angle} (arrowhead angle +in degrees), filltype @code{filltype} (one of @code{FillDraw}, @code{Fill}, +@code{NoFill}, @code{UnFill}, @code{Draw}) +and (except for @code{MidArrow} and @code{Arrows}) a +relative real @code{position} along the path (an @code{arctime}) where +the tip of the arrow should be placed. The default arrowhead size when drawn +with a pen @code{p} is @code{arrowsize(p)}. There are also arrow versions with +slightly modified default values of @code{size} and @code{angle} suitable for +curved arrows: @code{BeginArcArrow}, @code{EndArcArrow} (or equivalently +@code{ArcArrow}), @code{MidArcArrow}, and @code{ArcArrows}. + +@cindex @code{NoMargin} +@cindex @code{BeginMargin} +@cindex @code{EndMargin} +@cindex @code{Margin} +@cindex @code{Margins} +@cindex @code{BeginPenMargin} +@cindex @code{EndPenMargin} +@cindex @code{PenMargin} +@cindex @code{PenMargins} +@cindex @code{BeginDotMargin} +@cindex @code{EndDotMargin} +@cindex @code{DotMargin} +@cindex @code{DotMargins} +@cindex @code{Margin} +@cindex @code{TrueMargin} +Margins can be used to shrink the visible portion of a path by +@code{labelmargin(p)} to avoid overlap with other drawn objects. +Typical values of @code{margin} +are @code{NoMargin}, @code{BeginMargin}, @code{EndMargin} (or +equivalently @code{Margin}), and @code{Margins} (which leaves a margin +at both ends of the path). One may use @code{Margin(real begin, real end)} +to specify the size of the beginning and ending margin, respectively, +in multiples of the units @code{labelmargin(p)} used for aligning labels. +Alternatively, @code{BeginPenMargin}, @code{EndPenMargin} +(or equivalently @code{PenMargin}), @code{PenMargins}, +@code{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 @code{DotMargin}, an +abbreviation for @code{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 @code{dotfactor*linewidth(p)}. The qualifiers +@code{BeginDotMargin}, @code{EndDotMargin}, and @code{DotMargins} work +similarly. The qualifier @code{TrueMargin(real begin, real end)} allows one to +specify a margin directly in @code{PostScript} units, independent of +the pen line width. + +The use of arrows, bars, and margins is illustrated by the examples +@code{Pythagoras.asy}, @code{sqrtx01.asy}, and @code{triads.asy}. + +The legend for a picture @code{pic} can be fit and aligned to a frame +with the routine: +@cindex @code{legend} +@verbatim +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); +@end verbatim +@noindent +Here @code{xmargin} and @code{ymargin} specify the surrounding @math{x} +and @math{y} margins, @code{perline} specifies the number of entries +per line (default 1; 0 means choose this number automatically), +@code{linelength} specifies the length of the path lines, @code{hskip} +and @code{vskip} specify the line skip (as a multiple of the legend entry +size), @code{maxwidth} and @code{maxheight} specify optional upper limits +on the width and height of the resulting legend (0 means unlimited), +@code{hstretch} and @code{vstretch} allow the legend to stretch +horizontally or vertically, and @code{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 @code{dest} using @code{add} or @code{attach} +(@pxref{add about}). + +@cindex @code{dot} +To draw a dot, simply draw a path containing a single point. +The @code{dot} command defined in the module @code{plain} draws a +dot having a diameter equal to an explicit pen line width or the +default line width magnified by @code{dotfactor} (6 by default), +using the specified filltype (@pxref{filltype}): +@verbatim +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); +@end verbatim + +@cindex @code{Label} +If the variable @code{Label} is given as the @code{Label} +argument to the second routine, the @code{format} argument will be +used to format a string based on the dot location (here @code{defaultformat} +is @code{"$%.4g$"}). +The third routine draws a dot at every point of a pair array @code{z}. +One can also draw a dot at every node of a path: +@verbatim +void dot(picture pic=currentpicture, Label[] L=new Label[], + path g, align align=RightSide, string format=defaultformat, + pen p=currentpen, filltype filltype=Fill); +@end verbatim +See @ref{pathmarkers} and @ref{markers} for more general +methods for marking path nodes. + +To draw a fixed-sized object (in @code{PostScript} coordinates) about +the user coordinate @code{origin}, use the routine +@cindex @code{draw} +@verbatim +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); +@end verbatim + +@cindex @code{fill} +@node fill +@section fill +@verbatim +void fill(picture pic=currentpicture, path g, pen p=currentpen); +@end verbatim + +Fill the interior region bounded by the cyclic path @code{g} on the picture +@code{pic}, using the pen @code{p}. + +@cindex @code{filldraw} +There is also a convenient @code{filldraw} command, which fills the path +and then draws in the boundary. One can specify separate pens for each +operation: +@verbatim +void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen, + pen drawpen=currentpen); +@end verbatim + +@cindex @code{fill} +This fixed-size version of @code{fill} allows one to fill an object +described in @code{PostScript} coordinates about the user coordinate +@code{origin}: +@verbatim +void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen); +@end verbatim + +@noindent +This is just a convenient abbreviation for the commands: +@verbatim +picture opic; +fill(opic,g,p); +add(pic,opic,origin); +@end verbatim + +The routine +@cindex @code{filloutside} +@verbatim +void filloutside(picture pic=currentpicture, path g, pen p=currentpen); +@end verbatim +@noindent +fills the region exterior to the path @code{g}, out to the current +boundary of picture @code{pic}. + +@anchor{gradient shading} +@cindex gradient shading + +@cindex shading +@cindex @code{latticeshade} +Lattice gradient shading varying smoothly over a two-dimensional +array of pens @code{p}, using fill rule @code{fillrule}, can be produced with +@verbatim +void latticeshade(picture pic=currentpicture, path g, bool stroke=false, + pen fillrule=currentpen, pen[][] p) +@end verbatim +@cindex @code{stroke} +If @code{stroke=true}, the region filled is the same as the region that +would be drawn by @code{draw(pic,g,fillrule+zerowinding)}; in this case the path +@code{g} need not be cyclic. +The pens in @code{p} must belong to the same color space. One can use the +functions @code{rgb(pen)} or @code{cmyk(pen)} to promote pens to a +higher color space, as illustrated in the example file +@code{latticeshading.asy}. + +@cindex @code{axialshade} +Axial gradient shading varying smoothly from @code{pena} to @code{penb} in the +direction of the line segment @code{a--b} can be achieved with +@verbatim +void axialshade(picture pic=currentpicture, path g, bool stroke=false, + pen pena, pair a, + pen penb, pair b); +@end verbatim + +@cindex @code{radialshade} +Radial gradient shading varying smoothly from +@code{pena} on the circle with center @code{a} and radius @code{ra} to +@code{penb} on the circle with center @code{b} and radius @code{rb} +is similar: +@verbatim +void radialshade(picture pic=currentpicture, path g, bool stroke=false, + pen pena, pair a, real ra, + pen penb, pair b, real rb); +@end verbatim +@noindent +Illustrations of radial shading are provided in the example files +@code{shade.asy}, @code{ring.asy}, and @code{shadestroke.asy}. + +@cindex @code{gouraudshade} +Gouraud shading using fill rule @code{fillrule} and the vertex colors in the +pen array @code{p} on a triangular lattice defined by the vertices +@code{z} and edge flags @code{edges} is implemented with +@verbatim +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); +@end verbatim +@noindent +In the second form, the elements of @code{z} are taken to be successive +nodes of path @code{g}. The pens in @code{p} must belong to the same +color space. Illustrations of Gouraud shading are provided in the example file +@code{Gouraud.asy} and in the solid geometry module @code{solids.asy}. +The edge flags used in Gouraud shading are documented here: +@quotation +@url{http://partners.adobe.com/public/developer/en/ps/sdk/TN5600.SmoothShading.pdf}. +@end quotation + +@cindex Coons shading +@cindex tensor product shading +@cindex @code{tensorshade} +Tensor product shading using fill rule @code{fillrule} on patches +bounded by the @math{n} cyclic paths of length 4 in path array @code{b}, +using the vertex colors specified in the @math{n \times 4} pen array +@code{p} and internal control points in the @math{n \times 4} +array @code{z}, is implemented with +@verbatim +void tensorshade(picture pic=currentpicture, path g, bool stroke=false, + pen fillrule=currentpen, pen[][] p, path[] b=g, + pair[][] z=new pair[][]); +@end verbatim +@noindent +If the array @code{z} is empty, Coons shading, in which the color +control points are calculated automatically, is used. +The pens in @code{p} must belong to the same color space. +A simpler interface for the case of a single patch (@math{n=1}) is also +available: +@verbatim +void tensorshade(picture pic=currentpicture, path g, bool stroke=false, + pen fillrule=currentpen, pen[] p, path b=g, + pair[] z=new pair[]); +@end verbatim +One can also smoothly shade the regions between consecutive paths of a +sequence using a given array of pens: +@verbatim +void draw(picture pic=currentpicture, path[] g, pen[] p); +@end verbatim +@noindent +Illustrations of tensor product and Coons shading are provided in the +example files @code{tensor.asy}, @code{Coons.asy}, @code{BezierSurface.asy}, +and @code{rainbow.asy}. + +@cindex Function shading +@cindex function shading +@cindex @code{functionshade} +More general shading possibilities are available with the @code{pdflatex}, +@code{xetex}, and @code{pdftex} @TeX{} engines: the routine +@verbatim +void functionshade(picture pic=currentpicture, path[] g, bool stroke=false, + pen fillrule=currentpen, string shader); +@end verbatim +@noindent +shades on picture @code{pic} the interior of path @code{g} according +to fill rule @code{fillrule} using the @code{PostScript} calculator routine +specified by the string @code{shader}; this routine takes 2 arguments, +each in [0,1], and returns @code{colors(fillrule).length} color components. +Function shading is illustrated in the example @code{functionshading.asy}. + +@cindex unfill +The following routine uses @code{evenodd} clipping together with the +@code{^^} operator to unfill a region: + +@verbatim +void unfill(picture pic=currentpicture, path g); +@end verbatim + +@cindex @code{clip} +@cindex @code{stroke} +@node clip +@section clip +@verbatim +void clip(picture pic=currentpicture, path g, stroke=false, + pen fillrule=currentpen); +@end verbatim + +Clip the current contents of picture @code{pic} to the region bounded +by the path @code{g}, using fill rule @code{fillrule} (@pxref{fillrule}). +If @code{stroke=true}, the clipped portion is the same as the region +that would be drawn with @code{draw(pic,g,fillrule+zerowinding)}; in +this case the path @code{g} need not be cyclic. For an illustration of +picture clipping, see the first example in @ref{LaTeX usage}. + +@cindex @code{label} +@node label +@section label +@verbatim +void label(picture pic=currentpicture, Label L, pair position, + align align=NoAlign, pen p=nullpen, filltype filltype=NoFill) +@end verbatim + +Draw Label @code{L} on picture @code{pic} using pen @code{p}. If +@code{align} is @code{NoAlign}, the label will be centered at user +coordinate @code{position}; otherwise it will be aligned in the +direction of @code{align} and displaced from @code{position} by +the @code{PostScript} offset @code{align*labelmargin(p)}. +@cindex @code{Align} +The constant @code{Align} can be used to align the +bottom-left corner of the label at @code{position}. +@cindex @code{nullpen} +If @code{p} is @code{nullpen}, the pen specified within the +Label, which defaults to @code{currentpen}, will be used. +@anchor{Label} +The Label @code{L} can either be a string or the structure obtained by calling +one of the functions +@verbatim +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); +@end verbatim +The text of a Label can be scaled, slanted, rotated, or shifted by +multiplying it on the left by an affine transform (@pxref{Transforms}). +For example, @code{rotate(45)*xscale(2)*L} first scales @code{L} in the +@math{x} direction and then rotates it counterclockwise by 45 +degrees. The final position of a Label can also be shifted by a +@code{PostScript} coordinate translation: @code{shift(10,0)*L}. +The @code{embed} argument determines how the Label should transform with the +embedding picture: +@table @code +@item Shift +@cindex @code{Shift} +only shift with embedding picture; + +@item Rotate +@cindex @code{Rotate} +only shift and rotate with embedding picture (default); + +@item Rotate(pair z) +@cindex @code{Rotate(pair z)} +rotate with (picture-transformed) vector @code{z}. + +@item Slant +@cindex @code{Slant} +only shift, rotate, slant, and reflect with embedding picture; + +@item Scale +@cindex @code{Scale} +shift, rotate, slant, reflect, and scale with embedding picture. + +@end table + +To add a label to a path, use +@verbatim +void label(picture pic=currentpicture, Label L, path g, align align=NoAlign, + pen p=nullpen, filltype filltype=NoFill); +@end verbatim +@cindex @code{Relative} +By default the label will be positioned at the midpoint of the path. +An alternative label location (an @code{arctime} value between 0 and +@code{length(g)} @pxref{arctime}) may be specified as real value for +@code{position} in constructing the Label. The position +@code{Relative(real)} specifies a location relative to the total +arclength of the path. These convenient abbreviations are predefined: +@cindex @code{BeginPoint} +@cindex @code{MidPoint} +@cindex @code{EndPoint} +@verbatim +position BeginPoint=Relative(0); +position MidPoint=Relative(0.5); +position EndPoint=Relative(1); +@end verbatim + +@cindex @code{Relative} +@cindex @code{LeftSide} +@cindex @code{Center} +@cindex @code{RightSide} +Path labels are aligned in the direction @code{align}, which may +be specified as an absolute compass direction (pair) or a direction +@code{Relative(pair)} measured relative to a north axis +in the local direction of the path. For convenience @code{LeftSide}, +@code{Center}, and @code{RightSide} are defined as @code{Relative(W)}, +@code{Relative((0,0))}, and @code{Relative(E)}, respectively. +Multiplying @code{LeftSide}, @code{Center}, @code{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 @code{arrowlength} pointing +to @code{b} from direction @code{dir} can be produced with the routine +@cindex @code{arrow} +@verbatim +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); +@end verbatim +If no alignment is specified (either in the Label or as an explicit +argument), the optional Label will be aligned in the direction @code{dir}, +using margin @code{margin}. + +@cindex including images +@cindex @code{graphic} +@cindex @acronym{EPS} +The function @code{string graphic(string name, string options="")} +returns a string that can be used to include an encapsulated +@code{PostScript} (@acronym{EPS}) file. Here, @code{name} is the name +of the file to include and @code{options} is a string containing a +comma-separated list of optional bounding box (@code{bb=llx lly urx +ury}), width (@code{width=value}), height (@code{height=value}), +rotation (@code{angle=value}), scaling (@code{scale=factor}), clipping +(@code{clip=bool}), and draft mode (@code{draft=bool}) parameters. The +@code{layer()} function can be used to force future objects to be +drawn on top of the included image: +@verbatim +label(graphic("file.eps","width=1cm"),(0,0),NE); +layer(); +@end verbatim + +@cindex @code{baseline} +The @code{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 @code{Pythagoras.asy} for an example. + +One can prevent labels from overwriting one another with the +@code{overwrite} pen attribute (@pxref{overwrite}). + +The structure @code{object} defined in @code{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 +@cindex @code{pack} +@verbatim +frame pack(pair align=2S ... object inset[]); +@end verbatim +@noindent +To draw or fill a box (or ellipse or other path) around a Label and +return the bounding object, use one of the routines +@verbatim +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); +@end verbatim +@noindent +Here @code{envelope} is a boundary-drawing routine such as @code{box}, +@code{roundbox}, or @code{ellipse} defined in @code{plain_boxes.asy} +(@pxref{envelope}). + +@cindex @code{texpath} +The function @code{path[] texpath(Label L)} returns the path array that +@TeX{} would fill to draw the Label @code{L}. + +@cindex @code{minipage} +The @code{string minipage(string s, width=100pt)} function can be used +to format string @code{s} into a paragraph of width @code{width}. +This example uses @code{minipage}, @code{clip}, and @code{graphic} to +produce a CD label: +@sp 1 +@center @image{CDlabel} +@verbatiminclude CDlabel.asy +@node Programming +@chapter Programming +@cindex programming + +Here is a short introductory example to the @code{Asymptote} programming +language that highlights the similarity of its control structures +with those of C, C++, and Java: +@cindex declaration +@cindex assignment +@cindex conditional +@cindex loop +@cindex @code{if} +@cindex @code{else} +@cindex @code{for} +@verbatim +// 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); +} + +@end verbatim + +@cindex @code{while} +@cindex @code{do} +@cindex @code{break} +@cindex @code{continue} +@code{Asymptote} supports @code{while}, @code{do}, @code{break}, and +@code{continue} statements just as in C/C++. It also supports the Java-style +shorthand for iterating over all elements of an array: + +@cindex array iteration +@anchor{array iteration} +@verbatim +// Iterate over an array +int[] array={1,1,2,3,5}; +for(int k : array) { + write(k); +} +@end verbatim +@noindent +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 @code{Asymptote} packages +* Static:: Where to allocate your variable? +@end menu + +@node Data types +@section Data types +@cindex data types +@code{Asymptote} supports the following data types (in addition to +user-defined types): + +@table @code + +@item void +@cindex @code{void} +The void type is used only by functions that take or return no arguments. + +@item bool +@cindex @code{bool} +a boolean type that can only take on the values @code{true} or +@code{false}. For example: +@verbatim +bool b=true; +@end verbatim + +@noindent +defines a boolean variable @code{b} and initializes it to the value +@code{true}. If no initializer is given: +@verbatim +bool b; +@end verbatim + +@noindent +the value @code{false} is assumed. + +@item bool3 +@cindex @code{bool3} +an extended boolean type that can take on the values +@code{true}, @code{default}, or @code{false}. A bool3 type can be cast +to or from a bool. The default initializer for bool3 is @code{default}. + +@item int +@cindex @code{int} +@cindex @code{intMin} +@cindex @code{intMax} +an integer type; if no initializer is given, the implicit value @code{0} +is assumed. The minimum allowed value of an integer is @code{intMin} and the +maximum value is @code{intMax}. + +@item real +@cindex @code{real} +@cindex @code{realMin} +@cindex @code{realMax} +@cindex @code{realEpsilon} +@cindex @code{realDigits} +a real number; this should be set to the highest-precision native +floating-point type on the architecture. The implicit initializer for +reals is @code{0.0}. Real numbers have precision +@code{realEpsilon}, with @code{realDigits} significant digits. +The smallest positive real number is @code{realMin} and the largest +positive real number is @code{realMax}. + +@item pair +@cindex @code{pair} +complex number, that is, an ordered pair of real components @code{(x,y)}. +The real and imaginary parts of a pair @code{z} can read as @code{z.x} +and @code{z.y}. We say that @code{x} and @code{y} are virtual members of +the data element pair; they cannot be directly modified, however. +The implicit initializer for pairs is @code{(0.0,0.0)}. + +There are a number of ways to take the complex conjugate of a pair: +@example +pair z=(3,4); +z=(z.x,-z.y); +z=z.x-I*z.y; +z=conj(z); +@end example + +Here @code{I} is the pair @code{(0,1)}. +A number of built-in functions are defined for pairs: + +@table @code +@item pair conj(pair z) +@cindex @code{conj} +returns the conjugate of @code{z}; + +@item real length(pair z) +@cindex @code{length} +@cindex @code{abs} +returns the complex modulus @code{|z|} of its argument @code{z}. +For example, +@example +pair z=(3,4); +length(z); +@end example +returns the result 5. A synonym for @code{length(pair)} is @code{abs(pair)}; + +@item real angle(pair z) +@cindex @code{angle} +returns the angle of @code{z} in radians in the interval +[-@code{pi},@code{pi}]; + +@item real degrees(pair z, bool warn=true) +@cindex @code{degrees} +returns the angle of @code{z} in degrees in the interval [0,360) +or @code{0} if @code{warn} is @code{false} and @code{z.x=z.y=0} (rather than +producing an error); + +@item pair unit(pair z) +@cindex @code{unit} +returns a unit vector in the direction of the pair @code{z}; + +@item pair expi(real angle) +@cindex @code{expi} +returns a unit vector in the direction @code{angle} measured in radians; + +@item pair dir(real degrees) +@cindex @code{dir} +returns a unit vector in the direction @code{degrees} measured in degrees; + +@item real xpart(pair z) +@cindex @code{xpart} +returns @code{z.x}; + +@item real ypart(pair z) +@cindex @code{ypart} +returns @code{z.y}; + +@item pair realmult(pair z, pair w) +@cindex @code{realmult} +returns the element-by-element product @code{(z.x*w.x,z.y*w.y)}; + +@item real dot(pair z, pair w) +@cindex @code{dot} +returns the dot product @code{z.x*w.x+z.y*w.y}; + +@item pair minbound(pair z, pair w) +@cindex @code{minbound} +returns @code{(min(z.x,w.x),min(z.y,w.y))}; + +@item pair maxbound(pair z, pair w) +@cindex @code{maxbound} +returns @code{(max(z.x,w.x),max(z.y,w.y))}. + +@end table + +@item triple +@cindex @code{triple} +an ordered triple of real components @code{(x,y,z)} used for +three-dimensional drawings. The respective components of a triple +@code{v} can read as @code{v.x}, @code{v.y}, and @code{v.z}. +The implicit initializer for triples is @code{(0.0,0.0,0.0)}. + +Here are the built-in functions for triples: +@table @code +@item real length(triple v) +@cindex @code{length} +returns the length @code{|v|} of the vector @code{v}. +A synonym for @code{length(triple)} is @code{abs(triple)}; + +@item real polar(triple v) +@cindex @code{polar} +returns the colatitude of @code{v} measured from the @math{z} axis in radians; + +@item real azimuth(triple v) +@cindex @code{azimuth} +returns the longitude of @code{v} measured from the @math{x} axis in radians; + +@item real colatitude(triple v) +@cindex @code{colatitude} +returns the colatitude of @code{v} measured from the @math{z} axis in degrees; + +@item real latitude(triple v) +@cindex @code{latitude} +returns the latitude of @code{v} measured from the @math{xy} plane in degrees; + +@item real longitude(triple v, bool warn=true) +@cindex @code{longitude} +returns the longitude of @code{v} measured from the @math{x} axis in degrees; +or @code{0} if @code{warn} is @code{false} and @code{v.x=v.y=0} (rather than +producing an error); + +@item triple unit(triple v) +@cindex @code{unit} +returns a unit triple in the direction of the triple @code{v}; + +@item triple expi(real polar, real azimuth) +@cindex @code{expi} +returns a unit triple in the direction @code{(polar,azimuth)} +measured in radians; + +@item triple dir(real colatitude, real longitude) +@cindex @code{dir} +returns a unit triple in the direction @code{(colatitude,longitude)} +measured in degrees; + +@item real xpart(triple v) +@cindex @code{xpart} +returns @code{v.x}; + +@item real ypart(triple v) +@cindex @code{ypart} +returns @code{v.y}; + +@item real zpart(triple v) +@cindex @code{zpart} +returns @code{v.z}; + +@item real dot(triple u, triple v) +@cindex @code{dot} +returns the dot product @code{u.x*v.x+u.y*v.y+u.z*v.z}; + +@item triple cross(triple u, triple v) +@cindex @code{cross} +returns the cross product + +@code{(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)}; + +@item triple minbound(triple u, triple v) +@cindex @code{minbound} +returns @code{(min(u.x,v.x),min(u.y,v.y),min(u.z,v.z))}; + +@item triple maxbound(triple u, triple v) +@cindex @code{maxbound} +returns @code{(max(u.x,v.x),max(u.y,v.y),max(u.z,v.z)}). + +@end table + +@item string +@cindex @code{string} +@cindex @TeX{} string +a character string, implemented using the STL @code{string} class. + +Strings delimited by double quotes (@code{"}) are subject to the +following mappings to allow the use of double quotes in @TeX{} (e.g.@ for +using the @code{babel} package, @pxref{babel}): + +@itemize @bullet +@item \" maps to " +@item \\ maps to \\ +@end itemize + +@cindex @code{C} string +Strings delimited by single quotes (@code{'}) have the same mappings as +character strings in ANSI @code{C}: + +@itemize @bullet +@item \' maps to ' +@item \" maps to " +@item \? maps to ? +@item \\ maps to backslash +@item \a maps to alert +@item \b maps to backspace +@item \f maps to form feed +@item \n maps to newline +@item \r maps to carriage return +@item \t maps to tab +@item \v maps to vertical tab +@item \0-\377 map to corresponding octal byte +@item \x0-\xFF map to corresponding hexadecimal byte +@end itemize + +The implicit initializer for strings is the empty string @code{""}. +Strings may be concatenated with the @code{+} operator. In the following +string functions, position @code{0} denotes the start of the string: +@table @code + +@cindex @code{length} +@item int length(string s) +returns the length of the string @code{s}; + +@cindex @code{find} +@item int find(string s, string t, int pos=0) +returns the position of the first occurrence of string @code{t} in string +@code{s} at or after position @code{pos}, or -1 if @code{t} is not a +substring of @code{s}; + +@cindex @code{rfind} +@item int rfind(string s, string t, int pos=-1) +returns the position of the last occurrence of string @code{t} in string +@code{s} at or before position @code{pos} (if @code{pos}=-1, at the end +of the string @code{s}), or -1 if @code{t} is not a substring of @code{s}; + +@cindex @code{insert} +@item string insert(string s, int pos, string t) +returns the string formed by inserting string @code{t} at position +@code{pos} in @code{s}; + +@cindex @code{erase} +@item string erase(string s, int pos, int n) +returns the string formed by erasing the string of length @code{n} +(if @code{n}=-1, to the end of the string @code{s}) at +position @code{pos} in @code{s}; + +@cindex @code{substr} +@item string substr(string s, int pos, int n=-1) +returns the substring of @code{s} starting at position @code{pos} +and of length @code{n} (if @code{n}=-1, until the end of the +string @code{s}); + +@cindex @code{reverse} +@item string reverse(string s) +returns the string formed by reversing string @code{s}; + +@item string replace(string s, string before, string after) +@cindex @code{replace} +returns a string with all occurrences of the string @code{before} in the +string @code{s} changed to the string @code{after}; + +@item string replace(string s, string[][] table) +returns a string constructed by translating in string @code{s} all +occurrences of the string @code{before} in an array @code{table} of +string pairs @{@code{before},@code{after}@} to the corresponding +string @code{after}; + +@cindex @code{split} +@item string[] split(string s, string delimiter) +returns an array of strings obtained by splitting @code{s} into substrings +delimited by @code{delimiter}; + +@anchor{format} +@item string format(string s, int n) +@cindex @code{format} +returns a string containing @code{n} formatted according to the C-style +format string @code{s} using the current locale; + +@item string format(string s, real x, string locale="") +returns a string containing @code{x} formatted according to the C-style format +string @code{s} using locale @code{locale} (or the current locale if an +empty string is specified), following the behaviour of the C function +@code{fprintf}), except that only one data field is allowed, trailing +zeros are removed by default (unless @code{#} is specified), and @TeX{} +is used to typeset scientific notation; + +@cindex @code{hex} +@cindex @code{hexidecimal} +@item int hex(string s); +casts a hexidecimal string @code{s} to an integer. + +@cindex @code{string} +@item string string(real x, int digits=realDigits) +casts @code{x} to a string using precision @code{digits} and the C locale; + +@cindex @code{locale} +@item string locale(string s="") +sets the locale to the given string, if nonempty, and returns the +current locale. + +@item string time(string format="%a %b %d %T %Z %Y") +@cindex @code{time} +@cindex @code{date} +@cindex @code{strftime} +returns the current time formatted by the ANSI C routine +@code{strftime} according to the string @code{format} using the current +locale. Thus +@verbatim +time(); +time("%a %b %d %H:%M:%S %Z %Y"); +@end verbatim + +@noindent +are equivalent ways of returning the current time in the default +format used by the @code{UNIX} @code{date} command; + +@cindex @code{seconds} +@cindex @code{strptime} +@item 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 @code{strptime} +according to the string @code{format} using the current locale, or the +current time if @code{t} is the empty string. +Note that the @code{"%Z"} extension to the POSIX @code{strptime} +specification is ignored by the current GNU C Library. If an error occurs, the +value -1 is returned. Here are some examples: +@verbatim +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); +@end verbatim +The last example returns today's ordinal date, measured from the +beginning of the year. + +@cindex @code{time} +@cindex @code{strftime} +@item string time(int seconds, string format="%a %b %d %T %Z %Y") +returns the time corresponding to @code{seconds} seconds after the Epoch +(Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C routine +@code{strftime} according to the string @code{format} using the current +locale. For example, to return the date corresponding to 24 hours ago: +@verbatim +time(seconds()-24*60*60); +@end verbatim + +@cindex @code{abort} +@item void abort(string s) +aborts execution (with a non-zero return code in batch mode); if string +@code{s} is nonempty, a diagnostic message constructed from the source +file, line number, and @code{s} is printed; + +@cindex @code{exit} +@item void exit() +exits with a zero error return code in batch mode; + +@cindex @code{sleep} +@item void sleep(int seconds) +pauses for the given number of seconds; + +@cindex @code{usleep} +@item void usleep(int microseconds) +pauses for the given number of microseconds; + +@cindex @code{beep} +@item void beep() +produces a beep on the console; + +@end table + +@cindex @code{typedef} + +@end table + +As in C/C++, complicated types may be abbreviated with @code{typedef} +(see the example in @ref{Functions}). + +@node Paths and guides +@section Paths and guides + +@table @code + +@item path +@cindex @code{path} +a cubic spline resolved into a fixed path. +The implicit initializer for paths is @code{nullpath}. + +@cindex @code{circle} +@anchor{circle} +For example, the routine @code{circle(pair c, real r)}, which returns a +Bezier curve approximating a circle of radius @code{r} centered on @code{c}, +is based on @code{unitcircle} (@pxref{unitcircle}): +@verbatim +path circle(pair c, real r) +{ + return shift(c)*scale(r)*unitcircle; +} +@end verbatim +If high accuracy is needed, a true circle may be produced with the +routine @code{Circle} defined in the module @code{graph.asy}: +@cindex @code{Circle} +@verbatim +import graph; +path Circle(pair c, real r, int n=nCircle); +@end verbatim + +A circular arc consistent with @code{circle} centered on +@code{c} with radius @code{r} from @code{angle1} to @code{angle2} +degrees, drawing counterclockwise if @code{angle2 >= angle1}, can be +constructed with +@cindex @code{arc} +@verbatim +path arc(pair c, real r, real angle1, real angle2); +@end verbatim +One may also specify the direction explicitly: +@verbatim +path arc(pair c, real r, real angle1, real angle2, bool direction); +@end verbatim +Here the direction can be specified as CCW (counter-clockwise) or CW +(clockwise). For convenience, an arc centered at @code{c} from pair +@code{z1} to @code{z2} (assuming @code{|z2-c|=|z1-c|}) in the may also +be constructed with @verbatim +path arc(pair c, explicit pair z1, explicit pair z2, + bool direction=CCW) +@end verbatim + +If high accuracy is needed, true arcs may be produced with routines +in the module @code{graph.asy} that produce Bezier curves with @code{n} +control points: +@cindex @code{Arc} +@verbatim +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); +@end verbatim + +An ellipse can be drawn with the routine +@verbatim +@cindex @code{ellipse} +path ellipse(pair c, real a, real b) +{ + return shift(c)*scale(a,b)*unitcircle; +} +@end verbatim + +This example illustrates the use of all five guide connectors discussed +in @ref{Tutorial}: +@verbatiminclude join.asy +@sp 1 +@center @image{join} + +Here are some useful functions for paths: + +@table @code + +@cindex @code{length} +@item int length(path p); +This is the number of (linear or cubic) segments in path @code{p}. +If @code{p} is cyclic, this is the same as the number of nodes in @code{p}. + +@cindex @code{size} +@item int size(path p); +This is the number of nodes in the path @code{p}. +If @code{p} is cyclic, this is the same as @code{length(p)}. + +@cindex @code{cyclic} +@item bool cyclic(path p); +returns @code{true} iff path @code{p} is cyclic. + +@cindex @code{straight} +@item bool straight(path p, int i); +returns @code{true} iff the segment of path @code{p} between node +@code{i} and node @code{i+1} is straight. + +@cindex @code{piecewisestraight} +@item bool piecewisestraight(path p) +returns @code{true} iff the path @code{p} is piecewise straight. + +@cindex @code{point} +@item pair point(path p, int t); +If @code{p} is cyclic, return the coordinates of node @code{t} mod +@code{length(p)}. Otherwise, return the coordinates of node @code{t}, +unless @code{t} < 0 (in which case @code{point(0)} is returned) or +@code{t} > @code{length(p)} (in which case @code{point(length(p))} +is returned). + +@item pair point(path p, real t); +This returns the coordinates of the point between node @code{floor(t)} +and @code{floor(t)+1} corresponding to the cubic spline parameter +@code{t-floor(t)} (@pxref{Bezier}). If @code{t} lies outside the range +[0,@code{length(p)}], it is first reduced modulo @code{length(p)} +in the case where @code{p} is cyclic or else converted to the corresponding +endpoint of @code{p}. + +@cindex @code{dir} +@item pair dir(path p, int t, int sign=0, bool normalize=true); +If @code{sign < 0}, return the direction (as a pair) of the incoming tangent +to path @code{p} at node @code{t}; if @code{sign > 0}, return the +direction of the outgoing tangent. If @code{sign=0}, the mean of these +two directions is returned. + +@item pair dir(path p, real t, bool normalize=true); +returns the direction of the tangent to path @code{p} at the point +between node @code{floor(t)} and @code{floor(t)+1} corresponding to the +cubic spline parameter @code{t-floor(t)} (@pxref{Bezier}). + +@cindex @code{accel} +@item pair accel(path p, int t, int sign=0); +If @code{sign < 0}, return the acceleration of the incoming path +@code{p} at node @code{t}; if @code{sign > 0}, return the +acceleration of the outgoing path. If @code{sign=0}, the mean of these +two accelerations is returned. + +@cindex @code{accel} +@item pair accel(path p, real t); +returns the acceleration of the path @code{p} at the point @code{t}. + +@cindex @code{radius} +@item pair radius(path p, real t); +returns the radius of curvature of the path @code{p} at the point @code{t}. + +@cindex @code{precontrol} +@item pair precontrol(path p, int t); +returns the precontrol point of @code{p} at node @code{t}. + +@item pair precontrol(path p, real t); +returns the effective precontrol point of @code{p} at parameter @code{t}. + +@cindex @code{postcontrol} +@item pair postcontrol(path p, int t); +returns the postcontrol point of @code{p} at node @code{t}. + +@item pair postcontrol(path p, real t); +returns the effective postcontrol point of @code{p} at parameter @code{t}. + +@cindex @code{arclength} +@item real arclength(path p); +returns the length (in user coordinates) of the piecewise linear +or cubic curve that path @code{p} represents. + +@anchor{arctime} +@cindex @code{arctime} +@item 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 @code{point(path p, real t)}, at which the +cumulative arclength (measured from the beginning of the path) equals @code{L}. + +@cindex @code{dirtime} +@item 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 @code{point(path, real)}, at which the tangent +to the path has the direction of pair @code{z}, or -1 if this never happens. + +@cindex @code{reltime} +@item real reltime(path p, real l); +returns the time on path @code{p} at the relative fraction @code{l} of +its arclength. + +@cindex @code{relpoint} +@item pair relpoint(path p, real l); +returns the point on path @code{p} at the relative fraction @code{l} of its +arclength. + +@cindex @code{midpoint} +@item pair midpoint(path p); +returns the point on path @code{p} at half of its arclength. + +@cindex @code{reverse} +@item path reverse(path p); +returns a path running backwards along @code{p}. + +@cindex @code{subpath} +@item path subpath(path p, int a, int b); +returns the subpath of @code{p} running from node @code{a} to node @code{b}. +If @code{a} < @code{b}, the direction of the subpath is reversed. + +@item path subpath(path p, real a, real b); +returns the subpath of @code{p} running from path time @code{a} to path +time @code{b}, in the sense of @code{point(path, real)}. If @code{a} < +@code{b}, the direction of the subpath is reversed. + +@cindex @code{intersect} +@item real[] intersect(path p, path q, real fuzz=-1); +If @code{p} and @code{q} have at least one intersection point, return a +real array of length 2 containing the times representing the respective +path times along @code{p} and @code{q}, in the sense of +@code{point(path, real)}, for one such intersection point (as chosen by +the algorithm described on page 137 of @code{The MetaFontbook}). +The computations are performed to the absolute error specified by @code{fuzz}, +or, if @code{fuzz < 0}, to machine precision. If the paths do not +intersect, return a real array of length 0. + +@cindex @code{intersections} +@item real[][] intersections(path p, path q, real fuzz=-1); +Return all (unless there are infinitely many) intersection times of +paths @code{p} and @code{q} as a sorted array of real arrays of length 2 +(@pxref{sort}). The computations are performed to the absolute error +specified by @code{fuzz}, or, if @code{fuzz < 0}, to machine precision. + +@cindex @code{intersections} +@item real[] intersections(path p, explicit pair a, explicit pair b, + real fuzz=-1); +Return all (unless there are infinitely many) intersection times of path +@code{p} with the (infinite) line through points @code{a} and @code{b} +as a sorted array. The intersections returned are guaranteed to be +correct to within the absolute error specified by @code{fuzz}, or, if +@code{fuzz < 0}, to machine precision. + +@cindex @code{times} +@item real[] times(path p, real x) +returns all intersection times of path @code{p} with the vertical line +through @code{(x,0)}. + +@cindex @code{times} +@item real[] times(path p, explicit pair z) +returns all intersection times of path @code{p} with the horizontal line +through @code{(0,z.y)}. + +@cindex @code{mintimes} +@item real[] mintimes(path p) +returns an array of length 2 containing times at which path @code{p} +reaches its minimal horizontal and vertical extents, respectively. + +@cindex @code{maxtimes} +@item real[] maxtimes(path p) +returns an array of length 2 containing the times at which path @code{p} +reaches its maximal horizontal and vertical extents, respectively. + +@cindex @code{intersectionpoint} +@item pair intersectionpoint(path p, path q, real fuzz=-1); +returns the intersection point @code{point(p,intersect(p,q,fuzz)[0])}. + +@cindex @code{intersectionpoints} +@item pair[] intersectionpoints(path p, path q, real fuzz=-1); +returns an array containing all intersection points of the paths +@code{p} and @code{q}. + +@anchor{extension} +@cindex @code{whatever} +@cindex @code{extension} +@item pair extension(pair P, pair Q, pair p, pair q); +returns the intersection point of the extensions of the line segments +@code{P--Q} and @code{p--q}, or, if the lines are parallel, +@code{(infinity,infinity)}. + +@cindex @code{cut} +@cindex @code{slice} +@item slice cut(path p, path knife, int n); +returns the portions of path @code{p} before and after the @code{n}th +intersection of @code{p} with path @code{knife} as a structure +@code{slice} (if no intersection exist is found, the entire path is +considered to be `before' the intersection): +@verbatim +struct slice { + path before,after; +} +@end verbatim +The argument @code{n} is treated as modulo the number of intersections. + +@cindex @code{firstcut} +@cindex @code{slice} +@item slice firstcut(path p, path knife); +equivalent to @code{cut(p,knife,0);} +@cindex @code{MetaPost cutbefore} +Note that @code{firstcut.after} plays the role of the @code{MetaPost +cutbefore} command. + +@cindex @code{lastcut} +@item slice lastcut(path p, path knife); +equivalent to @code{cut(p,knife,-1);} +@cindex @code{MetaPost cutafter} +Note that @code{lastcut.before} plays the role of the +@code{MetaPost cutafter} command. + +@cindex @code{buildcycle} +@item 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 +@code{MetaPost buildcycle} command. + +@cindex @code{min} +@item pair min(path p); +returns the pair (left,bottom) for the path bounding box of path @code{p}. + +@cindex @code{max} +@item pair max(path p); +returns the pair (right,top) for the path bounding box of path @code{p}. + +@cindex @code{windingnumber} +@cindex @code{undefined} +@item int windingnumber(path p, pair z); +returns the winding number of the cyclic path @code{p} relative to the point +@code{z}. The winding number is positive if the path encircles @code{z} in the +counterclockwise direction. If @code{z} lies on @code{p} the constant +@code{undefined} (defined to be the largest odd integer) is returned. + +@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 +the region bounded by the cyclic path @code{p} according to the fill +rule @code{fillrule} (@pxref{fillrule}). + +@cindex @code{inside} +@item int inside(path p, path q, pen fillrule=currentpen); +returns @code{1} if the cyclic path @code{p} strictly contains @code{q} +according to the fill rule @code{fillrule} (@pxref{fillrule}), @code{-1} +if the cyclic path @code{q} strictly contains @code{p}, and @code{0} +otherwise. + +@cindex @code{inside} +@item pair inside(path p, pen fillrule=currentpen); +returns an arbitrary point strictly inside a cyclic path @code{p} +according to the fill rule @code{fillrule} (@pxref{fillrule}). + +@cindex @code{strokepath} +@item path[] strokepath(path g, pen p=currentpen); +returns the path array that @code{PostScript} would fill in drawing path +@code{g} with pen @code{p}. + +@end table + +@item guide +@cindex @code{guide} +an unresolved cubic spline (list of cubic-spline nodes and control points). +The implicit initializer for a guide is @code{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: + +@verbatiminclude mexicanhat.asy +@sp 1 +@center @image{mexicanhat} + +We point out an efficiency distinction in the use of guides and paths: +@verbatim +guide g; +for(int i=0; i < 10; ++i) + g=g--(i,i); +path p=g; +@end verbatim + +@noindent +runs in linear time, whereas +@verbatim +path p; +for(int i=0; i < 10; ++i) + p=p--(i,i); +@end verbatim + +@noindent +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): + +@table @code + +@cindex @code{size} +@item int size(guide g); +Analogous to @code{size(path p)}. + +@cindex @code{length} +@item int length(guide g); +Analogous to @code{length(path p)}. + +@cindex @code{cyclic} +@item bool cyclic(path p); +Analogous to @code{cyclic(path p)}. + +@cindex @code{point} +@item pair point(guide g, int t); +Analogous to @code{point(path p, int t)}. + +@cindex @code{reverse} +@item guide reverse(guide g); +Analogous to @code{reverse(path p)}. If @code{g} is cyclic and +also contains a secondary cycle, it is first solved to a +path, then reversed. If @code{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. + +@cindex @code{dirSpecifier} +@item 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 +@code{(0,0)} if none specified) for the segment of guide @code{g} +between nodes @code{i} and @code{i+1}. + +@cindex @code{controlSpecifier} +@item pair[] controlSpecifier(guide g, int i); +If the segment of guide @code{g} between nodes @code{i} and @code{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. + +@cindex @code{tensionSpecifier} +@item tensionSpecifier tensionSpecifier(guide g, int i); +This returns the tension specifier for the segment of guide @code{g} between +nodes @code{i} and @code{i+1}. The individual components of the +@code{tensionSpecifier} type can be accessed as the virtual members +@code{in}, @code{out}, and @code{atLeast}. + +@cindex @code{curlSpecifier} +@item 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 @code{g}. + +@end table + +As a technical detail we note that a direction specifier given to +@code{nullpath} modifies the node on the other side: the guides +@verbatim +a..{up}nullpath..b; +c..nullpath{up}..d; +e..{up}nullpath{down}..f; +@end verbatim +are respectively equivalent to +@verbatim +a..nullpath..{up}b; +c{up}..nullpath..d; +e{down}..nullpath..{up}f; +@end verbatim + +@end table + +@node Pens +@section Pens + +@cindex @code{pen} +@cindex @code{currentpen} +@cindex @code{MetaPost pickup} +In @code{Asymptote}, pens provide a context for the four basic drawing +commands (@pxref{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 +@code{currentpen}. This provides the same functionality as the +@code{MetaPost} command @code{pickup}. +The implicit initializer for pens is @code{defaultpen}. + +@cindex @code{+} +@cindex @code{*} +Pens may be added together with the nonassociative binary +operator @code{+}. 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 @code{dashed+red+green} or @code{red+green+dashed} +or @code{red+dashed+green}. The binary operator @code{*} +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. + +@itemize @bullet + +@item Colors are specified using one of the following colorspaces: +@cindex color +@table @code +@item pen gray(real g); +@cindex @code{gray} +@cindex grayscale +This produces a grayscale color, where the intensity @code{g} lies in the +interval [0,1], with 0.0 denoting black and 1.0 denoting white. + +@item pen rgb(real r, real g, real b); +@cindex @code{rgb} +This produces an @acronym{RGB} color, where each of the red, green, +and blue intensities @code{r}, @code{g}, @code{b}, lies in the interval [0,1]. + +@item pen cmyk(real c, real m, real y, real k); +@cindex @code{cmyk} +This produces a @acronym{CMYK} color, where each of the cyan, magenta, +yellow, and black intensities @code{c}, @code{m}, @code{y}, @code{k}, +lies in the interval [0,1]. + +@item pen invisible; +@cindex @code{invisible} +This special pen writes in invisible ink, but adjusts the bounding +box as if something had been drawn (like the @code{\phantom} +command in @TeX{}). The function @code{bool invisible(pen)} can be used +to test whether a pen is invisible. + +@end table + +@cindex @code{defaultpen} +The default color is @code{black}; this may be changed with the routine +@code{defaultpen(pen)}. The function @code{colorspace(pen p)} returns +the colorspace of pen @code{p} as a string (@code{"gray"}, @code{"rgb"}, +@code{"cmyk"}, or @code{""}). + +@cindex @code{colors} +The function @code{real[] colors(pen)} returns the color components of a pen. +The functions @code{pen gray(pen)}, @code{pen rgb(pen)}, and +@code{pen cmyk(pen)} return new pens obtained by converting their +arguments to the respective color spaces. +@cindex @code{colorless} +The function @code{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 +@cindex @code{rgb} +@cindex @code{hexidecimal} +@verbatim +pen rgb(string s); +@end verbatim + +Various shades and mixtures of the grayscale primary colors +@code{black} and @code{white}, @acronym{RGB} primary colors +@code{red}, @code{green}, and @code{blue}, and +@acronym{RGB} secondary colors @code{cyan}, @code{magenta}, and @code{yellow} +are defined as named colors, along with the @acronym{CMYK} primary +colors @code{Cyan}, @code{Magenta}, @code{Yellow}, and @code{Black}, in +the module @code{plain}: +@sp 1 +@center @image{colors} + +The standard 140 @acronym{RGB} @code{X11} colors can be imported with +the command +@verbatim +import x11colors; +@end verbatim +and the standard 68 @acronym{CMYK} @TeX{} colors can be imported with +the command +@verbatim +import texcolors; +@end verbatim +Note that there is some overlap between these two standards +and the definitions of some colors (e.g.@ @code{Green}) actually disagree. + +@code{Asymptote} also comes with a @code{asycolors.sty} @code{LaTeX} package +that defines to @code{LaTeX} @acronym{CMYK} versions of +@code{Asymptote}'s predefined colors, so that they can be used +directly within @code{LaTeX} strings. Normally, such colors are +passed to @code{LaTeX} via a pen argument; however, to change the +color of only a portion of a string, say for a slide presentation, +(@pxref{slide}) it may be desirable to specify the color directly to +@code{LaTeX}. This file can be passed to @code{LaTeX} with the +@code{Asymptote} command +@verbatim +usepackage("asycolors"); +@end verbatim + +The structure @code{hsv} defined in @code{plain_pens.asy} may be used +to convert between @acronym{HSV} and @acronym{RGB} spaces, where +the hue @code{h} is an angle in @math{[0,360)} and the saturation +@code{s} and value @code{v} lie in @code{[0,1]}: +@verbatim +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 +@end verbatim + +@item Line types are specified with the function +@code{pen linetype(string s, real offset=0, bool scale=true, bool adjust=true)}, +@cindex @code{solid} +@cindex @code{dashed} +@cindex @code{dotted} +@cindex @code{longdashed} +@cindex @code{dashdotted} +@cindex @code{longdashdotted} +where @code{s} is a string of integer or real numbers separated by spaces. +The optional parameter @code{offset} specifies where in the pattern +to begin. The first number specifies how far (if @code{scale} is +@code{true}, in units of the pen line width; otherwise in +@code{PostScript} units) to draw with the pen on, the second number +specifies how far to draw with the pen off, and so on. If +@code{adjust} is @code{true}, these spacings are automatically +adjusted by @code{Asymptote} to fit the arclength of the path. Here +are the predefined line types: +@verbatim +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);} +@end verbatim +@sp 1 +@center @image{linetype} + +@cindex @code{defaultpen} +The default line type is @code{solid}; this may be changed with +@code{defaultpen(pen)}. +The line type of a pen is returned by @code{int linetype(pen p=currentpen)}. + +@cindex @code{linewidth} +@cindex @code{defaultpen} +@item The pen line width is specified in @code{PostScript} units with +@code{pen linewidth(real)}. The default line width is 0.5 bp; this value +may be changed with @code{defaultpen(pen)}. The line width of a pen +is returned by @code{real linewidth(pen p=currentpen)}. +For convenience, in the module @code{plain} we define +@verbatim +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;} +@end verbatim +so that one may set the line width like this: +@verbatim +defaultpen(2); +pen p=red+0.5; +@end verbatim + +@cindex @code{linecap} +@cindex @code{squarecap} +@cindex @code{roundcap} +@cindex @code{extendcap} +@cindex @code{defaultpen} +@item A pen with a specific @code{PostScript} line cap is returned on +calling @code{linecap} with an integer argument: +@verbatim +pen squarecap=linecap(0); +pen roundcap=linecap(1); +pen extendcap=linecap(2); +@end verbatim + +@noindent +The default line cap, @code{roundcap}, may be changed with +@code{defaultpen(pen)}. The line cap of a pen is returned by +@code{int linecap(pen p=currentpen)}. + +@cindex @code{linejoin} +@cindex @code{miterjoin} +@cindex @code{roundjoin} +@cindex @code{beveljoin} +@item A pen with a specific @code{PostScript} join style is returned on +calling @code{linejoin} with an integer argument: +@verbatim +pen miterjoin=linejoin(0); +pen roundjoin=linejoin(1); +pen beveljoin=linejoin(2); +@end verbatim + +@noindent +The default join style, @code{roundjoin}, may be changed with +@code{defaultpen(pen)}.The join style of a pen is returned by +@code{int linejoin(pen p=currentpen)}. + +@cindex @code{miterlimit} +@item A pen with a specific @code{PostScript} miter limit is returned by +calling @code{miterlimit(real)}. +The default miterlimit, @code{10.0}, may be changed with +@code{defaultpen(pen)}. The miter limit of a pen is returned by +@code{real miterlimit(pen p=currentpen)}. + +@cindex @code{fillrule} +@cindex @code{zerowinding} +@cindex @code{evenodd} +@anchor{fillrule} +@item A pen with a specific @code{PostScript} fill rule is returned on +calling @code{fillrule} with an integer argument: +@verbatim +pen zerowinding=fillrule(0); +pen evenodd=fillrule(1); +@end verbatim + +@noindent +The fill rule, which identifies the algorithm used to determine the +insideness of a path or array of paths, only affects the @code{clip}, +@code{fill}, and @code{inside} functions. For the @code{zerowinding} +fill rule, a point @code{z} is outside the region bounded by a path if +the number of upward intersections of the path with the horizontal +line @code{z--z+infinity} minus the number of downward intersections +is zero. For the @code{evenodd} fill rule, @code{z} is considered to +be outside the region if the total number of such intersections is even. +The default fill rule, @code{zerowinding}, may be changed with +@code{defaultpen(pen)}. The fill rule of a pen is returned by +@code{int fillrule(pen p=currentpen)}. + +@cindex @code{nobasealign} +@cindex @code{basealign} +@anchor{basealign} +@item A pen with a specific text alignment setting is returned on +calling @code{basealign} with an integer argument: +@verbatim +pen nobasealign=basealign(0); +pen basealign=basealign(1); +@end verbatim + +@noindent +The default setting, @code{nobasealign},which may be changed with +@code{defaultpen(pen)}, causes the label alignment routines to use the +full label bounding box for alignment. In contrast, @code{basealign} +requests that the @TeX{} baseline be respected. +The base align setting of a pen is returned by +@code{int basealigin(pen p=currentpen)}. + +@cindex @code{fontsize} +@cindex @code{lineskip} +@cindex @code{defaultpen} +@cindex @code{fix-cm} +@item The font size is specified in @TeX{} points (1 pt = 1/72.27 inches) with +the function @code{pen fontsize(real size, real lineskip=1.2*size)}. +The default font size, 12pt, may be changed with @code{defaultpen(pen)}. +Nonstandard font sizes may require inserting +@verbatim +import fontsize; +@end verbatim +at the beginning of the file (this requires the @code{fix-cm} package +available from +@quotation +@url{http://www.ctan.org/tex-archive/help/Catalogue/entries/fix-cm} +@end quotation +and included in recent @code{LaTeX} distributions). The font size and line +skip of a pen can be examined with the routines +@code{real fontsize(pen p=currentpen)} and +@code{real lineskip(pen p=currentpen)}, respectively. + +@cindex @code{font} +@cindex @code{LaTeX fonts} +@cindex @code{NFSS} +@cindex @code{font command} +@item A pen using a specific @code{LaTeX} @code{NFSS} font is returned +by calling the function @code{pen font(string encoding, string family, +string series="m", string shape="n")}. The default setting, +@code{font("OT1","cmr","m","n")}, corresponds to 12pt Computer Modern Roman; +this may be changed with @code{defaultpen(pen)}. +The font setting of a pen is returned by +@code{string font(pen p=currentpen)}. +Support for standardized international characters is provided by the +@code{unicode} package (@pxref{unicode}). + +@cindex @code{TeX fonts} +Alternatively, one may select a fixed-size @TeX{} font (on which +@code{fontsize} has no effect) like @code{"cmr12"} (12pt Computer Modern +Roman) or @code{"pcrr"} (Courier) using the function @code{pen font(string +name)}. An optional size argument can also be given to scale the font +to the requested size: @code{pen font(string name, real size)}. + +@cindex @code{fontcommand} +A nonstandard font command can be generated with +@code{pen fontcommand(string)}. + +@cindex @code{PostScript fonts} +A convenient interface to the following standard @code{PostScript} +fonts is also provided: +@verbatim +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"); +@end verbatim + +@anchor{transparency} +@cindex transparency +@cindex @code{opacity} +@item The transparency of a pen can be changed with the command: +@verbatim +pen opacity(real opacity=1, string blend="Compatible"); +@end verbatim +The opacity can be varied from @code{0} (fully transparent) to the default +value of @code{1} (opaque), and @code{blend} specifies one of the +following foreground--background blending operations: +@verbatim +"Compatible","Normal","Multiply","Screen","Overlay","SoftLight", +"HardLight","ColorDodge","ColorBurn","Darken","Lighten","Difference", +"Exclusion","Hue","Saturation","Color","Luminosity", +@end verbatim +as described in + +@url{http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf}. +Since @code{PostScript} does not support transparency, this feature is +only effective with the @code{-f pdf} output format option; other +formats can be produced from the resulting @acronym{PDF} file with the +@code{ImageMagick} @code{convert} program. +Labels are always drawn with an @code{opacity} of 1. +A simple example of transparent filling is provided in the example file +@code{transparency.asy}. + +@cindex patterns +@cindex tilings +@item @code{PostScript} commands within a @code{picture} may be used +to create a tiling pattern, identified by the string @code{name}, for +@code{fill} and @code{draw} operations by adding it to the +global @code{PostScript} frame @code{currentpatterns}, +with optional left-bottom margin @code{lb} and right-top margin @code{rt}. +@verbatim +import patterns; +void add(string name, picture pic, pair lb=0, pair rt=0); +@end verbatim + +To @code{fill} or @code{draw} using pattern @code{name}, use +the pen @code{pattern("name")}. For example, rectangular tilings +can be constructed using the routines +@code{picture tile(real Hx=5mm, real Hy=0, pen p=currentpen, +filltype filltype=NoFill)}, +@code{picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)}, and +@code{picture brick(real Hx=5mm, real Hy=0, pen p=currentpen)} defined in +@code{patterns.asy}: +@cindex grid +@cindex tile +@cindex checker +@cindex brick +@verbatiminclude tile.asy +@sp 1 +@center @image{tile} + +@cindex hatch +@cindex crosshatch +Hatch patterns can be generated with the routines +@code{picture hatch(real H=5mm, pair dir=NE, pen p=currentpen)}, +@code{picture crosshatch(real H=5mm, pen p=currentpen)}: +@verbatiminclude hatch.asy +@sp 1 +@center @image{hatch} + +You may need to turn off aliasing in your @code{PostScript} viewer for +patterns to appear correctly. Custom patterns can easily be constructed, +following the examples in @code{patterns.asy}. The tiled pattern can +even incorporate shading (@pxref{gradient shading}), as illustrated +in this example (not included in the manual because not all printers support +@code{PostScript} 3): +@verbatiminclude shadedtiling.asy + +@anchor{makepen} +@cindex @code{makepen} +@item One can specify a custom pen nib as an arbitrary polygonal path +with @code{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 @code{path nib(pen)}. Unlike in +@code{MetaPost}, the path need not be convex: + +@verbatiminclude makepen.asy +@sp 1 +@center @image{makepen} + +The value @code{nullpath} represents a circular pen nib (the default); +an elliptical pen can be achieved simply by multiplying the pen by a +transform: @code{yscale(2)*currentpen}. + +@anchor{overwrite} +@cindex @code{overwrite} +@item One can prevent labels from overwriting one another by using +the pen attribute @code{overwrite}, which takes a single argument: + +@table @code +@cindex @code{Allow} +@cindex @code{defaultpen} +@item Allow +Allow labels to overwrite one another. This is the default behaviour (unless +overridden with @code{defaultpen(pen)}. + +@cindex @code{Suppress} +@item Suppress +Suppress, with a warning, each label that would overwrite another label. + +@cindex @code{SuppressQuiet} +@item SuppressQuiet +Suppress, without warning, each label that would overwrite another label. + +@cindex @code{Move} +@item 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 @code{PostScript} +coordinates) it could result in a larger figure than requested. + +@cindex @code{MoveQuiet} +@item MoveQuiet +Move a label that would overwrite another out of the way, without warning. +As this adjustment is during the final output phase (in @code{PostScript} +coordinates) it could result in a larger figure than requested. + +@end table + +@end itemize + +@cindex @code{defaultpen} +@cindex @code{resetdefaultpen} +The routine @code{defaultpen()} returns the current default pen attributes. +Calling the routine @code{resetdefaultpen()} resets all pen default +attributes to their initial values. + +@node Transforms +@section Transforms + +@cindex @code{transform} +@code{Asymptote} makes extensive use of affine transforms. A pair +@code{(x,y)} is transformed by the transform +@code{t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)} to @code{(x',y')}, where +@verbatim +x' = t.x + t.xx * x + t.xy * y +y' = t.y + t.yx * x + t.yy * y +@end verbatim +@noindent +This is equivalent to the @code{PostScript} transformation +@code{[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 +@code{*}) on the left (@pxref{circle} for an example). +@cindex @code{inverse} +Transforms can be composed with one another and inverted with the +function @code{transform inverse(transform t)}; they can also be raised to any +integer power with the @code{^} operator. + +The built-in transforms are: + +@table @code +@item transform identity(); +@cindex @code{identity} +the identity transform; +@item transform shift(pair z); +@cindex @code{shift} +translates by the pair @code{z}; +@item transform shift(real x, real y); +@cindex @code{shift} +translates by the pair @code{(x,y)}; +@item transform xscale(real x); +@cindex @code{xscale} +scales by @code{x} in the @math{x} direction; +@item transform yscale(real y); +@cindex @code{yscale} +scales by @code{y} in the @math{y} direction; +@item transform scale(real s); +@cindex @code{scale} +scale by @code{s} in both @math{x} and @math{y} directions; +@item transform scale(real x, real y); +@cindex @code{scale} +scale by @code{x} in the @math{x} direction and by @code{y} in the +@math{y} direction; +@item transform slant(real s); +@cindex @code{slant} +maps @code{(x,y)} --> @code{(x+s*y,y)}; +@item transform rotate(real angle, pair z=(0,0)); +rotates by @code{angle} in degrees about @code{z}; +@item transform reflect(pair a, pair b); +@cindex @code{reflect} +reflects about the line @code{a--b}. +@end table + +@cindex @code{shift} +@cindex @code{shiftless} +The implicit initializer for transforms is @code{identity()}. +The routines @code{shift(transform t)} and @code{shiftless(transform t)} +return the transforms @code{(t.x,t.y,0,0,0,0)} and +@code{(0,0,t.xx,t.xy,t.yx,t.yy)} respectively. + + +@node Frames and pictures +@section Frames and pictures + +@table @code + +@item frame +@cindex @code{frame} +@cindex @code{newframe} +@cindex @code{empty} +@cindex @code{erase} +@cindex @code{min} +@cindex @code{max} +Frames are canvases for drawing in @code{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 @code{newframe}. The function +@code{bool empty(frame f)} returns @code{true} only if the frame @code{f} +is empty. A frame may be erased with the @code{erase(frame)} routine. +The functions @code{pair min(frame)} and @code{pair max(frame)} +return the (left,bottom) and (right,top) coordinates of the frame +bounding box, respectively. The contents of frame @code{src} may be +appended to frame @code{dest} with the command +@verbatim +void add(frame dest, frame src); +@end verbatim +or prepended with +@verbatim +void prepend(frame dest, frame src); +@end verbatim +A frame obtained by aligning frame @code{f} in the direction +@code{align}, in a manner analogous to the @code{align} argument of +@code{label} (@pxref{label}), is returned by +@verbatim +frame align(frame f, pair align); +@end verbatim + +@cindex @code{box} +@cindex @code{ellipse} +@anchor{envelope} +@cindex @code{envelope} +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 @code{envelope} routines +@verbatim +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); +@end verbatim + +@item picture +@cindex @code{picture} +Pictures are high-level structures (@pxref{Structures}) defined in +the module @code{plain} that provide canvases for drawing in user coordinates. +The default picture is called @code{currentpicture}. A new picture +can be created like this: +@verbatim +picture pic; +@end verbatim +@noindent +Anonymous pictures can be made by the expression @code{new picture}. + +The @code{size} routine specifies the dimensions of the desired picture: + +@anchor{size} +@cindex @code{size} +@verbatim +void size(picture pic=currentpicture, real x, real y=x, + bool keepAspect=Aspect); +@end verbatim + +If the @code{x} and @code{y} sizes are both 0, user coordinates will be +interpreted as @code{PostScript} coordinates. In this case, the transform +mapping @code{pic} to the final output frame is @code{identity()}. + +If exactly one of @code{x} or @code{y} is 0, no size restriction +is imposed in that direction; it will be scaled the same as the other +direction. + +@cindex @code{Aspect} +If @code{keepAspect} is set to @code{Aspect} or @code{true}, +the picture will be scaled with its aspect ratio preserved such that +the final width is no more than @code{x} and the final height is +no more than @code{y}. + +@cindex @code{IgnoreAspect} +If @code{keepAspect} is set to @code{IgnoreAspect} or @code{false}, +the picture will be scaled in both directions so that the final width +is @code{x} and the height is @code{y}. + +To make the user coordinates of picture @code{pic} +represent multiples of @code{x} units in the @math{x} direction and +@code{y} units in the @math{y} direction, use +@anchor{unitsize} +@cindex @code{unitsize} +@verbatim +void unitsize(picture pic=currentpicture, real x, real y=x); +@end verbatim +When nonzero, these @code{x} and @code{y} values override the +corresponding size parameters of picture @code{pic}. + +The routine +@cindex @code{size} +@verbatim +void size(picture pic=currentpicture, real xsize, real ysize, + pair min, pair max); +@end verbatim +forces the final picture scaling to map the user coordinates +@code{box(min,max)} to a region of width @code{xsize} and height @code{ysize} +(when these parameters are nonzero). + +Alternatively, calling the routine +@cindex @code{fixedscaling} +@verbatim +transform fixedscaling(picture pic=currentpicture, pair min, + pair max, pen p=nullpen, bool warn=false); +@end verbatim +will cause picture @code{pic} to use a fixed scaling to map user +coordinates in @code{box(min,max)} to the (already specified) picture size, +taking account of the width of pen @code{p}. A warning will be issued if +the final picture exceeds the specified size. + +A picture @code{pic} can be fit to a frame and output to a file +@code{prefix}.@code{format} using image format @code{format} +by calling the @code{shipout} function: +@anchor{shipout} +@cindex @code{shipout} +@verbatim +void shipout(string prefix=defaultfilename, picture pic, + orientation orientation=orientation, + string format="", bool wait=false, bool view=true); +void shipout(string prefix=defaultfilename, + orientation orientation=orientation, + string format="", bool wait=false, bool view=true); +@end verbatim +@noindent +The default output format, @code{PostScript}, may be changed +with the @code{-f} or @code{-tex} command-line options. +A @code{shipout()} command is added implicitly at file exit if no +previous @code{shipout} commands have been executed. +@cindex @code{orientation} +@cindex @code{Portrait} +@cindex @code{Landscape} +@cindex @code{UpsideDown} +The default page orientation is @code{Portrait}; this may be modified +by changing the variable @code{orientation}. To output in landscape +mode, simply set the variable @code{orientation=Landscape} or issue +the command +@verbatim +shipout(Landscape); +@end verbatim + +@cindex @code{Seascape} +To rotate the page by @math{-90} degrees, use the orientation @code{Seascape}. +@cindex @code{UpsideDown} +The orientation @code{UpsideDown} rotates the page by 180 degrees. + +@cindex subpictures +@cindex @code{fit} +A picture @code{pic} can be explicitly fit to a frame by calling +@verbatim +frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize, + bool keepAspect=pic.keepAspect); +@end verbatim +The default size and aspect ratio settings are those given to the +@code{size} command (which default to @code{0}, @code{0}, and +@code{true}, respectively). +@cindex @code{calculateTransform} +The transformation that would currently be used to fit a picture +@code{pic} to a frame is returned by the member function +@code{pic.calculateTransform()}. + +In certain cases (e.g.@ 2D graphs) where only an approximate size +estimate for @code{pic} is available, the picture fitting routine +@verbatim +frame pic.scale(real xsize=this.xsize, real ysize=this.ysize, + bool keepAspect=this.keepAspect); +@end verbatim +(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. + +@cindex @code{box} +To draw a bounding box with margins around a picture, fit the +picture to a frame using the function +@verbatim +frame bbox(picture pic=currentpicture, real xmargin=0, + real ymargin=xmargin, pen p=currentpen, + filltype filltype=NoFill); +@end verbatim +@anchor{filltype} +Here @code{filltype} specifies one of the following fill types: +@table @code +@cindex @code{FillDraw} +@item FillDraw +Fill the interior and draw the boundary. + +@item FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen, + @code{pen drawpen=nullpen);} +@cindex @code{nullpen} +If @code{fillpen} is @code{nullpen}, fill with the drawing pen; +otherwise fill with pen @code{fillpen}. +If @code{drawpen} is @code{nullpen}, draw the boundary with @code{fillpen}; +otherwise with @code{drawpen}. An optional margin of +@code{xmargin} and @code{ymargin} can be specified. + +@cindex @code{Fill} +@item Fill +Fill the interior. + +@cindex @code{nullpen} +@item Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen) +If @code{p} is @code{nullpen}, fill with the drawing pen; +otherwise fill with pen @code{p}. An optional margin of +@code{xmargin} and @code{ymargin} can be specified. + +@cindex @code{NoFill} +@item NoFill +Do not fill. + +@item Draw +Draw only the boundary. + +@cindex @code{Draw} +@item Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen) +If @code{p} is @code{nullpen}, draw the boundary with the drawing pen; +otherwise draw with pen @code{p}. An optional margin of +@code{xmargin} and @code{ymargin} can be specified. + +@cindex @code{UnFill} +@item UnFill +Clip the region. + +@cindex @code{UnFill} +@item UnFill(real xmargin=0, real ymargin=xmargin) +Clip the region and surrounding margins @code{xmargin} and @code{ymargin}. + +@cindex @code{RadialShade} +@item RadialShade(pen penc, pen penr) +Fill varying radially from @code{penc} at the center of the bounding +box to @code{penr} at the edge. + +@end table + +@cindex bounding box +@cindex background color +For example, to draw a bounding box around a picture with a 0.25 cm +margin and output the resulting frame, use the command: +@verbatim +shipout(bbox(0.25cm)); +@end verbatim +A @code{picture} may be fit to a frame with the background color of +pen @code{p} with the function @code{bbox(p,Fill)}. + +The functions +@verbatim +pair min(picture pic, user=false); +pair max(picture pic, user=false); +pair size(picture pic, user=false); +@end verbatim +calculate the @code{PostScript} bounds that picture @code{pic} would +have if it were currently fit to a frame using its default size specification. +If @code{user} is @code{false} the returned value is in +@code{PostScript} coordinates, otherwise it is in user coordinates. + +The function +@verbatim +pair point(picture pic=currentpicture, pair dir, bool user=true); +@end verbatim +is a convenient way of determining the point on the bounding box of +@code{pic} in the direction @code{dir} relative to its center, ignoring +the contributions from fixed-size objects (such as labels and arrowheads). +If @code{user} is @code{true} the returned value is in user coordinates, +otherwise it is in @code{PostScript} coordinates. + +The function +@verbatim +pair truepoint(picture pic=currentpicture, pair dir, bool user=true); +@end verbatim +is identical to @code{point}, except that it also accounts for +fixed-size objects, using the scaling transform that picture @code{pic} +would have if currently fit to a frame using its default size +specification. If @code{user} is @code{true} the returned value is in +user coordinates, otherwise it is in @code{PostScript} coordinates. + +@anchor{add} +Sometimes it is useful to draw objects on separate pictures and add one +picture to another using the @code{add} function: +@cindex @code{add} +@verbatim +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); +@end verbatim +@noindent +The first example adds @code{src} to @code{currentpicture}; the second +one adds @code{src} to @code{dest}. +The @code{group} option specifies whether or not the graphical user +interface @code{xasy} should treat all of the elements of @code{src} +as a single entity (@pxref{GUI}), @code{filltype} requests optional +background filling or clipping, and @code{above} specifies +whether to add @code{src} above or below existing objects. + +There are also routines to add a picture or frame @code{src} specified +in postscript coordinates to another picture @code{dest} (or +@code{currentpicture}) about the user coordinate +@code{position}: +@anchor{add about} +@cindex @code{add} +@cindex picture alignment +@verbatim +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); +@end verbatim + +The optional @code{align} argument in the last three forms specifies a +direction to use for aligning the frame, in a manner analogous to the +@code{align} argument of @code{label} (@pxref{label}). However, one key +difference is that when @code{align} is not specified, labels are +centered, whereas frames and pictures are aligned so that their origin is +at @code{position}. Illustrations of frame alignment can be found in +the examples @ref{errorbars} and @ref{image}. If you want to align three +or more subpictures, group them two at a time: + +@verbatiminclude subpictures.asy +@sp 1 +@center @image{subpictures} + +Alternatively, one can use @code{attach} to automatically increase the +size of picture @code{dest} to accommodate adding a frame @code{src} +about the user coordinate @code{position}: +@verbatim +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); +@end verbatim + +@cindex @code{erase} +To erase the contents of a picture (but not the size specification), use +the function +@verbatim +void erase(picture pic=currentpicture); +@end verbatim + +@cindex @code{save} +To save a snapshot of @code{currentpicture}, @code{currentpen}, and +@code{currentprojection}, use the function @code{save()}. + +@cindex @code{restore} +To restore a snapshot of @code{currentpicture}, @code{currentpen}, and +@code{currentprojection}, use the function @code{restore()}. + +Many further examples of picture and frame operations are provided in +the base module @code{plain}. + +@cindex verbatim +@cindex @code{postscript} +It is possible to insert verbatim @code{PostScript} commands in a picture with +one of the routines +@verbatim +void postscript(picture pic=currentpicture, string s); +void postscript(picture pic=currentpicture, string s, pair min, + pair max) +@end verbatim +Here @code{min} and @code{max} can be used to specify explicit bounds +associated with the resulting @code{PostScript} code. + +@anchor{tex} +@cindex @code{tex} +Verbatim @TeX{} commands can be inserted in the intermediate +@code{LaTeX} output file with one of the functions +@verbatim +void tex(picture pic=currentpicture, string s); +void tex(picture pic=currentpicture, string s, pair min, pair max) +@end verbatim +Here @code{min} and @code{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: +@cindex @code{texpreamble} +@verbatim +void texpreamble(string s); +@end verbatim + +The @TeX{} environment can be reset to its initial state, clearing all +macro definitions, with the function +@cindex @code{texreset} +@verbatim +void texreset(); +@end verbatim + +@cindex @code{usepackage} +The routine +@verbatim +void usepackage(string s, string options=""); +@end verbatim +provides a convenient abbreviation for +@verbatim +texpreamble("\usepackage["+options+"]{"+s+"}"); +@end verbatim +@noindent +that can be used for importing @code{LaTeX} packages. + +@end table + +@node Files +@section Files + +@cindex @code{file} +@code{Asymptote} can read and write text files (including comma-separated +value) files and portable @acronym{XDR} (External Data Representation) +binary files. + +An input file must first be opened with +@code{input(string name, bool check=true, string comment="#")}; +reading is then done by assignment: +@cindex open +@cindex @code{input} +@cindex reading +@verbatim +file fin=input("test.txt"); +real a=fin; +@end verbatim + +@cindex comment character +@cindex @code{error} +If the optional boolean argument @code{check} is @code{false}, no check will +be made that the file exists. If the file does not exist or is not +readable, the function @code{bool error(file)} will return @code{true}. +The first character of the string @code{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. + +@anchor{cd} +@cindex @code{cd} +@cindex directory +If the @code{-globalwrite} (or @code{-nosafe}) option is enabled, one can +change the current working directory to the contents of the string +@code{s} with the function @code{string cd(string s)}, which returns the +new working directory. If @code{string s} is empty, the path is reset to +the value it had at program startup. + +@cindex @code{getc} +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, @code{Asymptote} provides the function +@code{string getc(file)} to read the next character (treating the +comment character as an ordinary character) and return it as a string. + +@cindex @code{output} +@cindex @code{update} +@cindex append +A file named @code{name} can be open for output with +@verbatim +file output(string name, bool update=false); +@end verbatim +@noindent +If @code{update=false}, any existing data in the file will be erased +and only write operations can be used on the file. +If @code{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 @code{-globalwrite} +(or @code{-nosafe}) command-line option is specified. + +@cindex @code{stdin} +@cindex @code{stdout} +There are two special files: @code{stdin}, which reads from the keyboard, +and @code{stdout}, which writes to the terminal. The implicit +initializer for files is @code{null}. + +Data of a built-in type @code{T} can be written to an output file by +calling one of the functions +@cindex @code{write} +@verbatim +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); +@end verbatim +@cindex @code{none} +@cindex @code{flush} +@cindex @code{endl} +@cindex @code{newl} +@cindex @code{tab} +@cindex @code{comma} +If @code{file} is not specified, @code{stdout} is used and +terminated by default with a newline. If specified, the optional +identifying string @code{s} is written before the data @code{x}. +An arbitrary number of data values may be listed when writing scalars +or one-dimensional arrays. The @code{suffix} may be one of the following: +@code{none} (do nothing), @code{flush} (output buffered data), +@code{endl} (terminate with a newline and flush), +@code{newl} (terminate with a newline), +@code{tab} (terminate with a tab), or @code{comma} (terminate with a +comma). Here are some simple examples of data output: +@verbatim +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" +@end verbatim +@noindent + +@cindex binary format +@cindex @code{xinput} +@cindex @code{xoutput} +@cindex @code{binput} +@cindex @code{boutput} +@cindex @code{single} +@cindex @code{double} +A file may also be opened with @code{xinput} or @code{xoutput}, instead of +@code{input} or @code{output}, to read or write +double precision (64-bit) real values and single precision (32-bit) +integer values in Sun Microsystem's @acronym{XDR} (External +Data Representation) portable binary format (available on all +@code{UNIX} platforms). +A file may also be opened with @code{binput} or @code{boutput} to read +or write double precision values in the native (nonportable) +machine binary format. The function @code{file single(file,0.0)} may +be used to set a file to read single precision real @acronym{XDR} or binary +values; calling @code{file single(file,0.0,false)} sets it back to read +doubles again. The functions @code{file single(file,0)} and +@code{file single(file,0,false)} can be used to change the default +integer precision (single). The functions @code{file +single(file)} and @code{file single(file,false)} may be used to set the +precision for both real and integer values. + +@cindex @code{eof} +@cindex @code{eol} +@cindex @code{error} +@cindex @code{flush} +@cindex @code{clear} +@cindex @code{precision} +@cindex @code{seek} +@cindex @code{tell} +@cindex rewind +@cindex @code{seekeof} +One can test a file for end-of-file with the boolean function @code{eof(file)}, +end-of-line with @code{eol(file)}, and for I/O errors with @code{error(file)}. +One can flush the output buffers with @code{flush(file)}, clear a +previous I/O error with @code{clear(file)}, and close the file with +@code{close(file)}. The function +@code{int precision(file file=stdout, int digits=0)} +sets the number of digits of output precision for @code{file} to @code{digits}, +provided @code{digits} is nonzero, and returns the previous +precision setting. The function @code{int tell(file)} returns +the current position in a file relative to the beginning. +The routine @code{seek(file file, int pos)} can be used to +change this position, where a negative value for the position @code{pos} +is interpreted as relative to the end-of-file. For example, one can +rewind a file @code{file} with the command @code{seek(file,0)} +and position to the final character in the file with @code{seek(file,-1)}. +The command @code{seekeof(file)} sets the position to the end of the file. + +@cindex @code{scroll} +@anchor{scroll} +Assigning @code{settings.scroll=n} for a positive integer @code{n} +requests a pause after every @code{n} output lines to @code{stdout}. +One may then press @code{Enter} to continue to the next @code{n} output lines, +@code{s} followed by @code{Enter} to scroll without further interruption, +or @code{q} followed by @code{Enter} to quit the current output +operation. If @code{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, @code{settings.scroll=0}, specifies continuous scrolling. + +The routines +@cindex @code{getstring} +@cindex @code{getreal} +@cindex @code{getpair} +@cindex @code{gettriple} +@verbatim +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); +@end verbatim +@noindent +defined in the module @code{plain} may be used to prompt for a value from +@code{stdin} using the @acronym{GNU} @code{readline} library. +If @code{store=true}, the history of values for @code{name} is +stored in the file @code{".asy_history_"+name} (@pxref{history}). The most +recent value in the history will be used to provide a default value +for subsequent runs. The default value (initially @code{default}) is +displayed after @code{prompt}. These functions are based on the internal +routines +@cindex @code{readline} +@cindex @code{saveline} +@verbatim +string readline(string prompt="", string name="", bool tabcompletion=false); +void saveline(string name, string value, bool store=true); +@end verbatim +Here, @code{readline} prompts the user with the default value +formatted according to @code{prompt}, while @code{saveline} +is used to save the string @code{value} in a local history named +@code{name}, optionally storing the local history in a file +@code{".asy_history_"+name}. + +@cindex @code{history} +The routine @code{history(string name, int n=1)} can be used to look up +the @code{n} most recent values (or all values up to @code{historylines} +if @code{n=0}) entered for string @code{name}. +The routine @code{history(int n=0)} returns the interactive history. +For example, +@verbatim +write(output("transcript.asy"),history()); +@end verbatim +@noindent +outputs the interactive history to the file @code{transcript.asy}. + +@cindex @code{delete} +The function @code{int delete(string s)} deletes the file named by the +string @code{s}. Unless the @code{-globalwrite} (or @code{-nosafe}) +option is enabled, the file must reside in the current directory. +@cindex @code{rename} +The function @code{int rename(string from, string to)} may be used to +rename file @code{from} to file @code{to}. +Unless the @code{-globalwrite} (or @code{-nosafe}) option is enabled, +this operation is restricted to the current directory. +@cindex @code{convert} +@cindex @code{animate} +The functions +@verbatim +int convert(string args="", string file="", string format=""); +int animate(string args="", string file="", string format=""); +@end verbatim +@noindent +call the @code{ImageMagick} commands @code{convert} and @code{animate}, +respectively, with the arguments @code{args} and the file name constructed +from the strings @code{file} and @code{format}. +@cindex @code{system} +If the setting @code{safe} is false, then the function +@code{int system(string s)} can be used to call the arbitrary system +command @code{s}. + +@node Variable initializers +@section Variable initializers +@cindex variable initializers +@cindex @code{operator init} +@cindex initializers + +A variable can be assigned a value when it is declared, as in +@code{int x=3;} where the variable @code{x} is assigned the value @code{3}. +As well as literal constants such as @code{3}, arbitary expressions can be used +as initializers, as in @code{real x=2*sin(pi/2);}. + +A variable is not added to the namespace until after the initializer is +evaluated, so for example, in + +@verbatim +int x=2; +int x=5*x; +@end verbatim +@noindent +the @code{x} in the initializer on the second line refers to the variable +@code{x} declared on the first line. The second line, then, declares a variable +@code{x} shadowing the original @code{x} and initializes it to the value +@code{10}. + +Variables of most types can be declared without an explicit initializer and they +will be initialized by the default initializer of that type: + +@itemize +@item Variables of the numeric types @code{int}, @code{real}, and @code{pair} +are all initialized to zero; variables of type @code{triple} are +initialized to @code{O=(0,0,0)}. +@item @code{boolean} variables are initialized to @code{false}. +@item @code{string} variables are initialized to the empty string. +@item @code{transform} variables are initialized to the identity transformation. +@item @code{path} and @code{guide} variables are initialized to +@code{nullpath}. +@item @code{pen} variables are initialized to the default pen. +@item @code{frame} and @code{picture} variables are initialized to empty +frames and pictures, respectively. +@item @code{file} variables are initialized to @code{null}. +@end itemize + +The default initializers for user-defined array, structure, and function types +are explained in their respective sections. Some types, such as +@code{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 @code{T} can be redeclared by defining the +function @code{T operator init()}. For instance, @code{int} variables are +usually initialized to zero, but in + +@verbatim +int operator init() { + return 3; +} +int y; +@end verbatim + +@noindent +the variable @code{y} is initialized to @code{3}. This example was given for +illustrative purposes; redeclaring the initializers of built-in types is not +recommended. Typically, @code{operator init} is used to define sensible +defaults for user-defined types. + +@node Structures +@section Structures +@cindex @code{struct} +@cindex structures +@cindex @code{public} +@cindex @code{restricted} +@cindex @code{private} +@cindex @code{this} +@cindex @code{new} +@cindex @code{null} + +Users may also define their own data types as structures, along with +user-defined operators, much as in C++. By default, structure members +are @code{public} (may be read and modified anywhere in the code), but may be +optionally declared @code{restricted} (readable anywhere but writeable +only inside the structure where they are defined) or @code{private} +(readable and writable only inside the structure). In a structure definition, +the keyword @code{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: + +@verbatim +struct T { + int x; +} + +T foo=new T; +T bar=foo; +bar.x=5; +@end verbatim + +The variable @code{foo} holds a reference to an instance of the structure +@code{T}. When @code{bar} is assigned the value of @code{foo}, it too +now holds a reference to the same instance as @code{foo} does. The assignment +@code{bar.x=5} changes the value of the field @code{x} in that instance, so +that @code{foo.x} will also be equal to @code{5}. + +The expression @code{new T} creates a new instance of the structure @code{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: + +@verbatim +int Tcount=0; +struct T { + int x; + ++Tcount; +} + +T foo=new T; +@end verbatim + +Here, the expression @code{new T} will produce a new instance of the class, but +will also cause @code{Tcount} to be incremented, so that it keeps track of the +number of instances produced. + +The expression @code{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. + +@cindex alias +@cindex @code{==} +@cindex @code{!=} +The function @code{bool alias(T,T)} checks to see if two structure references +refer to the same instance of the structure (or both to @code{null}). For +example, in the example code at the start of the section, @code{alias(foo,bar)} +would return true, but @code{alias(foo,new T)} would return false, as @code{new +T} creates a new instance of the structure @code{T}. The boolean operators +@code{==} and @code{!=} are by default equivalent to @code{alias} and +@code{!alias} respectively, but may be overwritten for a particular type +(for example, to do a deep comparison). + +After the definition of a structure @code{T}, a variable of type @code{T} is +initialized to a new instance (@code{new T}) by default. During the definition +of the structure, however, variables of type @code{T} are initialized to +@code{null} by default. This special behaviour is to avoid infinite +recursion of creating new instances in code such as + +@verbatim +struct tree { + int value; + tree left; + tree right; +} +@end verbatim + +Here is a simple example that illustrates the use of structures: + +@verbatim +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 + +@end verbatim + +@cindex constructors +It is often convenient to have functions that construct new instances of a +structure. Say we have a @code{Person} structure: + +@verbatim +struct Person { + string firstname; + string lastname; +} + +Person joe=new Person; +joe.firstname="Joe"; +joe.lastname="Jones"; +@end verbatim +@noindent +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 +@code{Person(string,string)}: + +@verbatim +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"); +@end verbatim + +While it is now easier than before to create a new instance, we still +have to refer to the constructor by the qualified name +@code{Person.Person}. If we add the line + +@verbatim +from Person unravel Person; +@end verbatim +@noindent +immediately after the structure definition, then the constructor can be used +without qualification: @code{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. + +@cindex @code{operator init} +If, in the body of a structure, Asymptote encounters the definition of +a function of the form @code{void operator init(@var{args})}, it implicitly +defines a constructor function of the arguments @code{@var{args}} that +uses the @code{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 @code{Foo}): + +@example +static Foo Foo(@var{args}) @{ + Foo instance=new Foo; + instance.operator init(@var{args}); + return instance; +@} +@end example + +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 @code{Person} example can thus be implemented as: + +@verbatim +struct Person { + string firstname; + string lastname; + + void operator init(string firstname, string lastname) { + this.firstname=firstname; + this.lastname=lastname; + } +} + +Person joe=Person("Joe", "Jones"); +@end verbatim + +The use of @code{operator init} to implicitly define constructors should not be +confused with its use to define default values for variables +(@pxref{Variable initializers}). Indeed, in the +first case, the return type of the @code{operator init} must be @code{void} +while in the second, it must be the (non-@code{void}) type of the variable. + +@cindex @code{cputime} +The function @code{cputime()} +returns a structure @code{cputime} with cumulative @acronym{CPU} times +broken down into the fields @code{parent.user}, @code{parent.system}, +@code{child.user}, and @code{child.system}. For convenience, the +incremental fields @code{change.user} and @code{change.system} indicate +the change in the corresponding total parent and child @acronym{CPU} +times since the last call to @code{cputime()}. The function +@verbatim +void write(file file=stdout, string s="", cputime c, + string format=cputimeformat, suffix suffix=none); +@end verbatim +@noindent +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''. + +@cindex inheritance +@cindex virtual functions +Much like in C++, casting (@pxref{Casts}) provides for an elegant +implementation of structure inheritance, including virtual functions: +@verbatim +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; +@end verbatim + +For further examples of structures, see @code{Legend} and @code{picture} in +the @code{Asymptote} base module @code{plain}. + +@node Operators +@section Operators +@cindex operators + +@menu +* Arithmetic & logical:: Basic mathematical operators +* Self & prefix operators:: Increment and decrement +* User-defined operators:: Overloading operators +@end menu + +@node Arithmetic & logical +@subsection Arithmetic & logical operators +@cindex arithmetic operators +@cindex binary operators +@cindex boolean operators +@cindex logical operators +@cindex integer division +@cindex @code{quotient} + +@code{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 +@code{int quotient(int x, int y)} returns the greatest integer less +than or equal to @code{x/y}. In all other cases both operands are +promoted to the same type, which will also be the type of the result: +@table @code +@cindex @code{+} +@item + +addition +@cindex @code{-} +@item - +subtraction +@cindex @code{*} +@item * +multiplication +@cindex @code{/} +@item / +division +@cindex @code{%} +@item % +modulo; the result always has the same sign as the divisor. +In particular, this makes @code{q*quotient(p,q)+p%q == p} for all +integers @code{p} and nonzero integers @code{q}. +@cindex @code{^} +@item ^ +@cindex @code{**} +power; if the exponent (second argument) is an int, recursive +multiplication is used; otherwise, logarithms and exponentials are used +(@code{**} is a synonym for @code{^}). + +@end table + +The usual boolean operators are also defined: +@table @code +@cindex @code{==} +@item == +equals +@cindex @code{!=} +@item != +not equals +@cindex @code{<} +@item < +less than +@cindex @code{<=} +@item <= +less than or equals +@cindex @code{>=} +@item >= +greater than or equals +@cindex @code{>} +@item > +greater than +@cindex @code{&&} +@item && +and (with conditional evaluation of right-hand argument) +@cindex @code{&} +@item & +and +@cindex @code{||} +@item || +or (with conditional evaluation of right-hand argument) +@cindex @code{|} +@item | +or +@cindex @code{^} +@item ^ +xor +@cindex @code{!} +@item ! +not +@end table + +@code{Asymptote} also supports the C-like conditional syntax: +@cindex @code{:} +@cindex @code{?} +@cindex conditional +@verbatim +bool positive=(pi >= 0) ? true : false; +@end verbatim + +@cindex @code{interp} +The function @code{T interp(T a, T b, real t)} returns @code{(1-t)*a+t*b} +for nonintegral built-in arithmetic types @code{T}. If @code{a} and +@code{b} are pens, they are first promoted to the same color space. + +@cindex @code{AND} +@cindex @code{OR} +@cindex @code{XOR} +@cindex @code{NOT} +@code{Asymptote} also defines bitwise functions @code{int AND(int,int)}, +@code{int OR(int,int)}, @code{int XOR(int,int)}, and @code{int NOT(int)}. + +@node Self & prefix operators +@subsection Self & prefix operators +@cindex self operators +@cindex prefix operators +@cindex @code{+=} +@cindex @code{-=} +@cindex @code{*=} +@cindex @code{/=} +@cindex @code{%=} +@cindex @code{^=} +@cindex @code{++} +@cindex @code{--} + +As in C, each of the arithmetic operators @code{+}, @code{-}, @code{*}, +@code{/}, @code{%}, and @code{^} can be used as a self operator. +The prefix operators @code{++} (increment by one) and @code{--} (decrement +by one) are also defined. +For example, +@verbatim +int i=1; +i += 2; +int j=++i; +@end verbatim + +@noindent +is equivalent to the code +@verbatim +int i=1; +i=i+2; +int j=i=i+1; +@end verbatim + +@cindex postfix operators +However, postfix operators like @code{i++} and @code{i--} are not defined +(because of the inherent ambiguities that would arise with the @code{--} +path-joining operator). In the rare instances where @code{i++} +and @code{i--} are really needed, one can substitute the expressions +@code{(++i-1)} and @code{(--i+1)}, respectively. + +@node User-defined operators +@subsection User-defined operators +@cindex user-defined operators +@cindex @code{operator} +The following symbols may be used with @code{operator} to define or redefine +operators on structures and built-in types: +@verbatim +- + * / % ^ ! < > == != <= >= & | ^^ .. :: -- --- ++ +<< >> $ $$ @ @@ +@end verbatim +@noindent +The operators on the second line have precedence one higher than the +boolean operators @code{<}, @code{>}, @code{<=}, and @code{>=}. + +Guide operators like @code{..} may be overloaded, say, to write +a user function that produces a new guide from a given guide: +@verbatim +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); +@end verbatim + +@node Implicit scaling +@section Implicit scaling +@cindex implicit scaling + +If a numeric literal is in front of certain types of expressions, then the two +are multiplied: +@verbatim +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); +@end verbatim + +This produces the output +@verbatim +6 +5 +6 +-3.204e-19 +(1,1) +8 +10 +18 +2.72789228047704 +2.48046543129542 +283.464008929116 +@end verbatim + +@node Functions +@section Functions +@cindex functions + +@code{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 (@pxref{Structures}). + +Here are some significant features of @code{Asymptote} functions: + +@enumerate +@item Variables with signatures (functions) and without signatures +(nonfunction variables) are distinct: +@verbatim +int x, x(); +x=5; +x=new int() {return 17;}; +x=x(); // calls x() and puts the result, 17, in the scalar x +@end verbatim + +@item Traditional function definitions are allowed: +@verbatim +int sqr(int x) +{ + return x*x; +} +sqr=null; // but the function is still just a variable. +@end verbatim + +@item Casting can be used to resolve ambiguities: +@verbatim +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. +@end verbatim + +@item Anonymous (so-called "high-order") functions are also allowed: +@cindex @code{typedef} +@verbatim +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. +@end verbatim + +@item +@cindex overloading functions +One may redefine a function @code{f}, even for calls to @code{f} in previously +declared functions, by assigning another (anonymous or named) +function to it. However, if @code{f} is overloaded by a +new function definition, previous calls will still access the original +version of @code{f}, as illustrated in this example: +@verbatim +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" +@end verbatim + +@cindex function declarations +@item 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: +@verbatim +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. +@end verbatim + +@end enumerate + +@code{Asymptote} is the only language we know of that treats functions +as variables, but allows overloading by distinguishing variables +based on their signatures. + +@cindex @code{libsigsegv} +@anchor{stack overflow} +@cindex recursion +@cindex stack overflow +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 @acronym{GNU} +library @code{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 + +@end menu + +@node Default arguments +@subsection Default arguments +@cindex default arguments +@cindex arguments + +@code{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 (@pxref{Casts}) one can often avoid ambiguities by ordering +function arguments from the simplest to the most complicated. +For example, given +@verbatim +real f(int a=1, real b=0) {return a+b;} +@end verbatim +@noindent +then @code{f(1)} returns 1.0, but @code{f(1.0)} returns 2.0. + +The value of a default argument is determined by evaluating the +given @code{Asymptote} expression in the scope where the called +function is defined. + +@node Named arguments +@subsection Named arguments +@cindex keywords +@cindex 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, +@emph{not within the local scope}. The command-line option @code{-d} +may be used to check @code{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, +@verbatim +int f(int x, int y) { + return 10x+y; +} +write(f(4,x=3)); +@end verbatim +@noindent +outputs 34, as @code{x} is already matched when we try to match the +unnamed argument @code{4}, so it gets matched to the next item, @code{y}. + +For the rare occasions where it is desirable to assign a value to +local variable within a function argument (generally @emph{not} a good +programming practice), simply enclose the assignment in +parentheses. For example, given the definition of @code{f} in the +previous example, +@verbatim +int x; +write(f(4,(x=3))); +@end verbatim +@noindent +is equivalent to the statements +@verbatim +int x; +x=3; +write(f(4,3)); +@end verbatim +@noindent +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 +@verbatim +int f(int x, int x()) { + return x+x(); +} +int seven() {return 7;} +@end verbatim +@noindent +is legal in @code{Asymptote}, with @code{f(2,seven)} returning 9. +A named argument matches the first unmatched formal of the same name, so +@code{f(x=2,x=seven)} is an equivalent call, but @code{f(x=seven,2)} +is not, as the first argument is matched to the first formal, and +@code{int ()} cannot be implicitly cast to @code{int}. Default +arguments do not affect which formal a named argument is matched to, +so if @code{f} were defined as +@verbatim +int f(int x=3, int x()) { + return x+x(); +} +@end verbatim +@noindent +then @code{f(x=seven)} would be illegal, even though @code{f(seven)} +obviously would be allowed. + +@node Rest arguments +@subsection Rest arguments +@cindex rest arguments + +Rest arguments allow one to write functions that take a variable +number of arguments: +@verbatim +// 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 +@end verbatim + +@cindex packing +Putting an argument into a rest array is called @emph{packing}. +One can give an explicit list of arguments for the rest +argument, so @code{subtract} could alternatively be implemented as +@verbatim +int subtract(int start ... int[] subs) { + return start - sum(... subs); +} +@end verbatim + +One can even combine normal arguments with rest arguments: +@verbatim +sum(1,2,3 ... new int[] {4,5,6}); // returns 21 +@end verbatim +@noindent +@cindex unpacking +This builds a new six-element array that is passed to @code{sum} as +@code{nums}. The opposite operation, @emph{unpacking}, is not allowed: +@verbatim +subtract(... new int[] {10, 1, 2}); +@end verbatim +@noindent +is illegal, as the start formal is not matched. + +If no arguments are packed, then a zero-length array (as opposed to +@code{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 @code{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. + +@verbatim +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 +@end verbatim + +@node Mathematical functions +@subsection Mathematical functions +@cindex mathematical functions +@cindex functions +@cindex @code{libm} routines + +@cindex @code{sin} +@cindex @code{cos} +@cindex @code{tan} +@cindex @code{asin} +@cindex @code{acos} +@cindex @code{atan} +@cindex @code{exp} +@cindex @code{log} +@cindex @code{pow10} +@cindex @code{log10} +@cindex @code{sinh} +@cindex @code{cosh} +@cindex @code{tanh} +@cindex @code{asinh} +@cindex @code{acosh} +@cindex @code{atanh} +@cindex @code{sqrt} +@cindex @code{cbrt} +@cindex @code{fabs} +@cindex @code{expm1} +@cindex @code{log1p} +@cindex @code{identity} +@cindex @code{J} +@cindex @code{Y} +@cindex @code{gamma} +@cindex @code{erf} +@cindex @code{erfc} +@cindex @code{atan2} +@cindex @code{hypot} +@cindex @code{fmod} +@cindex @code{remainder} +@code{Asymptote} has built-in versions of the standard @code{libm} mathematical +real(real) functions @code{sin}, @code{cos}, @code{tan}, @code{asin}, +@code{acos}, @code{atan}, @code{exp}, @code{log}, @code{pow10}, +@code{log10}, @code{sinh}, @code{cosh}, @code{tanh}, @code{asinh}, +@code{acosh}, @code{atanh}, @code{sqrt}, @code{cbrt}, @code{fabs}, @code{expm1}, +@code{log1p}, as well as the identity function @code{identity}. +@code{Asymptote} also defines the order @code{n} Bessel functions of +the first kind @code{J(int n, real)} and second kind +@code{Y(int n, real)}, as well as the gamma function @code{gamma}, +the error function @code{erf}, and the complementary error function +@code{erfc}. The standard real(real, real) functions @code{atan2}, +@code{hypot}, @code{fmod}, @code{remainder} are also included. + +@cindex @code{degrees} +@cindex @code{radians} +@cindex @code{Degrees} +The functions @code{degrees(real radians)} and @code{radians(real degrees)} +can be used to convert between radians and degrees. The function +@code{Degrees(real radians)} returns the angle in degrees in the +interval [0,360). +@cindex @code{Sin} +@cindex @code{Cos} +@cindex @code{Tan} +@cindex @code{aSin} +@cindex @code{aCos} +@cindex @code{aTan} +For convenience, @code{Asymptote} defines variants @code{Sin}, +@code{Cos}, @code{Tan}, @code{aSin}, @code{aCos}, and @code{aTan} of +the standard trigonometric functions that use degrees rather than radians. +We also define complex versions of the @code{sqrt}, @code{sin}, @code{cos}, +@code{exp}, @code{log}, and @code{gamma} functions. + +@cindex @code{floor} +@cindex @code{ceil} +@cindex @code{round} +@cindex @code{sgn} +The functions @code{floor}, @code{ceil}, and @code{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 @code{Floor}, @code{Ceil}, and @code{Round} are +respectively similar, except that if the result cannot be converted +to a valid int, they return @code{intMax} +for positive arguments and @code{intMin} for negative arguments, +rather than generating an integer overflow. +We also define a function @code{sgn}, which returns the sign of its +real argument as an integer (-1, 0, or 1). + +@cindex @code{abs} +There is an @code{abs(int)} function, as well as an @code{abs(real)} +function (equivalent to @code{fabs(real)}), an @code{abs(pair)} function +(equivalent to @code{length(pair)}). + +@cindex @code{srand} +@cindex @code{rand} +@cindex @code{randMax} +@cindex @code{unitrand} +@cindex @code{Gaussrand} +@cindex @code{histogram} +@cindex @code{factorial} +@cindex @code{choose} +Random numbers can be seeded with @code{srand(int)} and generated with +the @code{int rand()} function, which returns a random integer between 0 +and the integer @code{randMax}. The @code{unitrand()} function returns +a random number uniformly distributed in the interval [0,1]. +A Gaussian random number generator +@code{Gaussrand} and a collection of statistics routines, including +@code{histogram}, are provided in the base file @code{stats.asy}. +The functions @code{factorial(int n)}, which returns @math{n!}, and +@code{choose(int n, int k)}, which returns @math{n!/(k!(n-k)!)}, are +also defined. + +@cindex @acronym{GNU} Scientific Library +@cindex @code{gsl} +@cindex Airy +@cindex Bessel +@cindex Legendre +@cindex elliptic functions +@cindex exponential integral +@cindex trigonometric integrals +@cindex Riemann zeta function +@cindex @code{Ai} +@cindex @code{Bi} +@cindex @code{Ai_deriv} +@cindex @code{Bi_deriv} +@cindex @code{zero_Ai} +@cindex @code{zero_Bi} +@cindex @code{zero_Ai_deriv} +@cindex @code{zero_Bi_deriv} +@cindex @code{J} +@cindex @code{Y} +@cindex @code{I} +@cindex @code{K} +@cindex @code{i_scaled} +@cindex @code{k_scaled} +@cindex @code{zero_J} +@cindex @code{F} +@cindex @code{E} +@cindex @code{P} +@cindex @code{Ei} +@cindex @code{Si} +@cindex @code{Ci} +@cindex @code{Pl} +@cindex @code{zeta} +When configured with the @acronym{GNU} Scientific Library (GSL), available from +@url{http://www.gnu.org/software/gsl/}, +@code{Asymptote} contains an internal module @code{gsl} that +defines the airy functions @code{Ai(real)}, +@code{Bi(real)}, @code{Ai_deriv(real)}, @code{Bi_deriv(real)}, +@code{zero_Ai(int)}, @code{zero_Bi(int)}, +@code{zero_Ai_deriv(int)}, @code{zero_Bi_deriv(int)}, the Bessel functions +@code{I(int, real)}, @code{K(int, real)}, @code{j(int, real)}, +@code{y(int, real)}, @code{i_scaled(int, real)}, @code{k_scaled(int, real)}, +@code{J(real, real)}, @code{Y(real, real)}, @code{I(real, real)}, +@code{K(real, real)}, @code{zero_J(real, int)}, the elliptic functions +@code{F(real, real)}, @code{E(real, real)}, and @code{P(real, real)}, +the exponential/trigonometric integrals @code{Ei}, @code{Si}, and @code{Ci}, +the Legendre polynomials @code{Pl(int, real)}, and the Riemann zeta +function @code{zeta(real)}. For example, to compute the sine integral +@code{Si} of 1.0: +@verbatim +import gsl; +write(Si(1.0)); +@end verbatim + +@code{Asymptote} also provides a few general purpose numerical routines: + +@table @code + +@cindex @code{newton} +@item @code{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 @code{f}, given its derivative @code{fprime} and +an initial guess @code{x}. Diagnostics for +each iteration are printed if @code{verbose=true}. +If the iteration fails after the maximum allowed number of loops +(@code{iterations}), @code{realMax} is returned. + +@cindex @code{newton} +@item @code{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 @code{f} within an interval +[@code{x1},@code{x2}] (on which the endpoint values of @code{f} have +opposite signs), given its derivative @code{fprime}. Diagnostics for +each iteration are printed if @code{verbose=true}. +If the iteration fails after the maximum allowed number of loops +(@code{iterations}), @code{realMax} is returned. + +@cindex @code{simpson} +@item @code{real simpson(real f(real), real a, real b, real acc=realEpsilon, real dxmax=b-a)} +returns the integral of @code{f} from @code{a} to @code{b} using adaptive Simpson integration. + +@end table + +@node Arrays +@section Arrays +@cindex arrays + +@menu +* Slices:: Python-style array slices +@end menu + +Appending @code{[]} to a built-in or user-defined type yields an array. +The array element @code{i} of an array @code{A} can be accessed as @code{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 @code{A} with an integer array @code{B}: +the array @code{A[B]} is formed by indexing array @code{A} with +successive elements of array @code{B}. +A convenient Java-style shorthand exists for iterating over all elements of an +array; see @ref{array iteration}. + +The declaration +@verbatim +real[] A; +@end verbatim + +@noindent +initializes @code{A} to be an empty (zero-length) array. Empty arrays should be +distinguished from null arrays. If we say +@verbatim +real[] A=null; +@end verbatim + +@noindent +then @code{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: +@verbatim +real[] A={0,1,2}; +@end verbatim + +Array assignment in @code{Asymptote} does a shallow copy: only +the pointer is copied (if one copy if modified, the other will be too). +The @code{copy} function listed below provides a deep copy of an array. + +@cindex @code{length} +@cindex @code{cyclic} +@cindex @code{cyclicflag} +@cindex @code{keys} +@cindex @code{push} +@cindex @code{append} +@cindex @code{pop} +@cindex @code{insert} +@cindex @code{delete} +@cindex @code{initialized} +Every array @code{A} of type @code{T[]} has the virtual members +@itemize +@item @code{int length}, +@item @code{void cyclic(bool b)}, +@item @code{bool cyclicflag}, +@item @code{int[] keys}, +@item @code{T push(T x)}, +@item @code{void append(T[] a)}, +@item @code{T pop()}, +@item @code{void insert(int i ... T[] x)}, +@item @code{void delete(int i, int j=i)}, +@item @code{void delete()}, and +@item @code{bool initialized(int n)}. +@end itemize + +The member @code{A.length} evaluates to the length of the array. +Setting @code{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 +@code{A.cyclicflag} returns the current setting of the @code{cyclic} flag. + +The member @code{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 @code{n} with all entries initialized, @code{A.keys} evaluates +to the array of integers from @code{0} to @code{n-1} inclusive. A new keys +array is produced each time @code{A.keys} is evaluated. + +The functions @code{A.push} and @code{A.append} append their +arguments onto the end of the array, while @code{A.insert(int i ... T[] x)} +inserts @code{x} into the array at index @code{i}. +For convenience @code{A.push} returns the pushed item. +The function @code{A.pop()} pops and returns the last element, +while @code{A.delete(int i, int j=i)} deletes elements with indices in +the range [@code{i},@code{j}], shifting the position of all higher-indexed +elements down. If no arguments are given, @code{A.delete()} provides a +convenient way of deleting all elements of @code{A}. The routine +@code{A.initialized(int n)} can be used to examine whether the element +at index @code{n} is initialized. Like all @code{Asymptote} functions, +@code{cyclic}, @code{push}, @code{append}, @code{pop}, @code{insert}, +@code{delete}, and @code{initialized} can be "pulled off" of the array +and used on their own. For example, +@verbatim +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}. +@end verbatim + +The @code{[]} suffix can also appear after the variable name; this +is sometimes convenient for declaring a list of variables and arrays +of the same type: +@verbatim +real a,A[]; +@end verbatim +@noindent +This declares @code{a} to be @code{real} and implicitly declares @code{A} to +be of type @code{real[]}. + +In the following list of built-in array functions, @code{T} represents a +generic type. Note that the internal functions @code{alias}, @code{array}, +@code{copy}, @code{concat}, @code{sequence}, @code{map}, and +@code{transpose}, which depend on type @code{T[]}, are defined only after the +first declaration of a variable of type @code{T[]}. + +@table @code + +@cindex @code{new} +@item new T[] +returns a new empty array of type @code{T[]}; + +@cindex @code{new} +@item new T[] @{list@} +returns a new array of type @code{T[]} initialized with @code{list} (a comma +delimited list of elements). + +@item new T[n] +returns a new array of @code{n} elements of type @code{T[]}. +These @code{n} array elements are not initialized unless they are arrays +themselves (in which case they are each initialized to empty arrays). + +@cindex @code{array} +@item T[] array(int n, T value, int depth=intMax) +returns an array consisting of @code{n} copies of value. By default, if +@code{value} is itself an array, a deep copy of that array is made for +each entry in the new array. If @code{depth} is specified, this deep copying +only recurses to the number of levels specified. + +@cindex @code{sequence} +@item int[] sequence(int n) +if @code{n >= 1} returns the array @code{@{0,1,...,n-1@}} (otherwise returns +a null array); + +@item int[] sequence(int n, int m) +if @code{m >= n} returns an array @code{@{n,n+1,...,m@}} (otherwise +returns a null array); + +@item T[] sequence(T f(int), int n) +if @code{n >= 1} returns the sequence @code{@{f_i :i=0,1,...n-1@}} given a +function @code{T f(int)} and integer @code{int n} (otherwise returns a +null array); + +@cindex @code{map} +@item T[] map(T f(T), T[] a) +returns the array obtained by applying the function @code{f} to each +element of the array @code{a}. This is equivalent to +@code{sequence(new T(int i) @{return f(a[i]);@},a.length)}. + +@cindex @code{reverse} +@item int[] reverse(int n) +if @code{n >= 1} returns the array @code{@{n-1,n-2,...,0@}} (otherwise +returns a null array); + +@cindex @code{complement} +@item int[] complement(int[] a, int n) +returns the complement of the integer array @code{a} in +@code{@{0,1,2,...,n-1@}}, so that @code{b[complement(a,b.length)]} yields the +complement of @code{b[a]}. + +@cindex @code{uniform} +@item real[] uniform(real a, real b, int n) +if @code{n >= 1} returns a uniform partition of @code{[a,b]} into +@code{n} subintervals (otherwise returns a null array); + +@cindex @code{find} +@item int find(bool[], int n=1) +returns the index of the @code{n}th @code{true} value or -1 if not found. +If @code{n} is negative, search backwards from the end of the array for the +@code{-n}th value; + +@cindex @code{search} +@item int search(T[] a, T key) +For built-in ordered types @code{T}, searches a sorted ordered array +@code{a} of @code{n} elements to find an interval containing +@code{key}, returning @code{-1} if @code{key} is less than the first +element, @code{n-1} if @code{key} is greater than or equal to the last +element, and otherwise the index corresponding to the left-hand +(smaller) endpoint. + +@cindex @code{copy} +@item T[] copy(T[] a) +returns a deep copy of the array @code{a}; + +@cindex @code{copy} +@item T[][] copy(T[][] a) +returns a deep copy of the array @code{a}; + +@cindex @code{copy} +@item T[][][] copy(T[][][] a) +returns a deep copy of the array @code{a}; + +@cindex @code{concat} +@item T[] concat(... T[][] a) +returns a new array formed by concatenating the arrays given as arguments; + +@cindex @code{alias} +@item bool alias(T[] a, T[] b) +returns @code{true} if the arrays @code{a} and @code{b} are identical; + +@cindex @code{sort} +@item T[] sort(T[] a) +For built-in ordered types @code{T}, returns a copy of @code{a} sorted in +ascending order; + +@anchor{sort} +@item T[][] sort(T[][] a) +For built-in ordered types @code{T}, returns a copy of @code{a} with the rows +sorted by the first column, breaking ties with successively higher +columns. For example: +@verbatim +string[][] a={{"bob","9"},{"alice","5"},{"pete","7"}, + {"alice","4"}}; +// Row sort (by column 0, using column 1 to break ties): +write(sort(a)); +@end verbatim + +produces +@verbatim +alice 4 +alice 5 +bob 9 +pete 7 +@end verbatim + +@cindex @code{sort} +@item T[] sort(T[] a, bool compare(T i, T j)) +returns a copy of @code{a} stably sorted in ascending order such that +element @code{i} precedes element @code{j} if @code{compare(i,j)} is true. + +@cindex @code{transpose} +@item T[][] transpose(T[][] a) +returns the transpose of @code{a}. + +@cindex @code{transpose} +@item T[][][] transpose(T[][][] a, int[] perm) +returns the 3D transpose of @code{a} obtained by applying the permutation +@code{perm} of @code{new int[]@{0,1,2@}} to the indices of each entry. + +@cindex @code{sum} +@item T sum(T[] a) +For arithmetic types @code{T}, returns the sum of @code{a}. +In the case where @code{T} is @code{bool}, the number of true elements in +@code{a} is returned. + +@cindex @code{min} +@item T min(T[] a) +@item T min(T[][] a) +@item T min(T[][][] a) +For built-in ordered types @code{T}, returns the minimum element of @code{a}. + +@cindex @code{max} +@item T max(T[] a) +@item T max(T[][] a) +@item T max(T[][][] a) +For built-in ordered types @code{T}, returns the maximum element of @code{a}. + +@cindex @code{min} +@item T[] min(T[] a, T[] b) +For built-in ordered types @code{T}, and arrays @code{a} and @code{b} +of the same length, returns an array composed of the minimum of the +corresponding elements of @code{a} and @code{b}. + +@cindex @code{max} +@item T[] max(T[] a, T[] b) +For built-in ordered types @code{T}, and arrays @code{a} and @code{b} +of the same length, returns an array composed of the maximum of the +corresponding elements of @code{a} and @code{b}. + +@cindex @code{pairs} +@item pair[] pairs(real[] x, real[] y); +For arrays @code{x} and @code{y} of the same length, returns the pair array +@code{sequence(new pair(int i) @{return (x[i],y[i]);@},x.length)}. + +@cindex @code{fft} +@item pair[] fft(pair[] a, int sign=1) +returns the Fast Fourier Transform of @code{a} (if the optional +@code{FFTW} package is installed), using the given @code{sign}. Here +is a simple example: +@verbatim +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); +@end verbatim + +@cindex @code{solve} +@item real dot(real[] a, real[] b) +returns the dot product of the vectors @code{a} and @code{b}. + +@anchor{tridiagonal} +@cindex @code{tridiagonal} +@item real[] tridiagonal(real[] a, real[] b, real[] c, real[] f); +Solve the periodic tridiagonal problem @math{L@code{x}=@code{f}} and return the +solution @code{x}, where @code{f} +is an @math{n} vector and @math{L} is the @math{n \times n} matrix +@verbatim +[ 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] ] +@end verbatim +For Dirichlet boundary conditions (denoted here by @code{u[-1]} and +@code{u[n]}), replace @code{f[0]} by @code{f[0]-a[0]u[-1]} and +@code{f[n-1]-c[n-1]u[n]}; then set @code{a[0]=c[n-1]=0}. + +@cindex @code{solve} +@item real[] solve(real[][] a, real[] b, bool warn=true) +Solve the linear equation @math{@code{a}x=@code{b}} by LU decomposition +and return the solution @math{x}, where @code{a} is an +@math{n \times n} matrix and @code{b} is an array of length @math{n}. +For example: +@verbatim +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); +@end verbatim +If @code{a} is a singular matrix and @code{warn} is @code{false}, return an +empty array. +If the matrix @code{a} is tridiagonal, the routine @code{tridiagonal} provides +a more efficient algorithm (@pxref{tridiagonal}). + +@anchor{solve} + +@cindex @code{solve} +@item real[][] solve(real[][] a, real[][] b, bool warn=true) +Solve the linear equation @math{@code{a}x=@code{b}} and return the +solution @math{x}, where @code{a} is an @math{n \times n} matrix and +@code{b} is an @math{n \times m} matrix. If @code{a} is a singular +matrix and @code{warn} is @code{false}, return an empty matrix. + +@cindex @code{identity} +@item real[][] identity(int n); +returns the @math{n \times n} identity matrix. + +@cindex @code{diagonal} +@item real[][] diagonal(... real[] a) +returns the diagonal matrix with diagonal entries given by a. + +@cindex @code{inverse} +@item real[][] inverse(real[][] a) +returns the inverse of a square matrix @code{a}. + +@cindex @code{quadraticroots} +@item @code{real[] quadraticroots(real a, real b, real c);} +This numerically robust solver returns the real roots of the +quadratic equation @math{ax^2+bx+c=0}, in ascending order. Multiple +roots are listed separately. + +@cindex @code{quadraticroots} +@item @code{pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);} +This numerically robust solver returns the two complex roots of the +quadratic equation @math{ax^2+bx+c=0}. + +@cindex @code{cubicroots} +@item @code{real[] cubicroots(real a, real b, real c, real d);} +This numerically robust solver returns the real roots of the +cubic equation @math{ax^3+bx^2+cx+d=0}. Multiple roots are listed separately. + +@end table + +@cindex vectorization +@code{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 +@verbatim +real[] a={1,2}; +real[] b={3,2}; +@end verbatim +@noindent +then @code{a == b} and @code{a >= 2} both evaluate to the vector +@code{@{false, true@}}. +@cindex @code{all} +To test whether all components of @code{a} and @code{b} agree, +use the boolean function @code{all(a == b)}. One can also use conditionals like +@code{(a >= 2) ? a : b}, which returns the array @code{@{3,2@}}, or +@code{write((a >= 2) ? a : null}, which returns the array @code{@{2@}}. + +All of the standard built-in @code{libm} functions of signature +@code{real(real)} also take a real array as an argument, effectively like an +implicit call to @code{map}. + +As with other built-in types, arrays of the basic data types can be read +in by assignment. In this example, the code +@verbatim +file fin=input("test.txt"); +real[] A=fin; +@end verbatim + +@cindex @code{eof} +@cindex @code{eol} +@cindex @code{line} +@cindex line mode +@noindent +reads real values into @code{A} until the end-of-file is reached (or an +I/O error occurs). If line mode is set with @code{line(file)}, then +reading will stop once the end of the line is reached instead +(line mode may be cleared with @code{line(file,false)}): +@verbatim +file fin=input("test.txt"); +real[] A=line(fin); +@end verbatim + +@cindex reading string arrays +@cindex @code{word} +@cindex white-space string delimiter mode +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 +@code{word(file)} and cleared with @code{word(file,false)}, which causes +string reads to respect white-space delimiters, instead of the default +end-of-line delimiter: +@verbatim +file fin=word(line(input("test.txt"))); +real[] A=fin; +@end verbatim + +@cindex @code{csv} +@cindex comma-separated-value mode +Another useful mode is comma-separated-value mode, set with @code{csv(file)} +and cleared with @code{csv(file,false)}, which causes reads to respect +comma delimiters: +@verbatim +file fin=csv(input("test.txt")); +real[] A=fin; +@end verbatim + +@cindex @code{dimension} +To restrict the number of values read, use the @code{dimension(file,int)} +function: +@verbatim +file fin=input("test.txt"); +real[] A=dimension(fin,10); +@end verbatim + +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: +@verbatim +file fin=input("test.txt"); +real[][] A=dimension(fin,2,3); +real[][][] B=dimension(fin,2,3,4); +@end verbatim +@noindent +Again, an integer limit of zero means no restriction. + +@cindex @code{read1} +@cindex @code{read2} +@cindex @code{read3} +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 @code{read1}, @code{read2}, and @code{read3}, respectively: +@verbatim +file fin=input("test.txt"); +real[] A=read1(fin); +real[][] B=read2(fin); +real[][][] C=read3(fin); +@end verbatim + +@cindex @code{write} +One, two, and three-dimensional arrays of the basic data types can be +output with the functions @code{write(file,T[])}, +@code{write(file,T[][])}, @code{write(file,T[][][])}, respectively. + +@node Slices +@subsection Slices +@cindex slices + +Asymptote allows a section of an array to be addressed as a slice +using a Python-like syntax. If @code{A} is an array, the expression +@code{A[m:n]} returns a new array consisting of the elements of @code{A} with +indices from @code{m} up to but not including @code{n}. For example, + +@verbatim +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}; +@end verbatim + +If the left index is omitted, it is taken be @code{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: + +@verbatim +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. +@end verbatim + +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 @code{A[m:n]} still consists of the cells with +indices in the set [@code{m},@code{n}), but now negative +values and values beyond the length of the array are allowed. The indices +simply wrap around. For example: + +@verbatim +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} +@end verbatim + +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: + +@verbatim +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"} +@end verbatim + +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 @code{x[m:n]=x} is equivalent +to @code{x[m:n]=copy(x)}. One can use the shorthand @code{x[m:m]=y} to insert +the contents of the array @code{y} into the array @code{x} starting at the +location just before @code{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 @code{A} is a cyclic array of length 10, @code{A[8:12]}, +@code{A[-3:1]}, and @code{A[5:25]} are bridging slices whereas @code{A[3:7]}, +@code{A[7:10]}, @code{A[-3:0]} and @code{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 @code{A[0]} and an error is +reported. Non-bridging slices may be assigned an array of any length. + +For a cyclic array @code{A} an expression of the form +@code{A[A.length:A.length]} is equivalent to the expression @code{A[0:0]} and +so assigning to this slice will insert values at the start of the array. +@code{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. + +@node Casts +@section Casts +@cindex casts +@cindex implicit casts +@cindex @code{explicit} + +@code{Asymptote} implicitly casts @code{int} to @code{real}, @code{int} to +@code{pair}, @code{real} to @code{pair}, @code{pair} to @code{path}, +@code{pair} to @code{guide}, @code{path} to @code{guide}, @code{guide} +to @code{path}, @code{real} to @code{pen}, +@code{pair[]} to @code{guide[]}, @code{pair[]} to @code{path[]}, +@code{path} to @code{path[]}, and @code{guide} to @code{path[]}, +along with various three-dimensional casts defined in @code{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 @code{explicit} in the function signature, say to avoid an +ambiguous function call in the following example, which outputs 0: + +@verbatim +int f(pair a) {return 0;} +int f(explicit real x) {return 1;} + +write(f(0)); +@end verbatim + +@cindex explicit casts +Other conversions, say @code{real} to @code{int} or +@code{real} to @code{string}, require an explicit cast: +@verbatim +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 +@end verbatim + +@cindex operator cast +Casting to user-defined types is also possible using @code{operator cast}: +@verbatim +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) +@end verbatim + +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 +@verbatim +real operator cast(int x) {return x*100;} +@end verbatim +is equivalent to an infinite recursion, since the result @code{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: +@verbatim +real convert(int x) {return x*100;} +real operator cast(int x)=convert; +@end verbatim + +@cindex operator ecast +Explicit casts are implemented similarly, with @code{operator ecast}. + +@node Import +@section Import +@cindex @code{access} +While @code{Asymptote} provides many features by default, +some applications require specialized features contained in +external @code{Asymptote} modules. For instance, the lines +@verbatim +access graph; +graph.axes(); +@end verbatim +@noindent +draw @math{x} and @math{y} axes on a two-dimensional graph. Here, the +command looks up the module under the name @code{graph} in a global dictionary +of modules and puts it in a new variable named @code{graph}. +The module is a structure, and we can refer to its fields as we usually +would with a structure. + +@cindex @code{from} +Often, one wants to use module functions without having to specify +the module name. The code +@verbatim +from graph access axes; +@end verbatim +@noindent +adds the @code{axes} field of @code{graph} into the local name space, +so that subsequently, one can just write @code{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: + +@verbatim +from graph access axes, xaxis, yaxis; +@end verbatim +@noindent +Wild card notation can be used to add all non-private fields and types of a +module to the local name space: + +@verbatim +from graph access *; +@end verbatim + +@cindex @code{unravel} +Similarly, one can add the non-private fields and types of a structure +to the local environment with the @code{unravel} keyword: + +@verbatim +struct matrix { + real a,b,c,d; +} + +real det(matrix m) { + unravel m; + return a*d-b*c; +} +@end verbatim +Alternatively, one can unravel selective fields: +@verbatim +real det(matrix m) { + from m unravel a,b,c as C,d; + return a*d-b*C; +} +@end verbatim + +@cindex @code{import} +The command +@verbatim +import graph; +@end verbatim +is a convenient abbreviation for the commands +@verbatim +access graph; +unravel graph; +@end verbatim +That is, @code{import graph} first loads a module into a structure called +@code{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 @code{import} commands at the start of an +@code{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. + +@cindex @code{as} +To rename modules or fields when adding them to the local environment, use +@code{as}: + +@verbatim +access graph as graph2d; +from graph access xaxis as xline, yaxis as yline; +@end verbatim + +The command +@verbatim +import graph as graph2d; +@end verbatim +is a convenient abbreviation for the commands +@verbatim +access graph as graph2d; +unravel graph2d; +@end verbatim + +Except for a few built-in modules, such as @code{settings}, all modules +are implemented as @code{Asymptote} files. When looking up a module +that has not yet been loaded, @code{Asymptote} searches the standard +search paths (@pxref{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: + +@noindent +@code{access "@value{Datadir}/asymptote/graph.asy" as graph;} + +@noindent +@code{from "@value{Datadir}/asymptote/graph.asy" access axes;} + +@noindent +@code{import "@value{Datadir}/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. + +@cindex runtime imports +@cindex @code{eval} +However, you can import an @code{Asymptote} module determined by the +string @code{s} at runtime like this: +@verbatim +eval("import "+s,true); +@end verbatim + +@cindex @code{asy} +To conditionally execute an array of asy files, use +@verbatim +void asy(string format, bool overwrite ... string[] s); +@end verbatim +The file will only be processed, using output format @code{format}, if +overwrite is @code{true} or the output file is missing. + +One can evaluate an @code{Asymptote} expression (without any return +value, however) contained in the string @code{s} with: +@cindex @code{eval} +@verbatim +void eval(string s, bool embedded=false); +@end verbatim +It is not necessary to terminate the string @code{s} with a semicolon. +If @code{embedded} is @code{true}, the string will be evaluated +at the top level of the current environment. +If @code{embedded} is @code{false} (the default), the string +will be evaluated in an independent environment, sharing the same +@code{settings} module (@pxref{settings}). + +@cindex @code{quote} +One can evaluate arbitrary @code{Asymptote} code (which may +contain unescaped quotation marks) with the command +@verbatim +void eval(code s, bool embedded=false); +@end verbatim +Here @code{code} is a special type used with @code{quote @{@}} +to enclose @code{Asymptote code} like this: +@verbatim +real a=1; +code s=quote { + write(a); +}; +eval(s,true); // Outputs 1 +@end verbatim + +To include the contents of a file @code{graph} verbatim (as if the +contents of the file were inserted at that point), use one of the forms: +@verbatim +include graph; +@end verbatim + +@noindent +@code{include "@value{Datadir}/asymptote/graph.asy";} + +To list all global functions and variables defined in a module named +by the contents of the string @code{s}, use the function +@verbatim +void list(string s, bool imports=false); +@end verbatim +@noindent +Imported global functions and variables are also listed if +@code{imports} is @code{true}. + +@node Static +@section Static +@cindex @code{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 +@verbatim +struct s { + int count() { + static int c=0; + ++c; + return c; + } +} +@end verbatim + +@noindent +there is one instance of the variable @code{c} for each +object @code{s} (as opposed to each call of @code{count}). + +Similarly, in +@verbatim +int factorial(int n) { + int helper(int k) { + static int x=1; + x *= k; + return k == 1 ? x : helper(k-1); + } + return helper(n); +} +@end verbatim + +@noindent +there is one instance of @code{x} for every call to +@code{factorial} (and not for every call to @code{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, +@verbatim +struct A { + struct B { + static pair z; + } +} +@end verbatim + +@noindent +creates one object @code{z} for each object of type @code{A} created. + +In this example, +@verbatim +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; +} +@end verbatim + +@noindent +there is one instance of @code{x} for each call to @code{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: + +@verbatim +void f(); +for(int i=0; i < 10; ++i) { + int x=i; + if(x==5) { + f=new void () { write(x); } + } +} +f(); +@end verbatim + +Here, every iteration of the loop has its own variable @code{x}, so @code{f()} +will write @code{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: + +@verbatim +void f() { + static int x; + for(int i=0; i < 10; ++i) { + static int y; + } +} +@end verbatim +@noindent +both @code{x} and @code{y} will be allocated in the same place, which is +also where @code{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: + +@verbatim +struct A { + static int x; +} +pair A; + +int y=A.x; +@end verbatim +@noindent +does the @code{A} in @code{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. + +@node LaTeX usage +@chapter @code{LaTeX} usage +@cindex @code{LaTeX} usage +@cindex @code{asymptote.sty} + +@code{Asymptote} comes with a convenient @code{LaTeX} style file +@code{asymptote.sty} that makes @code{LaTeX} +@code{Asymptote}-aware. Entering @code{Asymptote} code +directly into the @code{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 +@code{\usepackage@{asymptote@}} at the beginning of your file +and enclose your @code{Asymptote} code within a +@code{\begin@{asy@}...\end@{asy@}} environment. As with the +@code{LaTeX} @code{comment} environment, the @code{\end@{asy@}} command +must appear on a line by itself, with no leading spaces or trailing +commands/comments. + +The sample @code{LaTeX} file below, named @code{latexusage.tex}, can +be run as follows: +@verbatim +latex latexusage +asy latexusage +latex latexusage +@end verbatim + +@noindent +or + +@verbatim +pdflatex latexusage +asy latexusage +pdflatex latexusage +@end verbatim + +To switch between using @code{latex} and @code{pdflatex} you may first +need to remove the files @code{latexusage-*}, @code{latexusage_.pre}, and +@code{latexusage.aux}. + +@cindex @code{width} +@cindex @code{height} +@cindex @code{viewportwidth} +@cindex @code{viewportheight} +@cindex @code{attach} +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 +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, +as annotated (but printable) attachments. For many applications, the +annotated attachment method tends to be more convenient. +The default value of @code{viewportwidth} is @code{\the\linewidth} for +inline 3D figures and @code{0} for attachments. + +If the @code{inline} option is given to the +@code{asymptote.sty} package, inline @code{LaTeX} code is generated instead of +@acronym{EPS} or @acronym{PDF} files. This makes LaTeX symbols visible to the +@code{\begin@{asy@}...\end@{asy@}} environment. In this mode, +Asymptote correctly aligns LaTeX symbols defined outside of +@code{\begin@{asy@}...\end@{asy@}}, but treats their size as zero; an +optional second string can be given to @code{Label} to provide an +estimate of the unknown label size. + +Note that if @code{latex} is used with the @code{inline} option, +the labels might not show up in @acronym{DVI} viewers that cannot +handle raw @code{PostScript} code. One can use @code{dvips}/@code{dvipdf} to +produce @code{PostScript}/@acronym{PDF} output (we recommend using the +modified version of @code{dvipdf} in the @code{Asymptote} patches +directory, which accepts the @code{dvips -z} hyperdvi option). + +An excellent tutorial by Dario Teixeira on integrating @code{Asymptote} and +@code{LaTeX} is available at @url{http://dario.dse.nl/projects/asylatex/}. + +Here now is @code{latexusage.tex}: +@verbatiminclude latexusage.tex +@page +@image{latexusage,,25cm} + +@node Base modules +@chapter Base modules +@cindex base modules + +@code{Asymptote} currently ships with the following base modules: + +@menu +* plain:: Default @code{Asymptote} base file +* simplex:: Linear programming: simplex method +* math:: Extend @code{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 @acronym{PDF} and @acronym{MPEG} movies +* embed:: Embedding movies, sounds, and 3D objects +* slide:: Making presentations with @code{Asymptote} +* MetaPost:: @code{MetaPost} compatibility routines +* unicode:: Accept @code{unicode} (UTF-8) characters +* latin1:: Accept @code{ISO 8859-1} characters +* babel:: Interface to @code{LaTeX} @code{babel} package +* labelpath:: Drawing curved labels +* labelpath3:: Drawing curved labels in 3D +* annotate:: Annotate your @acronym{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 + +@end menu + +@node plain +@section @code{plain} +@cindex @code{plain} + +This is the default @code{Asymptote} base file, which defines key parts of the +drawing language (such as the @code{picture} structure). + +By default, an implicit @code{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 @code{plain}, of course). This means that +the types and functions defined in @code{plain} are accessible in +almost all @code{Asymptote} code. Use the @code{-noautoplain} command-line +option to disable this feature. + +@node simplex +@section @code{simplex} +@cindex @code{simplex} +@cindex @code{deferred drawing} +This package solves the two-variable linear programming problem using the +simplex method. It is used by the module @code{plain} for automatic +sizing of pictures. + +@node math +@section @code{math} +@cindex @code{math} +This package extends @code{Asymptote}'s mathematical capabilities with +intersection algorithms and matrix arithmetic: + +@table @code + +@cindex @code{drawline} +@item void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen); +draw the visible portion of the (infinite) line going through +@code{P} and @code{Q}, without altering the size of picture @code{pic}, +using pen @code{p}. + +@cindex @code{intersect} +@item real intersect(triple P, triple Q, triple n, triple Z); +returns the intersection time of the extension of the line segment @code{PQ} +with the plane perpendicular to @code{n} and passing through @code{Z}. + +@cindex @code{intersectionpoint} +@item triple intersectionpoint(triple n0, triple P0, triple n1, triple P1); +Return any point on the intersection of the two planes with normals +@code{n0} and @code{n1} passing through points @code{P0} and @code{P1}, +respectively. If the planes are parallel, return +@code{(infinity,infinity,infinity)}. + +@cindex @code{quarticroots} +@item @code{pair[] quarticroots(real a, real b, real c, real d, real e);} +returns the four complex roots of the quartic equation +@math{ax^4+bx^3+cx^2+dx+e=0}. + +@end table + +@node interpolate +@section @code{interpolate} +@cindex @code{interpolate} +This module implements Lagrange, Hermite, and standard cubic spline +interpolation in @code{Asymptote}, as illustrated in the example +@code{interpolate1.asy}. + +@node geometry +@section @code{geometry} +@cindex @code{geometry} +@cindex @code{triangle} +@cindex @code{perpendicular} +This module, written by Philippe Ivaldi, provides an extensive set of +geometry routines, including @code{perpendicular} symbols and a @code{triangle} +structure. It is documented here: +@url{http://piprim.tuxfamily.org/asymptote/geometry_en.pdf}, +including an extensive set of examples, +@url{http://piprim.tuxfamily.org/asymptote/travaux/}, and an index: +@quotation +@url{http://piprim.tuxfamily.org/asymptote/travaux/modules/geometry_dev.asy.index.type.html} +@end quotation + +@node trembling +@section @code{trembling} +@cindex @code{trembling} +This module, written by Philippe Ivaldi and illustrated in the example +@code{floatingdisk.asy}, allows one to draw wavy lines, as if drawn by +hand. Further examples are posted at +@url{http://piprim.tuxfamily.org/asymptote/modules} + +@node stats +@section @code{stats} +@cindex @code{stats} +@cindex @code{leastsquares} +This package implements a Gaussian random number generator +and a collection of statistics routines, including @code{histogram} +and @code{leastsquares}. + +@node patterns +@section @code{patterns} +@cindex @code{patterns} +This package implements @code{Postscript} tiling patterns and includes +several convenient pattern generation routines. + +@node markers +@section @code{markers} +@cindex @code{markers} +This package implements specialized routines for marking paths and angles. +The principal mark routine provided by this package is +@verbatim +markroutine markinterval(int n=1, frame f, bool rotated=false); +@end verbatim +@noindent +which centers @code{n} copies of frame @code{f} within uniformly space +intervals in arclength along the path, optionally rotated by the angle of the +local tangent. + +The @code{marker} (@pxref{marker}) routine can be used to construct new +markers from these predefined frames: + +@cindex @code{stickframe} +@verbatim +frame stickframe(int n=1, real size=0, pair space=0, real angle=0, + pair offset=0, pen p=currentpen); +@end verbatim +@cindex @code{circlebarframe} +@verbatim +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); +@end verbatim +@cindex @code{crossframe} +@verbatim +frame crossframe(int n=3, real size=0, pair space=0, + real angle=0, pair offset=0, pen p=currentpen); +@end verbatim +@cindex @code{tildeframe} +@verbatim +frame tildeframe(int n=1, real size=0, pair space=0, + real angle=0, pair offset=0, pen p=currentpen); +@end verbatim + +For convenience, this module also constructs the markers +@code{StickIntervalMarker}, @code{CrossIntervalMarker}, +@code{CircleBarIntervalMarker}, and @code{TildeIntervalMarker} +from the above frames. The example @code{markers1.asy} illustrates the +use of these markers: + +@sp 1 +@center @image{markers1} + +This package also provides a routine for marking an angle @math{AOB}: +@cindex @code{markangle} +@verbatim +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); +@end verbatim +@noindent +as illustrated in the example @code{markers2.asy}. + +@sp 1 +@center @image{markers2} + +@node tree +@section @code{tree} +@cindex @code{tree} +This package implements an example of a dynamic binary search tree. + +@node binarytree +@section @code{binarytree} +@cindex @code{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 @code{binarytreetest.asy}: +@verbatiminclude binarytreetest.asy +@sp 1 +@center @image{binarytreetest} + +@node drawtree +@section @code{drawtree} +@cindex @code{drawtree} +This is a simple tree drawing module used by the example @code{treetest.asy}. + +@node syzygy +@section @code{syzygy} +@cindex @code{syzygy} +This module automates the drawing of braids, relations, and syzygies, +along with the corresponding equations, as illustrated in the example +@code{knots.asy}. + +@node feynman +@section @code{feynman} +@cindex @code{feynman} +This package, contributed by Martin Wiebusch, is useful for drawing +Feynman diagrams, as illustrated by the examples @code{eetomumu.asy} +and @code{fermi.asy}. + +@node roundedpath +@section @code{roundedpath} +@cindex @code{roundedpath} +This package, contributed by Stefan Knorr, is useful for rounding the +sharp corners of paths, as illustrated in the example file @code{roundpath.asy}. + +@node animation +@section @code{animation} +@cindex @code{animation} +@cindex @code{merge} +@cindex @code{convert} +@cindex animation +@cindex @code{ImageMagick} +This module allows one to generate animations, as illustrated by the +files @code{wheel.asy}, @code{wavelet.asy}, and @code{cube.asy} in +the @code{animations} subdirectory of the examples directory. These +animations use the @code{ImageMagick} @code{convert} program to +@code{merge} multiple images into a @acronym{GIF} or @acronym{MPEG} +movie. + +@cindex @code{animate} +@anchor{animate} +The related @code{animate} module, derived from the @code{animation} +module, generates higher-quality portable clickable @acronym{PDF} movies, with +optional controls. This requires installing the package +@quotation +@url{http://www.ctan.org/tex-archive/macros/latex/contrib/animate/animate.sty} +@noindent +@end quotation +@noindent +(version 2007/11/30 or later) in a new directory @code{animate} in the +local @code{LaTeX} directory (for example, in +@code{/usr/local/share/texmf/tex/latex/animate}). On @code{UNIX} systems, +one must then execute the command @code{texhash}. + +The example @code{pdfmovie.asy} in the @code{animations} +directory, along with the slide presentations @code{slidemovies.asy} +and @code{intro.asy}, illustrate the use of embedded @acronym{PDF} movies. +The examples @code{inlinemovie.tex} and @code{inlinemovie3.tex} +show how to generate and embed @acronym{PDF} movies directly within a +@code{LaTeX} file (@pxref{LaTeX usage}). +The member function +@verbatim +string pdf(fit fit=NoBox, real delay=animationdelay, string options="", + bool keep=settings.keep, bool multipage=true); +@end verbatim +@noindent +of the @code{animate} structure accepts any of the @code{animate.sty} options, +as described here: +@quotation +@url{http://www.ctan.org/tex-archive/macros/latex/contrib/animate/doc/animate.pdf} +@end quotation + +@node embed +@section @code{embed} +@cindex @code{embed} +This module provides an interface to the @code{LaTeX} package +(included with @code{MikTeX}) +@quotation +@url{http://www.ctan.org/tex-archive/macros/latex/contrib/movie15} +@end quotation +@noindent +for embedding movies, sounds, and 3D objects into a @acronym{PDF} document. +@noindent +@cindex @code{XeLaTeX} +However, @code{XeLaTeX} users need to rename the modified version +@code{movie15_dvipdfmx.sty} from +@quotation +@url{http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/patches/} +@end quotation +to @code{movie15.sty} and place it in their @code{LaTeX} path. + +The latest version (2008/10/08) of the @code{movie15} package requires both +@code{pdflatex} version 1.20 or later and the file +@quotation +@url{http://www.ctan.org/tex-archive/macros/latex/contrib/oberdiek/ifdraft.dtx} +@end quotation +@noindent +which can be installed by placing it in a directory @code{ifdraft} in +the local @code{LaTeX} directory +(e.g.@ @code{/usr/local/share/texmf/tex/latex/ifdraft}) and executing in that +directory the commands: +@verbatim +tex ifdraft.dtx +texhash +@end verbatim + +@cindex @code{external} +An example of embedding @code{U3D} code is provided in the file +@code{embeddedu3d.asy}. +As of version 7.0.8, @code{Adobe Reader} supports the @code{U3D} format +under Linux. + +Unfortunately, Adobe has not yet made available an embedded movie plugin +for the Linux version of @code{Adobe Reader}. A portable method for +embedding movie files, which should work on any platform and does not require +the @code{movie15} or @code{ifdraft} packages, is provided by using the +@code{external} module instead of @code{embed}. An example of these +interfaces is provided in the file @code{embeddedmovie.asy} and +@code{externalmovie.asy} in the @code{animations} subdirectory of the +examples directory. For a higher quality movie generated directly by +@code{Asymptote}, use the @code{animate} module along with the +@code{animate.sty} package to embed a portable @acronym{PDF} animation +(@pxref{animate}). + +@node slide +@section @code{slide} +@cindex @code{slide} +This package provides a simple yet high-quality facility for making +presentation slides, including portable embedded @acronym{PDF} animations (see +the file @code{slidemovies.asy}). A simple example is provided in the file +@code{slidedemo.asy}. + +@node MetaPost +@section @code{MetaPost} +@cindex @code{MetaPost} +This package provides some useful routines to help @code{MetaPost} users +migrate old @code{MetaPost} code to @code{Asymptote}. Further +contributions here are welcome. + +@cindex @code{implicit linear solver} +@cindex @code{MetaPost whatever} +@cindex @code{extension} +Unlike @code{MetaPost}, @code{Asymptote} does not implicitly solve +linear equations and therefore does not have the notion of a +@code{whatever} unknown. The routine @code{extension} (@pxref{extension}) +provides a useful replacement for a common use of @code{whatever}: finding the +intersection point of the lines through @code{P}, @code{Q} and +@code{p}, @code{q}. For less common occurrences of @code{whatever}, one +can use the built-in explicit linear equation solver @code{solve} instead. + +@node unicode +@section @code{unicode} +@cindex @code{unicode} +@cindex international characters +Import this package at the beginning of the file to instruct +@code{LaTeX} to accept @code{unicode} (UTF-8) standardized international +characters. +@noindent +@cindex Cyrillic +@cindex Russian +To use Cyrillic fonts, you will need to change the font encoding: +@verbatim +import unicode; +texpreamble("\usepackage{mathtext}\usepackage[russian]{babel}"); +defaultpen(font("T2A","cmr")); +@end verbatim +@noindent +@cindex Chinese +@cindex Japanese +@cindex Korean +@cindex CJK +Support for Chinese, Japanese, and Korean fonts is provided by the +CJK package: +@quotation +@url{http://www.ctan.org/tex-archive/languages/chinese/CJK/} +@end quotation +@noindent +The following commands enable the CJK song family (within a label, you +can also temporarily switch to another family, say kai, by prepending +@code{"\CJKfamily@{kai@}"} to the label string): +@verbatim +texpreamble("\usepackage{CJK} +\AtBeginDocument{\begin{CJK*}{GBK}{song}} +\AtEndDocument{\clearpage\end{CJK*}}"); +@end verbatim + +@node latin1 +@section @code{latin1} +@cindex @code{latin1} +If you don't have @code{LaTeX} support for @code{unicode} installed, +you can enable support for Western European languages (ISO 8859-1) by +importing the module @code{latin1}. This module can be used as a +template for providing support for other ISO 8859 alphabets. + +@node babel +@section @code{babel} +@cindex @code{babel} +This module implements the @code{LaTeX} @code{babel} package in +@code{Asymptote}. For example: +@verbatim +import babel; +babel("german"); +@end verbatim + +@node labelpath +@section @code{labelpath} +@cindex @code{labelpath} +This module uses the @code{PSTricks} @code{pstextpath} macro to fit labels +along a path (properly kerned, as illustrated in the example file +@code{curvedlabel.asy}), using the command +@verbatim +void labelpath(picture pic=currentpicture, Label L, path g, + string justify=Centered, pen p=currentpen); +@end verbatim +@noindent +Here @code{justify} is one of @code{LeftJustified}, @code{Centered}, or +@code{RightJustified}. The @math{x} component of a shift transform +applied to the Label is interpreted as a shift along the curve, whereas +the @math{y} component is interpreted as a shift away from the curve. +All other Label transforms are ignored. This package requires the +@code{latex} tex engine and inherits the limitations of the +@code{PSTricks} @code{\pstextpath} macro. + +@node labelpath3 +@section @code{labelpath3} +@cindex @code{labelpath3} +This module, contributed by Jens Schwaiger, implements a 3D version of +@code{labelpath} that does not require the @code{PSTricks} package. +An example is provided in @code{curvedlabel3.asy}. + +@node annotate +@section @code{annotate} +@cindex @code{annotate} +This module supports @acronym{PDF} annotations for viewing with +@code{Adobe Reader}, via the function +@verbatim +void annotate(picture pic=currentpicture, string title, string text, + pair position); +@end verbatim +@noindent +Annotations are illustrated in the example file @code{annotation.asy}. +Currently, annotations are only implemented for the @code{latex} +(default) and @code{tex} @TeX{} engines. + +@node CAD +@section @code{CAD} +@cindex @code{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 +@code{CAD.pdf}. + +@node graph +@section @code{graph} +@cindex @code{graph} +@cindex 2D graphs +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 @code{guide} (that can be drawn with +the draw command, with an optional legend) constructed with one of +the following routines: + +@itemize +@item +@verbatim +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 --); +@end verbatim + +Returns a graph using the scaling information for picture @code{pic} +(@pxref{automatic scaling}) of the function @code{f} on the interval +[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points +evenly spaced in [@code{a},@code{b}], optionally restricted by the +bool3 function @code{cond} on [@code{a},@code{b}]. If @code{cond} is: +@itemize @bullet +@item @code{true}, the point is added to the existing guide; +@item @code{default}, the point is added to a new guide; +@item @code{false}, the point is omitted and a new guide is begun. +@end itemize +Th points are connected using the interpolation specified by @code{join}: +@itemize @bullet + +@cindex @code{operator --} +@cindex @code{Straight} +@item @code{operator --} (linear interpolation; the abbreviation +@code{Straight} is also accepted); + +@cindex @code{operator ..} +@cindex @code{Spline} +@item @code{operator ..} (piecewise Bezier cubic spline interpolation; +the abbreviation @code{Spline} is also accepted); + +@cindex @code{Hermite} +@cindex @code{Hermite(splinetype splinetype} +@item @code{Hermite} (standard cubic spline interpolation using boundary +condition @code{notaknot}, @code{natural}, @code{periodic}, +@code{clamped(real slopea, real slopeb)}), or @code{monotonic}. +The abbreviation @code{Hermite} is equivalent to +@code{Hermite(notaknot)} for nonperiodic data and +@code{Hermite(periodic)} for periodic data). + +@end itemize + +@item +@verbatim +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 --); +@end verbatim + +Returns a graph using the scaling information for picture @code{pic} +of the parametrized function +(@code{x}(@math{t}),@code{y}(@math{t})) for @math{t} in the interval +[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points +evenly spaced in [@code{a},@code{b}], optionally restricted by the +bool3 function @code{cond} on [@code{a},@code{b}], using the given +interpolation type. + +@item +@verbatim +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 --); +@end verbatim + +Returns a graph using the scaling information for picture @code{pic} +of the parametrized function +@code{z}(@math{t}) for @math{t} in the interval +[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points +evenly spaced in [@code{a},@code{b}], optionally restricted by the +bool3 function @code{cond} on [@code{a},@code{b}], using the given +interpolation type. + +@item +@verbatim +guide graph(picture pic=currentpicture, pair[] z, + interpolate join=operator --); +guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond, + interpolate join=operator --); +@end verbatim + +Returns a graph using the scaling information for picture @code{pic} +of the elements of the array @code{z}, optionally restricted to +those indices for which the elements of the boolean array @code{cond} are +@code{true}, using the given interpolation type. + +@item +@verbatim +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 --); +@end verbatim + +Returns a graph using the scaling information for picture @code{pic} +of the elements of the arrays (@code{x},@code{y}), optionally +restricted to those indices for which the elements of the boolean +array @code{cond} are @code{true}, using the given interpolation type. + +@item +@cindex @code{polargraph} +@verbatim +guide polargraph(picture pic=currentpicture, real f(real), real a, + real b, int n=ngraph, interpolate join=operator --); +@end verbatim + +Returns a polar-coordinate graph using the scaling information for +picture @code{pic} of the function @code{f} on the interval +[@code{a},@code{b}], sampling at @code{n} evenly spaced points, with +the given interpolation type. + +@end itemize + +@verbatim + + +@end verbatim + +An axis can be drawn on a picture with one of the following commands: + +@itemize + +@item +@verbatim +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); +@end verbatim + +Draw an @math{x} axis on picture @code{pic} from @math{x}=@code{xmin} to +@math{x}=@code{xmax} using pen @code{p}, optionally labelling it with +Label @code{L}. The relative label location along the axis (a real number from +[0,1]) defaults to 1 (@pxref{Label}), so that the label is drawn at the +end of the axis. An infinite value of @code{xmin} +or @code{xmax} specifies that the corresponding axis limit will be +automatically determined from the picture limits. +The optional @code{arrow} argument takes the same values as in the +@code{draw} command (@pxref{arrows}). The axis is drawn before any +existing objects in the current picture unless @code{above=true}. +The axis placement is determined by one of the following @code{axis} types: + +@table @code + +@cindex @code{YZero} +@item YZero(bool extend=true) +Request an @math{x} axis at @math{y}=0 (or @math{y}=1 on a logarithmic axis) +extending to the full dimensions of the picture, unless @code{extend}=false. + +@cindex @code{YEquals} +@item YEquals(real Y, bool extend=true) +Request an @math{x} axis at @math{y}=@code{Y} extending to the full +dimensions of the picture, unless @code{extend}=false. + +@cindex @code{Bottom} +@item Bottom(bool extend=false) +Request a bottom axis. + +@cindex @code{Top} +@item Top(bool extend=false) +Request a top axis. + +@cindex @code{BottomTop} +@item BottomTop(bool extend=false) +Request a bottom and top axis. + +@end table + +@cindex custom axis types +Custom axis types can be created by following the examples in @code{graph.asy}. +One can easily override the default values for the standard axis types: +@verbatim +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(); + +@end verbatim + +@anchor{ticks} +@cindex @code{ticks} +@cindex @code{NoTicks} +@cindex @code{LeftTicks} +@cindex @code{RightTicks} +@cindex @code{Ticks} +The default tick option is @code{NoTicks}. +The options @code{LeftTicks}, @code{RightTicks}, or @code{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: +@verbatim +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); +@end verbatim + +If any of these parameters are omitted, reasonable defaults will +be chosen: +@table @code +@item Label format +@cindex @code{defaultformat} +@cindex @code{trailingzero} +override the default tick label format (@code{defaultformat}, initially +"$%.4g$"), rotation, pen, and alignment (for example, @code{LeftSide}, +@code{Center}, or @code{RightSide}) relative to the axis. To enable +@code{LaTeX} math mode fonts, the format string should begin and +end with @code{$} @pxref{format}. If the format string is @code{trailingzero}, +trailing zeros will be added to the tick labels; if the format string is +@code{"%"}, the tick label will be suppressed; +@item ticklabel +is a function @code{string(real x)} returning the label (by default, +format(format.s,x)) for each major tick value @code{x}; +@item bool beginlabel +include the first label; +@item bool endlabel +include the last label; +@item int N +when automatic scaling is enabled (the default; @pxref{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; +@item int n +divide each interval into this many subintervals, separated by minor ticks; +@item real Step +the tick value spacing between major ticks +(if @code{N}=@code{0}); +@item real step +the tick value spacing between minor ticks (if @code{n}=@code{0}); +@item bool begin +include the first major tick; +@item bool end +include the last major tick; +@item tickmodifier modify; +an optional function that takes and returns a @code{tickvalue} structure having +real[] members @code{major} and @code{minor} consisting of the tick values +(to allow modification of the automatically generated tick values); +@item real Size +the size of the major ticks (in @code{PostScript} coordinates); +@item real size +the size of the minor ticks (in @code{PostScript} coordinates); +@item bool extend; +extend the ticks between two axes (useful for drawing a grid on the graph); +@item pen pTick +an optional pen used to draw the major ticks; +@item pen ptick +an optional pen used to draw the minor ticks. + +@end table + +For convenience, the predefined tickmodifier @code{OmitTick(... real[] x)} +tickmodifier can be used to remove specific auto-generated ticks and +their labels. The @code{OmitFormat(string s=defaultformat ... real[] x)} +ticklabel can be used to remove specific tick labels but not the +corresponding ticks. The tickmodifier @code{NoZero} is an abbreviation for +@code{OmitTick(0)} and the ticklabel @code{NoZeroFormat} is an +abbrevation for @code{OmitFormat(0)}. + +@cindex custom tick locations +@cindex @code{LeftTicks} +@cindex @code{RightTicks} +@cindex @code{Ticks} +It is also possible to specify custom tick locations with +@code{LeftTicks}, @code{RightTicks}, and @code{Ticks} by passing explicit real +arrays @code{Ticks} and (optionally) @code{ticks} containing the +locations of the major and minor ticks, respectively: +@verbatim +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) +@end verbatim + +@item +@verbatim +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); +@end verbatim + +Draw a @math{y} axis on picture @code{pic} from @math{y}=@code{ymin} to +@math{y}=@code{ymax} using pen @code{p}, optionally labelling it with +Label @code{L}. The relative location of the label (a real number from +[0,1]) defaults to 1 (@pxref{Label}). An infinite value of @code{ymin} +or @code{ymax} specifies that the corresponding axis limit will be +automatically determined from the picture limits. +The optional @code{arrow} argument takes the same values as in the +@code{draw} command (@pxref{arrows}). The axis is drawn before any +existing objects in the current picture unless @code{above=true}. +The tick type is specified by @code{ticks} and the axis placement is +determined by one of the following @code{axis} types: + +@table @code + +@cindex @code{XZero} +@item XZero(bool extend=true) +Request a @math{y} axis at @math{x}=0 (or @math{x}=1 on a logarithmic axis) +extending to the full dimensions of the picture, unless @code{extend}=false. + +@cindex @code{XEquals} +@item XEquals(real X, bool extend=true) +Request a @math{y} axis at @math{x}=@code{X} extending to the full +dimensions of the picture, unless @code{extend}=false. + +@cindex @code{Left} +@item Left(bool extend=false) +Request a left axis. + +@cindex @code{Right} +@item Right(bool extend=false) +Request a right axis. + +@cindex @code{LeftRight} +@item LeftRight(bool extend=false) +Request a left and right axis. + +@end table + +@item +@cindex @code{xequals} +@cindex @code{yequals} +For convenience, the functions +@verbatim +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); +@end verbatim +and +@verbatim +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); +@end verbatim +can be respectively used to call @code{yaxis} and +@code{xaxis} with the appropriate axis types @code{XEquals(x,extend)} and +@code{YEquals(y,extend)}. This is the recommended way of drawing vertical +or horizontal lines and axes at arbitrary locations. + +@item +@verbatim +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); +@end verbatim +This convenience routine draws both @math{x} and @math{y} axes +on picture @code{pic} from @code{min} to @code{max}, +with optional labels @code{xlabel} and @code{ylabel} +and any arrows specified by @code{arrow}. The axes are drawn on top of +existing objects in the current picture only if @code{above=true}. + +@item +@verbatim +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); +@end verbatim + +This routine can be used to draw on picture @code{pic} a general axis +based on an arbitrary path @code{g}, using pen @code{p}. +One can optionally label the axis with Label @code{L} and add an arrow +@code{arrow}. The tick type is given by @code{ticks}. +The optional integer array @code{divisor} specifies what tick divisors +to try in the attempt to produce uncrowded tick labels. A @code{true} +value for the flag @code{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 @code{above=true}. +The tick locator @code{ticklocate} is constructed by the routine +@verbatim +ticklocate ticklocate(real a, real b, autoscaleT S=defaultS, + real tickmin=-infinity, real tickmax=infinity, + real time(real)=null, pair dir(real)=zero); +@end verbatim +@noindent +where @code{a} and @code{b} specify the respective tick values at +@code{point(g,0)} and @code{point(g,length(g))}, @code{S} specifies +the autoscaling transformation, the function @code{real time(real v)} +returns the time corresponding to the value @code{v}, and +@code{pair dir(real t)} returns the absolute tick direction as a +function of @code{t} (zero means draw the tick perpendicular to the axis). + +@item These routines are useful for manually putting ticks and labels on axes +(if the variable @code{Label} is given as the @code{Label} +argument, the @code{format} argument will be used to format a string based on +the tick location): +@cindex xtick +@cindex ytick +@cindex labelx +@cindex labely +@cindex tick +@cindex Label +@verbatim +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); +@end verbatim +@end itemize + +Here are some simple examples of two-dimensional graphs: + +@enumerate + +@cindex textbook graph +@item This example draws a textbook-style graph of +@math{y=} exp@math{(x)}, with the @math{y} axis starting at @math{y=0}: +@verbatiminclude exp.asy +@sp 1 +@center @image{exp} + + +@item 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 @code{xasy} (@pxref{GUI}). If an +@code{UnFill(real xmargin=0, real ymargin=xmargin)} or +@code{Fill(pen)} option is specified to @code{add}, the legend will obscure +any underlying objects. Here we illustrate how to clip the portion of +the picture covered by a label: + +@cindex scientific graph +@verbatiminclude lineargraph0.asy +@sp 1 +@center @image{lineargraph0} + +@cindex @code{attach} +To specify a fixed size for the graph proper, use @code{attach}: +@verbatiminclude lineargraph.asy + +@cindex @code{legend} +A legend can have multiple entries per line: +@verbatiminclude legend.asy +@sp 1 +@center @image{legend} + +@item 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 @math{y} axis. +@verbatiminclude datagraph.asy +@sp 1 +@center @image{datagraph} + +@item This example shows how to graph columns of data read from a file. +@verbatiminclude filegraph.asy +@sp 1 +@center @image{filegraph} + +@cindex @code{polygon} +@cindex @code{cross} +@cindex @code{errorbars} +@cindex @code{marker} +@cindex @code{marknodes} +@cindex @code{markuniform} +@cindex @code{mark} +@anchor{pathmarkers} +@item 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 +@verbatim +marker marker(path g, markroutine markroutine=marknodes, + pen p=currentpen, filltype filltype=NoFill, + bool above=true); +@end verbatim +using the path @code{unitcircle} (@pxref{filltype}), are drawn +below each node. Any frame can be converted to a marker, using +@anchor{marker} +@verbatim +marker marker(frame f, markroutine markroutine=marknodes, + bool above=true); +@end verbatim +In the right-hand graph, the unit @math{n}-sided regular polygon +@code{polygon(int n)} and the unit @math{n}-point cyclic cross +@code{cross(int n, bool round=true, real r=0)} (where @code{r} is an +optional ``inner'' radius) are used to build a custom marker frame. +@anchor{markuniform} +Here @code{markuniform(bool centered=false, int n, bool rotated=false)} +adds this frame at @code{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 @code{n} evenly +spaced arclength intervals). Alternatively, one can use +markroutine @code{marknodes} to request that the marks be placed at each +Bezier node of the path, or +markroutine @code{markuniform(pair z(real t), real a, real b, int n)} +to place marks at points @code{z(t)} for n evenly spaced values of +@code{t} in @code{[a,b]}. + +These markers are predefined: +@verbatim +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) +}; +@end verbatim + +The example also illustrates the @code{errorbar} routines: + +@verbatim +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); +@end verbatim + +@noindent +Here, the positive and negative extents of the error are given by the +absolute values of the elements of the pair array @code{dp} and the +optional pair array @code{dm}. If @code{dm} is not specified, the +positive and negative extents of the error are assumed to be equal. +@anchor{errorbars} +@verbatiminclude errorbars.asy +@sp 1 +@center @image{errorbars} + +@cindex custom mark routine +@item A custom mark routine can be also be specified: +@verbatiminclude graphmarkers.asy +@sp 1 +@center @image{graphmarkers} + +@item This example shows how to label an axis with arbitrary strings. +@verbatiminclude monthaxis.asy +@sp 1 +@center @image{monthaxis} + +@item The next example draws a graph of a parametrized curve. +@cindex parametrized curve +@cindex cropping graphs +@cindex @code{xlimits} +@cindex @code{ylimits} +@cindex @code{limits} +@cindex @code{crop} +The calls to +@verbatim +xlimits(picture pic=currentpicture, real min=-infinity, + real max=infinity, bool crop=NoCrop); +@end verbatim +@noindent +and the analogous function @code{ylimits} can be uncommented +to set the respective axes limits for picture @code{pic} to the +specified @code{min} and @code{max} values. Alternatively, the function +@verbatim +void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop); +@end verbatim +can be used to limit the axes to the box having opposite vertices at +the given pairs). Existing objects in picture @code{pic} will be cropped to lie +within the given limits if @code{crop}=@code{Crop}. The function +@code{crop(picture pic)} can be used to crop a graph to the current +graph limits. +@verbatiminclude parametricgraph.asy +@sp 1 +@center @image{parametricgraph} + +@cindex scaled graph +The next example illustrates how one can extract a common axis scaling +factor. +@verbatiminclude scaledgraph.asy +@sp 1 +@center @image{scaledgraph} + +@anchor{automatic scaling} +@cindex @code{scale} +@cindex @code{Linear} +@cindex @code{Log} +@cindex automatic scaling +Axis scaling can be requested and/or automatic selection of the +axis limits can be inhibited with one of these @code{scale} routines: +@verbatim +void scale(picture pic=currentpicture, scaleT x, scaleT y); + +void scale(picture pic=currentpicture, bool xautoscale=true, + bool yautoscale=xautoscale, bool zautoscale=yautoscale); +@end verbatim + +This sets the scalings for picture @code{pic}. The @code{graph} routines +accept an optional @code{picture} argument for determining the appropriate +scalings to use; if none is given, it uses those set for +@code{currentpicture}. + +Two frequently used scaling routines +@code{Linear} and @code{Log} are predefined in @code{graph}. + +All picture coordinates (including those in paths and those given +to the @code{label} and @code{limits} functions) are always treated as linear +(post-scaled) coordinates. Use +@cindex @code{Scale} +@verbatim +pair Scale(picture pic=currentpicture, pair z); +@end verbatim +to convert a graph coordinate into a scaled picture coordinate. + +The @math{x} and @math{y} components can be individually scaled using +the analogous routines +@verbatim +real ScaleX(picture pic=currentpicture, real x); +real ScaleY(picture pic=currentpicture, real y); +@end verbatim + +The predefined scaling routines can be given two optional boolean arguments: +@code{automin=false} and @code{automax=automin}. These default to +@code{false} but can be respectively set to @code{true} to enable +automatic selection of "nice" axis minimum and maximum values. The +@code{Linear} scaling can also take as optional final arguments a +multiplicative scaling factor and intercept (e.g.@ for a depth axis, +@code{Linear(-1)} requests axis reversal). + +@cindex logarithmic graph +@cindex log-log graph +For example, to draw a log/log graph of a function, use @code{scale(Log,Log)}: +@verbatiminclude loggraph.asy +@sp 1 +@center @image{loggraph} + +@cindex grid +By extending the ticks, one can easily produce a logarithmic grid: +@verbatiminclude loggrid.asy + +@sp 1 +@center @image{loggrid} + +One can also specify custom tick locations and formats for logarithmic axes: +@verbatiminclude logticks.asy +@sp 1 +@center @image{logticks} + +@cindex @code{log2} graph +It is easy to draw logarithmic graphs with respect to other bases: +@verbatiminclude log2graph.asy +@sp 1 +@center @image{log2graph} + +@cindex broken axis +Here is an example of "broken" linear @math{x} and logarithmic +@math{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. +@verbatiminclude brokenaxis.asy +@sp 1 +@center @image{brokenaxis} + +@cindex secondary axis +@cindex @code{secondaryX} +@cindex @code{secondaryY} +@item @code{Asymptote} can draw secondary axes with the routines +@verbatim +picture secondaryX(picture primary=currentpicture, void f(picture)); +picture secondaryY(picture primary=currentpicture, void f(picture)); +@end verbatim + +In this example, @code{secondaryY} is used to draw a secondary linear +@math{y} axis against a primary logarithmic @math{y} axis: +@verbatiminclude Bode.asy +@sp 1 +@center @image{Bode} + +A secondary logarithmic @math{y} axis can be drawn like this: +@verbatiminclude secondaryaxis.asy +@sp 1 +@center @image{secondaryaxis} + +@item Here is a histogram example, which uses the @code{stats} module. +@cindex @code{axis} +@verbatiminclude histogram.asy +@sp 1 +@center @image{histogram} + +@item Here is an example of reading column data in from a file and a +least-squares fit, using the @code{stats} module. +@cindex @code{leastsquares} +@verbatiminclude leastsquares.asy +@sp 1 +@center @image{leastsquares} + +@item Here is an example that illustrates the general @code{axis} routine. +@cindex @code{axis} +@verbatiminclude generalaxis.asy +@sp 1 +@center @image{generalaxis} + +@item To draw a vector field of @code{n} arrows evenly spaced along the arclength of a path, use the routine +@cindex @code{vectorfield} +@verbatim +picture vectorfield(path vector(real), path g, int n, bool truesize=false, + pen p=currentpen, arrowbar arrow=Arrow); +@end verbatim +as illustrated in this simple example of a flow field: +@verbatiminclude flow.asy +@sp 1 +@center @image{flow} + +@item To draw a vector field of @code{nx}@math{\times}@code{ny} arrows in @code{box(a,b)}, use the routine +@cindex @code{vectorfield} +@verbatim +picture vectorfield(path vector(pair), pair a, pair b, + int nx=nmesh, int ny=nx, + bool autoscale=true, bool truesize=false, + pen p=currentpen, arrowbar arrow=Arrow); +@end verbatim +as illustrated in this example: +@verbatiminclude vectorfield.asy +@sp 1 +@center @image{vectorfield} + +@item The following scientific graphs, which illustrate many features of +@code{Asymptote}'s graphics routines, were generated from the examples +@code{diatom.asy} and @code{westnile.asy}, using the comma-separated +data in @code{diatom.csv} and @code{westnile.csv}. +@page + +@sp 1 +@center @image{diatom} +@sp 1 +@center @image{westnile,,7.5cm} +@end enumerate + +@page +@node palette +@section @code{palette} +@anchor{images} +@code{Asymptote} can also generate color density images +and palettes. The following palettes are predefined in +@code{palette.asy}: + +@table @code + +@cindex @code{Grayscale} +@item pen[] Grayscale(int NColors=256) +a grayscale palette; + +@cindex @code{Rainbow} +@item pen[] Rainbow(int NColors=32766) +a rainbow spectrum; + +@cindex @code{BWRainbow} +@item pen[] BWRainbow(int NColors=32761) +a rainbow spectrum tapering off to black/white at the ends; + +@cindex @code{BWRainbow2} +@item pen[] BWRainbow2(int NColors=32761) +a double rainbow palette tapering off to black/white at the ends, with +a linearly scaled intensity. + +@cindex @code{Wheel} +@item pen[] Wheel(int NColors=32766) +a full color wheel palette; + +@cindex @code{Gradient} +@item pen[] Gradient(int NColors=256 ... pen[] p) +a palette varying linearly over the specified array of pens, using +NColors in each interpolation interval; + +@end table + +The function @code{cmyk(pen[] Palette)} may be used to convert any +of these palettes to the @acronym{CMYK} colorspace. + +A color density plot using palette @code{palette} can be generated from +a function @code{f}(@math{x},@math{y}) and added to a picture @code{pic}: +@cindex @code{image} +@verbatim +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) +@end verbatim +The function @code{f} will be sampled at @code{nx} and @code{ny} +evenly spaced points over a rectangle defined by the points +@code{initial} and @code{final}, respecting the current graphical +scaling of @code{pic}. The color space is scaled according to the +@math{z} axis scaling (@pxref{automatic scaling}). A bounds structure +for the function values is returned: +@verbatim +struct bounds { + real min; + real max; + // Possible tick intervals: + int[] divisor; +} +@end verbatim +@noindent +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 @code{range}, which can be @code{Full}, @code{Automatic}, +or an explicit range @code{Range(real min, real max)}. +Here @code{Full} specifies a range varying from the +minimum to maximum values of the function over the sampling interval, +while @code{Automatic} selects "nice" limits. +The example @code{imagecontour.asy} illustrates how level sets +(contour lines) can be drawn on a color density plot (@pxref{contour}). + +A color density plot can also be generated from an explicit real[][] +array @code{data}: +@cindex @code{image} +@verbatim +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); +@end verbatim +@noindent +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: @math{x}, second index: @math{y}) +rather than the usual matrix convention (first index: @math{-y}, +second index: @math{x}). + +To construct an image from an array of irregularly spaced points +and an array of values @code{f} at these points, use one of the routines +@verbatim +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) +@end verbatim + +An optionally labelled palette bar may be generated with the routine +@verbatim +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); +@end verbatim +The color space of @code{palette} is taken to be over bounds @code{bounds} with +scaling given by the @math{z} scaling of @code{pic}. +The palette orientation is specified by @code{axis}, which may be one of +@code{Right}, @code{Left}, @code{Top}, or @code{Bottom}. +The bar is drawn over the rectangle from @code{initial} to @code{final}. +The argument @code{paletteticks} is a special tick type (@pxref{ticks}) +that takes the following arguments: +@verbatim +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); +@end verbatim + +The image and palette bar can be fit to a frame and added and +optionally aligned to a picture at the desired location: + +@anchor{image} +@verbatiminclude image.asy +@sp 1 +@center @image{image} + +Here is an example that uses logarithmic scaling of the function values: + +@anchor{logimage} +@verbatiminclude logimage.asy +@sp 1 +@center @image{logimage} + +One can also draw an image directly from a two-dimensional pen array: +@verbatim +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); +@end verbatim +@noindent +as illustrated in the following example: + +@anchor{penimage} +@verbatiminclude penimage.asy +@sp 1 +@center @image{penimage} + +For convenience, the module @code{palette} also defines functions +that may be used to construct a pen array from a given function and palette: +@verbatim +pen[] palette(real[] f, pen[] palette); +pen[][] palette(real[][] f, pen[] palette); +@end verbatim + +@node three +@section @code{three} +@cindex @code{three} +@cindex @code{guide3} +@cindex @code{path3} +@cindex @code{cycle} +@cindex @code{curl} +@cindex @code{tension} +@cindex @code{controls} +This module fully extends the notion of guides and paths in @code{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 @code{(x,y,z)} are used in place of pairs +@code{(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 @code{Asymptote}, +@code{MetaPost}, and @code{MetaFont} [cf.@ J. C. Bowman, Proceedings in +Applied Mathematics and Mechanics, 7:1, 2010021-2010022 (2007)]. + +For example, a unit circle in the @math{XY} plane may be filled and +drawn like this: +@verbatiminclude unitcircle3.asy +@sp 1 +@center @image{unitcircle3} +@noindent +and then distorted into a saddle: +@verbatiminclude saddle.asy +@sp 1 +@center @image{saddle} +@noindent + +Module @code{three} provides constructors for converting two-dimensional +paths to three-dimensional ones, and vice-versa: +@cindex @code{path3} +@cindex @code{path} +@verbatim +path3 path3(path p, triple plane(pair)=XYplane); +path path(path3 p, pair P(triple)=xypart); +@end verbatim + +@cindex @code{surface} +A Bezier surface, the natural two-dimensional generalization of Bezier +curves, is defined in @code{three_surface.asy} as a structure +containing an array of Bezier patches. Surfaces may drawn with one of +the routines +@verbatim +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); +@end verbatim +The parameters @code{nu} and @code{nv} specify the number of subdivisions +for drawing optional mesh lines for each Bezier patch. +Here material is a structure defined in @code{three_light.asy}: +@verbatim +struct material { + pen[] p; // diffusepen,ambientpen,emissivepen,specularpen + real opacity; + real shininess; + real granularity; +... +} +@end verbatim +@noindent +These material properties are used to implement @code{OpenGL}-style lighting, +based on the Phong-Blinn specular model. Sample Bezier surfaces are +contained in the example files @code{BezierSurface.asy}, @code{teapot.asy}, +and @code{parametricsurface.asy}. + +@cindex patch-dependent colors +@cindex vertex-dependent colors +The examples +@code{elevation.asy} and @code{sphericalharmonic.asy} +illustrate how to draw a surface with patch-dependent colors. +The examples @code{vertexshading} and @code{smoothelevation} illustrate +vertex-dependent colors, which is supported for both +@code{Asymptote}'s native @code{OpenGL} renderer and two-dimensional +projections. Since the @acronym{PRC} output format does not currently support +vertex shading of Bezier surfaces, @acronym{PRC} patches are shaded +with the mean of the four vertex colors. + +@cindex @code{surface} +@cindex @code{planar} +A surface can be constructed from a cyclic @code{path3} with the constructor +@verbatim +surface surface(path3 external, triple[] internal=new triple[], + triple[] normals=new triple[], pen[] colors=new pen[], + bool3 planar=default); +@end verbatim +@noindent +and then filled: +@verbatim +draw(surface(path3(polygon(5))),red); +draw(surface(unitcircle3),red); +draw(surface(unitcircle3,new pen[] {red,green,blue,black})); +@end verbatim +@noindent +The last example constructs a patch with vertex-specific colors. +A three-dimensional planar surface in the plane @code{plane} can be +constructed from a two-dimensional cyclic path @code{g} with the constructor +@cindex @code{surface} +@verbatim +surface surface(path p, triple plane(pair)=XYplane); +@end verbatim +@noindent +and then filled: +@verbatim +draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red); +@end verbatim +@noindent +@cindex @code{bezulate} +Planar Bezier surfaces patches are constructed using Orest Shardt's +@code{bezulate} routine, which decomposes (possibly nonsimply +connected) regions bounded by nonselfintersecting cyclic paths +(according to the @code{zerowinding} fill rule) into subregions +bounded by cyclic paths of length @code{4} or less. + +@cindex @code{thin} +@cindex @code{thick} +@cindex @code{tube} +Arbitrary thick three-dimensional curves and line caps (which the +@code{OpenGL} standard does not require implementations to provide) are +constructed with the routine +@verbatim +surface tube(path3 g, real width); +@end verbatim +@noindent +which returns a tube of diameter @code{width} centered on @code{g}. +This can make files slow to render, +especially with the @code{Adobe Reader} renderer. The setting +@code{thick=false} can be used to disable this feature and force all +lines to be drawn with @code{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 @code{thin} is set to @code{false}. The pens +@code{thin()} and @code{thick()} defined in plain_pens.asy can also be used +to override these defaults for specific draw commands. + +@noindent +There are four choices for viewing 3D @code{Asymptote} output: +@enumerate +@cindex @code{OpenGL} +@cindex @code{render} +@cindex @code{outformat} +@cindex @code{multisample} +@item Use the native @code{Asymptote} adaptive @code{OpenGL}-based +renderer (with the command-line option @code{-V} and the default settings +@code{outformat=""} and @code{render=-1}). If you encounter warnings +from your graphics card driver, try specifying @code{-glOptions=-indirect} +on the command line. On @code{UNIX} systems with graphics support for +multisampling, we recommend installing the latest SVN (antialiased) +version of the @code{freeglut} library +(@pxref{multisampling}); the sample width can be +controlled with the setting @code{multisample}. An initial screen +position can be specified with the pair setting @code{position}, where +negative values are interpreted as relative to the corresponding +maximum screen dimension. The mouse bindings are: +@cindex mouse bindings +@itemize +@item Left: rotate +@item shift Left: zoom +@item ctrl Left: shift +@item Middle: menu +@item Wheel: zoom +@item Right: zoom +@item Right double click: menu +@item shift Right: rotate about the X axis +@item ctrl Right: rotate about the Y axis +@item alt Right: rotate about the Z axis +@end itemize +The keyboard shortcuts are: +@cindex keyboard bindings: +@itemize +@item h: home +@item f: toggle fitscreen +@item x: spin about the X axis +@item y: spin about the Y axis +@item z: spin about the Z axis +@item s: stop spinning +@item m: rendering mode (solid/mesh/patch) +@item e: export +@item c: show camera parameters +@item +: expand +@item =: expand +@item -: shrink +@item _: shrink +@item q: exit +@item Ctrl-q: exit +@end itemize + +@cindex @code{antialias} +@cindex @code{maxviewport} +@cindex @code{maxtile} +@cindex @code{glOptions} +@cindex @code{iconic} +@item Render the scene to a specified rasterized format @code{outformat} +at the resolution of @code{n} pixels per @code{bp}, as specified by the +setting @code{render=n}. A negative value of @code{n} is interpreted +as @code{|2n|} for @acronym{EPS} and @acronym{PDF} formats and +@code{|n|} for other formats. The default value of @code{render} is -1. +By default, the scene is internally rendered at twice the specified +resolution; this can be disabled by setting @code{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 @code{maxtile} beyond the screen +dimensions (indicated by @code{maxtile=(0,0)}. The tile size is also +limited by the setting @code{maxviewport}, which restricts the maximum +width and height of the viewport. On @code{UNIX} systems some graphics +drivers support batch mode (@code{-noV}) rendering in an +iconified window; this can be enabled with the setting @code{iconify=true}. +Other @code{UNIX} graphics drivers may require the command line setting +@code{-glOptions=-indirect}. + +@cindex @code{prc} +@cindex @code{views} +@item Embed the 3D @acronym{PRC} format in a @acronym{PDF} file +and view the resulting @acronym{PDF} file with +version @code{8.0} or later of @code{Adobe Reader}. +In addition to the default @code{settings.prc=true}, this requires +@code{settings.outformat="pdf"}, which can be specified by the command +line option @code{-f pdf}, put in the @code{Asymptote} configuration +file (@pxref{configuration file}), or specified in the script before +@code{three.asy} (or @code{graph3.asy}) is imported. +Version 2008/10/08 or later of the @code{movie15} package is also +required (@pxref{embed}). The example @code{pdb.asy} illustrates +how one can generate a list of predefined views (see @code{100d.views}). +A stationary preview image with a resolution of @code{n} pixels per +@code{bp} can be embedded with the setting @code{render=n}; this allows +the file to be viewed with other @code{PDF} viewers. Alternatively, the +file @code{externalprc.tex} illustrates how the resulting @acronym{PRC} and +rendered image files can be extracted and processed in a separate +@code{LaTeX} file. However, see @ref{LaTeX usage} for an easier way +to embed three-dimensional @code{Asymptote} pictures within @code{LaTeX}. +The open-source @acronym{PRC} specification is available from +@url{http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/}. + +@item Project the scene to a two-dimensional vector (@acronym{EPS} or +@acronym{PDF}) format with @code{render=0}. Only limited hidden surface +removal facilities are currently available with this approach +(@pxref{PostScript3D}). + +@end enumerate + +@cindex @code{double deferred drawing} +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 +@cindex @code{size3} +@verbatim +void size3(picture pic=currentpicture, real x, real y=x, real z=y, + bool keepAspect=pic.keepAspect); +@end verbatim +@noindent +@cindex margins +@cindex @code{viewportmargin} +@cindex @code{viewportsize} +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 @code{size} parameters. The global pair @code{viewportmargin} +may be used to add horizontal and vertical margins to the viewport +dimensions. Alternatively, a minimum @code{viewportsize} may be specified. + +@cindex @code{O} +@cindex @code{X} +@cindex @code{Y} +@cindex @code{Z} +@cindex @code{unitcircle} +For convenience, the @code{three} module defines @code{O=(0,0,0)}, +@code{X=(1,0,0)}, @code{Y=(0,1,0)}, and @code{Z=(0,0,1)}, along with a +unitcircle in the XY plane: +@verbatim +path3 unitcircle3=X..Y..-X..-Y..cycle; +@end verbatim + +@cindex @code{circle} +A general (approximate) circle can be drawn perpendicular to the direction +@code{normal} with the routine +@verbatim +path3 circle(triple c, real r, triple normal=Z); +@end verbatim + +@cindex @code{arc} +A circular arc centered at @code{c} with radius @code{r} from +@code{c+r*dir(theta1,phi1)} to @code{c+r*dir(theta2,phi2)}, +drawing counterclockwise relative to the normal vector +@code{cross(dir(theta1,phi1),dir(theta2,phi2))} if @code{theta2 > theta1} +or if @code{theta2 == theta1} and @code{phi2 >= phi1}, can be constructed with +@verbatim +path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, + triple normal=O); +@end verbatim +The normal must be explicitly specified if @code{c} and the endpoints +are colinear. If @code{r} < 0, the complementary arc of radius +@code{|r|} is constructed. +For convenience, an arc centered at @code{c} from triple @code{v1} to +@code{v2} (assuming @code{|v2-c|=|v1-c|}) in the direction CCW +(counter-clockwise) or CW (clockwise) may also be constructed with +@verbatim +path3 arc(triple c, triple v1, triple v2, triple normal=O, + bool direction=CCW); +@end verbatim +@noindent +When high accuracy is needed, the routines @code{Circle} and +@code{Arc} defined in @code{graph3} may be used instead. +See @ref{GaussianSurface} for an example of a three-dimensional circular arc. + +@cindex @code{plane} +The representation @code{O--O+u--O+u+v--O+v--cycle} +of the plane passing through point @code{O} with normal +@code{cross(u,v)} is returned by +@verbatim +path3 plane(triple u, triple v, triple O=O); +@end verbatim +A three-dimensional box with opposite vertices at triples @code{v1} +and @code{v2} may be drawn with the function +@cindex @code{box} +@verbatim +path3[] box(triple v1, triple v2); +@end verbatim +@noindent +For example, a unit box is predefined as +@cindex @code{box} +@cindex @code{unitbox} +@verbatim +path3[] unitbox=box(O,(1,1,1)); +@end verbatim +@code{Asymptote} also provides optimized definitions for the +three-dimensional paths @code{unitsquare3} and @code{unitcircle3}, +along with the surfaces @code{unitdisk}, @code{unitplane}, @code{unitcube}, +@code{unitcylinder}, @code{unitcone}, @code{unitsolidcone}, +@code{unitfrustum(real t1, real t2)}, @code{unitsphere}, and +@code{unithemisphere}. + +@noindent +These projections to two dimensions are predefined: +@table @code +@item oblique +@item oblique(real angle); +@cindex @code{oblique} +@cindex @code{obliqueZ} +The point @code{(x,y,z)} is projected to @code{(x-0.5z,y-0.5z)}. +If an optional real argument is given, the +negative @math{z} axis is drawn at this angle in degrees. +The projection @code{obliqueZ} is a synonym for @code{oblique}. + +@item obliqueX +@item obliqueX(real angle) +@cindex @code{obliqueX} +The point @code{(x,y,z)} is projected to @code{(y-0.5x,z-0.5x)}. +If an optional real argument is given, the +negative @math{x} axis is drawn at this angle in degrees. + +@item obliqueY +@item obliqueY(real angle) +@cindex @code{obliqueY} +The point @code{(x,y,z)} is projected to @code{(x+0.5y,z+0.5y)}. +If an optional real argument is given, the +positive @math{y} axis is drawn at this angle in degrees. + +@cindex @code{orthographic} +@cindex @code{up} +@cindex @code{target} +@cindex @code{showtarget} +@cindex @code{autoadjust} +@cindex @code{center} +@item orthographic(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=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 @code{unit(camera)}, orienting the camera +so that, if possible, the vector @code{up} points upwards. Parallel +lines are projected to parallel lines. The bounding volume is expanded +to include @code{target} if @code{showtarget=true}. If @code{autoadjust=true}, +the camera will automatically be adjusted to lie outside the bounding volume +for all possible interactive rotations about @code{target}. +If @code{center=true}, the target will be adjusted to the center of the +bounding volume. + +@item orthographic(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false) +This is equivalent to +@code{orthographic((x,y,z),up,target,showtarget,autoadjust, +center)}. + +@item perspective(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false) +@cindex @code{perspective} +@cindex @code{NURBS} +This projects from three to two dimensions, taking account of +perspective, as seen from the location @code{camera} looking at @code{target}, +orienting the camera so that, if possible, the vector @code{up} points upwards. +If @code{render=0}, projection of three-dimensional cubic Bezier splines +is implemented by approximating a two-dimensional nonuniform rational B-spline +(@acronym{NURBS}) with a two-dimensional Bezier curve containing +additional nodes and control points. If @code{autoadjust=true}, +the camera will automatically be adjusted to lie outside the bounding volume +for all possible interactive rotations about @code{target}. +If @code{center=true}, the target will be adjusted to the center of the +bounding volume. + +@item perspective(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false) +This is equivalent to @code{perspective((x,y,z),up,target,showtarget, +autoadjust,center)}. +@end table + +@cindex @code{currentprojection} +@noindent +The default projection, @code{currentprojection}, is initially set to +@code{perspective(5,4,2)}. + +A triple or path3 can be projected to a pair or path, +with @code{project(triple, projection P=currentprojection)} or +@code{project(path3, projection P=currentprojection)}. + +It is occasionally useful to be able to invert a projection, sending +a pair @code{z} onto the plane perpendicular to @code{normal} and passing +through @code{point}: +@cindex @code{invert} +@verbatim +triple invert(pair z, triple normal, triple point, + projection P=currentprojection); +@end verbatim +@noindent +A pair @code{z} on the projection plane can be inverted to a triple +with the routine +@verbatim +triple invert(pair z, projection P=currentprojection); +@end verbatim +@noindent +A pair direction @code{dir} on the projection plane can be inverted to +a triple direction relative to a point @code{v} with the routine +@verbatim +triple invert(pair dir, triple v, projection P=currentprojection). +@end verbatim + +@cindex @code{transform3} +Three-dimensional objects may be transformed with one of the following +built-in transform3 types: + +@table @code +@item shift(triple v) +@cindex @code{shift} +translates by the triple @code{v}; +@item xscale3(real x) +@cindex @code{xscale3} +scales by @code{x} in the @math{x} direction; +@item yscale3(real y) +@cindex @code{yscale3} +scales by @code{y} in the @math{y} direction; +@item zscale3(real z) +@cindex @code{zscale3} +scales by @code{z} in the @math{z} direction; +@item scale3(real s) +@cindex @code{scale3} +scales by @code{s} in the @math{x}, @math{y}, and @math{z} directions; +@item scale(real x, real y, real z) +@cindex @code{scale} +scales by @code{x} in the @math{x} direction, +by @code{y} in the @math{y} direction, and by @code{z} in the @math{z} +direction; +@item rotate(real angle, triple v) +rotates by @code{angle} in degrees about an axis @code{v} through the origin; +@item rotate(real angle, triple u, triple v) +rotates by @code{angle} in degrees about the axis @code{u--v}; +@item reflect(triple u, triple v, triple w) +reflects about the plane through @code{u}, @code{v}, and @code{w}. +@end table + +@cindex @code{transform} +Three-dimensional @TeX{} Labels, which are by default drawn as +Bezier surfaces directly on the projection plane, can be transformed +from the @code{XY} plane by any of the above transforms or mapped to a +specified two-dimensional plane with the transform3 types @code{XY}, +@code{YZ}, @code{ZX}, @code{YX}, @code{ZY}, @code{ZX}. There are also +modified versions of these transforms that take an optional argument +@code{projection P=currentprojection} that rotate and/or flip the +label so that it is more readable from the initial viewpoint. + +@cindex @code{planeproject} +A transform3 that projects in the direction @code{dir} onto the plane +with normal @code{n} through point @code{O} is returned by +@verbatim +transform3 planeproject(triple n, triple O=O, triple dir=n); +@end verbatim +@noindent +One can use +@cindex @code{normal} +@verbatim +triple normal(path3 p); +@end verbatim +@noindent +to find the unit normal vector to a planar three-dimensional path @code{p}. +As illustrated in the example @code{planeproject.asy}, a transform3 +that projects in the direction @code{dir} onto the plane defined by a +planar path @code{p} is returned by +@verbatim +transform3 planeproject(path3 p, triple dir=normal(p)); +@end verbatim + +The functions +@cindex @code{extrude} +@verbatim +surface extrude(path p, triple axis=Z); +surface extrude(Label L, triple axis=Z); +@end verbatim +@noindent +return the surface obtained by extruding path @code{p} or +Label @code{L} along @code{axis}. + +@cindex @code{length} +@cindex @code{size} +@cindex @code{point} +@cindex @code{dir} +@cindex @code{accel} +@cindex @code{radius} +@cindex @code{precontrol} +@cindex @code{postcontrol} +@cindex @code{arclength} +@cindex @code{arctime} +@cindex @code{reverse} +@cindex @code{subpath} +@cindex @code{intersect} +@cindex @code{intersections} +@cindex @code{intersectionpoint} +@cindex @code{intersectionpoints} +@cindex @code{min} +@cindex @code{max} +@cindex @code{cyclic} +@cindex @code{straight} +Three-dimensional versions of the path functions @code{length}, +@code{size}, @code{point}, @code{dir}, @code{accel}, @code{radius}, +@code{precontrol}, @code{postcontrol}, +@code{arclength}, @code{arctime}, @code{reverse}, @code{subpath}, +@code{intersect}, @code{intersections}, @code{intersectionpoint}, +@code{intersectionpoints}, @code{min}, @code{max}, @code{cyclic}, and +@code{straight} are also defined. + +Here is an example showing all five guide3 connectors: +@verbatiminclude join3.asy +@sp 1 +@center @image{join3} + +@cindex @code{BeginBar3} +@cindex @code{EndBar3} +@cindex @code{Bar3} +@cindex @code{Bars3} +@cindex @code{BeginArrow3} +@cindex @code{MidArrow3} +@cindex @code{EndArrow3} +@cindex @code{Arrow3} +@cindex @code{Arrows3} +@cindex @code{BeginArcArrow3} +@cindex @code{MidArcArrow3} +@cindex @code{EndArcArrow3} +@cindex @code{ArcArrow3} +@cindex @code{ArcArrows3} +@cindex @code{DefaultHead3} +@cindex @code{HookHead3} +@cindex @code{TeXHead3} +Three-dimensional versions of bars or arrows can be drawn with one of +the specifiers @code{None}, @code{Blank}, +@code{BeginBar3}, @code{EndBar3} (or equivalently @code{Bar3}), @code{Bars3}, +@code{BeginArrow3}, @code{MidArrow3}, +@code{EndArrow3} (or equivalently @code{Arrow3}), @code{Arrows3}, +@code{BeginArcArrow3}, @code{EndArcArrow3} (or equivalently +@code{ArcArrow3}), @code{MidArcArrow3}, and @code{ArcArrows3}. +Three-dimensional bars accept the optional arguments @code{(real size=0, +triple dir=O)}. If @code{size=O}, the default bar length is used; if +@code{dir=O}, the bar is drawn perpendicular to the path +and the initial viewing direction. The predefined three-dimensional +arrowhead styles are @code{DefaultHead3}, @code{HookHead3}, @code{TeXHead3}. +Versions of the two-dimensional arrowheads lifted to three-dimensional +space and aligned according to the initial viewpoint (or an optionally +specified @code{normal} vector) are also defined: +@code{DefaultHead2(triple normal=O)}, @code{HookHead2(triple normal=O)}, +@code{TeXHead2(triple normal=O)}. These are illustrated in the example +@code{arrows3.asy}. + +@cindex @code{NoMargin3} +@cindex @code{BeginMargin3} +@cindex @code{EndMargin3} +@cindex @code{Margin3} +@cindex @code{Margins3} +@cindex @code{BeginPenMargin2} +@cindex @code{EndPenMargin2} +@cindex @code{PenMargin2} +@cindex @code{PenMargins2} +@cindex @code{BeginPenMargin3} +@cindex @code{EndPenMargin3} +@cindex @code{PenMargin3} +@cindex @code{PenMargins3} +@cindex @code{BeginDotMargin3} +@cindex @code{EndDotMargin3} +@cindex @code{DotMargin3} +@cindex @code{DotMargins3} +@cindex @code{Margin3} +@cindex @code{TrueMargin3} +Module @code{three} also defines the three-dimensional margins +@code{NoMargin3}, @code{BeginMargin3}, @code{EndMargin3}, +@code{Margin3}, @code{Margins3}, +@code{BeginPenMargin2}, @code{EndPenMargin2}, @code{PenMargin2}, +@code{PenMargins2}, +@code{BeginPenMargin3}, @code{EndPenMargin3}, @code{PenMargin3}, +@code{PenMargins3}, +@code{BeginDotMargin3}, @code{EndDotMargin3}, @code{DotMargin3}, +@code{DotMargins3}, @code{Margin3}, and @code{TrueMargin3}. + +Further three-dimensional examples are provided in the files +@code{near_earth.asy}, @code{conicurv.asy}, and (in the @code{animations} +subdirectory) @code{cube.asy}. + +@anchor{PostScript3D} +Limited support for projected vector graphics (effectively three-dimensional +nonrendered @code{PostScript}) is available with the setting +@code{render=0}. This currently only works for piecewise planar +surfaces, such as those produced by the parametric @code{surface} +routines in the @code{graph3} module. Surfaces produced by the +@code{solids} package will also be properly rendered if the parameter +@code{nslices} is sufficiently large. + +@cindex hidden surface removal +@cindex @code{face} +In the module @code{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 @code{face} derived from +@code{picture}. A @code{face} may be given to a two-dimensional drawing +routine in place of any @code{picture} argument. An array of such faces +may then be drawn, removing hidden surfaces: +@verbatim +void add(picture pic=currentpicture, face[] faces, + projection P=currentprojection); +@end verbatim +Labels may be projected to two dimensions, using projection @code{P}, +onto the plane passing through point @code{O} with normal +@code{cross(u,v)} by multiplying it on the left by the transform +@verbatim +transform transform(triple u, triple v, triple O=O, + projection P=currentprojection); +@end verbatim + +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: +@verbatiminclude planes.asy +@sp 1 +@center @image{planes} + +@node obj +@section @code{obj} +@cindex @code{obj} +This module allows one to construct surfaces from simple obj files, +as illustrated in the example files @code{galleon.asy} and +@code{triceratops.asy}. + +@node graph3 +@section @code{graph3} +@cindex @code{graph3} +@cindex 3D graphs +This module implements three-dimensional versions of the +functions in @code{graph.asy}. +@cindex @code{xaxis} +@cindex @code{yaxis} +@cindex @code{zaxis} +@noindent +To draw an @math{x} axis in three dimensions, use the routine +@verbatim +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); +@end verbatim +@noindent +Analogous routines @code{yaxis} and @code{zaxis} can be used to draw +@math{y} and @math{z} axes in three dimensions. +There is also a routine for drawing all three axis: +@verbatim +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); +@end verbatim + +@cindex @code{YZEquals} +@cindex @code{XZEquals} +@cindex @code{XYEquals} +@cindex @code{YZZero} +@cindex @code{XZZero} +@cindex @code{XYZero} +@cindex @code{Bounds} +@noindent +The predefined three-dimensional axis types are +@verbatim +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); +@end verbatim +@noindent +The optional @code{align} parameter to these routines can be used to +specify the default axis and tick label alignments. The @code{Bounds} +axis accepts two type parameters, each of which must be one of +@code{Min}, @code{Max}, or @code{Both}. These parameters specify which +of the four possible three-dimensional bounding box edges should be drawn. + +@cindex @code{NoTicks3} +@cindex @code{InTicks} +@cindex @code{OutTicks} +@cindex @code{InOutTicks} +The three-dimensional tick options are @code{NoTicks3}, @code{InTicks}, +@code{OutTicks}, and @code{InOutTicks}. These specify the tick +directions for the @code{Bounds} axis type; other axis types inherit +the direction that would be used for the @code{Bounds(Min,Min)} axis. + +Here is an example of a helix and bounding box axes with ticks +and axis labels, using orthographic projection: +@verbatiminclude helix.asy +@sp 1 +@center @image{helix} + +The next example illustrates three-dimensional @math{x}, @math{y}, and +@math{z} axes, without autoscaling of the axis limits: +@cindex @code{axis} +@verbatiminclude axis3.asy +@sp 1 +@center @image{axis3} + +One can also place ticks along a general three-dimensional axis: +@cindex @code{axis} +@verbatiminclude generalaxis3.asy +@sp 1 +@center @image{generalaxis3} + +Surface plots of matrices and functions over the region +@code{box(a,b)} in the @math{XY} plane are also implemented: +@verbatim +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); +@end verbatim +@noindent +The final version draws a parametric surface for a function +@math{f(u,v)} over the parameter space @code{box(a,b)}, +as illustrated in the example @code{parametricsurface.asy}. +The boolean array or function @code{cond} can be used to control which +surface mesh cells are actually drawn (by default all mesh cells over +@code{box(a,b)} are drawn). +Surface lighting is illustrated in the example files +@code{parametricsurface.asy} and @code{sinc.asy}. +Lighting can be disabled by setting @code{light=nolight}, as in this example +of a Gaussian surface: +@anchor{GaussianSurface} +@verbatiminclude GaussianSurface.asy +@sp 1 +@center @image{GaussianSurface} +@noindent +A mesh can be drawn without surface filling by specifying @code{nullpen} +for the surfacepen. + +@node grid3 +@section @code{grid3} +@cindex @code{grid3} +@cindex 3D grids + +This module, contributed by Philippe Ivaldi, can be used for drawing +3D grids. Here is an example (further examples can be found in +@code{grid3.asy} and at @url{http://piprim.tuxfamily.org/asymptote/grid3/}): +@verbatiminclude grid3xyz.asy +@sp 1 +@center @image{grid3xyz} + +@node solids +@section @code{solids} +@cindex @code{solids} +This solid geometry package defines a structure @code{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 @code{O--1.5unit(Y+Z)} with perspective projection: +@verbatiminclude cylinderskeleton.asy +@sp 1 +@center @image{cylinderskeleton} + +Further illustrations are provided in the example files @code{cylinder.asy}, +@code{cones.asy}, @code{hyperboloid.asy}, and @code{torus.asy}. + +The structure @code{skeleton} contains the three-dimensional wireframe +used to visualize a volume of revolution: +@verbatim +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; +} +@end verbatim + +@node tube +@section @code{tube} +@cindex @code{tube} +This package extends the routine @code{tube} defined in @code{three_arrows.asy} +to arbitrary cross sections, colors, and spine transformations. +The routine +@verbatim +surface tube(path3 g, coloredpath section, + transform T(real)=new transform(real t) {return identity();}, + real corner=1, real relstep=0); +@end verbatim +@noindent +draws a tube along @code{g} with cross section @code{section}, after +applying the transformation @code{T(t)} at @code{relpoint(g,t)}. +The parameter @code{corner} controls the number of elementary tubes at +the angular points of @code{g}. A nonzero value of @code{relstep} +specifies a fixed relative time step (in the sense of +@code{relpoint(g,t)}) to use in constructing elementary tubes along @code{g}. +The type @code{coloredpath} is a generalization of @code{path} to +which a @code{path} can be cast: +@cindex @code{coloredpath} +@verbatim +struct coloredpath +{ + path p; + pen[] pens(real); + int colortype=coloredSegments; +} +@end verbatim +@noindent +@cindex @code{coloredSegments} +@cindex @code{coloredNodes} +Here @code{p} defines the cross section and +the method @code{pens(real t)} returns an array of pens (interpreted +as a cyclic array) used for shading the tube patches at +@code{relpoint(g,t)}. If @code{colortype=coloredSegments}, the tube patches +are filled as if each segment of the section was colored with the pen +returned by @code{pens(t)}, whereas if @code{colortype=coloredNodes}, the +tube components are vertex shaded as if the nodes of the section were colored. + +A @code{coloredpath} can be constructed with one of the routines: +@verbatim +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)); +@end verbatim +@noindent +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 @code{path} to @code{coloredpath} allows the +use of a @code{path} instead of a @code{coloredpath}; in this case the +shading behaviour is the default shading behavior for a surface. + +An example of @code{tube} is provided in the file +@code{trefoilknot.asy}. Further examples can be found at +@url{http://piprim.tuxfamily.org/asymptote/tube/}. + +@node flowchart +@section @code{flowchart} +@cindex @code{flowchart} +This package provides routines for drawing flowcharts. The primary +structure is a @code{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 @code{t}: + +@verbatim +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()); +@end verbatim +@cindex @code{block.top} +@cindex @code{block.left} +@cindex @code{block.right} +@cindex @code{block.bottom} +@cindex @code{block.topleft} +@cindex @code{block.topright} +@cindex @code{block.bottomleft} +@cindex @code{block.bottomright} + +@noindent +To obtain an arbitrary position along the boundary of the block in user +coordinates, use: +@verbatim +pair block.position(real x, transform t=identity()); +@end verbatim +@cindex @code{block.position} + +@noindent +@cindex @code{block.center} +The center of the block in user coordinates is stored in +@code{block.center} and the block size in @code{PostScript} coordinates +is given by @code{block.size}. + +@noindent +A frame containing the block is returned by +@verbatim +frame block.draw(pen p=currentpen); +@end verbatim +@cindex @code{block.draw} + +The following block generation routines accept a Label, string, or +frame for their object argument: + +@table @dfn +@item rectangular block with an optional header (and padding @code{dx} around header and body): +@cindex @code{rectangle} +@verbatim +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); +@end verbatim + +@item diamond-shaped flowchart block: +@cindex @code{diamond} +@verbatim +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); +@end verbatim + +@item circular flowchart block: +@cindex @code{circle} +@verbatim +block circle(object body, pair center=(0,0), pen fillpen=invisible, + pen drawpen=currentpen, real dr=3, + real mindiameter=mincirclediameter); +@end verbatim + +@item rectangular flowchart block with rounded corners: +@cindex @code{roundrectangle} +@verbatim +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); +@end verbatim + +@item rectangular flowchart block with beveled edges: +@cindex @code{bevel} +@verbatim +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); +@end verbatim + +@end table + +To draw paths joining the pairs in @code{point} with right-angled lines, +use the routine: +@cindex @code{path} +@cindex @code{Horizontal} +@cindex @code{Vertical} +@verbatim +path path(pair point[] ... flowdir dir[]); +@end verbatim +@noindent +The entries in @code{dir} identify whether successive +segments between the pairs specified by @code{point} should be drawn +in the @code{Horizontal} or @code{Vertical} direction. + +Here is a simple flowchart example: + +@verbatiminclude flowchartdemo.asy +@sp 1 +@center @image{flowchartdemo} + +@node contour +@section @code{contour} +@cindex @code{contour} +This package draws contour lines. +To construct contours corresponding to the values in an array @code{c} +for a function @code{f} on @code{box(a,b)}, use +@verbatim +guide[][] contour(real f(real, real), pair a, pair b, + real[] c, int nx=ngraph, int ny=nx, + interpolate join=operator --); +@end verbatim +@noindent +The integers @code{nx} and @code{ny} define the resolution. +The default resolution, @code{ngraph x ngraph} (here @code{ngraph} +defaults to @code{100}), can be increased for greater accuracy. The +default interpolation operator is @code{operator --} (linear). Spline +interpolation (@code{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 @code{box(a,b)}, use +@verbatim +guide[][] contour(real[][] f, real[][] midpoint=new real[][], + pair a, pair b, real[] c, + interpolate join=operator --); +@end verbatim + +To construct contours for an array of data values on a nonoverlapping +regular mesh specified by the two-dimensional array @code{z}, optionally +specifying the values of @code{f} at the mesh midpoints, use +@verbatim +guide[][] contour(pair[][] z, real[][] f, + real[][] midpoint=new real[][], real[] c, + interpolate join=operator --); + +@end verbatim +@noindent +To construct contours for an array of values @code{f} specified at +irregularly positioned points @code{z}, use the routine +@verbatim +guide[][] contour(pair[] z, real[] f, real[] c, + interpolate join=operator --); +@end verbatim +@noindent +The contours themselves can be drawn with one of the routines +@verbatim +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) +@end verbatim + +The following simple example draws the contour at value @code{1} +for the function @math{z=x^2+y^2}, which is a unit circle: +@verbatiminclude onecontour.asy +@sp 1 +@center @image{onecontour} + +The next example draws and labels multiple contours for the function +@math{z=x^2-y^2} with the resolution @code{100 x 100}, using a dashed +pen for negative contours and a solid pen for positive (and zero) contours: +@verbatiminclude multicontour.asy +@sp 1 +@center @image{multicontour} + +The next example illustrates how contour lines can be drawn on color +density images: +@verbatiminclude imagecontour.asy +@sp 1 +@center @image{imagecontour} + +Finally, here is an example that illustrates the construction of contours +from irregularly spaced data: +@verbatiminclude irregularcontour.asy +@sp 1 +@center @image{irregularcontour} + +In the above example, the contours of irregularly spaced data are constructed by +first creating a triangular mesh from an array @code{z} of pairs: + +@cindex @code{triangulate} +@verbatim +int[][] triangulate(pair[] z); +@end verbatim + +@verbatiminclude triangulate.asy +@sp 1 +@center @image{triangulate} + +The example @code{Gouraudcontour} illustrates how to produce color +density images over such irregular triangular meshes. +@code{Asymptote} uses a robust version of Paul Bourke's Delaunay triangulation +algorithm based on the public-domain exact arithmetic predicates written by +Jonathan Shewchuk. + +@node contour3 +@section @code{contour3} +@cindex @code{contour3} +This package draws surfaces described as the null space of real-valued +functions of @math{(x,y,z)} or real[][][] matrices. +Its usage is illustrated in the example file @code{magnetic.asy}. + +@node slopefield +@section @code{slopefield} +@cindex @code{slopefield} +To draw a slope field for the differential equation @math{dy/dx=f(x,y)} (or +@math{dy/dx=f(x)}), use: +@verbatim +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); +@end verbatim +@noindent +Here, the points @code{a} and @code{b} are the lower left and upper +right corners of the rectangle in which the slope field is to be drawn, +@code{nx} and @code{ny} are the respective number of ticks in the +@math{x} and @math{y} directions, @code{tickfactor} is the fraction of +the minimum cell dimension to use for drawing ticks, and @code{p} is +the pen to use for drawing the slope fields. +The return value is a picture that can be added to +@code{currentpicture} via the @code{add(picture)} command. + +The function +@cindex @code{curve} +@verbatim +path curve(pair c, real f(real,real), pair a, pair b); +@end verbatim +@noindent +takes a point (@code{c}) and a slope field-defining function @code{f} +and returns, as a path, the curve passing through that point. The points +@code{a} and @code{b} represent the rectangular boundaries over which +the curve is interpolated. + +Both @code{slopefield} and @code{curve} alternatively accept a function +@code{real f(real)} that depends on @math{x} only, as seen in this example: + +@verbatiminclude slopefield1.asy +@sp 1 +@center @image{slopefield1} + +@node Options +@chapter Options +@cindex options +@cindex command-line options +Type @code{asy -h} to see the full list of command-line options +supported by @code{Asymptote}: +@verbatiminclude options + +All boolean options can be negated by prepending @code{no} to the option name. + +If no arguments are given, @code{Asymptote} runs in interactive mode +(@pxref{Interactive mode}). In this case, the default output file +is @code{out.eps}. + +If @code{-} is given as the file argument, @code{Asymptote} reads from +standard input. + +If multiple files are specified, they are treated as separate +@code{Asymptote} runs. + +@cindex @code{autoimport} +If the string @code{autoimport} is nonempty, a module with this name is +automatically imported for each run as the final step in loading module +@code{plain}. + +@anchor{configuration file} +@cindex @code{ASYMPTOTE_CONFIG} +@cindex @code{config} +@cindex @code{settings} +@anchor{settings} +Default option values may be entered as @code{Asymptote} code in a +configuration file named @code{config.asy} (or the file specified by +the environment variable @code{ASYMPTOTE_CONFIG} or @code{-config} option). +@code{Asymptote} will look for this file in its usual search path. +Typically the configuration file is placed in the +@code{.asy} directory in the user's home directory +(@code{%USERPROFILE%\.asy} under @code{MSDOS}). +Configuration variables are accessed using the long form of the option names: +@verbatim +import settings; +outformat="pdf"; +batchView=false; +interactiveView=true; +batchMask=false; +interactiveMask=true; +@end verbatim +Command-line options override these defaults. Most configuration +variables may also be changed at runtime. +@cindex @code{dvipsOptions} +@cindex @code{convertOptions} +@cindex @code{gsOptions} +@cindex @code{psviewerOptions} +@cindex @code{pdfviewerOptions} +@cindex @code{glOptions} +The advanced configuration variables @code{dvipsOptions}, @code{convertOptions}, +@code{gsOptions}, @code{psviewerOptions}, @code{pdfviewerOptions}, and +@code{glOptions} allow specialized options to be passed as a string to +the respective applications or libraries. + +If you insert +@verbatim +import plain; +settings.autoplain=true; +@end verbatim +@noindent +at the beginning of the configuration file, it can contain arbitrary +@code{Asymptote} code. + +@cindex @code{convert} +@cindex @code{output} +@cindex @code{format} +@cindex @code{ImageMagick} +@cindex @code{render} +@cindex @code{antialias} +@cindex @code{size} +@anchor{convert} +The default output format is @acronym{EPS} for the (default) +@code{latex} tex engine and @acronym{PDF} for the @code{pdflatex} and +@code{xelatex} tex engines. +Alternative output formats may be produced using the @code{-f} option +(or @code{outformat} setting). The optional setting @code{-render n} requests +an output resolution of @code{n} pixels per @code{bp}. Antialiasing is +controlled by the parameter @code{antialias}, which by default +specifies a sampling width of 2 pixels. +@code{Asymptote} can produce any output format supported +by the @code{ImageMagick} @code{convert} program (version 6.3.5 or +later recommended; an @code{Invalid Parameter} error message indicates +that the @code{MSDOS} utility @code{convert} is being used instead of +the one that comes with @code{ImageMagick}). +To give specific options to @code{convert}, use the +@code{convertOptions} setting or call convert manually. This example +emulates how @code{Asymptote} produces antialiased @code{tiff} output at +one pixel per @code{bp}: +@verbatim +asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.tiff +@end verbatim + +@cindex @code{nosafe} +@cindex @code{safe} +@cindex @code{system} +If the option @code{-nosafe} is given, @code{Asymptote} runs +in unsafe mode. This enables the @code{int system(string s)} call, allowing one +to execute arbitrary shell commands. The default mode, @code{-safe}, +disables this call. + +@cindex offset +@cindex @code{align} +A @code{PostScript} offset may be specified as a pair (in @code{bp} +units) with the @code{-O} option: +@verbatim +asy -O 0,0 file +@end verbatim +@noindent +The default offset is zero. The default value of the page alignment +setting @code{align} is @code{Center}. + +@cindex @code{-c} +The @code{-c} (@code{command}) option may be used to execute arbitrary +@code{Asymptote} code on the command line as a string. It is not +necessary to terminate the string with a semicolon. Multiple @code{-c} +options are executed in the order they are given. For example +@verbatim +asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)" +@end verbatim +@noindent +produces the output +@verbatim +4 +0.841470984807897 +@end verbatim +@noindent +and draws a unitsquare of size @code{100}. + +@cindex @code{-u} +The @code{-u} (@code{user}) option may be used to specify arbitrary +@code{Asymptote} settings on the command line as a string. It is not +necessary to terminate the string with a semicolon. Multiple @code{-u} +options are executed in the order they are given. Command-line code like +@code{-u x=sqrt(2)} can be executed within a module like this: +@verbatim +real x; +usersetting(); +write(x); +@end verbatim + +@cindex @code{-l} +When the @code{-l} (@code{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 @code{-v} option: +@table @code +@item -v +Display top-level module and final output file names. +@item -vv +Also display imported and included module names and final @code{LaTeX} and +@code{dvips} processing information. +@item -vvv +Also output @code{LaTeX} bidirectional pipe diagnostics. +@item -vvvv +Also output knot guide solver diagnostics. +@item -vvvvv +Also output @code{Asymptote} traceback diagnostics. +@end table + +@node Interactive mode +@chapter Interactive mode +@cindex interactive mode +Interactive mode is entered by executing the command @code{asy} with +no file arguments. When the @code{-multiline} option is disabled (the default), +each line must be a complete @code{Asymptote} statement (unless +explicitly continued by a final backslash character @code{\}); +it is not necessary to terminate input lines with a semicolon. +If one assigns @code{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 @code{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 @code{write} +function exists) are automatically evaluated and written to @code{stdout}. + +The following special commands are supported only in interactive mode +and must be entered immediately after the prompt: + +@table @code +@cindex @code{help} +@item help +view the manual; +@item reset +reset the @code{Asymptote} environment to its initial state, except for +changes to the settings module (@pxref{settings}), the current directory +(@pxref{cd}), and breakpoints (@pxref{Debugger}); +@cindex @code{input} +@item input FILE +does an interactive reset, followed by the command +@code{include FILE}. If the file name @code{FILE} contains +nonalphanumeric characters, enclose it with quotation marks. +A trailing semi-colon followed by optional @code{Asymptote} commands may +be entered on the same line. +@cindex @code{quit} +@cindex @code{exit} +@anchor{history} +@item quit +exit interactive mode (@code{exit} is a synonym; the abbreviation +@code{q} is also accepted unless there exists a top-level variable named +@code{q}). +@cindex @code{historylines} +A history of the most recent 1000 (this number can be changed with the +@code{historylines} configuration variable) previous commands will be retained +in the file @code{.asy/history} in the user's home directory (unless +the command-line option @code{-localhistory} was specified, in which case +the history will be stored in the file @code{.asy_history} in the +current directory). + +@end table + +Typing @code{ctrl-C} interrupts the execution of @code{Asymptote} code +and returns control to the interactive prompt. + +Interactive mode is implemented with the @acronym{GNU} @code{readline} library, +with command history and auto-completion. To customize the key bindings, see: +@url{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html} + +@cindex @code{Python} usage +The file @code{asymptote.py} in the @code{Asymptote} system directory +provides an alternative way of entering @code{Asymptote} commands +interactively, coupled with the full power of @code{Python}. Copy this +file to your @code{Python path} and then execute from within +@code{Python} the commands +@verbatim +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") +@end verbatim + +@node GUI +@chapter Graphical User Interface +@cindex graphical user interface +@cindex @acronym{GUI} +@cindex mouse +@cindex wheel mouse +@cindex @code{Button-1} +@cindex @code{Button-2} +@cindex @code{xasy} + +In the event that adjustments to the final figure are required, the +preliminary Graphical User Interface (@acronym{GUI}) @code{xasy} included with +@code{Asymptote} allows you to move graphical objects and draw new ones. +The modified figure can then be saved as a normal @code{Asymptote} file. + +@menu +* GUI Installation:: Installing @code{xasy} +* GUI Usage:: +@end menu + +@node GUI Installation +@section GUI Installation +@cindex GUI installation + +As @code{xasy} is written in the interactive scripting language +@code{Python/TK}, it requires @code{Python} +(@url{http://www.python.org}), the Python Imaging Library +(@url{http://www.pythonware.com/products/pil/}), and the @code{tkinter} +package (included with s@code{Python} under @code{Microsoft Windows}) be +installed. @code{Fedora Linux} users can either install +@code{tkinter} with the commands +@verbatim +yum install tkinter +yum install tk-devel +@end verbatim +@noindent +or manually install the @code{tkinter}, @code{tix}, @code{tk}, +and @code{tk-devel} packages. + +Pictures are deconstructed into the @acronym{PNG} image format, which +supports full alpha channel transparency. Under @code{Microsoft +Windows}, this requires @code{Python 2.5 (or 2.5.1)} and the +@code{Python Imaging Library}: +@quotation +@url{http://www.python.org/ftp/python/2.5.1/python-2.5.1.msi} +@end quotation +@quotation +@url{http://effbot.org/downloads/PIL-1.1.6.win32-py2.5.exe}. +@end quotation +@noindent +On @code{UNIX} systems, place +@url{http://effbot.org/downloads/Imaging-1.1.6.tar.gz} in the +@code{Asymptote} source directory, and type (as the root user): +@verbatim +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 +@end verbatim + +Alternatively, @code{xasy} can deconstruct pictures into the @acronym{GIF} +image format (not recommended as this is very slow), using white as the +transparent color. This requires the lines +@verbatim +import settings; +xformat="gif"; +@end verbatim +@noindent +in the @code{Asymptote} configuration file (@pxref{configuration file}), +along with the @code{ImageMagick} (@pxref{convert}) program. + +@node GUI Usage +@section GUI Usage +@cindex GUI usage +@cindex @code{deconstruct} + +A wheel mouse is convenient for raising and lowering objects within +@code{xasy}, to expose the object to be moved. If a wheel mouse is not +available, mouse @code{Button-2} can be used to repeatedly lower an +object instead. When run from the command line, @code{xasy} accepts +a command line option @code{-x n}, which sets the initial magnification +to @code{n}. + +Deconstruction of compound objects (such as arrows) can be prevented +by enclosing them within the commands +@verbatim +void begingroup(picture pic=currentpicture); +void endgroup(picture pic=currentpicture); +@end verbatim +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 (@pxref{add}). + +@node PostScript to Asymptote +@chapter @code{PostScript} to @code{Asymptote} +@cindex @code{pstoedit} +The excellent @code{PostScript} editor @code{pstoedit} (version 3.45 or later; +available from @url{http://pstoedit.net}) includes an +@code{Asymptote} backend. Unlike virtually all other @code{pstoedit} +backends, this driver includes native clipping, even-odd fill rule, +@code{PostScript} subpath, and full image support. + +For full functionality, the patch @code{pstoedit-3.45asy.patch} +in the @code{patches} directory should be applied. On @code{UNIX} systems, as +the root user, place +@quotation +@url{http://prdownloads.sourceforge.net/pstoedit/pstoedit-3.45.tar.gz} +@end quotation +@noindent +in the @code{Asymptote} source directory, and type: + +@verbatim +tar -zxf pstoedit-3.45.tar.gz +cd pstoedit-3.45 +patch -p1 < ../patches/pstoedit-3.45asy.patch +autoconf +./configure --prefix=/usr +make install +@end verbatim + +@noindent +Then try: + +@noindent +@code{asy -V @value{Datadir}/doc/asymptote/examples/venn.asy} +@noindent +@verbatim +pstoedit -f asy venn.eps test.asy +asy -V test +@end verbatim + +@noindent +If the line widths aren't quite correct, try giving @code{pstoedit} the +@code{-dis} option. +If the fonts aren't typeset correctly, try giving @code{pstoedit} the +@code{-dt} option. + +@node Help +@chapter Help +@cindex help +@cindex forum + +A list of frequently asked questions (@acronym{FAQ}) is maintained at +@quotation +@url{http://asymptote.sourceforge.net/FAQ} +@end quotation +@noindent +Questions on installing and using @code{Asymptote} that are not +addressed in the @acronym{FAQ} should be sent to the +@code{Asymptote} forum: +@quotation +@url{http://sourceforge.net/forum/forum.php?forum_id=409349} +@end quotation +@noindent +Including an example that illustrates what you are trying to do will help +you get useful feedback. +@code{LaTeX} problems can often be diagnosed with the @code{-vv} or +@code{-vvv} command-line options. +Contributions in the form of patches or @code{Asymptote} modules can be +posted here: +@quotation +@url{http://sourceforge.net/tracker/?atid=685685&group_id=120000} +@end quotation +@noindent +To receive announcements of upcoming releases, please subscribe to +@code{Asymptote} at +@quotation +@url{http://freshmeat.net/projects/asy} +@end quotation +@cindex bug reports +@noindent +If you find a bug in @code{Asymptote}, please check (if possible) +whether the bug is still present in the latest @acronym{Subversion} +developmental code (@pxref{Subversion}) before submitting a bug +report. New bugs can be submitted using the Bug Tracking System at +@quotation +@url{http://sourceforge.net/projects/asymptote} +@end quotation +@noindent +To see if the bug has already been fixed, +check bugs with Status @code{Closed} and recent lines in +@quotation +@url{http://asymptote.sourceforge.net/ChangeLog} +@end quotation +@noindent + +@cindex stack overflow +@cindex segmentation fault +@cindex @code{libsigsegv} +@code{Asymptote} can be configured with the optional @acronym{GNU} library +@code{libsigsegv}, available from +@url{http://libsigsegv.sourceforge.net}, which allows one to distinguish +user-generated @code{Asymptote} stack overflows (@pxref{stack overflow}) +from true segmentation faults (due to internal C++ programming errors; +please submit the @code{Asymptote} code that generates such segmentation +faults along with your bug report). + +@node Debugger +@chapter Debugger +@cindex 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 @code{file} at line @code{line}, use the command + +@cindex @code{stop} +@verbatim +void stop(string file, int line, code s=quote{}); +@end verbatim +@noindent +The optional argument @code{s} may be used to conditionally set the variable +@code{ignore} in @code{plain_debugger.asy} to @code{true}. For example, the +first 10 instances of this breakpoint will be ignored (the +variable @code{int count=0} is defined in @code{plain_debugger.asy}): +@verbatim +stop("test",2,quote{ignore=(++count <= 10);}); +@end verbatim + +To set a break point in file @code{file} at the first line containing +the string @code{text}, use + +@verbatim +void stop(string file, string text, code s=quote{}); +@end verbatim +@noindent +To list all breakpoints, use: +@cindex @code{breakpoints} +@verbatim +void breakpoints(); +@end verbatim +@noindent +To clear a breakpoint, use: +@cindex @code{clear} +@verbatim +void clear(string file, int line); +@end verbatim +@noindent +To clear all breakpoints, use: +@verbatim +void clear(); +@end verbatim + +The following commands may be entered at the debugging prompt: + +@table @code +@cindex @code{help} +@item @code{h} +help; +@cindex @code{continue} +@item @code{c} +continue execution; + +@cindex @code{inst} +@item @code{i} +step to the next instruction; + +@cindex @code{step} +@item @code{s} +step to the next executable line; + +@cindex @code{next} +@item @code{n} +step to the next executable line in the current file; + +@cindex @code{file} +@item @code{f} +step to the next file; + +@cindex @code{return} +@item @code{r} +return to the file associated with the most recent breakpoint; + +@cindex @code{trace} +@item @code{t} +toggle tracing (@code{-vvvvv}) mode; + +@cindex @code{quit} +@item @code{q} +quit debugging and end execution; + +@cindex @code{exit} +@item @code{x} +exit the debugger and run to completion. + +@end table +@noindent +Arbitrary @code{Asymptote} code may also be entered at the debugging prompt; +however, since the debugger is implemented with @code{eval}, currently +only top-level (global) variables can be displayed or modified. + +The debugging prompt may be entered manually with the call +@verbatim +void breakpoint(code s=quote{}); +@end verbatim + +@node Credits +@chapter Acknowledgments +@cindex acknowledgments + +Financial support for the development of @code{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 @code{MetaPost} that inspired the development of +@code{Asymptote}, and Donald E. Knuth, author of @TeX{} and +@code{MetaFont} (on which @code{MetaPost} is based). + +The authors of @code{Asymptote} are Andy Hammerlindl, John Bowman, and +Tom Prince. Sean Healy designed the @code{Asymptote} logo. Other +contributors include Radoslav Marinov, Orest Shardt, Chris Savage, +Philippe Ivaldi, Olivier Guib@'e, Jacques Pienaar, Mark Henning, Steve +Melenchuk, Martin Wiebusch, and Stefan Knorr. + +@node Index +@unnumbered Index + +@printindex cp + +@bye + +@c LocalWords: randMax Gaussrand asy cindex indices resized LaTeX TK latin au +@c LocalWords: latexusage tex bbox PostScript subdirectory gcc emacs ASYDIR +@c LocalWords: documentclass usepackage subpath shipout sqrt xN Mx bw AcroRd +@c LocalWords: xscale xaxis yaxis BeginBar GIF postprocessing fpu de rpair xy +@c LocalWords: nomask noplain ImageMagick defaultfontsize defaultlinewidth cd +@c LocalWords: startup natively xasy tkinter VxN yingyang currentpicture toc +@c LocalWords: MetaPost MetaFont Hammerlindl Healy texinfo autoload setq setf +@c LocalWords: printindex setfilename settitle dircategory direntry titlepage +@c LocalWords: vskip filll insertcopying ifnottex detailmenu alist augroup PQ +@c LocalWords: bool behaviour facto zxf login Debian dev filetypedetect SVN +@c LocalWords: FFTW bp readline gv eps args Boehm gc evenoddoverlap png joe +@c LocalWords: boolean initializer expi dir xpart ypart STL substring rfind +@c LocalWords: pos substr strftime typedef pxref unitcircle yscale Bezier iff +@c LocalWords: postcontrol precontrol atleast nullpath arclength arctime rgb +@c LocalWords: dirtime currentpen colorspaces grayscale cmyk defaultpen x cx +@c LocalWords: linetype longdashed dashdotted longdashdotted linewidth y XP +@c LocalWords: fontsize defaultfilename keepAspect IgnoreAspect ise flushleft +@c LocalWords: src dest XDR txt getc fout stdin stdout endl xinput eof js prc +@c LocalWords: xoutput Microsystem's eol exponentials postfix sayhi th Ubuntu +@c LocalWords: sqr intop addby libm asin acos atan sinh tanh asinh acosh cbrt +@c LocalWords: atanh fabs hypot fmod ceil srand dereferenced alice pete sqrtx +@c LocalWords: eval fft csv runtime nonalphanumeric labely LeftTicks NoTicks +@c LocalWords: RightTicks BottomTop LeftRight Ticksize UTF BufNewFile BufRead +@c LocalWords: ticksize subintervals xlimits filetype plugin setlocal makeprg +@c LocalWords: ylimits uncommented automin automax cp uninstall reals ecast +@c LocalWords: scaleT unicode RightSide yx yy NoAlign legendmargin opic CCW +@c LocalWords: arrowbar LeftSide EndBar BeginArrow lly feynman isi showtarget +@c LocalWords: EndArrow BeginArcArrow EndArcArrow ArcArrow ArcArrows NoFill +@c LocalWords: filldraw fillpen drawpen errorformat bigsquare bezier darkblue +@c LocalWords: quartercircle darkgreen lightblue urx ury texpreamble sgn texi +@c LocalWords: lineargraph datagraph vertices parametricgraph uncomment ggv +@c LocalWords: loggraph generalaxis texhash arrowsize arrowangle arrowlength +@c LocalWords: SuppressQuiet MoveQuiet LIBREADLINE config MacOS prebuilt svn +@c LocalWords: ghostview gsview SIGHUP PDF acroread xpdf cutbefore strptime +@c LocalWords: libsigsegv intersectionpoint dotfactor vv firstcut pq logticks +@c LocalWords: Unisys dvips vvv vvvv vvvvv traceback lastcut cutafter infodir +@c LocalWords: zxvf xargs cond polargraph xmin xmax plabel YZero labelling ln +@c LocalWords: ymin ymax XZero xequals tickmin tickmax unlabelled se pq pena +@c LocalWords: yequals Nobre Barbarosie Schwaiger nearearth conicurv Wiebusch +@c LocalWords: unfill posterSize ngraph interpolatetype ctrl dt pic getint Ai +@c LocalWords: NNE jxf linecap linejoin unitsquare shadedtiling ei nomarker +@c LocalWords: westnile minipage ra penb paletteticks drawline nV FillDraw uv +@c LocalWords: susceptibleM flushright secondaryX secondaryY secondaryaxis tt +@c LocalWords: titlelabel columnlabel rb xtick ytick labelx XEquals YEquals +@c LocalWords: treetest eetomumu fermi backend pstoedit drawtree xFF MSDOS gz +@c LocalWords: vimrc CFLAGS verbatiminclude online noindent bezier superpath +@c LocalWords: evenodd squarecap roundcap extendcap miterjoin roundjoin NFSS +@c LocalWords: beveljoin fillrule zerowinding insideness lineskip cmr pcrr Hx +@c LocalWords: AvantGarde Bookman Helvetica NewCenturySchoolBook minbound pdf +@c LocalWords: Palatino TimesRoman ZapfChancery ZapfDingbats german basealign +@c LocalWords: nondeconstructed backends usr venn labelsquare nobasealign dp +@c LocalWords: NoMargin BeginMargin EndMargin BeginPenMargin EndPenMargin dm +@c LocalWords: PenMargin PenMargins TrueMargin labelmargin errorbars errorbar +@c LocalWords: dpx dpy dmx dmy barsize arrowsize BeginDotMargin DotMargin acc +@c LocalWords: EndDotMargin DotMargins NColors BWRainbow colorspace labelled +@c LocalWords: PaletteTicks defaultformat leastsquares bjam fprintf endgroup +@c LocalWords: begingroup xmargin ymargin pbox box ellipse wget exe Gouraud +@c LocalWords: multithreaded newframe init emph nums concat xline yline zpart +@c LocalWords: colatitude zscale cosh nullpen MetaFontbook cyclicflag FreeBSD +@c LocalWords: nodeps Ghostgum beginlabel endlabel pTick ptick loggrid SAS dy +@c LocalWords: currentprojection latticeshading subpictures colinear unitcube +@c LocalWords: Autoscaling solveQuadratic MidArrow MidArcArrow Prebuilt url +@c LocalWords: pdftex comment getstring getstringprefix getreal defaultS hsv +@c LocalWords: ticklocate autoscaleT autoscaling vectorfield autolimits dvi +@c LocalWords: zlimits inline dvipdf hyperdvi autoconf gui zerowindingoverlap +@c LocalWords: prepended intMax quadraticroots cubicroots filltype prepend dx +@c LocalWords: ticklabel popup UnFill markroutine marknodes markuniform erf +@c LocalWords: intersectpoint cyrillic mathtext russian brokenaxis Datadir ds +@c LocalWords: resetdefaultpen latticeshade axialshade radialshade erfc det +@c LocalWords: gouraudshade unescaped nmesh surfacepen getpair MikTeX dw YZ +@c LocalWords: meshpen localhistory axisT roundedpath unitsize aSin accel pre +@c LocalWords: fontcommand makepen aCos aTan Knorr roundpath BeginPoint nView +@c LocalWords: MidPoint EndPoint nmask antialiasing autoplain batchMask libgc +@c LocalWords: batchView clearGUI ignoreGUI interactiveMask interactiveView +@c LocalWords: listvariables outformat parseonly prepending psviewer nCircle +@c LocalWords: pdfviewer papertype tabcompletion noautoplain plugins Teixeira +@c LocalWords: embeddedmovie historylines RadialShade penc penr CJK tgz GPL +@c LocalWords: legendlinelength legendskip USERPROFILE LDFLAGS currentlight +@c LocalWords: subsampled sinc kai AtBeginDocument GBK clearpage lasy texpath +@c LocalWords: AtEndDocument zaxis maxbound truepoint paperwidth paperheight +@c LocalWords: GSL deriv texcolors fixedscaling UpsideDown texreset slidedemo +@c LocalWords: subitem newslide realMin realMax realEpsilon realDigits gsl dh +@c LocalWords: obliqueX asycolors monthaxis xautoscale yautoscale zautoscale +@c LocalWords: obliqueZ obliqueY cylinderskeleton block llcorner dr py nx CPU +@c LocalWords: loc topleft topright bottomleft bottomright flowrectangle UTC +@c LocalWords: chartblock flowdiamond flowcircle xlabel BezierSurface el xyz +@c LocalWords: flowroundrectangle flowbevel flowpath drawflow blocks ny cpu +@c LocalWords: multipleView usersetting mediumgray flowchartdemo ylabel nv xf +@c LocalWords: zlabel slopefields cputime roundrectangle slopefield libgccpp +@c LocalWords: tickfactor USERNAME writeable imagecontour logimage Dumoulin's +@c LocalWords: NoCrop parametricsurface realmult SoftLight HardLight interp +@c LocalWords: ColorDodge ColorBurn Ivaldi buildcycle autorotate mexicanhat +@c LocalWords: Gouraudcontour pdflatex preconfigured perline linelength hskip +@c LocalWords: penimage filloutside legendhskip legendvskip maxwidth CDlabel +@c LocalWords: tensorshade MPEG framepoint nonfunction Radoslav Marinov Mepis +@c LocalWords: Pienaar Melenchuk finalout Linspire Dpkg sudo dpkg dtx Tcount +@c LocalWords: windingnumber clickable pdfmovie dfn du animationdelay fprime +@c LocalWords: slidemovies ifdraft embeddedu externalmovie headerpen bodypen +@c LocalWords: GaussianSurface multiline binarytree tridiagonal portably AIX +@c LocalWords: binarytreetest Henning subsample breakpoint locator wireframe +@c LocalWords: labelpath intersectionpoints PSTricks pstextpath curvedlabel +@c LocalWords: LeftJustified RightJustified tickmodifier gunzip gmake IRIX dv +@c LocalWords: texcommand RET SITEDIR filegraph pathmarkers POSIX binput AOB +@c LocalWords: boutput nonportable markinterval stickframe circlebarframe tix +@c LocalWords: crossframe tildeframe markangle StickIntervalMarker gswin expm +@c LocalWords: CrossIntervalMarker CircleBarIntervalMarker Ghostscript syzygy +@c LocalWords: TildeIntervalMarker autoimport calculateTransform bitwise tk +@c LocalWords: headersize bodysize minheaderwidth minheaderheight minwidth ZX +@c LocalWords: minbodywidth minbodyheight minheight mindiameter reltime PNG +@c LocalWords: relpoint Syzygy syzygies seekeof splinetype notaknot slopea ZY +@c LocalWords: slopeb nonperiodic circlescale MarkFill ScaleX ScaleY xformat +@c LocalWords: onecontour multicontour irregularcontour dvipsOptions saveline +@c LocalWords: dirSpecifier controlSpecifier tensionSpecifier atleastflag bsp +@c LocalWords: curlSpecifier cputimeformat initializers arbitary redeclaring +@c LocalWords: firstname lastname multdiagonal Raphson OmitTick OmitFormat sp +@c LocalWords: NoZero NoZeroFormat abbrevation gsOptions namespace redeclared +@c LocalWords: atLeast intMin globalwrite quarticroots deconsruct substrings +@c LocalWords: usleep currentpatterns trailingzero Orest Shardt DefaultHead +@c LocalWords: SimpleHead HookHead TeXHead multipage NURBS inlinemovie dxmax +@c LocalWords: simpson NoBox truesize autoscale shadestroke recurses mintimes +@c LocalWords: nonoverlapping texdvicommand texengine maxtimes maxheight pdb +@c LocalWords: piecewisestraight unitrand graphmarkers antialias nolight newl +@c LocalWords: Delaunay Shewchuk convertOptions APPDATA pdfreload tempFile +@c LocalWords: pdfreloadOptions deferred OpenGL Phong Blinn renderer unitbox +@c LocalWords: bezulate Shardt's rasterized viewport unitdisk unitplane devel +@c LocalWords: unitcylinder unitcone solidcone unitfrustum unitsphere nslices +@c LocalWords: DPostScript YZZero freeglut externalprc nonrendered nosafe +@c LocalWords: unithemisphere versa XYplane xypart unitsolidcone YZEquals +@c LocalWords: XZEquals XYEquals XZZero XYZero InTicks OutTicks InOutTicks +@c LocalWords: fitscreen planeproject strokepath meshlight nullpens arrowdir +@c LocalWords: diffusepen ambientpen emissivepen specularpen arrowbarb keyval +@c LocalWords: hstretch vstretch roundbox nonconvex miterlimit basealigin +@c LocalWords: maxviewport maxtile antialiased sphericalharmonic attachfile +@c LocalWords: vertexshading smoothelevation glOptions iconified iconify +@c LocalWords: psviewerOptions pdfviewerOptions viewportmargin asyattach +@c LocalWords: multisampling autogen multisample coloredpath relstep flowdir +@c LocalWords: colortype coloredSegments coloredNodes trefoilknot scaledgraph +@c LocalWords: minblockwidth minblockheight mincirclediameter nonassociative +@c LocalWords: nonintegral gettriple enablerepo hexidecimal XeLaTeX xelatex +@c LocalWords: dvipdfmx autoadjust viewportsize viewportwidth viewportheight +@c LocalWords: subregions nonsimply functionshade xetex shader floatingdisk +@c LocalWords: functionshading nonselfintersecting |