diff options
author | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
---|---|---|
committer | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
commit | c6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch) | |
tree | 1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/utils/asymptote/doc/asymptote.texi | |
parent | 07ee7222e389b0777456b427a55c22d0e6ffd267 (diff) |
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/doc/asymptote.texi')
-rw-r--r-- | Build/source/utils/asymptote/doc/asymptote.texi | 10180 |
1 files changed, 0 insertions, 10180 deletions
diff --git a/Build/source/utils/asymptote/doc/asymptote.texi b/Build/source/utils/asymptote/doc/asymptote.texi deleted file mode 100644 index bd9671564aa..00000000000 --- a/Build/source/utils/asymptote/doc/asymptote.texi +++ /dev/null @@ -1,10180 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@setfilename asymptote.info -@settitle Asymptote: the Vector Graphics Language -@include version.texi -@finalout - -@codequoteundirected on - -@copying -This file documents @code{Asymptote}, version @value{VERSION}. - -@url{https://asymptote.sourceforge.io} - -Copyright @copyright{} 2004-20 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/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, Description, (dir), (dir) -@top Asymptote - -@insertcopying -@end ifnottex - -@menu -* Description:: What is @code{Asymptote}? -* Installation:: Downloading and installing -* Tutorial:: Getting started -* Drawing commands:: Four primitive graphics commands -* Bezier curves:: Path connectors and direction specifiers -* 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 -* Git:: Getting the latest development source -* Uninstall:: Goodbye, @code{Asymptote}! - -Tutorial - -* Drawing in batch mode:: Run @code{Asymptote} on a text file -* Drawing in interactive mode:: Running @code{Asymptote} interactively -* Figure size:: Specifying the figure size -* Labels:: Adding @code{LaTeX} labels -* Paths:: Drawing lines and curves - -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:: Bezier curves -* 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} modules -* 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 -* map:: Map keys to values -* 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 -* 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 -* smoothcontour3:: Smooth implicit surfaces -* slopefield:: Slope fields -* ode:: Ordinary differential equations - -Graphical User Interface - -* GUI installation:: Installing @code{xasy} -* GUI usage:: Using @code{xasy} to edit objects - -@end detailmenu -@end menu - -@node Description, Installation, Top, Top -@chapter Description -@cindex description - -@cindex @code{Asymptote Web Application} -@code{Asymptote} is a powerful descriptive vector graphics language that -provides a mathematical coordinate-based framework for technical drawing. -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 @code{PDF}, -@code{SVG}, @code{WebGL}, @code{PRC}, and any format that the -@code{ImageMagick} package can produce. You can even try it out in your -Web browser without installing it, using the @code{Asymptote Web -Application}: - -@url{http://asymptote.ualberta.ca} - -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 the ability to generate and embed 3D vector @acronym{WebGL} -graphics within @acronym{HTML} files; - -@item the ability to generate and embed 3D vector @acronym{PRC} -graphics within @acronym{PDF} files; - -@item a natural coordinate-based framework for technical drawing, -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; for example, a scientific graphing module is available -(@pxref{graph}). Examples of @code{Asymptote} code and output, -including animations, are available at -@quotation -@url{https://asymptote.sourceforge.io/gallery/} -@end quotation -@noindent -Clicking on an example file name in this manual, like -@code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}}, will display the @acronym{PDF} output, whereas clicking on its -@code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}} -extension will show the corresponding @code{Asymptote} code in a separate window. - -Links to many external resources, including an excellent user-written -@code{Asymptote} tutorial can be found at -@quotation -@url{https://asymptote.sourceforge.io/links.html} -@end quotation -@cindex reference -@cindex quick reference -A quick reference card for @code{Asymptote} is available at -@quotation -@url{https://asymptote.sourceforge.io/asyRefCard.pdf} -@end quotation - -@node Installation, Tutorial, Description, Top -@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 -* Git:: Getting the latest development source -* 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{https://sourceforge.net/projects/asymptote} -@end quotation -@noindent -Users may also wish to monitor the @code{Asymptote} forum: -@quotation -@url{https://sourceforge.net/p/asymptote/discussion/409349} -@end quotation -@noindent - -@node UNIX binary distributions, MacOS X binary distributions, Installation, Installation -@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 x86_64} @code{tgz} -distribution of version @code{x.xx} of @code{Asymptote} with the commands: -@verbatim -tar -C / -zxf asymptote-x.xx.x86_64.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{Docdir}/examples}. - -@noindent -@cindex Fedora -Fedora users can easily install a recent version of @code{Asymptote} -with the command -@verbatim -dnf --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, Microsoft Windows, UNIX binary distributions, Installation -@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 @code{Asymptote} binary available at - -@url{https://www.macports.org/} - -@noindent -Note that many @code{MacOS X} (and FreeBSD) systems lack the -@acronym{GNU} @code{readline} library. For full interactive -functionality, @acronym{GNU} @code{readline} version 4.3 or later must -be installed. - -@node Microsoft Windows, Configuring, MacOS X binary distributions, Installation -@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 (we recommend -@url{https://www.tug.org/texlive} or -@url{http://www.miktex.org}) will be required to typeset labels. -You will also need to install @code{GPL Ghostscript} version 9.52 or -later from @url{http://downloads.ghostscript.com/public}. - -To view @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{https://www.imagemagick.org/script/binary-releases.php} - -@noindent -is required to support output formats other than @acronym{HTML}, -@acronym{PDF}, @acronym{SVG}, and @acronym{PNG} (@pxref{convert}). -The @code{Python 3} interpreter from @url{https://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, Search paths, Microsoft Windows, Installation -@section Configuring -@cindex configuring -@cindex @code{-V} -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. -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{https://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{psviewer} -@cindex @code{pdfviewer} -@cindex @code{htmlviewer} -@cindex @code{gs} -@cindex @code{display} -@cindex @code{animate} -@cindex @code{settings} -@cindex configuration file -Configuration variables are most easily set as @code{Asymptote} -variables in an optional configuration file @code{config.asy} -@pxref{configuration file}). -For example, the setting @code{pdfviewer} specifies the location of -the @acronym{PDF} viewer. Here are the default values of several -important configuration variables under @code{UNIX}: - -@noindent -@verbatim -import settings; -pdfviewer="acroread"; -htmlviewer="google-chrome"; -psviewer="gv"; -display="display"; -animate="animate"; -gs="gs"; -libgs=""; -@end verbatim - -@noindent -@cindex @code{cmd} -Under @code{MSDOS}, the viewer settings -@code{htmlviewer}, @code{pdfviewer}, @code{psviewer}, -@code{display}, and @code{animate} default to the string @code{cmd}, -requesting the application normally associated with each file type. -The (installation-dependent) default values of @code{gs} -and @code{libgs} are determined automatically from the @code{Microsoft -Windows} registry. The @code{gs} setting specifies the location of the -@code{PostScript} processor @code{Ghostscript}, available from -@url{https://www.ghostscript.com/}. - -@noindent -@cindex @code{htmlviewer} -@cindex @code{absolute} -The configuration variable @code{htmlviewer} specifies the -browser to use to display 3D @code{WebGL} output. -The default setting is @code{google-chrome} under @code{UNIX} and -@code{cmd} under @code{Microsoft Windows}. Note that @code{Internet Explorer} -does not support @code{WebGL}; @code{Microsoft Windows} users should set their -default html browser to @code{chrome} or @code{microsoft-edge}. -By default, 2D and 3D @code{HTML} images expand to the enclosing canvas; -this can be disabled by setting the configuation variable @code{absolute} -to @code{true}. - -On @code{UNIX} systems, to support automatic document -reloading of @code{PDF} files 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 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{config} -@cindex @code{texpath} -@cindex @code{texcommand} -@cindex @code{dvips} -@cindex @code{dvisvgm} -@cindex @code{convert} -@cindex @code{ImageMagick} -@cindex @code{asygl} -These additional configuration variables normally do not require adjustment: -@verbatim -config -texpath -texcommand -dvips -dvisvgm -convert -asygl -@end verbatim -@noindent - -Warnings (such as "unbounded" and "offaxis") may be enabled or disabled with -the functions -@verbatim -warn(string s); -nowarn(string s); -@end verbatim -@noindent -or by directly modifying the string array @code{settings.suppress}, which lists -all disabled warnings. - -@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{View system information}; -@item Click the @code{Advanced} tab; -@item Click the @code{Environment Variables} button. -@end enumerate - -@node Search paths, Compiling from UNIX source, Configuring, Installation -@section Search paths -@cindex search paths - -In looking for @code{Asymptote} 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} or environment variable @code{ASYMPTOTE_DIR} -(separated by @code{:} under UNIX and -@code{;} under @code{MSDOS}); -@item -@cindex @code{.asy} -The directory specified by the environment variable -@code{ASYMPTOTE_HOME}; if this variable is not set, -the directory @code{.asy} in the user's home directory -(@code{%USERPROFILE%\.asy} under @code{MSDOS}) is used; -@item -The @code{Asymptote} system directory (by default, -@code{@value{Datadir}/asymptote} under @code{UNIX} and -@code{C:\Program Files\Asymptote} under @code{MSDOS}). -@item -The @code{Asymptote} examples directory (by default, -@code{@value{Docdir}/examples} under @code{UNIX} and -@code{C:\Program Files\Asymptote\examples} under @code{MSDOS}). -@end enumerate - -@node Compiling from UNIX source, Editing modes, Search paths, Installation -@section Compiling from UNIX source -@cindex Compiling from UNIX source - -To compile and install a @code{UNIX} executable from -the source release @code{asymptote-x.xx.src.tgz} in the subdirectory -@code{x.xx} under - -@url{https://sourceforge.net/projects/asymptote/files/} - -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{https://github.com/ivmai/bdwgc/releases/download/v8.0.4/gc-8.0.4.tar.gz} -@url{https://www.ivmaisoft.com/_bin/atomic_ops/libatomic_ops-7.6.10.tar.gz} -in the @code{Asymptote} source directory. - -On @code{UNIX} platforms (other than @code{MacOS X}), we recommend -using version @code{3.2.1} of the @code{freeglut} library. To compile -@code{freeglut}, download -@quotation -@url{https://prdownloads.sourceforge.net/freeglut/freeglut-3.2.1.tar.gz} -@end quotation -@noindent -and type (as the root user): -@verbatim -gunzip freeglut-3.2.1.tar.gz -tar -xf freeglut-3.2.1.tar -cd freeglut-3.2.1 -cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_C_FLAGS=-fcommon . -make -make install -@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{https://asymptote.sourceforge.io/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 -@cindex @code{MacOS X} configuration -@cindex @code{clang} -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, under -@code{MacOS X}, one can tell configure to use the @code{clang} compilers and -look for header files and libraries in nonstandard locations: -@verbatim -./configure CC=clang CXX=clang++ CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/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.3 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, Git, Compiling from UNIX source, Installation -@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{https://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 - -@cindex @code{KDE editor} -@cindex @code{Kate} -@cindex @code{asymptote.xml} -Syntax highlighting support for the @acronym{KDE} editor @code{Kate} -can be enabled by running @code{asy-kate.sh} in the -@code{@value{Datadir}/asymptote} directory and putting the generated -@code{asymptote.xml} file in @code{~/.kde/share/apps/katepart/syntax/}. - -@node Git, Uninstall, Editing modes, Installation -@section Git -@cindex git - -The following commands are needed to install the latest development version of -@code{Asymptote} using @code{git}: -@verbatim -git clone https://github.com/vectorgraphics/asymptote - -cd asymptote -./autogen.sh -./configure -make all -make install -@end verbatim - -@noindent -To compile without optimization, use the command @code{make CFLAGS=-g}. -On @code{Ubuntu} systems, you may need to first install the required -dependencies: -@verbatim -apt-get build-dep asymptote -@end verbatim -@noindent - -@node Uninstall, , Git, Installation -@section Uninstall -@cindex uninstall - -To uninstall a @code{Linux x86_64} binary distribution, use the commands -@verbatim -tar -zxvf asymptote-x.xx.x86_64.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, Drawing commands, Installation, Top -@chapter Tutorial -@cindex tutorial - -@menu -* Drawing in batch mode:: Run @code{Asymptote} on a text file -* Drawing in interactive mode:: Running @code{Asymptote} interactively -* Figure size:: Specifying the figure size -* Labels:: Adding @code{LaTeX} labels -* Paths:: Drawing lines and curves -@end menu - -A concise introduction to @code{Asymptote} is given here. -For a more thorough introduction, see the excellent @code{Asymptote} -tutorial written by Charles Staats: - -@url{https://asymptote.sourceforge.io/asymptote_tutorial.pdf} - -Another @code{Asymptote} tutorial is available as a wiki, -with images rendered by an online Asymptote engine: - -@url{https://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)} - -@node Drawing in batch mode, Drawing in interactive mode, Tutorial, Tutorial -@section Drawing in batch mode -@cindex batch mode -To draw a line from coordinate (0,0) to coordinate (100,100), -create a text file @code{test.asy} containing -@verbatiminclude diagonal.asy - -@noindent -Then execute the command -@verbatim -asy -V test -@end verbatim -@noindent -Alternatively, @code{MSDOS} users can drag and drop @code{test.asy} onto the -Desktop @code{asy} icon (or make @code{Asymptote} the default -application for the extension @code{asy}). - -@noindent -@cindex @code{-V} -This method, known as @emph{batch mode}, outputs a @code{PostScript} -file @code{test.eps}. If you prefer @acronym{PDF} output, use -the command line -@verbatim -asy -V -f pdf test -@end verbatim -In either case, the @code{-V} option opens up a viewer window so you -can immediately view the result: -@sp 1 -@center @image{./diagonal} -@cindex @code{bp} -@noindent -Here, the @code{--} connector joins the two points @code{(0,0)} and -@code{(100,100)} with a line segment. - -@node Drawing in interactive mode, Figure size, Drawing in batch mode, Tutorial -@section Drawing in interactive mode -@cindex interactive mode -Another method is @emph{interactive mode}, where @code{Asymptote} reads -individual commands as they are entered by the user. To try this out, enter -@code{Asymptote}'s interactive mode by clicking on the -@code{Asymptote} icon or typing the command @code{asy}. -Then type -@verbatim -draw((0,0)--(100,100)); -@end verbatim -@noindent -followed by @code{Enter}, to obtain the above image. -@cindex tab completion -@cindex arrow keys -@cindex erase -@cindex quit -@noindent -At this point you can type further @code{draw} commands, which will be added -to the displayed figure, @code{erase} to clear the canvas, -@verbatim -input test; -@end verbatim -@noindent -to execute all of the commands contained in the file @code{test.asy}, -or @code{quit} to exit interactive mode. -You can use the arrow keys in interactive mode to edit previous lines. -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}. - -@node Figure size, Labels, Drawing in interactive mode, Tutorial -@section Figure size -@cindex @code{size} -@cindex @code{pair} -In @code{Asymptote}, coordinates like @code{(0,0)} and @code{(100,100)}, -called @emph{pairs}, -are expressed in @code{PostScript} "big points" (1 @code{bp} = 1/72 -@code{inch}) and the default line width is @code{0.5bp}. -However, it is often inconvenient to work directly in -@code{PostScript} coordinates. -The next example produces identical output to the previous example, by -scaling the line @code{(0,0)--(1,1)} to fit a rectangle of width -@code{100.5 bp} and height @code{100.5 bp} (the extra @code{0.5bp} -accounts for the line width): -@verbatim -size(100.5,100.5); -draw((0,0)--(1,1)); -@end verbatim -@sp 1 -@center @image{./diagonal} - -@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}. -Two nonzero size arguments (or a single size argument) restrict the -size in both directions, preserving the aspect ratio. -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 bigdiagonal.asy -@sp 1 -@center @image{./bigdiagonal} - -@cindex @code{cycle} -To connect several points and create a cyclic path, use the -@code{cycle} keyword: -@verbatiminclude square.asy -@sp 1 -@center @image{./square} -@noindent -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 user coordinates -@cindex @code{unitsize} -To make the user coordinates represent multiples of exactly @code{1cm}: -@verbatim -unitsize(1cm); -draw(unitsquare); -@end verbatim -@noindent - -@node Labels, Paths, Figure size, Tutorial -@section Labels -@cindex @code{label} -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}). - -@node Paths, , Labels, Tutorial -@section Paths -@cindex @code{path} -This example draws a path that approximates a quarter circle, -terminated with an arrowhead: -@verbatiminclude quartercircle.asy -@sp 1 -@center @image{./quartercircle} -@noindent -Here the directions @code{up} and @code{left} in braces specify the -outgoing and incoming directions at the points @code{(1,0)} and -@code{(0,1)}, respectively. - -In general, a path is specified as a list of points (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 (@pxref{Bezier curves}). -@cindex @code{unitcircle} -@anchor{unitcircle} -@cindex @code{unitcircle} -Specifying a final @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 - -@cindex @code{PostScript} subpath -@cindex @code{^^} -@cindex @code{path[]} -@cindex superpath -@noindent -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 -@noindent -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 -the module @code{three} to construct the edges of a -cube @code{unitbox} without retracing steps (@pxref{three}): -@verbatiminclude cube.asy -@sp 1 -@center @image{./cube} - -See section @ref{graph} (or the online -@code{Asymptote} @uref{https://asymptote.sourceforge.io/gallery,,gallery} and -external links posted at @url{https://asymptote.sourceforge.io}) for -further examples, including two-dimensional and interactive -three-dimensional scientific graphs. Additional examples have been -posted by Philippe Ivaldi at @url{http://www.piprime.fr/asymptote}. - -@node Drawing commands, Bezier curves, Tutorial, Top -@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. - -@cindex @code{newpage} -A page break can be generated with the command -@verbatim -void newpage(picture pic=currentpicture); -@end verbatim - -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, fill, Drawing commands, Drawing commands -@section draw -@cindex @code{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)}. - -@cindex arrows -@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 real @code{position} (in the -sense of @code{point(path p, real t)}) along the path 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=begin)} -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=begin)} 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=begin)} -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{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}} and -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/sqrtx01.html,,sqrtx01}@uref{https://asymptote.sourceforge.io/gallery/sqrtx01.asy,,.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}) or @code{dotfilltype} -(@code{Fill} by default): -@verbatim -void dot(frame f, pair z, pen p=currentpen, filltype filltype=dotfilltype); -void dot(picture pic=currentpicture, pair z, pen p=currentpen, - filltype filltype=dotfilltype); -void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign, - string format=defaultformat, pen p=currentpen, filltype filltype=dotfilltype); -void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z, - align align=NoAlign, string format=defaultformat, pen p=currentpen, - filltype filltype=dotfilltype); -void dot(picture pic=currentpicture, path[] g, pen p=currentpen, - filltype filltype=dotfilltype); -void dot(picture pic=currentpicture, Label L, pen p=currentpen, - filltype filltype=dotfilltype); -@end verbatim - -@cindex @code{Label} -If the variable @code{Label} is given as the @code{Label} -argument to the third routine, the @code{format} argument will be -used to format a string based on the dot location (here @code{defaultformat} -is @code{"$%.4g$"}). -The fourth 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[], - explicit path g, align align=RightSide, string format=defaultformat, - pen p=currentpen, filltype filltype=dotfilltype); -@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, clip, draw, Drawing commands -@section fill -@cindex @code{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,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{@uref{https://asymptote.sourceforge.io/gallery/latticeshading.svg,,latticeshading}@uref{https://asymptote.sourceforge.io/gallery/latticeshading.asy,,.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, bool extenda=true, - pen penb, pair b, bool extendb=true); -@end verbatim -@noindent -The boolean parameters @code{extenda} and @code{extendb} indicate -whether the shading should extend beyond the axis endpoints @code{a} -and @code{b}. An example of axial shading is provided in the example file -@code{@uref{https://asymptote.sourceforge.io/gallery/axialshade.svg,,axialshade}@uref{https://asymptote.sourceforge.io/gallery/axialshade.asy,,.asy}}. - -@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, bool extenda=true, - pen penb, pair b, real rb, bool extendb=true); -@end verbatim -@noindent -The boolean parameters @code{extenda} and @code{extendb} indicate -whether the shading should extend beyond the radii @code{a} and @code{b}. -Illustrations of radial shading are provided in the example files -@code{@uref{https://asymptote.sourceforge.io/gallery/shade.svg,,shade}@uref{https://asymptote.sourceforge.io/gallery/shade.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/ring.pdf,,ring}@uref{https://asymptote.sourceforge.io/gallery/ring.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/shadestroke.pdf,,shadestroke}@uref{https://asymptote.sourceforge.io/gallery/shadestroke.asy,,.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{@uref{https://asymptote.sourceforge.io/gallery/Gouraud.pdf,,Gouraud}@uref{https://asymptote.sourceforge.io/gallery/Gouraud.asy,,.asy}}. -The edge flags used in Gouraud shading are documented here: -@quotation -@url{https://www.adobe.com/content/dam/acom/en/devnet/postscript/pdfs/TN5600.SmoothShading.pdf} -@end quotation - -@cindex Coons shading -@cindex tensor product shading -@cindex @code{tensorshade} -Tensor product shading using clipping path @code{g}, 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, pen fillrule=currentpen, path[] g, - pen[] p); -@end verbatim -@noindent -Illustrations of tensor product and Coons shading are provided in the -example files @code{@uref{https://asymptote.sourceforge.io/gallery/tensor.pdf,,tensor}@uref{https://asymptote.sourceforge.io/gallery/tensor.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/Coons.pdf,,Coons}@uref{https://asymptote.sourceforge.io/gallery/Coons.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.pdf,,BezierPatch}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.asy,,.asy}}, -and @code{@uref{https://asymptote.sourceforge.io/gallery/rainbow.pdf,,rainbow}@uref{https://asymptote.sourceforge.io/gallery/rainbow.asy,,.asy}}. - -@cindex Function shading -@cindex function shading -@cindex @code{functionshade} -More general shading possibilities are available using @TeX{} engines -that produce PDF output (@pxref{texengines}): 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{@uref{https://asymptote.sourceforge.io/gallery/functionshading.pdf,,functionshading}@uref{https://asymptote.sourceforge.io/gallery/functionshading.asy,,.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 - -@node clip, label, fill, Drawing commands -@section clip -@cindex @code{clip} -@cindex @code{stroke} -@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,zerowinding)}; in -this case the path @code{g} need not be cyclic. While clipping has no notion -of depth (it transcends layers and even pages), one can localize clipping -to a temporary picture, which can then be added to @code{pic}. -For an illustration of picture clipping, see the first example in @ref{LaTeX usage}. - -@node label, , clip, Drawing commands -@section label -@cindex @code{label} -@verbatim -void label(picture pic=currentpicture, Label L, pair position, - align align=NoAlign, pen p=currentpen, 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} -@cindex @code{Label} -@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}. -An explicit pen specified within the Label overrides other pen arguments. -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=currentpen, filltype filltype=NoFill); -@end verbatim -@cindex @code{Relative} -By default the label will be positioned at the midpoint of the path. -An alternative label position (in the sense of @code{point(path p, real t)}) -may be specified as a 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} and @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{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.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 Bezier curves, Programming, Drawing commands, Top -@chapter Bezier curves -@cindex Bezier curves -@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 3 and 2 ..(100,100)..(0,100)); -draw((100,0)..tension atleast 2 ..(100,100)..(0,100)); -@end verbatim - -In these examples there is a space between @code{2} and @code{..}. -This is needed as @code{2.} is interpreted as a numerical constant. - -@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). - -@node Programming, LaTeX usage, Bezier curves, Top -@chapter Programming -@cindex programming - -@menu -* Data types:: void, bool, int, real, pair, triple, string -* Paths and guides:: Bezier curves -* 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} modules -* Static:: Where to allocate your variable? -@end menu - -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. - -@node Data types, Paths and guides, Programming, Programming -@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} -@cindex @code{mask} -@cindex @code{inf} -@cindex @code{nan} -@cindex @code{isnan} -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}. -The variables @code{inf} and @code{nan}, along with the function -@code{bool isnan(real x)} are useful when floating-point exceptions -are masked with the @code{-mask} command-line option (the default in -interactive mode). - -@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} -@cindex @code{abs2} -returns the complex modulus @math{|@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)}. -The function @code{abs2(pair z)} returns @math{|@code{z}|^2}; - -@item real angle(pair z, bool warn=true) -@cindex @code{angle} -returns the angle of @code{z} in radians in the interval -[-@code{pi},@code{pi}] or @code{0} if @code{warn} is @code{false} and -@code{z=(0,0)} (rather than producing an error); - -@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=(0,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(explicit pair z, explicit pair w) -@cindex @code{dot} -returns the dot product @code{z.x*w.x+z.y*w.y}; - -@item real cross(explicit pair z, explicit pair w) -@cindex @code{cross} -returns the 2D scalar product @code{z.x*w.y-z.y*w.x}; - -@cindex @code{orient} -@item real orient(pair a, pair b, pair c); -returns a positive (negative) value if @code{a--b--c--cycle} is oriented -counterclockwise (clockwise) or zero if all three points are colinear. -Equivalently, a positive (negative) value is returned if -@code{c} lies to the left (right) of the line through @code{a} and @code{b} -or zero if @code{c} lies on this line. -The value returned can be expressed in terms of the 2D scalar cross product -as @code{cross(a-c,b-c)}, which is the determinant -@verbatim -|a.x a.y 1| -|b.x b.y 1| -|c.x c.y 1| -@end verbatim - -@cindex @code{incircle} -@item real incircle(pair a, pair b, pair c, pair d); -returns a positive (negative) value if @code{d} lies inside (outside) -the circle passing through the counterclockwise-oriented points @code{a,b,c} -or zero if @code{d} lies on the this circle. -The value returned is the determinant -@verbatim -|a.x a.y a.x^2+a.y^2 1| -|b.x b.y b.x^2+b.y^2 1| -|c.x c.y c.x^2+c.y^2 1| -|d.x d.y d.x^2+d.y^2 1| -@end verbatim - -@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} -@cindex @code{abs} -@cindex @code{abs2} -returns the length @math{|@code{v}|} of its argument @code{v}. -A synonym for @code{length(triple)} is @code{abs(triple)}. -The function @code{abs2(triple v)} returns @math{|@code{v}|^2}; - -@item real polar(triple v, bool warn=true) -@cindex @code{polar} -returns the colatitude of @code{v} measured from the @math{z} axis in radians -or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than -producing an error); - -@item real azimuth(triple v, bool warn=true) -@cindex @code{azimuth} -returns the longitude of @code{v} measured from the @math{x} axis in radians -or @code{0} if @code{warn} is @code{false} and @code{v.x=v.y=0} (rather than -producing an error); - -@item real colatitude(triple v, bool warn=true) -@cindex @code{colatitude} -returns the colatitude of @code{v} measured from the @math{z} axis in degrees -or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than -producing an error); - -@item real latitude(triple v, bool warn=true) -@cindex @code{latitude} -returns the latitude of @code{v} measured from the @math{xy} plane in degrees -or @code{0} if @code{warn} is @code{false} and @code{v=O} (rather than -producing an error); - -@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} (an empty delimiter signifies a space, -but with duplicate delimiters discarded); - -@cindex @code{array} -@cindex @code{operator +(...string[] a)}. -@item string[] array(string s) -returns an array of strings obtained by splitting @code{s} into -individual characters. The inverse operation is provided by -@code{operator +(...string[] a)}. - -@anchor{format} -@item string format(string s, int n, string locale="") -@cindex @code{format} -returns a string containing @code{n} 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. - -@item string format(string s=defaultformat, bool forcemath=false, string s=defaultseparator, 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 -if @code{s} specifies math mode or @code{forcemath=true}, @TeX{} is -used to typeset scientific notation using the -@code{defaultseparator="\!\times\!";}; - -@cindex @code{hex} -@cindex @code{hexadecimal} -@item int hex(string s); -casts a hexadecimal string @code{s} to an integer; - -@cindex @code{ascii} -@cindex @code{ascii} -@item int ascii(string s); -returns the ASCII code for the first character of string @code{s}; - -@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 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{system} -@item int system(string s) -@item int system(string[] s) -if the setting @code{safe} is false, call the arbitrary system command @code{s}; - -@cindex @code{asy} -@item void asy(string format, bool overwrite=false ... string[] s) -conditionally process each file name in array @code{s} in a new environment, -using format @code{format}, overwriting the output file only if -@code{overwrite} is true; - -@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{assert} -@item void assert(bool b, string s="") -aborts execution with an error message constructed from @code{s} if -@code{b=false}; - -@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, Pens, Data types, Programming -@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}: -@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} 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 -@cindex @code{ellipse} -@verbatim -path ellipse(pair c, real a, real b) -{ - return shift(c)*scale(a,b)*unitcircle; -} -@end verbatim - -A brace can be constructed between pairs @code{a} and @code{b} with -@cindex @code{brace} -@verbatim -path brace(pair a, pair b, real amplitude=bracedefaultratio*length(b-a)); -@end verbatim - -This example illustrates the use of all five guide connectors discussed -in @ref{Tutorial} and @ref{Bezier curves}: -@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 curves}). 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 curves}). - -@item pair dir(path p) -returns dir(p,length(p)). - -@item pair dir(path p, path q) -returns unit(dir(p)+dir(q)). - -@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 real 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. - -@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{arcpoint} -@item pair arcpoint(path p, real L); -returns @code{point(p,arctime(p,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 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{interior} -@item bool interior(int windingnumber, pen fillrule) -returns true if @code{windingnumber} corresponds to an interior point -according to @code{fillrule}. - -@cindex @code{inside} -@item bool inside(path p, pair z, pen fillrule=currentpen); -returns @code{true} iff the point @code{z} lies inside or on the edge of -the region bounded by the cyclic path @code{p} according to the fill -rule @code{fillrule} (@pxref{fillrule}). - -@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, Transforms, Paths and guides, Programming -@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 RGB(int r, int g, int 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,255]. - -@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 hexadecimal string can be converted to a pen with -the routine -@cindex @code{rgb} -@cindex @code{hexadecimal} -@verbatim -pen rgb(string s); -@end verbatim -@noindent -A pen can be converted to a hexadecimal string with -@cindex @code{hex} -@item string hex(pen p); - -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(real[] a, 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{a} is an array of real array numbers. -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(new real[]); -pen dotted=linetype(new real[] {0,4}); -pen dashed=linetype(new real[] {8,8}); -pen longdashed=linetype(new real[] {24,8}); -pen dashdotted=linetype(new real[] {8,8,0,8}); -pen longdashdotted=linetype(new real[] {24,8,0,8}); -pen Dotted(pen p=currentpen) {return linetype(new real[] {0,3})+2*linewidth(p);} -pen Dotted=Dotted(); -@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)}. -@cindex @code{linetype} -@cindex @code{offset} -@cindex @code{scale} -@cindex @code{adjust} -The line type of a pen can be determined with the functions -@code{real[] linetype(pen p=currentpen)}, -@code{real offset(pen p)}, @code{bool scale(pen p)}, and -@code{bool adjust(pen p)}. - -@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_pens} we define -@verbatim -void defaultpen(real w) {defaultpen(linewidth(w));} -pen operator +(pen p, real w) {return p+linewidth(w);} -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 basealign(pen p=currentpen)}. - -@cindex @code{fontsize} -@cindex @code{lineskip} -@cindex @code{defaultpen} -@cindex @code{type1cm} -@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{type1cm} package -available from -@quotation -@url{http://mirror.ctan.org/macros/latex/contrib/type1cm/} -@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 font -@cindex @LaTeX{} NFSS fonts -@cindex @code{font} -@item A pen using a specific @LaTeX{} NFSS font is returned -by calling the function @code{pen font(string encoding, string family, -string series, string shape)}. 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)}. - -@cindex @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 - -@cindex font -@cindex font encoding -@cindex input encoding -@cindex language context -@item Starting with the 2018/04/01 release, @LaTeX{} takes UTF-8 as -the new default input encoding. However, you can still set different input -encoding (so as the font, font encoding or even language context). -@noindent -@cindex Cyrillic -@cindex Russian -Here is an example for @code{cp1251} and Russian language in Cyrillic script -(font encoding @code{T2A}): -@verbatim -texpreamble("\usepackage[math]{anttor}"); -texpreamble("\usepackage[T2A]{fontenc}"); -texpreamble("\usepackage[cp1251]{inputenc}"); -texpreamble("\usepackage[russian]{babel}"); -@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{https://ctan.org/pkg/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 - - -@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{https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.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{@uref{https://asymptote.sourceforge.io/gallery/transparency.svg,,transparency}@uref{https://asymptote.sourceforge.io/gallery/transparency.asy,,.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 -module @code{patterns}: -@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 module @code{patterns}. 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, Frames and pictures, Pens, Programming -@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}. -@item transform zeroTransform; -@cindex @code{zeroTransform} -the zero transform; -@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. -The function @code{bool isometry(transform t)} can be used to test if @code{t} -is an isometry (preserves distance). - - -@node Frames and pictures, Files, Transforms, Programming -@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{keepAspect} -@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{keepAspect} -@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} -@cindex @code{outprefix} -@verbatim -void shipout(string prefix=defaultfilename, picture pic=currentpicture, - orientation orientation=orientation, - string format="", bool wait=false, bool view=true, - string options="", string script="", - light light=currentlight, projection P=currentprojection) -@end verbatim -@noindent -The default output format, @code{PostScript}, may be changed -with the @code{-f} or @code{-tex} command-line options. -The @code{options}, @code{script}, and @code{projection} parameters -are only relevant for 3D pictures. If @code{defaultfilename} is an -empty string, the prefix @code{outprefix()} will be used. - -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. - -@cindex @code{RadialShadeDraw} -@item RadialShadeDraw(real xmargin=0, real ymargin=xmargin, pen penc, - @code{pen penr, pen drawpen=nullpen)} -Fill with RadialShade and draw the boundary. - -@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 -pen @code{p}, using the function @code{bbox(p,Fill)}. - -@cindex @code{pad} -To pad a picture to a precise size in both directions, fit the picture -to a frame using the function -@verbatim -frame pad(picture pic=currentpicture, real xsize=pic.xsize, - real ysize=pic.ysize, filltype filltype=NoFill); -@end verbatim - -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 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 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 form 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}: -@cindex @code{attach} -@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, Variable initializers, Frames and pictures, Programming -@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. - -@cindex @code{input} -An input file can be opened with -@verbatim -input(string name="", bool check=true, string comment="#", string mode=""); -@end verbatim -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. If @code{Asymptote} is compiled with -support for @code{libcurl}, @code{name} can be a @acronym{URL}. - - -@anchor{cd} -@cindex @code{cd} -@cindex @code{noglobalread} -@cindex directory -Unless the @code{-noglobalread} command-line option is specified, -one can change the current working directory for read operations 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, string comment="#", string mode=""); -@end verbatim -@noindent -@cindex @code{noglobalread} -@cindex @code{globalwrite} -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. -Reading from files in other directories is allowed unless the -@code{-noglobalread} command-line option is specified. -@cindex @code{mktemp} -The function @code{string mktemp(string s)} may be used to create and -return the name of a unique temporary file in the current directory -based on the string @code{s}. - -@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{DOSendl} -@cindex @code{DOSnewl} -@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{DOSendl} (terminate with a DOS newline and flush), -@code{DOSnewl} (terminate with a DOS 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 single precision -@cindex double precision -@cindex @code{singlereal} -@cindex @code{singleint} -@cindex @code{signedint} -@cindex @code{mode} -@cindex @code{binary} -@cindex @code{xdr} -A file may be opened with @code{mode="xdr"}, to read or write -double precision (64-bit) reals and single precision (32-bit) -integers in Sun Microsystem's @acronym{XDR} (External -Data Representation) portable binary format (available on all -@code{UNIX} platforms). -Alternatively, a file may also be opened with @code{mode="binary"} -to read or write double precision reals and single -precision integers in the native (nonportable) machine binary format, -or to read the entire file into a string. -The virtual member functions -@code{file singlereal(bool b=true)} and @code{file singleint(bool b=true)} -be used to change the precision of real and integer I/O -operations, respectively, for an @acronym{XDR} or binary file @code{f}. -Similarly, the function @code{file signedint(bool b=true)} -can be used to modify the signedness of integer reads and writes for -an @acronym{XDR} or binary file @code{f}. - -@cindex @code{name} -@cindex @code{mode} -@cindex @code{singlereal} -@cindex @code{singleint} -@cindex @code{signedint} -The virtual members @code{name}, @code{mode}, @code{singlereal}, -@code{singleint}, and @code{signedint} may be used to query the -respective parameters for a given file. - -@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} -@cindex @code{globalwrite} -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}. - -@node Variable initializers, Structures, Files, Programming -@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. - -@cindex @code{var} -The special type @code{var} may be used to infer the type of a variable from -its initializer. If the initializer is an expression of a unique type, then -the variable will be defined with that type. For instance, -@verbatim -var x=5; -var y=4.3; -var reddash=red+dashed; -@end verbatim -@noindent -is equivalent to -@verbatim -int x=5; -real y=4.3; -pen reddash=red+dashed; -@end verbatim - -@code{var} may also be used with the extended @code{for} loop syntax. - -@verbatim -int[] a = {1,2,3}; -for (var x : a) - write(x); -@end verbatim - -@node Structures, Operators, Variable initializers, Programming -@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; -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; -T foo; -@end verbatim -@noindent -Here, @code{new T} produces a new instance of the class, which -causes @code{Tcount} to be incremented, tracking the -number of instances produced. The declarations @code{T foo=new T} and -@code{T foo} are equivalent: the second form implicitly creates a new -instance of @code{T}. -That is, 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 - -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}). -In example at the beginning of this 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). - -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; -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}, along with the cumulative -wall clock time in @code{parent.clock}, all measured in seconds. -For convenience, the incremental fields @code{change.user}, -@code{change.system}, and @code{change.clock} indicate the change in -the corresponding fields 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; - void operator init(int x) {this.x=x;} - void virtual(int) {write(0);} - void f() {virtual(1);} -} - -void write(parent p) {write(p.x);} - -struct child { - parent parent; - real y=3; - void operator init(int x) {parent.operator init(x);} - void virtual(int x) {write(x);} - parent.virtual=virtual; - void f()=parent.f; -} - -parent operator cast(child child) {return child.parent;} - -parent p=parent(1); -child c=child(2); - -write(c); // Outputs 2; - -p.f(); // Outputs 0; -c.f(); // Outputs 1; - -write(c.parent.x); // Outputs 2; -write(c.y); // Outputs 3; -@end verbatim - -For further examples of structures, see @code{Legend} and @code{picture} in -the @code{Asymptote} base module @code{plain}. - -@node Operators, Implicit scaling, Structures, Programming -@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, Self & prefix operators, Operators, Operators -@subsection Arithmetic & logical operators -@cindex arithmetic operators -@cindex binary operators -@cindex boolean operators -@cindex logical operators -@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 typically what is intended; otherwise -one can use the function @code{int quotient(int x, int y)}, which returns -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 integer division -@cindex @code{#} -@item # -integer division; equivalent to @code{quotient(x,y)}. Noting that the -@code{Python3} community adopted our comment symbol (@code{//}) for -integer division, we decided to reciprocate and use their comment -symbol for integer division in @code{Asymptote}! -@cindex @code{%} -@item % -modulo; the result always has the same sign as the divisor. -In particular, this makes @code{q*(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} -@cindex @code{CLZ} -@cindex @code{CTZ} -@code{Asymptote} also defines bitwise functions @code{int AND(int,int)}, -@code{int OR(int,int)}, @code{int XOR(int,int)}, @code{int NOT(int)}, -@code{int CLZ(int)} (count leading zeros), -@code{int CTZ(int)} (count trailing zeros), -@code{int popcount(int)} (count bits populated by ones), and -@code{int bitreverse(int a, int bits)} (reverse bits within a word of -length bits). - -@node Self & prefix operators, User-defined operators, Arithmetic & logical, 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{#}, @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, , Self & prefix operators, 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, Functions, Operators, Programming -@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, Arrays, Implicit scaling, Programming -@section Functions -@cindex functions - -@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 - -@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. - -Function 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} -@cindex stack overflow -@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). - -@node Default arguments, Named arguments, Functions, Functions -@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, Rest arguments, Default arguments, Functions -@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. - -@cindex @code{keyword} -@cindex keyword-only -Parameters can be specified as ``keyword-only'' by putting @code{keyword} -immediately before the parameter name, as in @code{int f(int keyword x)} or -@code{int f(int keyword x=77)}. This forces the caller of the function to use -a named argument to give a value for this parameter. That is, @code{f(x=42)} -is legal, but @code{f(25)} is not. Keyword-only parameters must be listed -after normal parameters in a function definition. - - -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, Mathematical functions, Named arguments, Functions -@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. - -In some cases, keyword-only parameters are helpful to avoid arguments intended -for the rest parameter to be assigned to other parameters. For example, here -the use of @code{keyword} is to avoid @code{pnorm(1.0,2.0,0.3)} matching -@code{1.0} to @code{p}. -@verbatim -real pnorm(real keyword p=2.0 ... real[] v) -{ - return sum(v^p)^(1/p); -} -@end verbatim - -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, , Rest arguments, 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{Jn(int n, real)} and second kind -@code{Yn(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 module @code{stats}. -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{sncndn} -@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{https://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 Jacobi elliptic functions @code{real[] sncndn(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 integral -@cindex integrate -@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, Casts, Functions, Programming -@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{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{int cyclic}, -@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.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 @code{@{0,1,...,n-1@}}. 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{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 @code{value}. -If @code{value} is itself an array, a deep copy of @code{value} is made -for each entry. If @code{depth} is specified, this deep copying only -recurses to the specified number of levels; - -@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{map} -@item T2[] map(T2 f(T1), T1[] a) -constructed by calling @code{mapArray("T1","T2")}, returns the array -obtained by applying the function @code{f} to each element of the -array @code{a}; - -@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[] a, int n=1) -returns the index of the @code{n}th @code{true} value in the boolean array -@code{a} 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{findall} -@item int[] findall(bool[] a) -returns the indices of all @code{true} values in the boolean array @code{a}; - -@cindex @code{search} -@item int search(T[] a, T key) -For built-in ordered types @code{T}, searches a sorted array -@code{a} of @code{n} elements for k, returning the index @code{i} -if @code{a[i] <= key < a[i+1]}, @code{-1} if @code{key} is -less than all elements of @code{a}, or @code{n-1} if @code{key} is -greater than or equal to the last element of @code{a}; - -@cindex @code{search} -@item int search(T[] a, T key, bool less(T i, T j)) -searches an array @code{a} sorted in ascending order such that element -@code{i} precedes element @code{j} if @code{less(i,j)} is true; - -@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 given one-dimensional -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; - -@cindex @code{sort} -@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 less(T i, T j), bool stable=true) -returns a copy of @code{a} sorted in ascending order such that -element @code{i} precedes element @code{j} if @code{less(i,j)} is -true, subject to (if @code{stable} is @code{true}) the stability constraint -that the original order of elements @code{i} and @code{j} is preserved if -@code{less(i,j)} and @code{less(j,i)} are both @code{false}; - -@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 unnormalized 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{fft} -@item pair[][] fft(pair[][] a, int sign=1) -returns the unnormalized two-dimensional Fourier transform of @code{a} -using the given @code{sign}; - -@cindex @code{fft} -@item pair[][][] fft(pair[][][] a, int sign=1) -returns the unnormalized three-dimensional Fourier transform of -@code{a} using the given @code{sign}; - -@cindex @code{dot} -@item real dot(real[] a, real[] b) -returns the dot product of the vectors @code{a} and @code{b}; - -@cindex @code{dot} -@item pair dot(pair[] a, pair[] b) -returns the complex dot product @code{sum(a*conj(b))} 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 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). - -The virtual members @code{dimension}, @code{line}, @code{csv}, -@code{word}, and @code{read} of a file are useful for reading arrays. -@cindex @code{line} -For example, if line mode is set with @code{file line(bool b=true)}, then -reading will stop once the end of the line is reached instead: -@verbatim -file fin=input("test.txt"); -real[] A=fin.line(); -@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, -@code{file word(bool b=true)}, which causes string reads to respect -white-space delimiters, instead of the default end-of-line delimiter: -@verbatim -file fin=input("test.txt").line().word(); -real[] A=fin; -@end verbatim - -@cindex @code{csv} -@cindex comma-separated-value mode -Another useful mode is comma-separated-value mode, -@code{file csv(bool b=true)}, which causes reads to respect comma delimiters: -@verbatim -file fin=input("test.txt").csv(); -real[] A=fin; -@end verbatim - -@cindex @code{dimension} -To restrict the number of values read, use the @code{file dimension(int)} -function: -@verbatim -file fin=input("test.txt"); -real[] A=fin.dimension(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=fin.dimension(2,3); -real[][][] B=fin.dimension(2,3,4); -@end verbatim -@noindent - -@cindex @code{read} -Sometimes the array dimensions are stored with the data as integer -fields at the beginning of an array. Such 1, 2, or 3 dimensional -arrays can be read in with the virtual member functions -@code{read(1)}, @code{read(2)}, or @code{read(3)}, respectively: -@verbatim -file fin=input("test.txt"); -real[] A=fin.read(1); -real[][] B=fin.read(2); -real[][][] C=fin.read(3); -@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, , Arrays, Arrays -@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, Import, Arrays, Programming -@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 module @code{three}. -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 -In situations where casting from a string to a type @code{T} fails, -an uninitialized variable is returned; this condition can be detected -with the function @code{bool initialized(T);} -@verbatim -int i=(int) "2.5"; -assert(initialized(i),"Invalid cast."); - -real x=(real) "2.5a"; -assert(initialized(x),"Invalid cast."); -@end verbatim - -@cindex @code{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 -@noindent -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 @code{operator ecast} -Explicit casts are implemented similarly, with @code{operator ecast}. - -@node Import, Static, Casts, Programming -@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} -@cindex @code{access} -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;} - -@cindex @acronym{URL} -@cindex @acronym{libcurl} -If @code{Asymptote} is compiled with support for @code{libcurl}, -the file name can even be a @acronym{URL}: -@noindent -@code{import "https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/axis3.asy" as axis3;} - -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 - -One application of @code{eval} is the creation of parametrized Asymptote -code, such as a map from one type to another (@pxref{map}). - -@cindex @code{include} -To include the contents of an existing 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, , Import, Programming -@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 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, Base modules, Programming, Top -@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} (v1.36 or later required) 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 trailing commands/comments. -A blank line is not allowed after @code{\begin@{asy@}}. - -The sample @code{LaTeX} file below, named @code{latexusage.tex}, can -be run as follows: -@verbatim -latex latexusage -asy latexusage-*.asy -latex latexusage -@end verbatim - -@noindent -or -@verbatim -pdflatex latexusage -asy latexusage-*.asy -pdflatex latexusage -@end verbatim -@noindent -To switch between using inline Asymptote code with @code{latex} and -@code{pdflatex} you may first need to remove the files @code{latexusage-*.tex}. - -@cindex @code{latexmk} -@cindex @code{perl} -An even better method for processing a @code{LaTeX} file with embedded -@code{Asymptote} code is to use the @code{latexmk} utility from -@quotation -@url{http://mirror.ctan.org/support/latexmk/} -@end quotation -@noindent -after putting the contents of -@url{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc} -@noindent -in a file @code{latexmkrc} in the same directory. The command -@verbatim -latexmk -pdf latexusage -@end verbatim -@noindent -will then call @code{Asymptote} automatically, recompiling only the figures -that have changed. Since each figure is compiled in a separate -system process, this method also tends to use less memory. -To store the figures in a separate directory named @code{asy}, one can define -@verbatim -\def\asydir{asy} -@end verbatim -in @code{latexusage.tex} and put the contents of -@url{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc_asydir} -in a file @code{latexmkrc} in the same directory. -@noindent -External @code{Asymptote} code can be included with -@cindex @code{asyinclude} -@verbatim -\asyinclude[<options>]{<filename.asy>} -@end verbatim -@noindent -so that @code{latexmk} will recognize when the code is changed. Note that -@code{latemk} requires @code{perl}, available from @url{https://www.perl.org/}. - -@cindex @code{width} -@cindex @code{height} -@cindex @code{keepAspect} -@cindex @code{viewportwidth} -@cindex @code{viewportheight} -@cindex @code{attach} -@cindex @code{inline} -One can specify @code{width}, @code{height}, @code{keepAspect}, -@code{viewportwidth}, @code{viewportheight}, @code{attach}, and @code{inline}. -@code{keyval}-style options to the @code{asy} and @code{asyinclude} -environments. -Three-dimensional @acronym{PRC} files may either be embedded within -the page (the default) or attached as annotated (but printable) -attachments, using the @code{attach} option and the @code{attachfile2} -(or older @code{attachfile}) @code{LaTeX} package. -The @code{inline} option generates -inline @code{LaTeX} code instead of @acronym{EPS} or @acronym{PDF} -files. This makes 2D LaTeX symbols visible to the -@code{\begin@{asy@}...\end@{asy@}} environment. In this mode, -Asymptote correctly aligns 2D 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 the @code{latex} @TeX{} engine is used with the -@code{inline} option, 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). - -Here now is @code{latexusage.tex}: -@verbatiminclude latexusage.tex -@page -@image{./latexusage,,25cm} - -@node Base modules, Options, LaTeX usage, Top -@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 -* map:: Map keys to values -* 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 -* 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 -* smoothcontour3:: Smooth implicit surfaces -* slopefield:: Slope fields -* ode:: Ordinary differential equations -@end menu - -@node plain, simplex, Base modules, Base modules -@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, math, plain, Base modules -@section @code{simplex} -@cindex @code{simplex} -@cindex @code{deferred drawing} -This module 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, interpolate, simplex, Base modules -@section @code{math} -@cindex @code{math} -This module extends @code{Asymptote}'s mathematical capabilities with -useful functions such as - -@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 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}. - -@cindex @code{time} -@item real time(path g, real x, int n=0) -returns the @code{n}th intersection time of path @code{g} with the vertical -line through x. - -@cindex @code{time} -@item real time(path g, explicit pair z, int n=0) -returns the @code{n}th intersection time of path @code{g} with the horizontal -line through @code{(0,z.y)}. - -@cindex @code{value} -@item real value(path g, real x, int n=0) -returns the @code{n}th @code{y} value of @code{g} at @code{x}. - -@cindex @code{value} -@item real value(path g, explicit pair z, int n=0) -returns the @code{n}th @code{x} value of @code{g} at @code{y=z.y}. - -@cindex @code{slope} -@item real slope(path g, real x, int n=0) -returns the @code{n}th slope of @code{g} at @code{x}. - -@cindex @code{slope} -@item real slope(path g, explicit pair z, int n=0) -returns the @code{n}th slope of @code{g} at @code{y=z.y}. - -@cindex @code{segment} -int[][] segment(bool[] b) -returns the indices of consecutive true-element segments of bool[] @code{b}. - -@cindex @code{partialsum} -@item real[] partialsum(real[] a) -returns the partial sums of a real array @code{a}. - -@cindex @code{partialsum} -@item real[] partialsum(real[] a, real[] dx) -returns the partial @code{dx}-weighted sums of a real array @code{a}. - -@cindex @code{increasing} -@item bool increasing(real[] a, bool strict=false) -returns, if @code{strict=false}, whether @code{i > j} implies -@code{a[i] >= a[j]}, or if @code{strict=true}, whether @code{i > j} implies -implies @code{a[i] > a[j]}. - -@cindex @code{unique} -@item int unique(real[] a, real x) -if the sorted array @code{a} does not contain @code{x}, insert it -sequentially, returning the index of @code{x} in the resulting array. - -@cindex @code{lexorder} -@item bool lexorder(pair a, pair b) -returns the strict lexicographical partial order of @code{a} and @code{b}. - -@cindex @code{lexorder} -@item bool lexorder(triple a, triple b) -returns the strict lexicographical partial order of @code{a} and @code{b}. -@end table - -@node interpolate, geometry, math, Base modules -@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, trembling, interpolate, Base modules -@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. Link to the documentation for the @code{geometry} module -are posted here: -@url{https://asymptote.sourceforge.io/links.html}, -including an extensive set of examples, -@url{http://www.piprime.fr/files/asymptote/geometry/}, and an index: -@quotation -@url{http://www.piprime.fr/files/asymptote/geometry/modules/geometry.asy.index.type.html} -@end quotation - -@node trembling, stats, geometry, Base modules -@section @code{trembling} -@cindex @code{trembling} -This module, written by Philippe Ivaldi and illustrated in the example -@code{@uref{https://asymptote.sourceforge.io/gallery/floatingdisk.svg,,floatingdisk}@uref{https://asymptote.sourceforge.io/gallery/floatingdisk.asy,,.asy}}, allows one to draw wavy lines, as if drawn by -hand. - -@node stats, patterns, trembling, Base modules -@section @code{stats} -@cindex @code{stats} -@cindex @code{leastsquares} -This module implements a Gaussian random number generator -and a collection of statistics routines, including @code{histogram} -and @code{leastsquares}. - -@node patterns, markers, stats, Base modules -@section @code{patterns} -@cindex @code{patterns} -This module implements @code{PostScript} tiling patterns and includes -several convenient pattern generation routines. - -@node markers, tree, patterns, Base modules -@section @code{markers} -@cindex @code{markers} -This module implements specialized routines for marking paths and angles. -The principal mark routine provided by this module 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{@uref{https://asymptote.sourceforge.io/gallery/markers1.svg,,markers1}@uref{https://asymptote.sourceforge.io/gallery/markers1.asy,,.asy}} illustrates the -use of these markers: - -@sp 1 -@center @image{./markers1} - -This module 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{@uref{https://asymptote.sourceforge.io/gallery/markers2.svg,,markers2}@uref{https://asymptote.sourceforge.io/gallery/markers2.asy,,.asy}}. - -@sp 1 -@center @image{./markers2} - -@node map, tree, markers, Base modules -@section @code{map} -@cindex @code{map} -This module creates a struct parameterized by the types specified in -strings @code{key} and @code{value}, mapping keys to values with a -specified default: -@verbatim -import map; - -mapTemplate(name="map",key="string",value="int",default="-1"); - -map M; - -M.add("z",2); -M.add("a",3); -M.add("d",4); -write(M.lookup("a")); -write(M.lookup("y")); -@end verbatim - -@node tree, binarytree, markers, Base modules -@section @code{tree} -@cindex @code{tree} -This module implements an example of a dynamic binary search tree. - -@node binarytree, drawtree, tree, Base modules -@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{@uref{https://asymptote.sourceforge.io/gallery/binarytreetest.svg,,binarytreetest}@uref{https://asymptote.sourceforge.io/gallery/binarytreetest.asy,,.asy}}: -@verbatiminclude binarytreetest.asy -@sp 1 -@center @image{./binarytreetest} - -@node drawtree, syzygy, binarytree, Base modules -@section @code{drawtree} -@cindex @code{drawtree} -This is a simple tree drawing module used by the example @code{@uref{https://asymptote.sourceforge.io/gallery/treetest.svg,,treetest}@uref{https://asymptote.sourceforge.io/gallery/treetest.asy,,.asy}}. - -@node syzygy, feynman, drawtree, Base modules -@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{@uref{https://asymptote.sourceforge.io/gallery/knots.svg,,knots}@uref{https://asymptote.sourceforge.io/gallery/knots.asy,,.asy}}. - -@node feynman, roundedpath, syzygy, Base modules -@section @code{feynman} -@cindex @code{feynman} -This module, contributed by Martin Wiebusch, is useful for drawing -Feynman diagrams, as illustrated by the examples @code{@uref{https://asymptote.sourceforge.io/gallery/eetomumu.svg,,eetomumu}@uref{https://asymptote.sourceforge.io/gallery/eetomumu.asy,,.asy}} -and @code{@uref{https://asymptote.sourceforge.io/gallery/fermi.svg,,fermi}@uref{https://asymptote.sourceforge.io/gallery/fermi.asy,,.asy}}. - -@node roundedpath, animation, feynman, Base modules -@section @code{roundedpath} -@cindex @code{roundedpath} -This module, contributed by Stefan Knorr, is useful for rounding the -sharp corners of paths, as illustrated in the example file @code{@uref{https://asymptote.sourceforge.io/gallery/roundpath.svg,,roundpath}@uref{https://asymptote.sourceforge.io/gallery/roundpath.asy,,.asy}}. - -@node animation, embed, roundedpath, Base modules -@section @code{animation} -@cindex @code{animation} -@cindex @code{convert} -@cindex animation -@cindex @code{ImageMagick} -This module allows one to generate animations, as illustrated by the -files @code{@uref{https://asymptote.sourceforge.io/gallery/animations/wheel.gif,,wheel}@uref{https://asymptote.sourceforge.io/gallery/animations/wheel.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/animations/wavepacket.gif,,wavepacket}@uref{https://asymptote.sourceforge.io/gallery/animations/wavepacket.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/animations/cube.gif,,cube}@uref{https://asymptote.sourceforge.io/gallery/animations/cube.asy,,.asy}} in -the @code{animations} subdirectory of the examples directory. These -animations use the @code{ImageMagick} @code{convert} program to -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 module -@quotation -@url{http://mirror.ctan.org/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{@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.pdf,,pdfmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.asy,,.asy}} in the @code{animations} -directory, along with the slide presentations @code{@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.pdf,,slidemovies}@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.asy,,.asy}} -and @code{@uref{https://asymptote.sourceforge.io/intro.pdf,,intro}}, 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://mirror.ctan.org/macros/latex/contrib/animate/doc/animate.pdf} -@end quotation - -@node embed, slide, animation, Base modules -@section @code{embed} -@cindex @code{embed} -This module provides an interface to the @code{LaTeX} package -(included with @code{MikTeX}) -@quotation -@url{http://mirror.ctan.org/macros/latex/contrib/media9} -@end quotation -@noindent -for embedding movies, sounds, and 3D objects into a @acronym{PDF} document. - -@cindex @code{external} -A more portable method for embedding movie files, which should work on any -platform and does not require the @code{media9} package, is provided -by using the @code{external} module instead of @code{embed}. - -Examples of the above two interfaces is provided in the file -@code{embeddedmovie.asy} in the @code{animations} subdirectory of the -examples directory and in -@code{@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.pdf,,externalmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.asy,,.asy}}. -For a higher quality embedded 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}). - -@cindex @code{U3D} -An example of embedding @code{U3D} code is provided in the file -@code{embeddedu3d}. - -@node slide, MetaPost, embed, Base modules -@section @code{slide} -@cindex @code{slide} -This module provides a simple yet high-quality facility for making -presentation slides, including portable embedded @acronym{PDF} animations (see -the file @code{@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.pdf,,slidemovies}@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.asy,,.asy}}). A simple example is provided in -@code{slidedemo.asy}. - -@node MetaPost, babel, slide, Base modules -@section @code{MetaPost} -@cindex @code{MetaPost} -This module 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 babel, labelpath, MetaPost, Base modules -@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, labelpath3, babel, Base modules -@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{@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.svg,,curvedlabel}@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.asy,,.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 module requires the -@code{latex} tex engine and inherits the limitations of the -@code{PSTricks} @code{\pstextpath} macro. - -@node labelpath3, annotate, labelpath, Base modules -@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{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/curvedlabel3.html,,curvedlabel3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/curvedlabel3.asy,,.asy}}. - -@node annotate, CAD, labelpath3, Base modules -@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{@uref{https://asymptote.sourceforge.io/gallery/annotation.pdf,,annotation}@uref{https://asymptote.sourceforge.io/gallery/annotation.asy,,.asy}}. -Currently, annotations are only implemented for the @code{latex} -(default) and @code{tex} @TeX{} engines. - -@node CAD, graph, annotate, Base modules -@section @code{CAD} -@cindex @code{CAD} -This module, 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, palette, CAD, Base modules -@section @code{graph} -@cindex @code{graph} -@cindex 2D graphs -This module 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 -The 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{notaknot} -@cindex @code{natural} -@cindex @code{periodic} -@cindex @code{clamped} -@cindex @code{monotonic} -@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. - -@item -@verbatim -guide polargraph(picture pic=currentpicture, real[] r, real[] theta, - interpolate join=operator--); -@end verbatim -Returns a polar-coordinate graph using the scaling information for -picture @code{pic} of the elements of the arrays (@code{r},@code{theta}), -using 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 @code{pic} 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 the -module @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 - -@cindex @code{OmitTick} -@cindex @code{OmitTickInterval} -@cindex @code{OmitTickIntervals} -For convenience, the predefined tickmodifiers @code{OmitTick(... real[] x)}, -@code{OmitTickInterval(real a, real b)}, and -@code{OmitTickIntervals(real[] a, real[] b)} -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, - bool autorotate=true); -@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 -a Label @code{L} that is autorotated unless @code{autorotate=false}. -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 @code{pic} 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="", - bool extend=true, - 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 @code{pic} 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 @code{pic} 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=currentpen); -void labelx(picture pic=currentpicture, Label L="", real x, - align align=S, string format="", pen p=currentpen); -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=currentpen); -void labely(picture pic=currentpicture, Label L="", real y, - align align=W, string format="", pen p=currentpen); -void labely(picture pic=currentpicture, Label L, - string format="", explicit pen p=currentpen); -@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 (@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} -@cindex path markers -@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} -@cindex error bars -@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 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 truesize=false, - real maxlength=truesize ? 0 : maxlength(a,b,nx,ny), - bool cond(pair z)=null, pen p=currentpen, - arrowbar arrow=Arrow, margin margin=PenMargin) -@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{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.svg,,diatom}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.svg,,westnile}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.asy,,.asy}}, using the comma-separated -data in @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.csv,,diatom.csv}} and @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.csv,,westnile.csv}}. -@page - -@sp 1 -@center @image{./diatom} -@sp 1 -@center @image{./westnile,,7.5cm} -@end enumerate - -@page -@node palette, three, graph, Base modules -@section @code{palette} -@anchor{images} -@cindex 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{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.svg,,imagecontour}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.asy,,.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 -or a function @code{pen f(int, int)}: -@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); -void image(picture pic=currentpicture, pen f(int, int), int width, int height, - pair initial, pair final, - bool transpose=(initial.x < final.x && initial.y < final.y), - bool antialias=false); -@end verbatim -@noindent -as illustrated in the following examples: - -@anchor{penimage} -@verbatiminclude penimage.asy -@sp 1 -@center @image{./penimage} - -@anchor{penfunctionimage} -@verbatiminclude penfunctionimage.asy -@sp 1 -@center @image{./penfunctionimage} - -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, obj, palette, Base modules -@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} -@cindex @code{render} -@cindex @code{defaultrender} -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=nolight, string name="", - render render=defaultrender); -void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1, - material[] surfacepen, pen meshpen, - light light=currentlight, light meshlight=nolight, string name="", - render render=defaultrender); -void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1, - material[] surfacepen, pen[] meshpen=nullpens, - light light=currentlight, light meshlight=nolight, string name="", - render render=defaultrender); - -@end verbatim -The parameters @code{nu} and @code{nv} specify the number of subdivisions -for drawing optional mesh lines for each Bezier patch. The optional -@code{name} parameter is used as a prefix for naming the surface -patches in the @acronym{PRC} model tree. -Here material is a structure defined in @code{three_light.asy}: -@cindex @code{material} -@cindex @code{diffusepen} -@cindex @code{emissivepen} -@cindex @code{specularpen} -@cindex @code{opacity} -@cindex @code{shininess} -@cindex @code{metallic} -@cindex @code{freshnel0} -@verbatim -struct material { - pen[] p; // diffusepen,emissivepen,specularpen - real opacity; - real shininess; - real metallic; - real fresnel0; -} -@end verbatim -@noindent -@cindex @code{PBR} -@cindex @code{physically based rendering} -These material properties are used to implement physically based -rendering (PBR) using light properties defined in @code{plain_prethree.asy} -and @code{three_light.asy}: -@cindex @code{light} -@cindex @code{diffuse} -@cindex @code{specular} -@cindex @code{background} -@cindex @code{specularfactor} -@cindex @code{position} -@cindex @code{currentlight} -@cindex @code{Viewport} -@cindex @code{White} -@cindex @code{Headlamp} -@cindex @code{nolight} -@verbatim -struct light { - real[][] diffuse; - real[][] specular; - pen background=nullpen; // Background color of the canvas. - real specularfactor; - triple[] position; // Only directional lights are currently implemented. -} - -light Viewport=light(specularfactor=3,(0.25,-0.25,1)); - -light White=light(new pen[] {rgb(0.38,0.38,0.45),rgb(0.6,0.6,0.67), - rgb(0.5,0.5,0.57)},specularfactor=3, - new triple[] {(-2,-1.5,-0.5),(2,1.1,-2.5),(-0.5,0,2)}); - -light Headlamp=light(gray(0.8),specular=gray(0.7), - specularfactor=3,dir(42,48)); - -currentlight=Headlamp; - -light nolight; -@end verbatim -@cindex @code{background} -@cindex @code{transparent} -The @code{currentlight.background} (or @code{background} member of the -specified @code{light}) can be used -to set the background colour for 2D (or 3D) images. The default -background is white for @code{HTML} images and transparent for all -other formats. One can request a completely transparent background for -3D @code{WebGL} images with -@code{currentlight.background=black+opacity(0.0);} - -Sample Bezier surfaces are -contained in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.html,,BezierSurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.html,,teapot}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.asy,,.asy}}, -and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}. The structure @code{render} contains -specialized rendering options documented at the beginning of module -@code{three}. - -@cindex patch-dependent colors -@cindex vertex-dependent colors -The examples -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.html,,elevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.html,,sphericalharmonic}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.asy,,.asy}} -illustrate how to draw a surface with patch-dependent colors. -The examples @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.html,,vertexshading}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.html,,smoothelevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.asy,,.asy}} illustrate -vertex-dependent colors, which are supported by -@code{Asymptote}'s native @code{OpenGL}/@code{WebGL} renderers -and the two-dimensional vector output format (@code{settings.render=0}). 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} -@cindex @code{Bezier patch} -@cindex @code{Bezier triangle} -A surface can be constructed from a cyclic @code{path3} with the constructor -@verbatim -surface surface(path3 external, triple[] internal=new triple[], - pen[] colors=new pen[], bool3 planar=default); -@end verbatim -@noindent -and then filled: -@verbatim -draw(surface(unitsquare3,new triple[] {X,Y,Z,O}),red); -draw(surface(O--X{Y}..Y{-X}--cycle,new triple[] {Z}),red); -draw(surface(path3(polygon(5))),red,nolight); -draw(surface(unitcircle3),red,nolight); -draw(surface(unitcircle3,new pen[] {red,green,blue,black}),nolight); -@end verbatim -@noindent -The first example draws a Bezier patch and the second example draws -a Bezier triangle. The third and fourth examples are planar surfaces. -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 (according to the @code{zerowinding} fill rule) -by simple cyclic paths (intersecting only at the endpoints) -into subregions bounded by cyclic paths of length @code{4} or less. - -A more efficient routine also exists for drawing tessellations -composed of many 3D triangles, with specified vertices, and optional -normals or vertex colors: -@cindex @code{draw} -@cindex @code{triangles} -@cindex @code{tessellation} -@verbatim -void draw(picture pic=currentpicture, triple[] v, int[][] vi, - triple[] n={}, int[][] ni=vi, material m=currentpen, pen[] p={}, - int[][] pi=vi, light light=currentlight); -@end verbatim -Here, the triple array @code{v} lists the (typically distinct) vertices, while -the array @code{vi} contains integer arrays of length 3 containing -the indices of the elements in @code{v} that form the vertices of each -triangle. Similarly, the arguments @code{n} and @code{ni} contain -optional normal data and @code{p} and @code{pi} contain optional pen -vertex data. If more than one normal or pen is specified for a vertex, the -last one specified is used. -An example of this tessellation facility is given in @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triangles.html,,triangles}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triangles.asy,,.asy}}. - -@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 -@verbatim -tube tube(path3 p, real width, render render=defaultrender); -@end verbatim -@noindent -this returns a tube structure representing a tube of diameter @code{width} -centered approximately on @code{g}. The tube structure consists of a -surface @code{s} and the actual tube center, path3 @code{center}. -Drawing thick lines as tubes can be 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 @code{plain_pens.asy} can -also be used to override these defaults for specific draw commands. - -@noindent -There are five choices for viewing 3D @code{Asymptote} output: -@enumerate - -@cindex @code{OpenGL} -@cindex @code{render} -@cindex @code{outformat} -@cindex @code{multisample} -@cindex @code{devicepixelratio} -@cindex @code{position} -@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}). On @code{UNIX} systems with -graphics support for multisampling, the sample width can be -controlled with the setting @code{multisample}. The ratio of physical to -logical screen pixels can be specified with the setting @code{devicepixelratio}. 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 default settings -@cindex mouse bindings -@verbatim -import settings; -leftbutton=new string[] {"rotate","zoom","shift","pan"}; -middlebutton=new string[] {""}; -rightbutton=new string[] {"zoom","rotateX","rotateY","rotateZ"}; -wheelup=new string[] {"zoomin"}; -wheeldown=new string[] {"zoomout"}; -@end verbatim -bind the mouse buttons as follows: -@itemize -@item Left: rotate -@item Shift Left: zoom -@item Ctrl Left: shift viewport -@item Alt Left: pan -@item Wheel Up: zoom in -@item Wheel Down: zoom out -@item Right: zoom -@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/patch/mesh) -@item e: export -@item c: show camera parameters -@item p: play animation -@item r: reverse animation -@item : step animation -@item +: expand -@item =: expand -@item >: expand -@item -: shrink -@item _: shrink -@item <: shrink -@item q: exit -@item Ctrl-q: exit -@end itemize - -@cindex @code{WebGL} -@cindex @code{HTML5} -@cindex @code{mobile browser} -@item Generate @code{WebGL} interactive vector graphics -output with the the command-line option and @code{-f html} -(or the setting @code{outformat="html"}). The resulting -3D @acronym{HTML} file can then be viewed directly in any modern desktop or -mobile browser, or even embedded within another web page: -@verbatim -<div> -<object data="logo3.html" - style="width:210;height:140;position:relative;top:0;left:0;"> -</object> -</div> -@end verbatim - -Normally, @code{WebGL} files generated by @code{Asymptote} are -dynamically remeshed to fit the browser window dimensions. -However, the setting @code{absolute=true} can be used to force the image to be -rendered at its designed size (accounting for multiple device pixels -per @code{css} pixel). - -The interactive @code{WebGL} files produced by @code{Asymptote} use the -default mouse and (many of the same) key bindings as the @code{OpenGL} -renderer. Zooming via the mouse wheel of a @code{WebGL} image embedded -within another page is disabled until the image is activated by a -click or touch event and will remain enabled until the @code{ESC} key -is pressed. - -By default, viewing the 3D @acronym{HTML} files generated by Asymptote requires -network access to download the @code{AsyGL} rendering library, which -is normally cached by the browser for future use. -However, the setting @code{offline=true} can be used to embed this -small (about 48kB) library within a stand-alone @acronym{HTML} file -that can be viewed offline. - -@cindex @code{antialias} -@cindex @code{maxviewport} -@cindex @code{maxtile} -@cindex @code{glOptions} -@cindex @code{iconify} -@cindex @code{black stripes} -@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} to your screen -dimensions (indicated by @code{maxtile=(0,0)}. If your video card -generates unwanted black stripes in the output, try setting the -horizontal and vertical components of @code{maxtiles} to something -less than your screen dimensions. 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}. - -@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{9.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 -module @code{three} (or @code{graph3}) is imported. -The @code{media9} LaTeX package is also required (@pxref{embed}). -The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/100d.html,,100d}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/pdb.asy,,.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}. -For specialized applications where only the raw @acronym{PRC} file is -required, specify @code{settings.outformat="prc"}. -The @acronym{PRC} specification is available from -@url{https://web.archive.org/web/20081204104459/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} -A 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. -A 3D picture @code{pic} can be explicitly fit to a 3D frame by calling -@cindex @code{fit3} -@verbatim -frame pic.fit3(projection P=currentprojection); -@end verbatim -@noindent -and then added to picture @code{dest} about @code{position} with -@cindex @code{add} -@verbatim -void add(picture dest=currentpicture, frame src, triple position=(0,0,0)); -@end verbatim - -@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{center} -@item orthographic(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, pair viewportshift=0, bool showtarget=true, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool center=false) -This projects from three to two dimensions using the view as seen at a point -infinitely far away in the direction @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{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, @*@ @ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, pair viewportshift=0, bool showtarget=true, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool center=false) -This is equivalent to -@verbatim -orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,center) -@end verbatim - -The routine -@cindex @code{camera} -@verbatim -triple camera(real alpha, real beta); -@end verbatim -can be used to compute the camera position with the @math{x} axis below -the horizontal at angle @code{alpha}, the @math{y} axis below the horizontal -at angle @code{beta}, and the @math{z} axis up. - -@cindex @code{autoadjust} -@item perspective(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust) -@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, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust) -This is equivalent to -@verbatim -perspective((x,y,z),up,target,zoom,angle,viewportshift,showtarget, - autoadjust,center) -@end verbatim -@end table - -@cindex @code{currentprojection} -@noindent -The default projection, @code{currentprojection}, is initially set to -@code{perspective(5,4,2)}. - -@cindex @code{LeftView} -@cindex @code{RightView} -@cindex @code{FrontView} -@cindex @code{BackView} -@cindex @code{BottomView} -@cindex @code{TopView} -We also define standard orthographic views used in technical drawing: -@verbatim -projection LeftView=orthographic(-X,showtarget=true); -projection RightView=orthographic(X,showtarget=true); -projection FrontView=orthographic(-Y,showtarget=true); -projection BackView=orthographic(Y,showtarget=true); -projection BottomView=orthographic(-Z,showtarget=true); -projection TopView=orthographic(Z,showtarget=true); -@end verbatim -@noindent -The function -@cindex @code{addViews} -@verbatim -void addViews(picture dest=currentpicture, picture src, - projection[][] views=SixViewsUS, - bool group=true, filltype filltype=NoFill); -@end verbatim -@noindent -adds to picture @code{dest} an array of views of picture @code{src} -using the layout projection[][] @code{views}. The default layout -@code{SixViewsUS} aligns the projection @code{FrontView} below -@code{TopView} and above @code{BottomView}, to the right of -@code{LeftView} and left of @code{RightView} and @code{BackView}. -The predefined layouts are: -@cindex @code{ThreeViewsUS} -@cindex @code{SixViewsUS} -@cindex @code{ThreeViewsFR} -@cindex @code{SixViewsFR} -@cindex @code{ThreeViews} -@cindex @code{SixViews} -@verbatim -projection[][] ThreeViewsUS={{TopView}, - {FrontView,RightView}}; - -projection[][] SixViewsUS={{null,TopView}, - {LeftView,FrontView,RightView,BackView}, - {null,BottomView}}; - -projection[][] ThreeViewsFR={{RightView,FrontView}, - {null,TopView}}; - -projection[][] SixViewsFR={{null,BottomView}, - {RightView,FrontView,LeftView,BackView}, - {null,TopView}}; - -projection[][] ThreeViews={{FrontView,TopView,RightView}}; - -projection[][] SixViews={{FrontView,TopView,RightView}, - {BackView,BottomView,LeftView}}; - -@end verbatim - -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} -@cindex @code{identity4} -Three-dimensional objects may be transformed with one of the following -built-in transform3 types (the identity transformation is @code{identity4}): - -@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; -@cindex @code{rotate} -@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}. -@cindex @code{XY} -@end table - -When not multiplied on the left by a transform3, three-dimensional -@TeX{} Labels are drawn as Bezier surfaces directly on the projection plane: -@cindex @code{label} -@verbatim -void label(picture pic=currentpicture, Label L, triple position, - align align=NoAlign, pen p=currentpen, - light light=nolight, string name="", - render render=defaultrender, interaction interaction= - settings.autobillboard ? Billboard : Embedded) -@end verbatim -@noindent -@cindex @code{Billboard} -@cindex @code{Embedded} -The optional @code{name} parameter is used as a prefix for naming the label -patches in the @acronym{PRC} model tree. -The default interaction is @code{Billboard}, which means that labels -are rotated interactively so that they always face the camera. -The interaction @code{Embedded} means that the label interacts as a -normal @code{3D} surface, as illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/billboard.html,,billboard}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/billboard.asy,,.asy}}. -@cindex @code{transform} -@cindex @code{XY} -@cindex @code{YZ} -@cindex @code{ZX} -@cindex @code{YX} -@cindex @code{ZY} -@cindex @code{ZX} -Alternatively, a label can be transformed from the @code{XY} plane by an -explicit transform3 or mapped to a specified two-dimensional plane with -the predefined 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{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/planeproject.html,,planeproject}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/planeproject.asy,,.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. - -The routine -@cindex @code{intersections} -@verbatim -real[] intersect(path3 p, surface s, real fuzz=-1); -@end verbatim -@noindent -returns a real array of length 3 containing the intersection times, if any, -of a path @code{p} with a surface @code{s}. -The routine -@verbatim -real[][] intersections(path3 p, surface s, real fuzz=-1); -@end verbatim -@noindent -returns all (unless there are infinitely many) intersection times of a -path @code{p} with a surface @code{s} as a sorted array of real arrays -of length 3, and -@cindex @code{intersectionpoints} -@verbatim -triple[] intersectionpoints(path3 p, surface s, real fuzz=-1); -@end verbatim -@noindent -returns the corresponding intersection points. -Here, the computations are performed to the absolute error specified by -@code{fuzz}, or if @code{fuzz < 0}, to machine precision. -The routine -@cindex @code{orient} -@verbatim -real orient(triple a, triple b, triple c, triple d); -@end verbatim -@noindent -is a numerically robust computation of @code{dot(cross(a-d,b-d),c-d)}, -which is the determinant -@verbatim -|a.x a.y a.z 1| -|b.x b.y b.z 1| -|c.x c.y c.z 1| -|d.x d.y d.z 1| -@end verbatim -The result is negative (positive) if @code{a}, @code{b}, @code{c} appear in -counterclockwise (clockwise) order when viewed from @code{d} or zero -if all four points are coplanar. - -The routine -@cindex @code{insphere} -@verbatim -real insphere(triple a, triple b, triple c, triple d, triple e); -@end verbatim -@noindent -returns a positive (negative) value if @code{e} lies inside (outside) -the sphere passing through points @code{a,b,c,d} oriented so that -@code{dot(cross(a-d,b-d),c-d)} is positive, -or zero if all five points are cospherical. -The value returned is the determinant -@verbatim -|a.x a.y a.z a.x^2+a.y^2+a.z^2 1| -|b.x b.y b.z b.x^2+b.y^2+b.z^2 1| -|c.x c.y c.z c.x^2+c.y^2+c.z^2 1| -|d.x d.y d.z d.x^2+d.y^2+d.z^2 1| -|e.x e.y e.z e.x^2+e.y^2+e.z^2 1| -@end verbatim - -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{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.html,,arrows3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.asy,,.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}. - -@cindex @code{pixel} -The routine -@verbatim -void pixel(picture pic=currentpicture, triple v, pen p=currentpen, - real width=1); -@end verbatim -@noindent -can be used to draw on picture @code{pic} a pixel of width @code{width} at -position @code{v} using pen @code{p}. - -Further three-dimensional examples are provided in the files -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/near_earth.html,,near_earth}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/near_earth.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/conicurv.html,,conicurv}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/conicurv.asy,,.asy}}, and (in the @code{animations} -subdirectory) @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cube.html,,cube}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cube.asy,,.asy}}. - -@anchor{PostScript3D} -@cindex 3D @code{PostScript} -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} module 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, graph3, three, Base modules -@section @code{obj} -@cindex @code{obj} -This module allows one to construct surfaces from simple obj files, -as illustrated in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/galleon.html,,galleon}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/galleon.asy,,.asy}} and -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triceratops.html,,triceratops}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triceratops.asy,,.asy}}. - -@node graph3, grid3, obj, Base modules -@section @code{graph3} -@cindex @code{graph3} -@cindex 3D graphs -This module implements three-dimensional versions of the -functions in @code{graph.asy}. -@cindex @code{xaxis3} -@cindex @code{yaxis3} -@cindex @code{zaxis3} -@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="", - bool extend=false, - 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} - -@cindex @code{surface} -@cindex @code{Spline} -@cindex parametric surface -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 xsplinetype, - splinetype ysplinetype=xsplinetype, bool[][] cond={}); -surface surface(real[][] f, real[] x, real[] y, - splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype, - 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 xsplinetype, splinetype ysplinetype=xsplinetype, - bool cond(pair z)=null); -surface surface(triple f(pair z), real[] u, real[] v, - splinetype[] usplinetype, splinetype[] vsplinetype=Spline, - 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); -surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu, - splinetype[] usplinetype, splinetype[] vsplinetype=Spline, - bool cond(pair z)=null); -@end verbatim -@noindent -The final two versions draw parametric surfaces for a function -@math{f(u,v)} over the parameter space @code{box(a,b)}, -as illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}. -An optional splinetype @code{Spline} may be specified. -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{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3D graphs/sinc.html,,sinc}@uref{https://asymptote.sourceforge.io/gallery/3D graphs/sinc.asy,,.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. - -A vector field of @code{nu}@math{\times}@code{nv} arrows on a -parametric surface @code{f} over @code{box(a,b)} can be drawn with the routine -@cindex @code{vectorfield3} -@verbatim -picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b, - int nu=nmesh, int nv=nu, bool truesize=false, - real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv), - bool cond(pair z)=null, pen p=currentpen, - arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3) -@end verbatim -as illustrated in the examples @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfield3.html,,vectorfield3}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfield3.asy,,.asy}} and -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfieldsphere.html,,vectorfieldsphere}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfieldsphere.asy,,.asy}}. - -@node grid3, solids, graph3, Base modules -@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://www.piprime.fr/files/asymptote/grid3/}): -@verbatiminclude grid3xyz.asy -@sp 1 -@center @image{./grid3xyz} - -@node solids, tube, grid3, Base modules -@section @code{solids} -@cindex @code{solids} -This solid geometry module 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{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cylinder.html,,cylinder}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cylinder.asy,,.asy}}, -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cones.html,,cones}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cones.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/hyperboloid.html,,hyperboloid}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/hyperboloid.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/torus.html,,torus}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/torus.asy,,.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, flowchart, solids, Base modules -@section @code{tube} -@cindex @code{tube} -This module extends the @code{tube} surfaces constructed in -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/three_arrows.html,,three_arrows}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/three_arrows.asy,,.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{point(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{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/trefoilknot.html,,trefoilknot}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/trefoilknot.asy,,.asy}}. Further examples can be found at -@url{http://www.piprime.fr/files/asymptote/tube/}. - -@node flowchart, contour, tube, Base modules -@section @code{flowchart} -@cindex @code{flowchart} -This module 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 parallelogram block: -@cindex @code{parallelogram} -@verbatim -block parallelogram(object body, pair center=(0,0), - pen fillpen=invisible, pen drawpen=currentpen, - real dx=3, real slope=2, - real minwidth=minblockwidth, - real minheight=minblockheight); -@end verbatim - -@item diamond-shaped 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 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 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 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 (see also the example -@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/controlsystem.html,,controlsystem}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/controlsystem.asy,,.asy}}): - -@verbatiminclude flowchartdemo.asy -@sp 1 -@center @image{./flowchartdemo} - -@node contour, contour3, flowchart, Base modules -@section @code{contour} -@cindex @code{contour} -This module draws contour lines. -To construct contours corresponding to the values in a real array @code{c} -for a function @code{f} on @code{box(a,b)}, use the routine -@verbatim -guide[][] contour(real f(real, real), pair a, pair b, - real[] c, int nx=ngraph, int ny=nx, - interpolate join=operator --, int subsample=1); -@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. -The @code{subsample} parameter indicates the number of interior points -that should be used to sample contours within each @code{1 x 1} box; -the default value of @code{1} is usually sufficient. - -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, pair a, pair b, real[] c, - interpolate join=operator --, int subsample=1); -@end verbatim - -To construct contours for an array of data values on a nonoverlapping -regular mesh specified by the two-dimensional array @code{z}, -@verbatim -guide[][] contour(pair[][] z, real[][] f, real[] c, - interpolate join=operator --, int subsample=1); - -@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{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/Gouraudcontour.pdf,,Gouraudcontour}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/Gouraudcontour.asy,,.asy}} 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, smoothcontour3, contour, Base modules -@section @code{contour3} -@cindex @code{contour3} -This module draws surfaces described as the null space of real-valued -functions of @math{(x,y,z)} or @code{real[][][]} matrices. -Its usage is illustrated in the example file @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/magnetic.html,,magnetic}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/magnetic.asy,,.asy}}. - -@node smoothcontour3, slopefield, contour3, Base modules -@section @code{smoothcontour3} -@cindex @code{smoothcontour3} -This module, written by Charles Staats, draws implicitly defined surfaces -with smooth appearance. -The purpose of this module is similar to that of @code{contour3}: given -a real-valued function @math{f(x,y,z)}, construct the surface described by -the equation @math{f(x,y,z) = 0}. The @code{smoothcontour3} module generally produces -nicer results than @code{contour3}, but takes longer to compile. Additionally, the -algorithm assumes that the function and the surface are both smooth; if they are not, -then @code{contour3} may be a better choice. - -To construct the null surface of a function @code{f(triple)} or @code{ff(real,real,real)} -over @code{box(a,b)}, use the routine -@cindex @code{implicitsurface} -@verbatim -surface implicitsurface(real f(triple)=null, - real ff(real,real,real)=null, - triple a, - triple b, - int n=nmesh, - bool keyword overlapedges=false, - int keyword nx=n, - int keyword ny=n, - int keyword nz=n, - int keyword maxdepth=8, - bool usetriangles=true); -@end verbatim -@noindent -The optional parameter @code{overlapedges} attempts to compensate for -an artifact that can cause the renderer to ``see through'' the -boundary between patches. Although -it defaults to @code{false}, it should usually be set to @code{true}. -The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.html,,genustwo}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.asy,,.asy}} illustrates the use of this function. -Additional examples, together with a more in-depth explanation of -the module's usage and pitfalls, are available at -@url{https://github.com/charlesstaats/smoothcontour3}. - -@node slopefield, ode, smoothcontour3, Base modules -@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 ode, , slopefield, Base modules -@section @code{ode} -@cindex @code{ode} -The @code{ode} module, illustrated in the example @code{@uref{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/examples/odetest.asy,,odetest.asy}}, -implements a number of explicit numerical integration schemes for -ordinary differential equations. - -@node Options, Interactive mode, Base modules, Top -@chapter Command-line 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 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 -(@pxref{Search paths}). 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{hyperrefOptions} -@cindex @code{convertOptions} -@cindex @code{gsOptions} -@cindex @code{htmlviewerOptions} -@cindex @code{psviewerOptions} -@cindex @code{pdfviewerOptions} -@cindex @code{pdfreloadOptions} -@cindex @code{glOptions} -@cindex @code{dvisvgmOptions} -The advanced configuration variables @code{dvipsOptions}, -@code{hyperrefOptions}, @code{convertOptions}, @code{gsOptions}, -@code{htmlviewerOptions}, @code{psviewerOptions}, -@code{pdfviewerOptions}, @code{pdfreloadOptions}, -@code{glOptions}, and @code{dvisvgmOptions} allow specialized options -to be passed as a string to the respective applications or -libraries. The default value of @code{hyperrefOptions} is -@code{setpagesize=false,unicode,pdfborder=0 0 0}. - -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} -@cindex @code{latex} -@cindex @code{tex} -@cindex @code{pdflatex} -@cindex @code{xelatex} -@cindex @code{context} -@cindex @code{luatex} -@cindex @code{lualatex} -@cindex @code{EPS} -@cindex @code{PDF} -@anchor{texengines} -@anchor{convert} -The default output format is @acronym{EPS} for the (default) -@code{latex} and @code{tex} tex engine and @acronym{PDF} for the -@code{pdflatex}, @code{xelatex}, @code{context}, @code{luatex}, and -@code{lualatex} tex engines. Alternative output formats may be -produced using the @code{-f} option (or @code{outformat} setting). - -@cindex @code{SVG} -@cindex @code{dvisvgm} -@cindex @code{libgs} -@cindex @code{graphic} -To produce @acronym{SVG} output, you will need @code{dvisvgm} (version -2.6.3 or later) from @url{https://dvisvgm.de}. -You might need to adjust the configuration variable @code{libgs} to -point to the location of your @code{Ghostscript} library -@code{libgs.so} (or to an empty string, depending on how -@code{dvisvgm} was configured). The 2.9.1 version of @code{dvisvgm} can -display @acronym{SVG} output (used by the @code{xasy} editor) for embedded -@acronym{EPS}, @acronym{PDF}, @acronym{PNG}, and @acronym{JPEG} images -included with the @code{graphic()} function. - -@code{Asymptote} can also 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}). -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. -To give other 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)} and -@code{int system(string[] s)} calls, allowing one -to execute arbitrary shell commands. The default mode, @code{-safe}, -disables this call. - -@cindex offset -@cindex @code{aligndir} -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 pair @code{aligndir} specifies -an optional direction on the boundary of the page (mapped to the -rectangle [-1,1]@math{\times}[-1,1]) to which the picture should be aligned; the -default value @code{(0,0)} species center alignment. - -@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, GUI, Options, Top -@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. - -@cindex @code{%} -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}. -If the expression is non-writable, its type signature will be printed out -instead. In either case, the expression can be referred to using the symbol -@code{%} in the next line input at the prompt. For example: -@verbatim -> 2+3 -5 -> %*4 -20 -> 1/% -0.05 -> sin(%) -0.0499791692706783 -> currentpicture -<picture currentpicture> -> %.size(200,0) -> -@end verbatim - -@cindex @code{operator answer} -The @code{%} symbol, when used as a variable, is shorthand for the identifier -@code{operator answer}, which is set by the prompt after each written -expression evaluation. - - -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 erase -erase @code{currentpicture}; -@cindex @code{input} -@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} -@cindex @code{history} -@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{https://tiswww.case.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 3} 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, PostScript to Asymptote, Interactive mode, Top -@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} - -@menu -* GUI installation:: Installing @code{xasy} -* GUI usage:: Using @code{xasy} to edit objects -@end menu - -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. - -@node GUI installation, GUI usage, GUI, GUI -@section GUI installation -@cindex GUI installation - -As @code{xasy} is written in the interactive scripting language -@code{Python/Qt}, it requires @code{Python} (@url{https://www.python.org}), -along with the @code{Python} packages @code{pyqt5}, @code{cson}, and -@code{numpy}: - -@verbatim -pip3 install cson numpy pyqt5 PyQt5.sip -@end verbatim - -Pictures are deconstructed into the @acronym{SVG} image format. -Since @code{Qt5} does not support @code{SVG} clipping, you will need -the @code{rsvg-convert} utility, which is part of the -@code{librsvg2-tools} package on @code{UNIX} systems -and the @code{librsvg} package on @code{MacOS X}; under -@code{Microsoft Windows}, it is available as - -@url{https://sourceforge.net/projects/tumagcc/files/rsvg-convert-2.40.20.7z} - -@node GUI usage, , GUI installation, GUI -@section GUI usage -@cindex GUI usage -@cindex arrow keys -@cindex mouse wheel -@cindex @code{deconstruct} -The arrow keys (or mouse wheel) are convenient for temporarily -raising and lowering objects within @code{xasy}, allowing an object to -be selected. Pressing the arrow keys will pan while the shift key is held -and zoom while the control key is held. The mouse wheel will pan while -the alt or shift keys is held and zoom while the control key is held. -In translate mode, an object can be dragged coarsely with the mouse -or positioned finely with the arrow keys while holding down the mouse button. - -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, Help, GUI, Top -@chapter @code{PostScript} to @code{Asymptote} -@cindex @code{pstoedit} -The excellent @code{PostScript} editor @code{pstoedit} (version 3.50 or later; -available from @url{https://sourceforge.net/projects/pstoedit/}) 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. Here is an example: -@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, Debugger, PostScript to Asymptote, Top -@chapter Help -@cindex help -@cindex forum - -A list of frequently asked questions (@acronym{FAQ}) is maintained at -@quotation -@url{https://asymptote.sourceforge.io/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{https://sourceforge.net/p/asymptote/discussion/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{https://sourceforge.net/p/asymptote/patches} -@end quotation -@noindent -To receive announcements of upcoming releases, please subscribe to -@code{Asymptote} at -@quotation -@url{https://sourceforge.net/projects/asymptote/} -@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 @code{git} -developmental code (@pxref{Git}) before submitting a bug -report. New bugs can be reported at -@quotation -@url{https://github.com/vectorgraphics/asymptote/issues} -@end quotation -@noindent -To see if the bug has already been fixed, -check bugs with Status @code{Closed} and recent lines in -@quotation -@url{https://asymptote.sourceforge.io/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{https://www.gnu.org/software/libsigsegv/}, 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, Credits, Help, Top -@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, Index, Debugger, Top -@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 Orest Shardt, Jesse Frohlich, Michail Vidiassov, -Charles Staats, Philippe Ivaldi, Olivier Guib@'e, Radoslav Marinov, -Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, -Martin Wiebusch, Stefan Knorr, and Supakorn ``Jamie'' Rassameemasmuang. -Pedram Emami developed the @code{Asymptote Web Application} at -@url{http://asymptote.ualberta.ca}. - - -@node Index, , Credits, Top -@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: ImageMagick cd asymptote Hy 0pt 1filll 's 3D 2D 'asy -@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 -@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 eof js prc ni -@c LocalWords: 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 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 -@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: 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 texengine maxtimes maxheight pdb TEXMFCONFIG Jn -@c LocalWords: piecewisestraight unitrand graphmarkers antialias nolight newl -@c LocalWords: Delaunay Shewchuk convertOptions APPDATA pdfreload tempFile Yn -@c LocalWords: pdfreloadOptions deferred OpenGL renderer unitbox 's -@c LocalWords: bezulate Shardt's rasterized viewport unitdisk unitplane devel -@c LocalWords: unitcylinder unitcone solidcone unitfrustum unitsphere nslices -@c LocalWords: DPostScript YZZero externalprc nonrendered nosafe KDE -@c LocalWords: unithemisphere versa XYplane xypart unitsolidcone YZEquals xml -@c LocalWords: XZEquals XYEquals XZZero XYZero InTicks OutTicks InOutTicks -@c LocalWords: fitscreen planeproject strokepath meshlight nullpens arrowdir -@c LocalWords: diffusepen emissivepen specularpen arrowbarb keyval -@c LocalWords: hstretch vstretch roundbox nonconvex miterlimit basealign cmd -@c LocalWords: maxviewport maxtile antialiased sphericalharmonic attachfile -@c LocalWords: vertexshading smoothelevation glOptions iconified iconify kate -@c LocalWords: psviewerOptions pdfviewerOptions viewportmargin asyattach SVG -@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 hexadecimal XeLaTeX xelatex -@c LocalWords: dvipdfmx autoadjust viewportsize viewportwidth viewportheight -@c LocalWords: subregions nonsimply functionshade shader floatingdisk TopView -@c LocalWords: functionshading maxlength LeftView odetest RadialShadeDraw CLZ -@c LocalWords: vectorfieldsphere RightView FrontView BackView BottomView CTZ -@c LocalWords: addViews outprefix addAllViews xsplinetype ysplinetype rotateX -@c LocalWords: usplinetype vsplinetype leftbutton middlebutton rightbutton -@c LocalWords: rotateY rotateZ wheelup zoomin wheeldown zoomout TeXLive pnorm -@c LocalWords: viewportshift signedint signedness psview multiplatform nowarn -@c LocalWords: singlereal singleint writeoverloaded dvisvg reddash lexorder -@c LocalWords: bigdiagonal autobillboard dvisvgm maxtiles hyperrefOptions xdr -@c LocalWords: setpagesize pdfborder controlsystem OmitTickInterval SixViews -@c LocalWords: OmitTickIntervals tickmodifiers autorotated SixViewsUS latexmk -@c LocalWords: ThreeViewsUS ThreeViewsFR SixViewsFR ThreeViews partialsum -@c LocalWords: defaultrender Vidiassov latexmkrc mktemp DOSendl DOSnewl perl -@c LocalWords: filename asyinclude latemk penfunctionimage Affine decrement -@c LocalWords: affine Redisplay redisplay isnan radians defaultseparator Jens -@c LocalWords: ascii piecewise arcpoint spacings tilings sncndn resizing -@c LocalWords: differentiable vectorization vectorized asydir normals quartic -@c LocalWords: wavepacket kerned parametrized specular hyperboloid Bourke's -@c LocalWords: Michail 0pt 1filll 's 3D labelpath3 2D graph3 0pt 3D -@c LocalWords: grid3 contour3 x86_64 psv a4 gsview32 freeglut 'load ' -@c LocalWords: 'asy 'lasy 'auto 5bp 1cm sqrtx01 4g extenda extendb -@c LocalWords: bb llx 2S 100pt 3t bezier2 bool3 x0 angle1 angle2 z1 -@c LocalWords: z2 before' struct X11 x11colors type1cm 12pt OT1 5mm -@c LocalWords: cmr12 x' y' xsize ysize 25cm s1 s2 neighbourhood u'' -@c LocalWords: s'' 3x 5x 3y 602e 2x 2y 3sin 10cm 204e addby7 10x -@c LocalWords: only'' pow10 log10 expm1 log1p atan2 0pt 1filll 's ' -@c LocalWords: x1 x2 graph2d attachfile2 n0 P0 n1 P1 markers1 3D 2D -@c LocalWords: interpolate1 markers2 inlinemovie3 media9 U3D T2A 5E -@c LocalWords: embeddedu3d curvedlabel3 value2 tickvalue inner'' 2N -@c LocalWords: lineargraph0 scalings log2 log2graph 5cm BWRainbow2 -@c LocalWords: guide3 path3 unitcircle3 2E 2n noV 100d PostScript3D -@c LocalWords: size3 fit3 theta1 phi1 theta2 phi2 v1 v2 unitsquare3 -@c LocalWords: t1 t2 5z 5y transform3 identity4 xscale3 yscale3 0pt -@c LocalWords: zscale3 scale3 join3 BeginBar3 EndBar3 Bar3 Bars3 's -@c LocalWords: BeginArrow3 MidArrow3 EndArrow3 Arrow3 Arrows3 axes3 -@c LocalWords: BeginArcArrow3 MidArcArrow3 EndArcArrow3 ArcArrow3 ' -@c LocalWords: ArcArrows3 DefaultHead3 HookHead3 TeXHead3 HookHead2 -@c LocalWords: DefaultHead2 TeXHead2 arrows3 NoMargin3 BeginMargin3 -@c LocalWords: EndMargin3 Margin3 Margins3 BeginPenMargin2 xaxis3 ' -@c LocalWords: EndPenMargin2 PenMargin2 PenMargins2 BeginPenMargin3 -@c LocalWords: EndPenMargin3 PenMargin3 PenMargins3 BeginDotMargin3 -@c LocalWords: EndDotMargin3 DotMargin3 DotMargins3 TrueMargin3 3D -@c LocalWords: yaxis3 zaxis3 ticks3 NoTicks3 arrowbar3 type2 axis3 -@c LocalWords: generalaxis3 vectorfield3 margin3 grid3xyz 5unit 2D -@c LocalWords: slopefield1 144x144 1filll 'load 'asy 'lasy 'auto 4g -@c LocalWords: libgs 'load 'asy 'lasy 'auto 5bp 1cm 2S 100pt 3t 5mm -@c LocalWords: bracedefaultratio incircle 12pt 25cm 3x 5x 3y 602e ' -@c LocalWords: 2x 2y 3sin 10cm 204e 10x 5E offaxis 'load 'lasy ' -@c LocalWords: 5cm 2N 2E 2n 100d 5z 5y 5unit dvisvgmOptions 144x144 -@c LocalWords: 4g texengines coplanar 0pt 1filll 's 3D 2D 'load 5bp -@c LocalWords: insphere cospherical 5unit luatex lualatex 'asy 1cm -@c LocalWords: 'lasy 'auto 4g 2S 100pt 3t 12pt 5mm 25cm 3x 5x 3y 2x -@c LocalWords: 602e 2y 3sin 10cm 204e 10x -@c LocalWords: unnormalized 5E 5cm 2N 2E 2n 100d 5z 5y 0pt 1filll -@c LocalWords: 5unit 144x144 aligndir smoothcontour3 's 3D 2D cmake -@c LocalWords: 'load 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t nan 3x -@c LocalWords: 12pt 5mm 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x -@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y nz -@c LocalWords: 5unit Staats implicitsurface overlapedges maxdepth ' -@c LocalWords: through'' genustwo 144x144 0pt 1filll 's 3D 2D 'load -@c LocalWords: 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t 12pt 5mm 3x -@c LocalWords: 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x -@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y 5unit 144x144 -@c LocalWords: Frohlich codequoteundirected center 0pt 1filll 's 3D -@c LocalWords: acknowledgments Colors 2D Color WebGL uref x86 dnf -@c LocalWords: htmlviewer asygl CPPFLAGS 'load 'asy 'lasy 'auto 5bp -@c LocalWords: 1cm labeling dotfilltype 4g color colors centered 2S -@c LocalWords: 100pt 3t forcemath gray colorless miter 12pt 5mm 3x -@c LocalWords: zeroTransform 25cm Python3 popcount bitreverse 5x 3y -@c LocalWords: 602e 2x 2y 3sin 10cm 204e 10x -@c LocalWords: findall ax 5a centers 5E 5cm 2N 2E 2n HTML5 html -@c LocalWords: logo3 remeshed css 42kB 100d 5z 5y 5unit colored Qt5 -@c LocalWords: behavior beveled usetriangles htmlviewerOptions cson -@c LocalWords: 144x144 pyqt5 numpy pip3 PyQt5 rsvg librsvg2 1filll -@c LocalWords: librsvg Supakorn Jamie'' Rassameemasmuang 2D Docdir -@c LocalWords: microsoft configuation 'load 'asy 'lasy 'auto dep 4g -@c LocalWords: 5bp 1cm BezierPatch 2S 100pt 3t abs2 12pt cp1251 5mm -@c LocalWords: anttor fontenc inputenc 25cm noglobalread 3x -@c LocalWords: 5x 3y 602e 2x 2y 3sin 10cm 204e 10x -@c LocalWords: mapArray 5a parameterized mapTemplate 5E 2N -@c LocalWords: 5cm freshnel0 fresnel0 PBR prethree specularfactor -@c LocalWords: renderers 2E ESC AsyGL 48kB 2n 100d 5z 5y 5unit -@c LocalWords: unicode 144x144 Pedram Emami |