Asymptote Package
Asymptote Package
Language
For version 3.04
symptote
This file documents Asymptote, version 3.04.
https://asymptote.sourceforge.io
Copyright c 2004-25 Andy Hammerlindl, John Bowman, and Tom Prince.
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Lesser General Public License (see the file LICENSE in
the top-level source directory).
i
Table of Contents
1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1 UNIX binary distributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 MacOS X binary distributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Microsoft Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4 Configuring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.5 Search paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 Compiling from UNIX source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.7 Editing modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.8 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.9 Building the documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.10 Uninstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1 Drawing in batch mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2 Drawing in interactive mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3 Figure size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4 Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.5 Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4 Drawing commands. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.1 draw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.3 clip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.4 label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5 Bezier curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
6 Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.1 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
6.2 Paths and guides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
6.3 Pens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.4 Transforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.5 Frames and pictures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
6.6 Deferred drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.7 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.8 Variable initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.9 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.10 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.10.1 Arithmetic & logical operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
ii
7 LaTeX usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
8 Base modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.1 plain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.2 simplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.3 simplex2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.4 math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8.5 interpolate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
8.6 geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
8.7 trembling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
8.8 stats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.9 patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.10 markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.11 map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.12 tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.13 binarytree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.14 drawtree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.15 syzygy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.16 feynman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.17 roundedpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.18 animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.19 embed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.20 slide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.21 MetaPost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.22 babel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.23 labelpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.24 labelpath3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.25 annotate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
iii
15 Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
16 Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
17 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
1
1 Description
Asymptote is a powerful descriptive vector graphics language that provides a mathematical
coordinate-based framework for technical drawing. Labels and equations are typeset with
LaTeX, for overall document consistency, yielding the same high-quality level of typesetting
that LaTeX provides for scientific text. By default it produces PostScript output, but it
can also generate OpenGL, PDF, SVG, WebGL, V3D, and legacy PRC vector graphics, along with
any format that the ImageMagick package can produce. You can even try it out in your
Web browser without installing it, using the Asymptote Web Application
http://asymptote.ualberta.ca
It is also possible to send remote commands to this server via the curl utility (see
Chapter 12 [Command-Line Interface], page 182).
A major advantage of Asymptote over other graphics packages is that it is a high-level
programming language, as opposed to just a graphics program: it can therefore exploit the
best features of the script (command-driven) and graphical-user-interface (GUI) methods
for producing figures. The rudimentary GUI xasy included with the package allows one
to move script-generated objects around. To make Asymptote accessible to the average
user, this GUI is currently being developed into a full-fledged interface that can generate
objects directly. However, the script portion of the language is now ready for general use by
users who are willing to learn a few simple Asymptote graphics commands (see Chapter 4
[Drawing commands], page 15).
Asymptote is mathematically oriented (e.g. one can use complex multiplication to rotate
a vector) and uses LaTeX to do the typesetting of labels. This is an important feature for
scientific applications. It was inspired by an earlier drawing program (with a weaker syntax
and capabilities) called MetaPost.
The Asymptote vector graphics language provides:
• a standard for typesetting mathematical figures, just as TEX/LaTeX is the de-facto
standard for typesetting equations.
• LaTeX typesetting of labels, for overall document consistency;
• the ability to generate and embed 3D vector WebGL graphics within HTML files;
• the ability to generate and embed 3D vector PRC graphics within PDF files;
• a natural coordinate-based framework for technical drawing, inspired by MetaPost,
with a much cleaner, powerful C++-like programming syntax;
• compilation of figures into virtual machine code for speed, without sacrificing portabil-
ity;
• the power of a script-based language coupled to the convenience of a GUI;
• customization using its own C++-like graphics programming language;
• sensible defaults for graphical features, with the ability to override;
• a high-level mathematically oriented interface to the PostScript language for vector
graphics, including affine transforms and complex variables;
• functions that can create new (anonymous) functions;
• deferred drawing that uses the simplex method to solve overall size constraint issues
between fixed-sized objects (labels and arrowheads) and objects that should scale with
figure size;
Chapter 1: Description 2
Many of the features of Asymptote are written in the Asymptote language itself. While
the stock version of Asymptote is designed for mathematics typesetting needs, one can write
Asymptote modules that tailor it to specific applications; for example, a scientific graphing
module is available (see Section 8.27 [graph], page 105). Examples of Asymptote code and
output, including animations, are available at
https://asymptote.sourceforge.io/gallery/
Clicking on an example file name in this manual, like Pythagoras, will display the PDF
output, whereas clicking on its .asy extension will show the corresponding Asymptote code
in a separate window.
Links to many external resources, including an excellent user-written Asymptote tutorial
can be found at
https://asymptote.sourceforge.io/links.html
A quick reference card for Asymptote is available at
https://asymptote.sourceforge.io/asyRefCard.pdf
3
2 Installation
After following the instructions for your specific distribution, please see also Section 2.4
[Configuring], page 4.
We recommend subscribing to new release announcements at
https://sourceforge.net/projects/asymptote
Users may also wish to monitor the Asymptote forum:
https://sourceforge.net/p/asymptote/discussion/409349
2.4 Configuring
In interactive mode, or when given the -V option (the default when running Asymptote on
a single file under MSDOS), Asymptote will automatically invoke your PostScript viewer
(evince under UNIX) to display graphical output. The PostScript viewer should be capable
of automatically redrawing whenever the output file is updated. The UNIX PostScript
viewer gv supports this (via a SIGHUP signal). Users of ggv will need to enable Watch file
under Edit/PostScript Viewer Preferences.
Configuration variables are most easily set as Asymptote variables in an optional con-
figuration file config.asy (see [configuration file], page 177). For example, the setting
pdfviewer specifies the location of the PDF viewer. Here are the default values of several
important configuration variables under UNIX:
import settings;
pdfviewer="acroread";
htmlviewer="google-chrome";
psviewer="evince";
display="display";
animate="animate";
gs="gs";
libgs="";
Under MSDOS, the viewer settings htmlviewer, pdfviewer, psviewer, display, and
animate default to the string cmd, requesting the application normally associated with
each file type. The (installation-dependent) default values of gs and libgs are determined
automatically from the Microsoft Windows registry. The gs setting specifies the location
of the PostScript processor Ghostscript, available from https://www.ghostscript.
com/.
The configuration variable htmlviewer specifies the browser to use to display 3D WebGL out-
put. The default setting is google-chrome under UNIX and cmd under Microsoft Windows.
Note that Internet Explorer does not support WebGL; Microsoft Windows users should
set their default html browser to chrome or microsoft-edge. By default, 2D and 3D HTML
images expand to the enclosing canvas; this can be disabled by setting the configuration
variable absolute to true.
On UNIX systems, to support automatic document reloading of PDF files in Adobe Reader,
we recommend copying the file reload.js from the Asymptote system directory (by default,
/usr/local/share/asymptote under UNIX to ~/.adobe/Acrobat/x.x/JavaScripts/,
where x.x represents the appropriate Adobe Reader version number. The automatic
document reload feature must then be explicitly enabled by putting
import settings;
Chapter 2: Installation 5
pdfreload=true;
pdfreloadOptions="-tempFile";
in the Asymptote configuration file. This reload feature is not useful under MSDOS since the
document cannot be updated anyway on that operating system until it is first closed by
Adobe Reader.
The configuration variable dir can be used to adjust the search path (see Section 2.5
[Search paths], page 6).
By default, Asymptote attempts to center the figure on the page, assuming that the paper
type is letter. The default paper type may be changed to a4 with the configuration variable
papertype. Alignment to other paper sizes can be obtained by setting the configuration
variables paperwidth and paperheight.
These additional configuration variables normally do not require adjustment:
config
texpath
texcommand
dvips
dvisvgm
convert
asygl
Warnings (such as "unbounded" and "offaxis") may be enabled or disabled with the
functions
warn(string s);
nowarn(string s);
or by directly modifying the string array settings.suppress, which lists all disabled warn-
ings.
Configuration variables may also be set or overwritten with a command-line option:
asy -psviewer=evince -V venn
Alternatively, system environment versions of the above configuration variables may be
set in the conventional way. The corresponding environment variable name is obtained by
converting the configuration variable name to upper case and prepending ASYMPTOTE_: for
example, to set the environment variable
ASYMPTOTE_PAPERTYPE="a4";
under Microsoft Windows XP:
1. Click on the Start button;
2. Right-click on My Computer;
3. Choose View system information;
4. Click the Advanced tab;
5. Click the Environment Variables button.
Chapter 2: Installation 6
https://asymptote.sourceforge.io/asymptote.pdf
in the directory doc and repeat the command make all.
For a (default) system-wide installation, the last command should be done as the root user.
To install without root privileges, change the ./configure command to
./configure --prefix=$HOME/asymptote
One can disable use of the Boehm garbage collector by configuring with ./configure
--disable-gc. For a list of other configuration options, say ./configure --help. For
example, under MacOS X, one can tell configure to use the clang compilers and look for
header files and libraries in nonstandard locations:
./configure CC=clang CXX=clang++ CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
If you are compiling Asymptote with gcc, you will need a relatively recent version (e.g.
3.4.4 or later). For full interactive functionality, you will need version 4.3 or later of the GNU
readline library. The file gcc3.3.2curses.patch in the patches directory can be used
to patch the broken curses.h header file (or a local copy thereof in the current directory) on
some AIX and IRIX systems.
The FFTW library is only required if you want Asymptote to be able to take Fourier
transforms of data (say, to compute an audio power spectrum). The GSL library is only
required if you require the special functions that it supports.
If you don’t want to install Asymptote system wide, just make sure the compiled binary
asy and GUI script xasy are in your path and set the configuration variable dir to point
to the directory base (in the top level directory of the Asymptote source code).
Particularly useful key bindings in this mode are C-c C-c, which compiles and displays the
current buffer, and the key binding C-c ?, which shows the available function prototypes
for the command at the cursor. For full functionality you should also install the Apache
Software Foundation package two-mode-mode:
https://www.dedasys.com/freesoftware/files/two-mode-mode.el
Once installed, you can use the hybrid mode lasy-mode to edit a LaTeX file containing
embedded Asymptote code (see Chapter 7 [LaTeX usage], page 92). This mode can be en-
abled within latex-mode with the key sequence M-x lasy-mode <RET>. On UNIX systems,
additional keywords will be generated from all asy files in the space-separated list of direc-
tories specified by the environment variable ASYMPTOTE_SITEDIR. Further documentation
of asy-mode is available within emacs by pressing the sequence keys C-h f asy-mode <RET>.
Chapter 2: Installation 8
2.8 Git
The following commands are needed to install the latest development version of Asymptote
using git:
git clone https://github.com/vectorgraphics/asymptote
cd asymptote
./autogen.sh
./configure
make all
make install
To compile without optimization On Ubuntu systems, you may need to first install the
required dependencies:
apt-get build-dep asymptote
2.10 Uninstall
To uninstall a Linux x86_64 binary distribution
tar -zxvf asymptote-x.xx.x86_64.tgz | xargs --replace=% rm /%
texhash
Chapter 2: Installation 9
To uninstall all Asymptote files installed from a source distribution, use the command
make uninstall
10
3 Tutorial
A concise introduction to Asymptote is given here. For a more thorough introduction, see
the excellent Asymptote tutorial written by Charles Staats:
https://asymptote.sourceforge.io/asymptote_tutorial.pdf
Another Asymptote tutorial is available as a wiki, with images rendered by an online
Asymptote engine:
https://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)
Here, the -- connector joins the two points (0,0) and (100,100) with a line segment.
to execute all of the commands contained in the file test.asy, or 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 Chapter 10
[Interactive mode], page 179.
One can also specify the size in pt (1 pt = 1/72.27 inch), cm, mm, or 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 (see [size], page 52):
size(0,100.5);
draw((0,0)--(2,1),Arrow);
To connect several points and create a cyclic path, use the cycle keyword:
size(3cm);
draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
Chapter 3: Tutorial 12
3.4 Labels
Adding labels is easy in Asymptote; one specifies the label as a double-quoted LaTeX string,
a coordinate, and an optional alignment direction:
size(3cm);
draw(unitsquare);
label("$A$",(0,0),SW);
label("$B$",(1,0),SE);
label("$C$",(1,1),NE);
label("$D$",(0,1),NW);
D C
A B
Asymptote uses the standard compass directions E=(1,0), N=(0,1), NE=unit(N+E), and
ENE=unit(E+NE), etc., which along with the directions up, down, right, and left are
defined as pairs in the Asymptote base module plain (a user who has a local variable
named E may access the compass direction E by prefixing it with the name of the module
where it is defined: plain.E).
3.5 Paths
This example draws a path that approximates a quarter circle, terminated with an arrow-
head:
size(100,0);
draw((1,0){up}..{left}(0,1),Arrow);
Chapter 3: Tutorial 13
Here the directions up and left in braces specify the outgoing and incoming directions at
the points (1,0) and (0,1), respectively.
In general, a path is specified as a list of points (or other paths) interconnected with --,
which denotes a straight line segment, or .., which denotes a cubic spline (see Chapter 5
[Bezier curves], page 24). Specifying a final ..cycle creates a cyclic path that connects
smoothly back to the initial node, as in this approximation (accurate to within 0.06%) of a
unit circle:
path unitcircle=E..N..W..S..cycle;
An Asymptote path, being connected, is equivalent to a PostScript subpath. The ^^ bi-
nary operator, which requests that the pen be moved (without drawing or affecting endpoint
curvatures) from the final point of the left-hand path to the initial point of the right-hand
path, may be used to group several Asymptote paths into a path[] array (equivalent to a
PostScript path):
size(0,100);
path unitcircle=E..N..W..S..cycle;
path g=scale(2)*unitcircle;
filldraw(unitcircle^^g,evenodd+yellow,black);
The PostScript even-odd fill rule here specifies that only the region bounded between the
two unit circles is filled (see [fillrule], page 44). In this example, the same effect can be
achieved by using the default zero winding number fill rule, if one is careful to alternate the
orientation of the paths:
filldraw(unitcircle^^reverse(g),yellow,black);
The ^^ operator is used by the box(triple, triple) function in the module three to
construct the edges of a cube unitbox without retracing steps (see Section 8.29 [three],
page 140):
import three;
Chapter 3: Tutorial 14
currentprojection=orthographic(5,4,2,center=true);
size(5cm);
size3(3cm,5cm,8cm);
draw(unitbox);
dot(unitbox,red);
label("$O$",(0,0,0),NW);
label("(1,0,0)",(1,0,0),S);
label("(0,1,0)",(0,1,0),E);
label("(0,0,1)",(0,0,1),Z);
See section Section 8.27 [graph], page 105, (or the online Asymptote gallery and exter-
nal links posted at 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 https://web.archive.org/web/20201130113133/
http://www.piprime.fr/asymptote.
15
4 Drawing commands
All of Asymptote’s graphical capabilities are based on four primitive commands. The three
PostScript drawing commands draw, fill, and clip add objects to a picture in the order
in which they are executed, with the most recently drawn object appearing on top. The
labeling command label can be used to add text labels and external EPS images, which
will appear on top of the PostScript objects (since this is normally what one wants), but
again in the relative order in which they were executed. After drawing objects on a picture,
the picture can be output with the shipout function (see [shipout], page 53).
If you wish to draw PostScript objects on top of labels (or verbatim tex commands;
see [tex], page 57), the layer command may be used to start a new PostScript/LaTeX
layer:
void layer(picture pic=currentpicture);
The layer function gives one full control over the order in which objects are drawn.
Layers are drawn sequentially, with the most recent layer appearing on top. Within each
layer, labels, images, and verbatim tex commands are always drawn after the PostScript
objects in that layer.
A page break can be generated with the command
void newpage(picture pic=currentpicture);
While some of these drawing commands take many options, they all have sensible default
values (for example, the picture argument defaults to currentpicture).
4.1 draw
void draw(picture pic=currentpicture, Label L="", path g,
align align=NoAlign, pen p=currentpen,
arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
Label legend="", marker marker=nomarker);
Draw the path g on the picture pic using pen p for drawing, with optional drawing
attributes (Label L, explicit label alignment align, arrows and bars arrow and bar, margins
margin, legend, and markers marker). Only one parameter, the path, is required. For
convenience, the arguments arrow and bar may be specified in either order. The argument
legend is a Label to use in constructing an optional legend entry.
Bars bar are useful for indicating dimensions. The possible values of bar are None,
BeginBar, EndBar (or equivalently Bar), and Bars (which draws a bar at both ends of the
path). Each of these bar specifiers (except for None) will accept an optional real argument
that denotes the length of the bar in PostScript coordinates. The default bar length is
barsize(pen).
The possible values of arrow are None, Blank (which draws no arrows or path),
BeginArrow, MidArrow, EndArrow (or equivalently Arrow), and Arrows (which draws an
arrow at both ends of the path).
There are also arrow versions with slightly modified default values of size and angle
suitable for curved arrows: BeginArcArrow, EndArcArrow (or equivalently ArcArrow),
MidArcArrow, and ArcArrows.
Chapter 4: Drawing commands 16
For example:
draw((0,0)--(1,1),arrow=Arrows);
All of the arrow specifiers except for None and Blank may be given optional arguments,
for example:
draw((0,0)--(1,1),arrow=Arrow(
arrowhead=HookHead,size=3mm,angle=20,filltype=Draw,position=0.9));
The function Arrow has the signature
arrowbar Arrow(arrowhead arrowhead=DefaultHead,
real size=0, real angle=arrowangle,
filltype filltype=null, position position=EndPoint)
Calling Arrow() returns Arrow, which is an arrowbar object. The parameters are:
• arrowhead can be one of the predefined arrowhead styles DefaultHead, SimpleHead,
HookHead, TeXHead.
• real size is the arrowhead size in PostScript coordinates.
The default arrowhead size when drawn with a pen p is arrowsize(p).
• real angle is the arrowhead angle in degrees.
• filltype filltype (see [filltype], page 53),
• (except for MidArrow and Arrows) real position (in the sense of point(path p, real
t)) along the path where the tip of the arrow should be placed.
Margins margin can be used to shrink the visible portion of a path by labelmargin(p)
to avoid overlap with other drawn objects.
Typical values of margin are:
NoMargin
BeginMargin
EndMargin
(equivalently Margin)
Margins leaves a margin at both ends of the path.
Margin(real begin, real end=begin)
specify the size of the beginning and ending margin, respectively, in multiples
of the units labelmargin(p) used for aligning labels.
BeginPenMargin
EndPenMargin
(equivalently PenMargin)
PenMargins
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.
DotMargin
an abbreviation for PenMargin(-0.5*dotfactor,0.5*dotfactor), used to
draw from the usual beginning point just up to the boundary of an end dot of
width dotfactor*linewidth(p).
Chapter 4: Drawing commands 17
BeginDotMargin
DotMargins
work similarly.
TrueMargin(real begin, real end=begin)
specify a margin directly in PostScript units, independent of the pen line
width.
The use of arrows, bars, and margins is illustrated by the examples Pythagoras.asy
and sqrtx01.asy.
The legend for a picture pic can be fit and aligned to a frame with the routine:
frame legend(picture pic=currentpicture, int perline=1,
real xmargin=legendmargin, real ymargin=xmargin,
real linelength=legendlinelength,
real hskip=legendhskip, real vskip=legendvskip,
real maxwidth=0, real maxheight=0,
bool hstretch=false, bool vstretch=false, pen p=currentpen);
Here xmargin and ymargin specify the surrounding x and y margins, perline specifies
the number of entries per line (default 1; 0 means choose this number automatically),
linelength specifies the length of the path lines, hskip and vskip specify the line skip
(as a multiple of the legend entry size), maxwidth and maxheight specify optional upper
limits on the width and height of the resulting legend (0 means unlimited), hstretch and
vstretch allow the legend to stretch horizontally or vertically, and p specifies the pen used
to draw the bounding box. The legend frame can then be added and aligned about a point
on a picture dest using add or attach (see [add about], page 55).
To draw a dot, simply draw a path containing a single point. The dot command defined
in the module plain draws a dot having a diameter equal to an explicit pen line width or
the default line width magnified by dotfactor (6 by default), using the specified filltype
(see [filltype], page 53) or dotfilltype (Fill by default):
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);
If the variable Label is given as the Label argument to the third routine, the format
argument will be used to format a string based on the dot location (here defaultformat is
"$%.4g$"). The fourth routine draws a dot at every point of a pair array z. One can also
draw a dot at every node of a path:
void dot(picture pic=currentpicture, Label[] L=new Label[],
Chapter 4: Drawing commands 18
4.2 fill
void fill(picture pic=currentpicture, path g, pen p=currentpen);
Fill the interior region bounded by the cyclic path g on the picture pic, using the pen
p.
There is also a convenient filldraw command, which fills the path and then draws in
the boundary. One can specify separate pens for each operation:
void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen,
pen drawpen=currentpen);
This fixed-size version of fill allows one to fill an object described in PostScript
coordinates about the user coordinate origin:
void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen);
This is just a convenient abbreviation for the commands:
picture opic;
fill(opic,g,p);
add(pic,opic,origin);
The routine
void filloutside(picture pic=currentpicture, path g, pen p=currentpen);
fills the region exterior to the path g, out to the current boundary of picture pic.
Lattice gradient shading varying smoothly over a two-dimensional array of pens p, using
fill rule fillrule, can be produced with
void latticeshade(picture pic=currentpicture, path g, bool stroke=false,
pen fillrule=currentpen, pen[][] p)
If stroke=true, the region filled is the same as the region that would be drawn by
draw(pic,g,zerowinding); in this case the path g need not be cyclic. The pens in p
must belong to the same color space. One can use the functions rgb(pen) or cmyk(pen) to
promote pens to a higher color space, as illustrated in the example file latticeshading.asy.
Axial gradient shading varying smoothly from pena to penb in the direction of the line
segment a--b can be achieved with
void axialshade(picture pic=currentpicture, path g, bool stroke=false,
pen pena, pair a, bool extenda=true,
pen penb, pair b, bool extendb=true);
Chapter 4: Drawing commands 19
The boolean parameters extenda and extendb indicate whether the shading should extend
beyond the axis endpoints a and b. An example of axial shading is provided in the example
file axialshade.asy.
Radial gradient shading varying smoothly from pena on the circle with center a and
radius ra to penb on the circle with center b and radius rb is similar:
void radialshade(picture pic=currentpicture, path g, bool stroke=false,
pen pena, pair a, real ra, bool extenda=true,
pen penb, pair b, real rb, bool extendb=true);
The boolean parameters extenda and extendb indicate whether the shading should extend
beyond the radii a and b. Illustrations of radial shading are provided in the example files
shade.asy, ring.asy, and shadestroke.asy.
Gouraud shading using fill rule fillrule and the vertex colors in the pen array p on a
triangular lattice defined by the vertices z and edge flags edges is implemented with
void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
pen fillrule=currentpen, pen[] p, pair[] z,
int[] edges);
void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
pen fillrule=currentpen, pen[] p, int[] edges);
In the second form, the elements of z are taken to be successive nodes of path g. The pens
in p must belong to the same color space. Illustrations of Gouraud shading are provided in
the example file Gouraud.asy. The edge flags used in Gouraud shading are documented on
pages 270–274 of the PostScript Language Reference (3rd edition):
https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf
Tensor product shading using clipping path g, fill rule fillrule on patches bounded by
the n cyclic paths of length 4 in path array b, using the vertex colors specified in the n × 4
pen array p and internal control points in the n × 4 array z, is implemented with
void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
pen fillrule=currentpen, pen[][] p, path[] b=g,
pair[][] z=new pair[][]);
If the array z is empty, Coons shading, in which the color control points are calculated
automatically, is used. The pens in p must belong to the same color space. A simpler
interface for the case of a single patch (n = 1) is also available:
void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
pen fillrule=currentpen, pen[] p, path b=g,
pair[] z=new pair[]);
One can also smoothly shade the regions between consecutive paths of a sequence using
a given array of pens:
void draw(picture pic=currentpicture, pen fillrule=currentpen, path[] g,
pen[] p);
Illustrations of tensor product and Coons shading are provided in the example files
tensor.asy, Coons.asy, BezierPatch.asy, and rainbow.asy.
More general shading possibilities are available using TEX engines that produce PDF
output (see [texengines], page 177): the routine
void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
Chapter 4: Drawing commands 20
4.3 clip
void clip(picture pic=currentpicture, path g, stroke=false,
pen fillrule=currentpen);
Clip the current contents of picture pic to the region bounded by the path g, using fill
rule fillrule (see [fillrule], page 44). If stroke=true, the clipped portion is the same as
the region that would be drawn with draw(pic,g,zerowinding); in this case the path 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 pic.
For an illustration of picture clipping, see the first example in Chapter 7 [LaTeX usage],
page 92.
4.4 label
void label(picture pic=currentpicture, Label L, pair position,
align align=NoAlign, pen p=currentpen, filltype filltype=NoFill)
Draw Label L on picture pic using pen p. If align is NoAlign, the label will be centered
at user coordinate position; otherwise it will be aligned in the direction of align and
displaced from position by the PostScript offset align*labelmargin(p).
Here, real labelmargin(pen p=currentpen) is a quantity used to align labels. In the
code below,
label("abcdefg",(0,0),align=up,basealign);
the baseline of the label will be exactly labelmargin(currentpen) PostScript units above
the center.
The constant Align can be used to align the bottom-left corner of the label at position.
The Label L can either be a string or the structure obtained by calling one of the functions
Label Label(string s="", pair position, align align=NoAlign,
pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
Label Label(string s="", align align=NoAlign,
pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
Label Label(Label L, pair position, align align=NoAlign,
pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
Label Label(Label L, align align=NoAlign,
pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
The text of a Label can be scaled, slanted, rotated, or shifted by multiplying it on
the left by an affine transform (see Section 6.4 [Transforms], page 50). For example,
Chapter 4: Drawing commands 21
layer();
One can prevent labels from overwriting one another with the overwrite pen attribute
(see [overwrite], page 50).
To draw or fill a box (or ellipse or other path) around a Label and return the bounding
object, use one of the routines
The function path[] texpath(Label L) returns the path array that TEX would fill to
draw the Label L.
Asymptote
The Vector Graphics Language
Andy Hammerlindl, John Bowman, and Tom Prince
https://asymptote.sourceforge.io
symptote
size(11.7cm,11.7cm);
asy(nativeformat(),"logo");
fill(unitcircle^^(scale(2/11.7)*unitcircle),
evenodd+rgb(124/255,205/255,124/255));
label(scale(1.1)*minipage(
"\centering\scriptsize \textbf{\LARGE {\tt Asymptote}\\
\smallskip
\small The Vector Graphics Language}\\
\smallskip
\textsc{Andy Hammerlindl, John Bowman, and Tom Prince}
https://asymptote.sourceforge.io\\
",8cm),(0,0.6));
label(graphic("logo","height=7cm"),(0,-0.22));
clip(unitcircle^^(scale(2/11.7)*unitcircle),evenodd);
24
5 Bezier curves
Each interior node of a cubic spline may be given a direction prefix or suffix {dir}: the
direction of the pair dir specifies the direction of the incoming or outgoing tangent, respec-
tively, to the curve at that node. Exterior nodes may be given direction specifiers only on
their interior side.
A cubic spline between the node z0 , with postcontrol point c0 , and the node z1 , with
precontrol point c1 , is computed as the Bezier curve
As illustrated in the diagram below, the third-order midpoint (m5 ) constructed from
two endpoints z0 and z1 and two control points c0 and c1 , is the point corresponding to
t = 1/2 on the Bezier curve formed by the quadruple (z0 , c0 , c1 , z1 ). 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:
c0 m1 c1
m3 m5 m4
m0
m2
z0 z1
Here m0 , m1 and m2 are the first-order midpoints, m3 and m4 are the second-order
midpoints, and m5 is the third-order midpoint. The curve is then constructed by recursively
applying the algorithm to (z0 , m0 , m3 , m5 ) and (m5 , m4 , m2 , z1 ).
In fact, an analogous property holds for points located at any fraction t in [0, 1] of each
segment, not just for midpoints (t = 1/2).
The Bezier curve constructed in this manner has the following properties:
• It is entirely contained in the convex hull of the given four points.
• It starts heading from the first endpoint to the first control point and finishes heading
from the second control point to the second endpoint.
The user can specify explicit control points between two nodes like this:
draw((0,0)..controls (0,100) and (100,100)..(100,0));
However, it is usually more convenient to just use the .. operator, which tells Asymptote
to choose its own control points using the algorithms described in Donald Knuth’s mono-
graph, The MetaFontbook, Chapter 14. The user can still customize the guide (or path)
by specifying direction, tension, and curl values.
Chapter 5: Bezier curves 25
The higher the tension, the straighter the curve is, and the more it approximates a
straight line. One can change the spline tension from its default value of 1 to any real value
greater than or equal to 0.75 (see John D. Hobby, Discrete and Computational Geometry
1, 1986):
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));
In these examples there is a space between 2 and ... This is needed as 2. is interpreted
as a numerical constant.
The curl parameter specifies the curvature at the endpoints of a path (0 means straight;
the default value of 1 means approximately circular):
draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));
The MetaPost ... path connector, which requests, when possible, an inflection-free
curve confined to a triangle defined by the endpoints and directions, is implemented in
Asymptote as the convenient abbreviation :: for ..tension atleast 1 .. (the ellipsis ...
is used in Asymptote to indicate a variable number of arguments; see Section 6.12.3 [Rest
arguments], page 72). For example, compare
draw((0,0){up}..(100,25){right}..(200,0){down});
with
draw((0,0){up}::(100,25){right}::(200,0){down});
The --- connector is an abbreviation for ..tension atleast infinity.. and the &
connector concatenates two paths, after first stripping off the last node of the first path
(which normally should coincide with the first node of the second path).
26
6 Programming
Here is a short introductory example to the Asymptote programming language that high-
lights the similarity of its control structures with those of C, C++, and Java:
// This is a comment.
Asymptote supports while, do, break, and continue statements just as in C/C++. It
also supports the Java-style shorthand for iterating over all elements of an array:
// Iterate over an array
int[] array={1,1,2,3,5};
for(int k : array) {
write(k);
}
In addition, it supports many features beyond the ones found in those languages.
bool3 an extended boolean type that can take on the values true, default, or false.
A bool3 type can be cast to or from a bool. The default initializer for bool3 is
default.
int an integer type; if no initializer is given, the implicit value 0 is assumed. The
minimum allowed value of an integer is intMin and the maximum value is
intMax.
real a real number; this should be set to the highest-precision native floating-point
type on the architecture. The implicit initializer for reals is 0.0. Real numbers
have precision realEpsilon, with realDigits significant digits. The smallest
positive real number is realMin and the largest positive real number is realMax.
The variables inf and nan, along with the function bool isnan(real x) are
useful when floating-point exceptions are masked with the -mask command-line
option (the default in interactive mode).
pair complex number, that is, an ordered pair of real components (x,y). The real
and imaginary parts of a pair z can read as z.x and z.y. We say that x and y
are virtual members of the data element pair; they cannot be directly modified,
however. The implicit initializer for pairs is (0.0,0.0).
There are a number of ways to take the complex conjugate of a pair:
pair z=(3,4);
z=(z.x,-z.y);
z=z.x-I*z.y;
z=conj(z);
Here I is the pair (0,1). A number of built-in functions are defined for pairs:
pair conj(pair z)
returns the conjugate of z;
real length(pair z)
returns the complex modulus |z| of its argument z. For example,
pair z=(3,4);
length(z);
returns the result 5. A synonym for length(pair) is abs(pair).
The function abs2(pair z) returns |z|2 ;
real angle(pair z, bool warn=true)
returns the angle of z in radians in the interval [-pi,pi] or 0 if warn
is false and z=(0,0) (rather than producing an error);
real degrees(pair z, bool warn=true)
returns the angle of z in degrees in the interval [0,360) or 0 if warn
is false and z=(0,0) (rather than producing an error);
pair unit(pair z)
returns a unit vector in the direction of the pair z;
pair expi(real angle)
returns a unit vector in the direction angle measured in radians;
Chapter 6: Programming 28
Strings delimited by double quotes (") are subject to the following mappings
to allow the use of double quotes in TEX (e.g. for using the babel package, see
Section 8.22 [babel], page 104):
• \" maps to "
• \\ maps to \\
Strings delimited by single quotes (') have the same mappings as character
strings in ANSI C:
• \’ maps to ’
• \" maps to "
• \? maps to ?
• \\ maps to backslash
• \a maps to alert
• \b maps to backspace
• \f maps to form feed
• \n maps to newline
• \r maps to carriage return
• \t maps to tab
• \v maps to vertical tab
• \0-\377 map to corresponding octal byte
• \x0-\xFF map to corresponding hexadecimal byte
The implicit initializer for strings is the empty string "". Strings may be con-
catenated with the + operator. In the following string functions, position 0
denotes the start of the string:
int length(string s)
returns the length of the string s;
int find(string s, string t, int pos=0)
returns the position of the first occurrence of string t in string s at
or after position pos, or -1 if t is not a substring of s;
int rfind(string s, string t, int pos=-1)
returns the position of the last occurrence of string t in string s at
or before position pos (if pos=-1, at the end of the string s), or -1
if t is not a substring of s;
string insert(string s, int pos, string t)
returns the string formed by inserting string t at position pos in s;
string erase(string s, int pos, int n)
returns the string formed by erasing the string of length n (if n=-1,
to the end of the string s) at position pos in s;
string substr(string s, int pos, int n=-1)
returns the substring of s starting at position pos and of length n
(if n=-1, until the end of the string s);
Chapter 6: Programming 31
string reverse(string s)
returns the string formed by reversing string s;
string replace(string s, string before, string after)
returns a string with all occurrences of the string before in the
string s changed to the string after;
string replace(string s, string[][] table)
returns a string constructed by translating in string s all
occurrences of the string before in an array table of string pairs
{before,after} to the corresponding string after;
string[] split(string s, string delimiter="")
returns an array of strings obtained by splitting s into substrings
delimited by delimiter (an empty delimiter signifies a space, but
with duplicate delimiters discarded);
string[] array(string s)
returns an array of strings obtained by splitting s into individ-
ual characters. The inverse operation is provided by operator
+(...string[] a).
string format(string s, int n, string locale="")
returns a string containing n formatted according to the C-style
format string s using locale locale (or the current locale if an
empty string is specified), following the behavior of the C function
fprintf), except that only one data field is allowed.
string format(string s=defaultformat, bool forcemath=false, string
s=defaultseparator, real x, string locale="")
returns a string containing x formatted according to the C-style
format string s using locale locale (or the current locale if an
empty string is specified), following the behavior of the C function
fprintf), except that only one data field is allowed, trailing zeros
are removed by default (unless # is specified), and if s specifies
math mode or forcemath=true, TEX is used to typeset scientific
notation using the defaultseparator="\!\times\!";;
int hex(string s);
casts a hexadecimal string s to an integer;
int ascii(string s);
returns the ASCII code for the first character of string s;
string string(real x, int digits=realDigits)
casts x to a string using precision digits and the C locale;
string locale(string s="")
sets the locale to the given string, if nonempty, and returns the
current locale;
string time(string format="%a %b %d %T %Z %Y")
returns the current time formatted by the ANSI C routine strftime
according to the string format using the current locale. Thus
Chapter 6: Programming 32
time();
time("%a %b %d %H:%M:%S %Z %Y");
are equivalent ways of returning the current time in the default
format used by the UNIX date command;
int seconds(string t="", string format="")
returns the time measured in seconds after the Epoch (Thu Jan
01 00:00:00 UTC 1970) as determined by the ANSI C routine
strptime according to the string format using the current locale,
or the current time if t is the empty string. Note that the "%Z"
extension to the POSIX strptime specification is ignored by the
current GNU C Library. If an error occurs, the value -1 is returned.
Here are some examples:
seconds("Mar 02 11:12:36 AM PST 2007","%b %d %r PST %Y");
seconds(time("%b %d %r %z %Y"),"%b %d %r %z %Y");
seconds(time("%b %d %r %Z %Y"),"%b %d %r "+time("%Z")+" %Y");
1+(seconds()-seconds("Jan 1","%b %d"))/(24*60*60);
The last example returns today’s ordinal date, measured from the
beginning of the year.
string time(int seconds, string format="%a %b %d %T %Z %Y")
returns the time corresponding to seconds seconds after the Epoch
(Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C routine
strftime according to the string format using the current locale.
For example, to return the date corresponding to 24 hours ago:
time(seconds()-24*60*60);
int system(string s)
int system(string[] s)
if the setting safe is false, call the arbitrary system command s;
void asy(string format, bool overwrite=false ... string[] s)
conditionally process each file name in array s in a new envi-
ronment, using format format, overwriting the output file only if
overwrite is true;
void abort(string s="")
aborts execution (with a non-zero return code in batch mode); if
string s is nonempty, a diagnostic message constructed from the
source file, line number, and s is printed;
void assert(bool b, string s="")
aborts execution with an error message constructed from s if
b=false;
void exit()
exits (with a zero error return code in batch mode);
void sleep(int seconds)
pauses for the given number of seconds;
Chapter 6: Programming 33
int n=nCircle);
path Arc(pair c, real r, real angle1, real angle2, int n=nCircle);
path Arc(pair c, explicit pair z1, explicit pair z2,
bool direction=CCW, int n=nCircle);
An ellipse can be drawn with the routine
path ellipse(pair c, real a, real b)
{
return shift(c)*scale(a,b)*unitcircle;
}
A brace can be constructed between pairs a and b with
path brace(pair a, pair b, real amplitude=bracedefaultratio*length(b-a));
This example illustrates the use of all five guide connectors discussed in Chap-
ter 3 [Tutorial], page 10, and Chapter 5 [Bezier curves], page 24:
size(300,0);
pair[] z=new pair[10];
path p=z[0]..z[1]---z[2]::{up}z[3]
&z[3]..z[4]--z[5]::{up}z[6]
&z[6]::z[7]---z[8]..{up}z[9];
draw(p,grey+linewidth(4mm));
dot(z);
int n=30;
real a=1.5;
real width=2a/n;
guide hat;
path solved;
draw(hat);
dot(hat,red);
draw(solved,dashed);
6.3 Pens
In Asymptote, pens provide a context for the four basic drawing commands (see Chapter 4
[Drawing commands], page 15). They are used to specify the following drawing attributes:
color, line type, line width, line cap, line join, fill rule, text alignment, font, font size,
pattern, overwrite mode, and calligraphic transforms on the pen nib. The default pen used
by the drawing routines is called currentpen. This provides the same functionality as the
MetaPost command pickup. The implicit initializer for pens is defaultpen.
Pens may be added together with the nonassociative binary operator +. This will add
the colors of the two pens. All other non-default attributes of the rightmost pen will
override those of the leftmost pen. Thus, one can obtain a yellow dashed pen by saying
dashed+red+green or red+green+dashed or red+dashed+green. The binary operator *
can be used to scale the color of a pen by a real number, until it saturates with one or more
color components equal to 1.
• Colors are specified using one of the following colorspaces:
pen gray(real g);
This produces a grayscale color, where the intensity g lies in the interval
[0,1], with 0.0 denoting black and 1.0 denoting white.
pen rgb(real r, real g, real b);
This produces an RGB color, where each of the red, green, and blue inten-
sities r, g, b, lies in the interval [0,1].
pen RGB(int r, int g, int b);
This produces an RGB color, where each of the red, green, and blue inten-
sities r, g, b, lies in the interval [0,255].
pen cmyk(real c, real m, real y, real k);
This produces a CMYK color, where each of the cyan, magenta, yellow,
and black intensities c, m, y, k, lies in the interval [0,1].
pen invisible;
This special pen writes in invisible ink, but adjusts the bounding box as
if something had been drawn (like the \phantom command in TEX). The
function bool invisible(pen) can be used to test whether a pen is invis-
ible.
The default color is black; this may be changed with the routine defaultpen(pen).
The function colorspace(pen p) returns the colorspace of pen p as a string ("gray",
"rgb", "cmyk", or "").
The function real[] colors(pen) returns the color components of a pen. The
functions pen gray(pen), pen rgb(pen), and pen cmyk(pen) return new pens
obtained by converting their arguments to the respective color spaces. The function
colorless(pen=currentpen) returns a copy of its argument with the color attributes
stripped (to avoid color mixing).
A 6-character RGB hexadecimal string can be converted to a pen with the routine
pen rgb(string s);
Chapter 6: Programming 42
The standard 140 RGB X11 colors can be imported with the command
import x11colors;
and the standard 68 CMYK TEX colors can be imported with the command
import texcolors;
Note that there is some overlap between these two standards and the definitions of
some colors (e.g. Green) actually disagree.
Asymptote also comes with a asycolors.sty LaTeX package that defines to LaTeX
CMYK versions of Asymptote’s predefined colors, so that they can be used directly
within LaTeX strings. Normally, such colors are passed to LaTeX via a pen argument;
however, to change the color of only a portion of a string, say for a slide presentation,
(see Section 8.20 [slide], page 104) it may be desirable to specify the color directly to
LaTeX. This file can be passed to LaTeX with the Asymptote command
usepackage("asycolors");
Chapter 6: Programming 43
The structure hsv defined in plain_pens.asy may be used to convert between HSV
and RGB spaces, where the hue h is an angle in [0, 360) and the saturation s and value
v lie in [0,1]:
pen p=hsv(180,0.5,0.75);
write(p); // ([default], red=0.375, green=0.75, blue=0.75)
hsv q=p;
write(q.h,q.s,q.v); // 180 0.5 0.75
• Line types are specified with the function pen linetype(real[] a, real offset=0,
bool scale=true, bool adjust=true), where a is an array of real array numbers.
The optional parameter offset specifies where in the pattern to begin. The first
number specifies how far (if scale is true, in units of the pen line width; otherwise in
PostScript units) to draw with the pen on, the second number specifies how far to
draw with the pen off, and so on. If adjust is true, these spacings are automatically
adjusted by Asymptote to fit the arclength of the path. Here are the predefined line
types:
pen solid=linetype(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();
The default line type is solid; this may be changed with defaultpen(pen). The
line type of a pen can be determined with the functions real[] linetype(pen
p=currentpen), real offset(pen p), bool scale(pen p), and bool adjust(pen p).
• The pen line width is specified in PostScript units with pen linewidth(real). The
default line width is 0.5 bp; this value may be changed with defaultpen(pen). The line
width of a pen is returned by real linewidth(pen p=currentpen). For convenience,
in the module plain_pens we define
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;}
so that one may set the line width like this:
defaultpen(2);
pen p=red+0.5;
• A pen with a specific PostScript line cap is returned on calling linecap with an
integer argument:
Chapter 6: Programming 44
pen squarecap=linecap(0);
pen roundcap=linecap(1);
pen extendcap=linecap(2);
The default line cap, roundcap, may be changed with defaultpen(pen). The line cap
of a pen is returned by int linecap(pen p=currentpen).
• A pen with a specific PostScript join style is returned on calling linejoin with an
integer argument:
pen miterjoin=linejoin(0);
pen roundjoin=linejoin(1);
pen beveljoin=linejoin(2);
The default join style, roundjoin, may be changed with defaultpen(pen).The join
style of a pen is returned by int linejoin(pen p=currentpen).
• A pen with a specific PostScript miter limit is returned by calling miterlimit(real).
The default miterlimit, 10.0, may be changed with defaultpen(pen). The miter limit
of a pen is returned by real miterlimit(pen p=currentpen).
• A pen with a specific PostScript fill rule is returned on calling fillrule with an
integer argument:
pen zerowinding=fillrule(0);
pen evenodd=fillrule(1);
The fill rule, which identifies the algorithm used to determine the insideness of a path or
array of paths, only affects the clip, fill, and inside functions. For the zerowinding
fill rule, a point z is outside the region bounded by a path if the number of upward
intersections of the path with the horizontal line z--z+infinity minus the number
of downward intersections is zero. For the evenodd fill rule, z is considered to be
outside the region if the total number of such intersections is even. The default fill
rule, zerowinding, may be changed with defaultpen(pen). The fill rule of a pen is
returned by int fillrule(pen p=currentpen).
• A pen with a specific text alignment setting is returned on calling basealign with an
integer argument:
pen nobasealign=basealign(0);
pen basealign=basealign(1);
The default setting, nobasealign, which may be changed with defaultpen(pen),
causes the label alignment routines to use the full label bounding box for alignment.
In contrast, basealign requests that the TEX baseline be respected. The base align
setting of a pen is returned by int basealign(pen p=currentpen).
For example, in the following image, the baselines of green π and γ are aligned, while
the bottom border of red −π and −γ are aligned.
import fontsize;
import three;
settings.autobillboard=false;
settings.embed=false;
currentprojection=orthographic(Z);
Chapter 6: Programming 45
defaultpen(fontsize(100pt));
dot(O);
label("acg",O,align=N,basealign);
label("ace",O,align=N,red);
label("acg",O,align=S,basealign);
label("ace",O,align=S,red);
label("acg",O,align=E,basealign);
label("ace",O,align=E,red);
label("acg",O,align=W,basealign);
label("ace",O,align=W,red);
picture pic;
dot(pic,(labelmargin(),0,0),blue);
dot(pic,(-labelmargin(),0,0),blue);
dot(pic,(0,labelmargin(),0),blue);
dot(pic,(0,-labelmargin(),0),blue);
add(pic,O);
dot((0,0));
label("acg",(0,0),align=N,basealign);
label("ace",(0,0),align=N,red);
label("acg",(0,0),align=S,basealign);
label("ace",(0,0),align=S,red);
label("acg",(0,0),align=E,basealign);
label("ace",(0,0),align=E,red);
label("acg",(0,0),align=W,basealign);
label("ace",(0,0),align=W,red);
picture pic;
dot(pic,(labelmargin(),0),blue);
dot(pic,(-labelmargin(),0),blue);
dot(pic,(0,labelmargin()),blue);
dot(pic,(0,-labelmargin()),blue);
add(pic,(0,0));
Chapter 6: Programming 46
acgacg
ace
aceacg
ace
acg
ace
Another method for aligning baselines is provided by the baseline function (see [base-
line], page 22).
• The font size is specified in TEX points (1 pt = 1/72.27 inches) with the function pen
fontsize(real size, real lineskip=1.2*size). The default font size, 12pt, may
be changed with defaultpen(pen). Nonstandard font sizes may require inserting
import fontsize;
at the beginning of the file (this requires the type1cm package available from
http://mirror.ctan.org/macros/latex/contrib/type1cm/
and included in recent LaTeX distributions). The font size and line skip of a pen
can be examined with the routines real fontsize(pen p=currentpen) and real
lineskip(pen p=currentpen), respectively.
• A pen using a specific LATEX NFSS font is returned by calling the function pen
font(string encoding, string family, string series, string shape). The
default setting, font("OT1","cmr","m","n"), corresponds to 12pt Computer Modern
Roman; this may be changed with defaultpen(pen). The font setting of a pen is
returned by string font(pen p=currentpen).
Alternatively, one may select a fixed-size TEX font (on which fontsize has no effect)
like "cmr12" (12pt Computer Modern Roman) or "pcrr" (Courier) using the function
pen font(string name). An optional size argument can also be given to scale the font
to the requested size: pen font(string name, real size).
A nonstandard font command can be generated with pen fontcommand(string).
A convenient interface to the following standard PostScript fonts is also provided:
pen AvantGarde(string series="m", string shape="n");
pen Bookman(string series="m", string shape="n");
pen Courier(string series="m", string shape="n");
pen Helvetica(string series="m", string shape="n");
pen NewCenturySchoolBook(string series="m", string shape="n");
pen Palatino(string series="m", string shape="n");
pen TimesRoman(string series="m", string shape="n");
pen ZapfChancery(string series="m", string shape="n");
pen Symbol(string series="m", string shape="n");
Chapter 6: Programming 47
add("tile",tile());
add("filledtilewithmargin",tile(6mm,4mm,red,Fill),(1mm,1mm),(1mm,1mm));
add("checker",checker());
add("brick",brick());
real s=2.5;
filldraw(unitcircle,pattern("tile"));
filldraw(shift(s,0)*unitcircle,pattern("filledtilewithmargin"));
filldraw(shift(2s,0)*unitcircle,pattern("checker"));
filldraw(shift(3s,0)*unitcircle,pattern("brick"));
Hatch patterns can be generated with the routines picture hatch(real H=5mm,
pair dir=NE, pen p=currentpen), picture crosshatch(real H=5mm, pen
p=currentpen):
size(0,100);
import patterns;
add("hatch",hatch());
add("hatchback",hatch(NW));
add("crosshatch",crosshatch(3mm));
real s=1.25;
filldraw(unitsquare,pattern("hatch"));
filldraw(shift(s,0)*unitsquare,pattern("hatchback"));
filldraw(shift(2s,0)*unitsquare,pattern("crosshatch"));
Chapter 6: Programming 49
You may need to turn off aliasing in your PostScript viewer for patterns to appear
correctly. Custom patterns can easily be constructed, following the examples in module
patterns. The tiled pattern can even incorporate shading (see [gradient shading],
page 18), as illustrated in this example (not included in the manual because not all
printers support PostScript 3):
size(0,100);
import patterns;
real d=4mm;
picture tiling;
path square=scale(d)*unitsquare;
axialshade(tiling,square,white,(0,0),black,(d,d));
fill(tiling,shift(d,d)*square,blue);
add("shadedtiling",tiling);
filldraw(unitcircle,pattern("shadedtiling"));
• One can specify a custom pen nib as an arbitrary polygonal path with pen
makepen(path); this path represents the mark to be drawn for paths containing a
single point. This pen nib path can be recovered from a pen with path nib(pen).
Unlike in MetaPost, the path need not be convex:
size(200);
pen convex=makepen(scale(10)*polygon(8))+grey;
draw((1,0.4),convex);
draw((0,0)---(1,1)..(2,0)--cycle,convex);
pen nonconvex=scale(10)*
makepen((0,0)--(0.25,-1)--(0.5,0.25)--(1,0)--(0.5,1.25)--cycle)+red;
draw((0.5,-1.5),nonconvex);
draw((0,-1.5)..(1,-0.5)..(2,-1.5),nonconvex);
Chapter 6: Programming 50
The value nullpath represents a circular pen nib (the default); an elliptical pen can
be achieved simply by multiplying the pen by a transform: yscale(2)*currentpen.
• One can prevent labels from overwriting one another by using the pen attribute
overwrite, which takes a single argument:
Allow Allow labels to overwrite one another. This is the default behavior (unless
overridden with defaultpen(pen).
Suppress Suppress, with a warning, each label that would overwrite another label.
SuppressQuiet
Suppress, without warning, each label that would overwrite another label.
Move Move a label that would overwrite another out of the way and issue a warn-
ing. As this adjustment is during the final output phase (in PostScript
coordinates) it could result in a larger figure than requested.
MoveQuiet
Move a label that would overwrite another out of the way, without warn-
ing. As this adjustment is during the final output phase (in PostScript
coordinates) it could result in a larger figure than requested.
The routine defaultpen() returns the current default pen attributes. Calling the routine
resetdefaultpen() resets all pen default attributes to their initial values.
6.4 Transforms
Asymptote makes extensive use of affine transforms. A pair (x,y) is transformed by the
transform t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy) to (x',y'), where
x' = t.x + t.xx * x + t.xy * y
y' = t.y + t.yx * x + t.yy * y
This is equivalent to the PostScript transformation [t.xx t.yx t.xy t.yy t.x t.y].
Transforms can be applied to pairs, guides, paths, pens, strings, transforms, frames, and
pictures by multiplication (via the binary operator *) on the left (see [circle], page 33, for
an example). Transforms can be composed with one another and inverted with the function
Chapter 6: Programming 51
transform inverse(transform t); they can also be raised to any integer power with the
^ operator.
The built-in transforms are:
transform identity;
the identity transform;
transform shift(pair z);
translates by the pair z;
transform shift(real x, real y);
translates by the pair (x,y);
transform xscale(real x);
scales by x in the x direction;
transform yscale(real y);
scales by y in the y direction;
transform scale(real s);
scale by s in both x and y directions;
transform scale(real x, real y);
scale by x in the x direction and by y in the y direction;
transform slant(real s);
maps (x,y) –> (x+s*y,y);
transform rotate(real angle, pair z=(0,0));
rotates by angle in degrees about z;
transform reflect(pair a, pair b);
reflects about the line a--b.
transform zeroTransform;
the zero transform;
The implicit initializer for transforms is identity(). The routines shift(transform
t) and shiftless(transform t) return the transforms (t.x,t.y,0,0,0,0) and
(0,0,t.xx,t.xy,t.yx,t.yy) respectively. The function bool isometry(transform t)
can be used to test if t is an isometry (preserves distance).
or prepended with
void prepend(frame dest, frame src);
A frame obtained by aligning frame f in the direction align, in a manner
analogous to the align argument of label (see Section 4.4 [label], page 20), is
returned by
frame align(frame f, pair align);
picture Pictures are high-level structures (see Section 6.9 [Structures], page 63) defined
in the module plain that provide canvases for drawing in user coordinates. The
default picture is called currentpicture. A new picture can be created like
this:
picture pic;
Anonymous pictures can be made by the expression new picture.
The size routine specifies the dimensions of the desired picture:
void size(picture pic=currentpicture, real x, real y=x,
bool keepAspect=pic.keepAspect);
If the x and y sizes are both 0, user coordinates will be interpreted as
PostScript coordinates. In this case, the transform mapping pic to the final
output frame is identity().
If exactly one of x or y is 0, no size restriction is imposed in that direction; it
will be scaled the same as the other direction.
If keepAspect is set to Aspect or true (the default), the picture will be scaled
with its aspect ratio preserved such that the final width is no more than x and
the final height is no more than y.
If keepAspect is set to IgnoreAspect or false, the picture will be scaled in
both directions so that the final width is x and the height is y.
To make the user coordinates of picture pic represent multiples of x units in
the x direction and y units in the y direction, use
void unitsize(picture pic=currentpicture, real x, real y=x);
When nonzero, these x and y values override the corresponding size parameters
of picture pic.
The routine
void size(picture pic=currentpicture, real xsize, real ysize,
pair min, pair max);
forces the final picture scaling to map the user coordinates box(min,max) to a
region of width xsize and height ysize (when these parameters are nonzero).
Alternatively, calling the routine
transform fixedscaling(picture pic=currentpicture, pair min,
pair max, pen p=nullpen, bool warn=false);
will cause picture pic to use a fixed scaling to map user coordinates in
box(min,max) to the (already specified) picture size, taking account of the
width of pen p. A warning will be issued if the final picture exceeds the
specified size.
Chapter 6: Programming 53
A picture pic can be fit to a frame and output to a file prefix.format using
image format format by calling the shipout function:
void shipout(string prefix=defaultfilename, picture pic=currentpicture,
orientation orientation=orientation,
string format="", bool wait=false, bool view=true,
string options="", string script="",
light light=currentlight, projection P=currentprojection)
The default output format, PostScript, may be changed with the -f or -tex
command-line options. The options, script, and projection parameters are
only relevant for 3D pictures. If defaultfilename is an empty string, the prefix
outprefix() will be used.
A shipout() command is added implicitly at file exit. Explicit shipout()
commands to the same file as the final implicit shipout are ignored. The
default page orientation is Portrait; this may be modified by changing the
variable orientation. To output in landscape mode, simply set the variable
orientation=Landscape or issue the command
shipout(Landscape);
To rotate the page by −90 degrees, use the orientation Seascape. The orien-
tation UpsideDown rotates the page by 180 degrees.
A picture pic can be explicitly fit to a frame by calling
frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize,
bool keepAspect=pic.keepAspect);
The default size and aspect ratio settings are those given to the size command
(which default to 0, 0, and true, respectively). The transformation that would
currently be used to fit a picture pic to a frame is returned by the member
function pic.calculateTransform().
In certain cases (e.g. 2D graphs) where only an approximate size estimate for
pic is available, the picture fitting routine
frame pic.scale(real xsize=this.xsize, real ysize=this.ysize,
bool keepAspect=this.keepAspect);
(which scales the resulting frame, including labels and fixed-size objects) will
enforce perfect compliance with the requested size specification, but should not
normally be required.
To draw a bounding box with margins around a picture, fit the picture to a
frame using the function
frame bbox(picture pic=currentpicture, real xmargin=0,
real ymargin=xmargin, pen p=currentpen,
filltype filltype=NoFill);
Here filltype specifies one of the following fill types:
FillDraw Fill the interior and draw the boundary.
FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen,
pen drawpen=nullpen) If fillpen is nullpen, fill with the drawing
pen; otherwise fill with pen fillpen. If drawpen is nullpen, draw
Chapter 6: Programming 54
objects (such as labels and arrowheads). If user is true the returned value is
in user coordinates, otherwise it is in PostScript coordinates.
The function
pair truepoint(picture pic=currentpicture, pair dir, bool user=true);
is identical to point, except that it also accounts for fixed-size objects, using
the scaling transform that picture pic would have if currently fit to a frame
using its default size specification. If user is true the returned value is in user
coordinates, otherwise it is in PostScript coordinates.
Sometimes it is useful to draw objects on separate pictures and add one picture
to another using the add function:
void add(picture src, bool group=true,
filltype filltype=NoFill, bool above=true);
void add(picture dest, picture src, bool group=true,
filltype filltype=NoFill, bool above=true);
The first example adds src to currentpicture; the second one adds src to
dest. The group option specifies whether or not the graphical user interface
should treat all of the elements of src as a single entity (see Chapter 11 [GUI],
page 181), filltype requests optional background filling or clipping, and above
specifies whether to add src above or below existing objects.
There are also routines to add a fixed-size picture or frame src to another
picture dest (or currentpicture) about the user coordinate position:
void add(picture src, pair position, bool group=true,
filltype filltype=NoFill, bool above=true);
void add(picture dest, picture src, pair position,
bool group=true, filltype filltype=NoFill, bool above=true);
void add(picture dest=currentpicture, frame src, pair position=0,
bool group=true, filltype filltype=NoFill, bool above=true);
void add(picture dest=currentpicture, frame src, pair position,
pair align, bool group=true, filltype filltype=NoFill,
bool above=true);
The optional align argument in the last form specifies a direction to use for
aligning the frame, in a manner analogous to the align argument of label (see
Section 4.4 [label], page 20). However, one key difference is that when align
is not specified, labels are centered, whereas frames and pictures are aligned so
that their origin is at position. Illustrations of frame alignment can be found
in the examples [errorbars], page 116, and [image], page 136. If you want to
align three or more subpictures, group them two at a time:
picture pic1;
real size=50;
size(pic1,size);
fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
picture pic2;
size(pic2,size);
fill(pic2,unitcircle,green);
Chapter 6: Programming 56
picture pic3;
size(pic3,size);
fill(pic3,unitsquare,blue);
picture pic;
add(pic,pic1.fit(),(0,0),N);
add(pic,pic2.fit(),(0,0),10S);
add(pic.fit(),(0,0),N);
add(pic3.fit(),(0,0),10S);
Alternatively, one can use attach to automatically increase the size of picture
dest to accommodate adding a frame src about the user coordinate position:
fill(f,circle((0,0),1.5pt));
add(f,position=(1,1),align=(0,0));
A deferred drawing routine is an object of type drawer, which is a function with signature
void(frame f, transform t). For example, if the drawing routine
void d(frame f, transform t){
fill(f,shift(3cm,0)*circle(t*(1,1),2pt));
}
is added to currentpicture with
currentpicture.add(d);
a filled circle of radius 2pt will be drawn on currentpicture centered 3cm to the right of user
coordinate (1,1). The parameter t is the affine transformation from user coordinates to
PostScript coordinates.
Even though the actual drawing is deferred, you still need to specify to the Asymptote
scaling routines that ultimately a fixed-size circle of radius 2pt will be drawn 3cm to the
right of user-coordinate (1,1), by adding a frame about (1,1) that extends beyond (1,1) from
(3cm-2pt,-2pt)+min(currentpen) to (3cm+2pt,2pt)+max(currentpen), where we have
even accounted for the pen linewidth. The following example will then produce a PDF file
10 cm wide:
settings.outformat="pdf";
size(10cm);
dot((0,0));
dot((1,1),red);
add(new void(frame f, transform t) {
fill(f,shift(3cm,0)*circle(t*(1,1),2pt));
});
pair trueMin=(3cm-2pt,-2pt)+min(currentpen);
pair trueMax=(3cm+2pt,2pt)+max(currentpen);
currentpicture.addPoint((1,1),trueMin);
currentpicture.addPoint((1,1),trueMax);
Here we specified the minimum and maximum user and truesize (fixed) coordinates of the
drawer with the picture routine
void addPoint(pair user, pair truesize);
Alternatively, one can use
void addBox(pair userMin, pair userMax, pair trueMin=0, pair trueMax=0) {
to specify a bounding box with bottom-left corner t*(1,1)+trueMin and top-right corner
t*(1,1)+trueMax, where t is the transformation that transforms from user coordinates to
PostScript coordinates.
For more details about deferred drawing, see “Asymptote: A vector graphics language,”
John C. Bowman and Andy Hammerlindl, TUGBOAT: The Communications of the TeX
Users Group, 29:2, 288-294 (2008),
https://www.math.ualberta.ca/~bowman/publications/asyTUG.pdf.
Chapter 6: Programming 59
6.7 Files
Asymptote can read and write text files (including comma-separated value) files and
portable XDR (External Data Representation) binary files.
An input file can be opened with
input(string name=""
reading is then done by assignment:
file fin=input("test.txt");
real a=fin;
If the optional boolean argument check is false, no check will be made that the file
exists. If the file does not exist or is not readable, the function bool error(file) will
return true. The first character of the string comment specifies a comment character. If
this character is encountered in a data file, the remainder of the line is ignored. When
reading strings, a comment character followed immediately by another comment character
is treated as a single literal comment character. If Asymptote is compiled with support for
libcurl, name can be a URL.
Unless the -noglobalread command-line option is specified, one can change the current
working directory for read operations to the contents of the string s with the function
string cd(string s), which returns the new working directory. If string s is empty, the
path is reset to the value it had at program startup.
When reading pairs, the enclosing parenthesis are optional. Strings are also read by
assignment, by reading characters up to but not including a newline. In addition, Asymptote
provides the function string getc(file) to read the next character (treating the comment
character as an ordinary character) and return it as a string.
A file named name can be open for output with
file output(string name="", bool update=false, string comment="#", string mode="");
If update=false, any existing data in the file will be erased and only write operations can
be used on the file. If update=true, any existing data will be preserved, the position will
be set to the end-of-file, and both reading and writing operations will be enabled. For
security reasons, writing to files in directories other than the current directory is allowed
only if the -globalwrite (or -nosafe) command-line option is specified. Reading from files
in other directories is allowed unless the -noglobalread command-line option is specified.
The function 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 s.
There are two special files: stdin, which reads from the keyboard, and stdout, which
writes to the terminal. The implicit initializer for files is null.
Data of a built-in type T can be written to an output file by calling one of the functions
write(string s="", T x, suffix suffix=endl ... T[]);
write(file file, string s="", T x, suffix suffix=none ... T[]);
write(file file=stdout, string s="", explicit T[] x ... T[][]);
write(file file=stdout, T[][]);
write(file file=stdout, T[][][]);
write(suffix suffix=endl);
write(file file, suffix suffix=none);
Chapter 6: Programming 60
If file is not specified, stdout is used and terminated by default with a newline. If
specified, the optional identifying string s is written before the data x. An arbitrary number
of data values may be listed when writing scalars or one-dimensional arrays. The suffix
may be one of the following: none (do nothing), flush (output buffered data), endl (termi-
nate with a newline and flush), newl (terminate with a newline), DOSendl (terminate with
a DOS newline and flush), DOSnewl (terminate with a DOS newline), tab (terminate with a
tab), or comma (terminate with a comma). Here are some simple examples of data output:
file fout=output("test.txt");
write(fout,1); // Writes "1"
write(fout, endl); // Writes a new line
write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
A file may be opened with mode="xdr", to read or write double precision (64-bit) reals
and single precision (32-bit) integers in Sun Microsystem’s XDR (External Data Repre-
sentation) portable binary format (available on all UNIX platforms). Alternatively, a file
may also be opened with mode="binary" to read or write double precision reals and sin-
gle precision integers in the native (nonportable) machine binary format, or to read the
entire file into a string. The virtual member functions file singlereal(bool b=true)
and file singleint(bool b=true) be used to change the precision of real and integer
I/O operations, respectively, for an XDR or binary file f. Similarly, the function file
signedint(bool b=true) can be used to modify the signedness of integer reads and writes
for an XDR or binary file f.
The virtual members name, mode, singlereal, singleint, and signedint may be used
to query the respective parameters for a given file.
One can test a file for end-of-file with the boolean function eof(file), end-of-line
with eol(file), and for I/O errors with error(file). One can flush the output buffers
with flush(file), clear a previous I/O error with clear(file), and close the file with
close(file). The function int precision(file file=stdout, int digits=0) sets the
number of digits of output precision for file to digits, provided digits is nonzero, and
returns the previous precision setting. The function int tell(file) returns the current
position in a file relative to the beginning. The routine seek(file file, int pos) can
be used to change this position, where a negative value for the position pos is interpreted
as relative to the end-of-file. For example, one can rewind a file file with the command
seek(file,0) and position to the final character in the file with seek(file,-1). The
command seekeof(file) sets the position to the end of the file.
Assigning settings.scroll=n for a positive integer n requests a pause after every n
output lines to stdout. One may then press Enter to continue to the next n output lines,
s followed by Enter to scroll without further interruption, or q followed by Enter to quit
the current output operation. If n is negative, the output scrolls a page at a time (i.e. by
one less than the current number of display lines). The default value, settings.scroll=0,
specifies continuous scrolling.
The routines
string getstring(string name="", string default="", string prompt="",
bool store=true);
int getint(string name="", int default=0, string prompt="",
bool store=true);
Chapter 6: Programming 61
Variables of most types can be declared without an explicit initializer and they will be
initialized by the default initializer of that type:
• Variables of the numeric types int, real, and pair are all initialized to zero; variables
of type triple are initialized to O=(0,0,0).
• boolean variables are initialized to false.
• string variables are initialized to the empty string.
• transform variables are initialized to the identity transformation.
• path and guide variables are initialized to nullpath.
• pen variables are initialized to the default pen.
• frame and picture variables are initialized to empty frames and pictures, respectively.
• file variables are initialized to null.
The default initializers for user-defined array, structure, and function types are explained
in their respective sections. Some types, such as code, do not have default initializers. When
a variable of such a type is introduced, the user must initialize it by explicitly giving it a
value.
The default initializer for any type T can be redeclared by defining the function T
operator init(). For instance, int variables are usually initialized to zero, but in
int operator init() {
return 3;
}
int y;
the variable y is initialized to 3. This example was given for illustrative purposes; redeclaring
the initializers of built-in types is not recommended. Typically, operator init is used to
define sensible defaults for user-defined types.
The special type 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,
var x=5;
var y=4.3;
var reddash=red+dashed;
is equivalent to
int x=5;
real y=4.3;
pen reddash=red+dashed;
var may also be used with the extended for loop syntax.
int[] a = {1,2,3};
for (var x : a)
write(x);
Chapter 6: Programming 63
6.9 Structures
Users may also define their own data types as structures, along with user-defined operators,
much as in C++. By default, structure members are public (may be read and modified
anywhere in the code), but may be optionally declared restricted (readable anywhere
but writeable only inside the structure where they are defined) or private (readable and
writable only inside the structure). In a structure definition, the keyword this can be used
as an expression to refer to the enclosing structure. Any code at the top-level scope within
the structure is executed on initialization.
Variables hold references to structures. That is, in the example:
struct T {
int x;
}
T foo;
T bar=foo;
bar.x=5;
The variable foo holds a reference to an instance of the structure T. When bar is
assigned the value of foo, it too now holds a reference to the same instance as foo does.
The assignment bar.x=5 changes the value of the field x in that instance, so that foo.x
will also be equal to 5.
The expression new T creates a new instance of the structure T and returns a reference
to that instance. In creating the new instance, any code in the body of the record definition
is executed. For example:
int Tcount=0;
struct T {
int x;
++Tcount;
}
T foo=new T;
T foo;
Here, new T produces a new instance of the class, which causes Tcount to be incremented,
tracking the number of instances produced. The declarations T foo=new T and T foo are
equivalent: the second form implicitly creates a new instance of T. That is, after the
definition of a structure T, a variable of type T is initialized to a new instance (new T) by
default. During the definition of the structure, however, variables of type T are initialized
to null by default. This special behavior is to avoid infinite recursion of creating new
instances in code such as
struct tree {
int value;
tree left;
tree right;
}
Chapter 6: Programming 64
The expression null can be cast to any structure type to yield a null reference, a reference
that does not actually refer to any instance of the structure. Trying to use a field of a null
reference will cause an error.
The function bool alias(T,T) checks to see if two structure references refer to the same
instance of the structure (or both to null). In the example at the beginning of this section,
alias(foo,bar) would return true, but alias(foo,new T) would return false, as new T
creates a new instance of the structure T. The boolean operators == and != are by default
equivalent to alias and !alias respectively, but may be overwritten for a particular type
(for example, to do a deep comparison).
Here is a simple example that illustrates the use of structures:
struct S {
real a=1;
real f(real a) {return a+this.a;}
}
write(s.f(2)); // Outputs 3
write((s+s).f(0)); // Outputs 2
It is often convenient to have functions that construct new instances of a structure. Say
we have a Person structure:
struct Person {
string firstname;
string lastname;
}
Person joe;
joe.firstname="Joe";
joe.lastname="Jones";
Creating a new Person is a chore; it takes three lines to create a new instance and to
initialize its fields (that’s still considerably less effort than creating a new person in real life,
though).
We can reduce the work by defining operator init:
struct Person {
string firstname;
string lastname;
Chapter 6: Programming 65
struct child {
parent parent;
real y=3;
Chapter 6: Programming 66
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;
For further examples of structures, see Legend and picture in the Asymptote base
module plain.
6.10 Operators
6.10.1 Arithmetic & logical operators
Asymptote uses the standard binary arithmetic operators. However, when one integer is
divided by another, both arguments are converted to real values before dividing and a real
quotient is returned (since this is typically what is intended; otherwise one can use the
function int quotient(int x, int y), which returns greatest integer less than or equal to
x/y). In all other cases both operands are promoted to the same type, which will also be
the type of the result:
+ addition
- subtraction
* multiplication
/ division
# integer division; equivalent to quotient(x,y). Noting that the Python3 com-
munity adopted our comment symbol (//) for integer division, we decided to
reciprocate and use their comment symbol for integer division in Asymptote!
% modulo; the result always has the same sign as the divisor. In particular, this
makes q*(p # q)+p % q == p for all integers p and nonzero integers q.
^ power; if the exponent (second argument) is an int, recursive multiplication is
used; otherwise, logarithms and exponentials are used (** is a synonym for ^).
The usual boolean operators are also defined:
== equals
Chapter 6: Programming 67
!= not equals
< less than
<= less than or equals
>= greater than or equals
> greater than
&& and (with conditional evaluation of right-hand argument)
& and
|| or (with conditional evaluation of right-hand argument)
| or
^ xor
! not
Asymptote also supports the C-like conditional syntax:
bool positive=(pi > 0) ? true : false;
The function T interp(T a, T b, real t) returns (1-t)*a+t*b for nonintegral built-in
arithmetic types T. If a and b are pens, they are first promoted to the same color space.
Asymptote also defines bitwise functions int AND(int,int), int OR(int,int),
int XOR(int,int), int NOT(int), int CLZ(int) (count leading zeros), int CTZ(int)
(count trailing zeros), int popcount(int) (count bits populated by ones), and int
bitreverse(int a, int bits) (reverse bits within a word of length bits).
write(3x);
write(2.5x);
write(3y);
write(-1.602e-19 y);
write(0.5(x,y));
write(2x^2);
write(3x+2y);
write(3(x+2y));
write(3sin(x));
write(3(sin(x))^2);
write(10cm);
This produces the output
6
5
Chapter 6: Programming 69
6
-3.204e-19
(1,1)
8
10
18
2.72789228047704
2.48046543129542
283.464008929116
6.12 Functions
Asymptote functions are treated as variables with a signature (non-function variables have
null signatures). Variables with the same name are allowed, so long as they have distinct
signatures.
Function arguments are passed by value. To pass an argument by reference, simply
enclose it in a structure (see Section 6.9 [Structures], page 63).
Here are some significant features of Asymptote functions:
1. Variables with signatures (functions) and without signatures (nonfunction variables)
are distinct:
int x, x();
x=5;
x=new int() {return 17;};
x=x(); // calls x() and puts the result, 17, in the scalar x
2. Traditional function definitions are allowed:
int sqr(int x)
{
return x*x;
}
sqr=null; // but the function is still just a variable.
3. Casting can be used to resolve ambiguities:
int a, a(), b, b(); // Valid: creates four variables.
a=b; // Invalid: assignment is ambiguous.
a=(int) b; // Valid: resolves ambiguity.
(int) (a=b); // Valid: resolves ambiguity.
(int) a=b; // Invalid: cast expressions cannot be L-values.
int c();
c=a; // Valid: only one possible assignment.
4. “Higher-order” functions, in other words functions that return functions, are allowed.
The return type must be given a signature-free alias with using or typedef:
using intop = int(int);
// typedef int intop(int); // Equivalent to previous line
intop adder(int m)
{
Chapter 6: Programming 70
void g() {
f();
}
void g(bool b) {
if(b) f(b);
else write(b);
}
f=new void(bool b) {
write(b);
g(false);
};
Asymptote is the only language we know of that treats functions as variables, but allows
overloading by distinguishing variables based on their signatures.
Chapter 6: Programming 71
Functions are allowed to call themselves recursively. As in C++, infinite nested recursion
will generate a stack overflow (reported as a segmentation fault, unless a fully working
version of the GNU library libsigsegv (e.g. 2.4 or later) is installed at configuration time).
is, f(x=42) is legal, but 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
int f(int x, int x()) {
return x+x();
}
int seven() {return 7;}
is legal in Asymptote, with f(2,seven) returning 9. A named argument matches the
first unmatched formal of the same name, so f(x=2,x=seven) is an equivalent call, but
f(x=seven,2) is not, as the first argument is matched to the first formal, and int ()
cannot be implicitly cast to int. Default arguments do not affect which formal a named
argument is matched to, so if f were defined as
int f(int x=3, int x()) {
return x+x();
}
then f(x=seven) would be illegal, even though f(seven) obviously would be allowed.
sum(1,2,3,4); // returns 10
sum(); // returns 0
subtract(10,1,2); // returns 7
subtract(10); // returns 10
subtract(); // illegal
Putting an argument into a rest array is called packing. One can give an explicit list of
arguments for the rest argument, so subtract could alternatively be implemented as
int subtract(int start ... int[] subs) {
return start - sum(... subs);
Chapter 6: Programming 73
}
One can even combine normal arguments with rest arguments:
sum(1,2,3 ... new int[] {4,5,6}); // returns 21
This builds a new six-element array that is passed to sum as nums. The opposite operation,
unpacking, is not allowed:
subtract(... new int[] {10, 1, 2});
is illegal, as the start formal is not matched.
If no arguments are packed, then a zero-length array (as opposed to null) is bound to
the rest parameter. Note that default arguments are ignored for rest formals and the rest
argument is not bound to a keyword.
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 keyword
is to avoid pnorm(1.0,2.0,0.3) matching 1.0 to p.
real pnorm(real keyword p=2.0 ... real[] v)
{
return sum(v^p)^(1/p);
}
The overloading resolution in Asymptote is similar to the function matching rules used
in C++. Every argument match is given a score. Exact matches score better than matches
with casting, and matches with formals (regardless of casting) score better than packing an
argument into the rest array. A candidate is maximal if all of the arguments score as well
in it as with any other candidate. If there is one unique maximal candidate, it is chosen;
otherwise, there is an ambiguity error.
int f(path g);
int f(guide g);
f((0,0)--(100,100)); // matches the second; the argument is a guide
g(3,4); // ambiguous; the first candidate is better for the first argument,
// but the second candidate is better for the second argument
i(3,4); // ambiguous; the first candidate is better for the first argument,
// but the second candidate is better for the second one
Chapter 6: Programming 74
6.13 Arrays
Appending [] to a built-in or user-defined type yields an array. The array element i of
an array A can be accessed as A[i]. By default, attempts to access or assign to an array
element using a negative index generates an error. Reading an array element with an index
beyond the length of the array also generates an error; however, assignment to an element
beyond the length of the array causes the array to be resized to accommodate the new
element. One can also index an array A with an integer array B: the array A[B] is formed
by indexing array A with successive elements of array B. A convenient Java-style shorthand
exists for iterating over all elements of an array; see [array iteration], page 26.
The declaration
real[] A;
initializes A to be an empty (zero-length) array. Empty arrays should be distinguished from
null arrays. If we say
real[] A=null;
Chapter 6: Programming 76
then A cannot be dereferenced at all (null arrays have no length and cannot be read from
or assigned to).
Arrays can be explicitly initialized like this:
real[] A={0,1,2};
Array assignment in Asymptote does a shallow copy: only the pointer is copied (if one
copy if modified, the other will be too). The copy function listed below provides a deep
copy of an array.
Every array A of type T[] has the virtual members
• int length,
• bool cyclic,
• int[] keys,
• T push(T x),
• void append(T[] a),
• T pop(),
• void insert(int i ... T[] x),
• void delete(int i, int j=i),
• void delete(), and
• bool initialized(int n).
The member A.length evaluates to the length of the array. Setting A.cyclic=true
signifies that array indices should be reduced modulo the current array length. Reading
from or writing to a nonempty cyclic array never leads to out-of-bounds errors or array
resizing.
The member A.keys evaluates to an array of integers containing the indices of initialized
entries in the array in ascending order. Hence, for an array of length n with all entries
initialized, A.keys evaluates to {0,1,...,n-1}. A new keys array is produced each time
A.keys is evaluated.
The functions A.push and A.append append their arguments onto the end of the array,
while A.insert(int i ... T[] x) inserts x into the array at index i. For convenience
A.push returns the pushed item. The function A.pop() pops and returns the last element,
while A.delete(int i, int j=i) deletes elements with indices in the range [i,j], shifting
the position of all higher-indexed elements down. If no arguments are given, A.delete()
provides a convenient way of deleting all elements of A. The routine A.initialized(int
n) can be used to examine whether the element at index n is initialized. Like all Asymptote
functions, push, append, pop, insert, delete, and initialized can be "pulled off" of the
array and used on their own. For example,
int[] A={1};
A.push(2); // A now contains {1,2}.
A.append(A); // A now contains {1,2,1,2}.
int f(int)=A.push;
f(3); // A now contains {1,2,1,2,3}.
int g()=A.pop;
write(g()); // Outputs 3.
A.delete(0); // A now contains {2,1,2}.
Chapter 6: Programming 77
real[] A=fin;
To restrict the number of values read, use the file dimension(int) function:
file fin=input("test.txt");
real[] A=fin.dimension(10);
This reads 10 values into A, unless end-of-file (or end-of-line in line mode) occurs first.
Attempting to read beyond the end of the file will produce a runtime error message. Speci-
fying a value of 0 for the integer limit is equivalent to the previous example of reading until
end-of-file (or end-of-line in line mode) is encountered.
Two- and three-dimensional arrays of the basic data types can be read in like this:
file fin=input("test.txt");
real[][] A=fin.dimension(2,3);
real[][][] B=fin.dimension(2,3,4);
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 read(1), read(2), or read(3), respectively:
file fin=input("test.txt");
real[] A=fin.read(1);
real[][] B=fin.read(2);
real[][][] C=fin.read(3);
One, two, and three-dimensional arrays of the basic data types can be output with the
functions write(file,T[]), write(file,T[][]), write(file,T[][][]), respectively.
6.13.1 Slices
Asymptote allows a section of an array to be addressed as a slice using a Python-like syntax.
If A is an array, the expression A[m:n] returns a new array consisting of the elements of A
with indices from m up to but not including n. For example,
int[] x={0,1,2,3,4,5,6,7,8,9};
int[] y=x[2:6]; // y={2,3,4,5};
int[] z=x[5:10]; // z={5,6,7,8,9};
If the left index is omitted, it is taken be 0. If the right index is omitted it is taken to be
the length of the array. If both are omitted, the slice then goes from the start of the array
to the end, producing a non-cyclic deep copy of the array. For example:
int[] x={0,1,2,3,4,5,6,7,8,9};
int[] y=x[:4]; // y={0,1,2,3}
int[] z=x[5:]; // z={5,6,7,8,9}
int[] w=x[:]; // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
If A is a non-cyclic array, it is illegal to use negative values for either of the indices.
If the indices exceed the length of the array, however, they are politely truncated to that
length.
For cyclic arrays, the slice A[m:n] still consists of the cells with indices in the set [m,n),
but now negative values and values beyond the length of the array are allowed. The indices
simply wrap around. For example:
int[] x={0,1,2,3,4,5,6,7,8,9};
Chapter 6: Programming 83
x.cyclic=true;
int[] y=x[8:15]; // y={8,9,0,1,2,3,4}.
int[] z=x[-5:5]; // z={5,6,7,8,9,0,1,2,3,4}
int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
Notice that with cyclic arrays, it is possible to include the same element of the original
array multiple times within a slice. Regardless of the original array, arrays produced by
slices are always non-cyclic.
If the left and right indices of a slice are the same, the result is an empty array. If the
array being sliced is empty, the result is an empty array. Any slice with a left index greater
than its right index will yield an error.
Slices can also be assigned to, changing the value of the original array. If the array being
assigned to the slice has a different length than the slice itself, elements will be inserted or
removed from the array to accommodate it. For instance:
string[] toppings={"mayo", "salt", "ham", "lettuce"};
toppings[0:2]=new string[] {"mustard", "pepper"};
// Now toppings={"mustard", "pepper", "ham", "lettuce"}
toppings[2:3]=new string[] {"turkey", "bacon" };
// Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
toppings[0:3]=new string[] {"tomato"};
// Now toppings={"tomato", "bacon", "lettuce"}
If an array is assigned to a slice of itself, a copy of the original array is assigned to the
slice. That is, code such as x[m:n]=x is equivalent to x[m:n]=copy(x). One can use the
shorthand x[m:m]=y to insert the contents of the array y into the array x starting at the
location just before x[m].
For a cyclic array, a slice is bridging if it addresses cells up to the end of the array and
then continues on to address cells at the start of the array. For instance, if A is a cyclic array
of length 10, A[8:12], A[-3:1], and A[5:25] are bridging slices whereas A[3:7], A[7:10],
A[-3:0] and A[103:107] are not. Bridging slices can only be assigned to if the number
of elements in the slice is exactly equal to the number of elements we are assigning to it.
Otherwise, there is no clear way to decide which of the new entries should be A[0] and an
error is reported. Non-bridging slices may be assigned an array of any length.
For a cyclic array A an expression of the form A[A.length:A.length] is equivalent to
the expression A[0:0] and so assigning to this slice will insert values at the start of the
array. A.append() can be used to insert values at the end of the array.
It is illegal to assign to a slice of a cyclic array that repeats any of the cells.
6.14 Casts
Asymptote implicitly casts int to real, int to pair, real to pair, pair to path, pair
to guide, path to guide, guide to path, real to pen, pair[] to guide[], pair[] to
path[], path to path[], and guide to path[], along with various three-dimensional casts
defined in module 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 explicit in the function signature, say to
avoid an ambiguous function call in the following example, which outputs 0:
int f(pair a) {return 0;}
Chapter 6: Programming 84
write(f(0));
Other conversions, say real to int or real to string, require an explicit cast:
int i=(int) 2.5;
string s=(string) 2.5;
real[] a={2.5,-3.5};
int[] b=(int []) a;
write(stdout,b); // Outputs 2,-3
In situations where casting from a string to a type T fails, an uninitialized variable is
returned; this condition can be detected with the function bool initialized(T);
int i=(int) "2.5";
assert(initialized(i),"Invalid cast.");
rpair x;
x.radius=1;
x.angle=pi/6;
6.15 Import
While Asymptote provides many features by default, some applications require specialized
features contained in external Asymptote modules. For instance, the lines
access graph;
graph.axes();
draw x and y axes on a two-dimensional graph. Here, the command looks up the module
under the name graph in a global dictionary of modules and puts it in a new variable named
graph. The module is a structure, and we can refer to its fields as we usually would with a
structure.
Often, one wants to use module functions without having to specify the module name.
The code
from graph access axes;
adds the axes field of graph into the local name space, so that subsequently, one can just
write axes(). If the given name is overloaded, all types and variables of that name are
added. To add more than one name, just use a comma-separated list:
from graph access axes, xaxis, yaxis;
Wild card notation can be used to add all non-private fields and types of a module to the
local name space:
from graph access *;
Similarly, one can add the non-private fields and types of a structure to the local envi-
ronment with the unravel keyword:
struct matrix {
real a,b,c,d;
}
real det(matrix m) {
unravel m;
return a*d-b*c;
}
Alternatively, one can unravel selective fields:
real det(matrix m) {
from m unravel a,b,c as C,d;
return a*d-b*C;
}
The command
import graph;
is a convenient abbreviation for the commands
access graph;
unravel graph;
That is, import graph first loads a module into a structure called graph and then adds
its non-private fields and types to the local environment. This way, if a member variable
(or function) is overwritten with a local variable (or function of the same signature), the
original one can still be accessed by qualifying it with the module name.
Chapter 6: Programming 86
Wild card importing will work fine in most cases, but one does not usually know all of the
internal types and variables of a module, which can also change as the module writer adds
or changes features of the module. As such, it is prudent to add import commands at the
start of an Asymptote file, so that imported names won’t shadow locally defined functions.
Still, imported names may shadow other imported names, depending on the order in which
they were imported, and imported functions may cause overloading resolution problems if
they have the same name as local functions defined later.
To rename modules or fields when adding them to the local environment, use as:
access graph as graph2d;
from graph access xaxis as xline, yaxis as yline;
The command
import graph as graph2d;
is a convenient abbreviation for the commands
access graph as graph2d;
unravel graph2d;
Except for a few built-in modules, such as settings, all modules are implemented as
Asymptote files. When looking up a module that has not yet been loaded, Asymptote
searches the standard search paths (see Section 2.5 [Search paths], page 6) for the matching
file. The file corresponding to that name is read and the code within it is interpreted as the
body of a structure defining the module.
If the file name contains nonalphanumeric characters, enclose it with quotation marks:
access "/usr/local/share/asymptote/graph.asy" as graph;
from "/usr/local/share/asymptote/graph.asy" access axes;
import "/usr/local/share/asymptote/graph.asy" as graph;
If Asymptote is compiled with support for libcurl, the file name can even be a URL:
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.
However, you can import an Asymptote module determined by the string s at runtime
like this:
eval("import "+s,true);
To conditionally execute an array of asy files, use
void asy(string format, bool overwrite ... string[] s);
The file will only be processed, using output format format, if overwrite is true or the
output file is missing.
One can evaluate an Asymptote expression (without any return value, however) con-
tained in the string s with:
void eval(string s, bool embedded=false);
It is not necessary to terminate the string s with a semicolon. If embedded is true, the
string will be evaluated at the top level of the current environment. If embedded is false
Chapter 6: Programming 87
(the default), the string will be evaluated in an independent environment, sharing the same
settings module (see [settings], page 177).
One can evaluate arbitrary Asymptote code (which may contain unescaped quotation
marks) with the command
void eval(code s, bool embedded=false);
Here code is a special type used with quote {} to enclose Asymptote code like this:
real a=1;
code s=quote {
write(a);
};
eval(s,true); // Outputs 1
To include the contents of an existing file graph verbatim (as if the contents of the file
were inserted at that point), use one of the forms:
include graph;
include "/usr/local/share/asymptote/graph.asy";
To list all global functions and variables defined in a module named by the contents of
the string s, use the function
void list(string s, bool imports=false);
Imported global functions and variables are also listed if imports is true.
6.16 Static
Static qualifiers allocate the memory address of a variable in a higher enclosing level.
For a function body, the variable is allocated in the block where the function is defined;
so in the code
struct s {
int count() {
static int c=0;
++c;
return c;
}
}
there is one instance of the variable c for each object s (as opposed to each call of count).
Similarly, in
int factorial(int n) {
int helper(int k) {
static int x=1;
x *= k;
return k == 1 ? x : helper(k-1);
}
return helper(n);
}
there is one instance of x for every call to factorial (and not for every call to helper), so
this is a correct, but ugly, implementation of factorial.
Similarly, a static variable declared within a structure is allocated in the block where
the structure is defined. Thus,
struct A {
struct B {
static pair z;
}
}
creates one object z for each object of type A created.
In this example,
int pow(int n, int k) {
struct A {
static int x=1;
void helper() {
x *= n;
}
Chapter 6: Programming 89
}
for(int i=0; i < k; ++i) {
A a;
a.helper();
}
return A.x;
}
there is one instance of x for each call to pow, so this is an ugly implementation of expo-
nentiation.
Loop constructs allocate a new frame in every iteration. This is so that higher-order
functions can refer to variables of a specific iteration of a loop:
void f();
for(int i=0; i < 10; ++i) {
int x=i;
if(x==5) {
f=new void() {write(x);};
}
}
f();
Here, every iteration of the loop has its own variable x, so f() will write 5. If a variable
in a loop is declared static, it will be allocated where the enclosing function or structure
was defined (just as if it were declared static outside of the loop). For instance, in:
void f() {
static int x;
for(int i=0; i < 10; ++i) {
static int y;
}
}
both x and y will be allocated in the same place, which is also where f is allocated.
Statements may also be declared static, in which case they are run at the place where
the enclosing function or structure is defined. Declarations or statements not enclosed
in a function or structure definition are already at the top level, so static modifiers are
meaningless. A warning is given in such a case.
Since structures can have static fields, it is not always clear for a qualified name whether
the qualifier is a variable or a type. For instance, in:
struct A {
static int x;
}
pair A;
int y=A.x;
does the A in A.x refer to the structure or to the pair variable. It is the convention in
Asymptote that, if there is a non-function variable with the same name as the qualifier, the
qualifier refers to that variable, and not to the type. This is regardless of what fields the
variable actually possesses.
Chapter 6: Programming 90
6.17 Autounravel
The autounravel modifier can be used to automatically unravel a field. This is useful
when building an associated library of functions that operate on a structure. For instance,
consider a simple implementation of the rational structure defined in rational.asy:
struct rational {
int p=0, q=1;
void operator init(int p, int q) {
this.p=p;
this.q=q;
}
}
rational operator +(rational a, rational b) {
return rational(a.p*b.q+b.p*a.q, a.q*b.q);
}
To allow rational to be used as a type parameter for a templated import that adds
instances of rational, we should move operator + into the body of the rational structure
and add the autounravel modifier:
struct rational {
int p=0, q=1;
void operator init(int p, int q) {
this.p=p;
this.q=q;
}
autounravel rational operator +(rational a, rational b) {
return rational(a.p*b.q+b.p*a.q, a.q*b.q);
}
}
This is almost equivalent to the previous code, but now the + operator will be accessible
wherever the rational structure is.
Currently, types cannot be autounraveled. Users who encounter a case where this
might be useful can submit a feature request at https://github.com/vectorgraphics/
asymptote/issues.
1
If top-level autounravel were allowed, a user might incorrectly assume that the field would be unraveled
whenever the module is accessed. The static modifier is allowed at the top level because, while it does
nothing, it does not mislead the user.
92
7 LaTeX usage
Asymptote comes with a convenient LaTeX style file asymptote.sty (v1.36 or later required)
that makes LaTeX Asymptote-aware. Entering Asymptote code directly into the LaTeX
source file, at the point where it is needed, keeps figures organized and avoids the need to
invent new file names for each figure. Simply add the line \usepackage{asymptote} at the
beginning of your file and enclose your Asymptote code within a \begin{asy}...\end{asy}
environment. As with the LaTeX comment environment, the \end{asy} command must
appear on a line by itself, with no trailing commands/comments. A blank line is not
allowed after \begin{asy}.
The sample LaTeX file below, named latexusage.tex, can be run as follows:
latex latexusage
asy latexusage-*.asy
latex latexusage
or
pdflatex latexusage
asy latexusage-*.asy
pdflatex latexusage
To switch between using inline Asymptote code with latex and pdflatex you may first
need to remove the files latexusage-*.tex.
An even better method for processing a LaTeX file with embedded Asymptote code is to
use the latexmk utility from
http://mirror.ctan.org/support/latexmk/
after putting the contents of https://raw.githubusercontent.com/vectorgraphics/
asymptote/HEAD/doc/latexmkrc in a file latexmkrc in the same directory. The command
latexmk -pdf latexusage
will then call 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 asy, one can define
\def\asydir{asy}
in latexusage.tex. External Asymptote code can be included with
\asyinclude[<options>]{<filename.asy>}
so that latexmk will recognize when the code is changed. Note that latexmk requires perl,
available from https://www.perl.org/.
One can specify width, height, keepAspect, viewportwidth, viewportheight, attach,
and inline. keyval-style options to the asy and asyinclude environments. Three-
dimensional PRC files may either be embedded within the page (the default) or attached as
annotated (but printable) attachments, using the attach option and the attachfile2 (or
older attachfile) LaTeX package. The inline option generates inline LaTeX code instead of
EPS or PDF files. This makes 2D LaTeX symbols visible to the \begin{asy}...\end{asy}
environment. In this mode, Asymptote correctly aligns 2D LaTeX symbols defined outside
of \begin{asy}...\end{asy}, but treats their size as zero; an optional second string can
be given to Label to provide an estimate of the unknown label size.
Chapter 7: LaTeX usage 93
Note that if the latex TEX engine is used with the inline option, labels might not show
up in DVI viewers that cannot handle raw PostScript code. One can use dvips/dvipdf
to produce PostScript/PDF output (we recommend using the modified version of dvipdf
in the Asymptote patches directory, which accepts the dvips -z hyperdvi option).
Here now is latexusage.tex:
\documentclass[12pt]{article}
% Use this form with latex or pdflatex to include inline LaTeX code by default:
\usepackage[inline]{asymptote}
% Use this form with latex or pdflatex to create PDF attachments by default:
%\usepackage[attach]{asymptote}
\begin{document}
\begin{asydef}
// Global Asymptote definitions can be put here.
settings.prc=true;
import three;
usepackage("bm");
texpreamble("\def\V#1{\bm{#1}}");
// One can globally override the default toolbar settings here:
// settings.toolbar=true;
\end{asydef}
\def\A{A}
\def\B{\V{B}}
%\begin{figure}
\begin{center}
\begin{asy}
size(4cm,0);
pen colour1=red;
Chapter 7: LaTeX usage 94
pen colour2=green;
pair z0=(0,0);
pair z1=(-1,0);
pair z2=(1,0);
real r=1.5;
path c1=circle(z1,r);
path c2=circle(z2,r);
fill(c1,colour1);
fill(c2,colour2);
add(intersection);
draw(c1);
draw(c2);
pair z=(0,-2);
real m=3;
margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
draw(z--z1,Arrow,Margin(0,m));
draw(z--z2,Arrow,Margin(0,m));
shipout(bbox(0.25cm));
\end{asy}
%\caption{Venn diagram}\label{venn}
\end{center}
%\end{figure}
Each graph is drawn in its own environment. One can specify the width
and height to \LaTeX\ explicitly. This 3D example can be viewed
interactively either with Adobe Reader or Asymptote's fast OpenGL-based
renderer. To support {\tt latexmk}, 3D figures should specify
\verb+inline=true+. It is sometimes desirable to embed 3D files as annotated
attachments; this requires the \verb+attach=true+ option as well as the
\verb+attachfile2+ \LaTeX\ package.
Chapter 7: LaTeX usage 95
\begin{center}
\begin{asy}[height=4cm,inline=true,attach=false,viewportwidth=\linewidth]
currentprojection=orthographic(5,4,2);
draw(unitcube,blue);
label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17pt));
\end{asy}
\end{center}
One can also scale the figure to the full line width:
\begin{center}
\begin{asy}[width=\the\linewidth,inline=true]
pair z0=(0,0);
pair z1=(2,0);
pair z2=(5,0);
pair zf=z1+0.75*(z2-z1);
draw(z1--z2);
dot(z1,red+0.15cm);
dot(z2,darkgreen+0.3cm);
label("$m$",z1,1.2N,red);
label("$M$",z2,1.5N,darkgreen);
label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue);
pair s=-0.2*I;
draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
s=-0.5*I;
draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
s=-0.95*I;
draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
\end{asy}
\end{center}
\end{document}
Chapter 7: LaTeX usage 96
A∩B
A B
A∪B
Each graph is drawn in its own environment. One can specify the width
and height to LATEX explicitly. This 3D example can be viewed interac-
tively either with Adobe Reader or Asymptote’s fast OpenGL-based ren-
derer. To support latexmk, 3D figures should specify inline=true. It is
sometimes desirable to embed 3D files as annotated attachments; this re-
quires the attach=true option as well as the attachfile2 LATEX package.
One can also scale the figure to the full line width:
m M
x
ˆ
x̄
1
97
8 Base modules
Asymptote currently ships with the following base modules:
8.1 plain
This is the default Asymptote base file drawing language (such as the picture structure).
By default, an implicit private import plain; occurs before translating a file and be-
fore the first command given in interactive mode. This also applies when translating files
for module definitions (except when translating plain, of course). This means that the
types and functions defined in plain are accessible in almost all Asymptote code. Use the
-noautoplain command-line option to disable this feature.
8.2 simplex
This module solves the general linear programming problem using the simplex method.
8.3 simplex2
This module solves a special case of the two-variable linear programming problem used by
the module plain for automatic sizing of pictures (see [deferred drawing], page 57).
8.4 math
This module extends Asymptote’s mathematical capabilities with useful functions such as
void drawline(picture pic=currentpicture
draw the visible portion of the (infinite) line going through P and Q, without
altering the size of picture pic, using pen p.
real intersect(triple P, triple Q, triple n, triple Z);
returns the intersection time of the extension of the line segment PQ with the
plane perpendicular to n and passing through Z.
triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);
Return any point on the intersection of the two planes with normals n0 and
n1 passing through points P0 and P1, respectively. If the planes are parallel,
return (infinity,infinity,infinity).
pair[] quarticroots(real a, real b, real c, real d, real e);
returns the four complex roots of the quartic equation ax4 +bx3 +cx2 +dx+e = 0.
real time(path g, real x, int n=0, real fuzz=-1)
returns the nth intersection time of path g with the vertical line through x.
real time(path g, explicit pair z, int n=0, real fuzz=-1)
returns the nth intersection time of path g with the horizontal line through
(0,z.y).
real value(path g, real x, int n=0, real fuzz=-1)
returns the nth y value of g at x.
Chapter 8: Base modules 98
8.5 interpolate
This module implements Lagrange, Hermite, and standard cubic spline interpolation in
Asymptote, as illustrated in the example interpolate1.asy.
8.6 geometry
This module, written by Philippe Ivaldi, provides an extensive set of geometry routines, in-
cluding perpendicular symbols and a triangle structure. Link to the documentation for
the geometry module are posted here: https://asymptote.sourceforge.io/links.html,
including an extensive set of examples, https://web.archive.org/web/20201130113133/
http://www.piprime.fr/files/asymptote/geometry/, and an index:
https://web.archive.org/web/20201130113133/http://www.piprime.fr/
files/asymptote/geometry/modules/geometry.asy.index.type.html
8.7 trembling
This module, written by Philippe Ivaldi and illustrated in the example floatingdisk.asy,
allows one to draw wavy lines, as if drawn by hand.
Chapter 8: Base modules 99
8.8 stats
This module implements a Gaussian random number generator and a collection of statistics
routines, including histogram and leastsquares.
8.9 patterns
This module implements PostScript tiling patterns and includes several convenient pattern
generation routines.
8.10 markers
This module implements specialized routines for marking paths and angles. The principal
mark routine provided by this module is
which centers n copies of frame f within uniformly space intervals in arclength along the
path, optionally rotated by the angle of the local tangent.
The marker (see [marker], page 116) routine can be used to construct new markers from
these predefined frames:
1 2
3 4
5 6
7 8
9 10
11 12
13 14
a
a
15 16
a
a
a
17
γ
C
−θ
θ F
D A B
8.11 map
This module creates a struct parameterized by the types specified in strings key and value,
mapping keys to values with a specified default:
from map(Key=string, Value=int) access map;
map M=map(Default=-1);
M.add("z",2);
M.add("a",3);
M.add("d",4);
write(M.lookup("a"));
write(M.lookup("y"));
8.12 tree
This module implements an example of a dynamic binary search tree.
8.13 binarytree
This module can be used to draw an arbitrary binary tree and includes an input routine for
the special case of a binary search tree, as illustrated in the example binarytreetest.asy:
import binarytree;
picture pic,pic2;
binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
draw(pic,bt,condensed=false);
binarytree st=searchtree(10,5,2,1,3,4,7,6,8,9,15,13,12,11,14,17,16,18,19);
draw(pic2,st,blue,condensed=true);
add(pic.fit(),(0,0),10N);
Chapter 8: Base modules 102
add(pic2.fit(),(0,0),10S);
2 3
4 0 6 7
10
5 15
2 7 13 17
1 3 6 8 12 14 16 18
4 9 11 19
8.14 drawtree
This is a simple tree drawing module used by the example treetest.asy.
8.15 syzygy
This module automates the drawing of braids, relations, and syzygies, along with the cor-
responding equations, as illustrated in the example knots.asy.
8.16 feynman
This module, contributed by Martin Wiebusch, is useful for drawing Feynman diagrams, as
illustrated by the examples eetomumu.asy and fermi.asy.
Chapter 8: Base modules 103
8.17 roundedpath
This module, contributed by Stefan Knorr, is useful for rounding the sharp corners of paths,
as illustrated in the example file roundpath.asy.
8.18 animation
This module allows one to generate animations, as illustrated by the files wheel.asy,
wavepacket.asy, and cube.asy in the animations subdirectory of the examples direc-
tory. These animations use the ImageMagick magick program to merge multiple images
into a GIF or MPEG movie.
The related animate module, derived from the animation module, generates higher-
quality portable clickable PDF movies, with optional controls. This requires installing the
module
http://mirror.ctan.org/macros/latex/contrib/animate/animate.sty
(version 2007/11/30 or later) in a new directory animate in the local LaTeX directory (for
example, in /usr/local/share/texmf/tex/latex/animate). On UNIX systems, one must
then execute the command texhash.
The example pdfmovie.asy in the animations directory, along with the slide presen-
tations slidemovies.asy and intro, illustrate the use of embedded PDF movies. The
examples inlinemovie.tex and inlinemovie3.tex show how to generate and embed PDF
movies directly within a LaTeX file (see Chapter 7 [LaTeX usage], page 92). The member
function
string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
bool keep=settings.keep, bool multipage=true);
of the animate structure accepts any of the animate.sty options, as described here:
http://mirror.ctan.org/macros/latex/contrib/animate/doc/animate.
pdf
8.19 embed
This module provides an interface to the LaTeX package (included with MikTeX)
http://mirror.ctan.org/macros/latex/contrib/media9
for embedding movies, sounds, and 3D objects into a PDF document.
A more portable method for embedding movie files, which should work on any platform
and does not require the media9 package, is provided by using the external module instead
of embed.
Examples of the above two interfaces is provided in the file embeddedmovie.asy in the
animations subdirectory of the examples directory and in externalmovie.asy. For a
higher quality embedded movie generated directly by Asymptote, use the animate module
along with the animate.sty package to embed a portable PDF animation (see [animate],
page 103).
An example of embedding U3D code is provided in the file embeddedu3d.
Chapter 8: Base modules 104
8.20 slide
This module provides a simple yet high-quality facility for making presentation slides, in-
cluding portable embedded PDF animations (see the file slidemovies.asy). A simple
example is provided in slidedemo.asy.
8.21 MetaPost
This module provides some useful routines to help MetaPost users migrate old MetaPost
code to Asymptote. Further contributions here are welcome.
Unlike MetaPost, Asymptote does not implicitly solve linear equations and therefore
does not have the notion of a whatever unknown. The routine extension (see [extension],
page 37) provides a useful replacement for a common use of whatever: finding the inter-
section point of the lines through P, Q and p, q. For less common occurrences of whatever,
one can use the built-in explicit linear equation solver solve instead.
8.22 babel
This module implements the LaTeX babel package in Asymptote. For example:
import babel;
babel("german");
8.23 labelpath
This module uses the PSTricks pstextpath macro to fit labels along a path (properly
kerned, as illustrated in the example file curvedlabel.asy), using the command
void labelpath(picture pic=currentpicture, Label L, path g,
string justify=Centered, pen p=currentpen);
Here justify is one of LeftJustified, Centered, or RightJustified. The x component
of a shift transform applied to the Label is interpreted as a shift along the curve, whereas
the y component is interpreted as a shift away from the curve. All other Label transforms
are ignored. This module requires the latex tex engine and inherits the limitations of the
PSTricks \pstextpath macro.
8.24 labelpath3
This module, contributed by Jens Schwaiger, implements a 3D version of labelpath that
does not require the PSTricks package. An example is provided in curvedlabel3.asy.
8.25 annotate
This module supports PDF annotations for viewing with Adobe Reader, via the function
void annotate(picture pic=currentpicture, string title, string text,
pair position);
Annotations are illustrated in the example file annotation.asy. Currently, annotations are
only implemented for the latex (default) and tex TEX engines.
Chapter 8: Base modules 105
8.26 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 CAD.pdf.
8.27 graph
This module implements two-dimensional linear and logarithmic graphs, including auto-
matic scale and tick selection (with the ability to override manually). A graph is a guide
(that can be drawn with the draw command, with an optional legend) constructed with one
of the following routines:
•
guide graph(picture pic=currentpicture, real f(real), real a, real b,
int n=ngraph, real T(real)=identity,
interpolate join=operator --);
guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
int n=ngraph, real T(real)=identity, bool3 cond(real),
interpolate join=operator --);
Returns a graph using the scaling information for picture pic (see [automatic scaling],
page 122) of the function f on the interval [T(a),T(b)], sampling at n points evenly
spaced in [a,b], optionally restricted by the bool3 function cond on [a,b]. If cond is:
• true, the point is added to the existing guide;
• default, the point is added to a new guide;
• false, the point is omitted and a new guide is begun.
The points are connected using the interpolation specified by join:
• operator -- (linear interpolation; the abbreviation Straight is also accepted);
• operator .. (piecewise Bezier cubic spline interpolation; the abbreviation Spline
is also accepted);
• linear (linear interpolation),
• Hermite (standard cubic spline interpolation using boundary condition notaknot,
natural, periodic, clamped(real slopea, real slopeb)), or monotonic. The
abbreviation Hermite is equivalent to Hermite(notaknot) for nonperiodic data
and Hermite(periodic) for periodic data).
•
guide graph(picture pic=currentpicture, real x(real), real y(real),
real a, real b, int n=ngraph, real T(real)=identity,
interpolate join=operator --);
guide[] graph(picture pic=currentpicture, real x(real), real y(real),
real a, real b, int n=ngraph, real T(real)=identity,
bool3 cond(real), interpolate join=operator --);
Returns a graph using the scaling information for picture pic of the parametrized
function (x(t),y(t)) for t in the interval [T(a),T(b)], sampling at n points evenly spaced
in [a,b], optionally restricted by the bool3 function cond on [a,b], using the given
interpolation type.
Chapter 8: Base modules 106
•
guide graph(picture pic=currentpicture, pair z(real), real a, real b,
int n=ngraph, real T(real)=identity,
interpolate join=operator --);
guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
int n=ngraph, real T(real)=identity, bool3 cond(real),
interpolate join=operator --);
Returns a graph using the scaling information for picture pic of the parametrized
function z(t) for t in the interval [T(a),T(b)], sampling at n points evenly spaced in [a,b],
optionally restricted by the bool3 function cond on [a,b], using the given interpolation
type.
•
guide graph(picture pic=currentpicture, pair[] z,
interpolate join=operator --);
guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
interpolate join=operator --);
Returns a graph using the scaling information for picture pic of the elements of the
array z, optionally restricted to those indices for which the elements of the boolean
array cond are true, using the given interpolation type.
•
guide graph(picture pic=currentpicture, real[] x, real[] y,
interpolate join=operator --);
guide[] graph(picture pic=currentpicture, real[] x, real[] y,
bool3[] cond, interpolate join=operator --);
Returns a graph using the scaling information for picture pic of the elements of the
arrays (x,y), optionally restricted to those indices for which the elements of the boolean
array cond are true, using the given interpolation type.
•
guide polargraph(picture pic=currentpicture, real f(real), real a,
real b, int n=ngraph, interpolate join=operator --);
Returns a polar-coordinate graph using the scaling information for picture pic of the
function f on the interval [a,b], sampling at n evenly spaced points, with the given
interpolation type.
•
guide polargraph(picture pic=currentpicture, real[] r, real[] theta,
interpolate join=operator--);
Returns a polar-coordinate graph using the scaling information for picture pic of the
elements of the arrays (r,theta), using the given interpolation type.
The default tick option is NoTicks. The options LeftTicks, RightTicks, or Ticks
can be used to draw ticks on the left, right, or both sides of the path, relative to the
direction in which the path is drawn. These tick routines accept a number of optional
arguments:
ticks LeftTicks(Label format="", ticklabel ticklabel=null,
Chapter 8: Base modules 108
1. This example draws a textbook-style graph of y = exp(x), with the y axis starting at
y = 0:
import graph;
size(150,0);
draw(graph(f,-4,2,operator ..),red);
xaxis("$x$");
yaxis("$y$",0);
labely(1,E);
label("$e^x$",F(1),SE);
Chapter 8: Base modules 112
ex
2. The next example draws a scientific-style graph with a legend. The position of the
legend can be adjusted either explicitly or by using the graphical user interface (see
Chapter 11 [GUI], page 181). If an UnFill(real xmargin=0, real ymargin=xmargin)
or Fill(pen) option is specified to add, the legend will obscure any underlying objects.
Here we illustrate how to clip the portion of the picture covered by a label:
import graph;
size(400,200,IgnoreAspect);
draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks(trailingzero));
label("LABEL",point(0),UnFill(1mm));
add(legend(),point(E),20E,UnFill);
Chapter 8: Base modules 113
1.0
0.5
sin(2πx)
y 0.0 LABEL
cos(2πx)
−0.5
−1.0
0 0.2 0.4 0.6 0.8 1
x
size(250,200,IgnoreAspect);
draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks(trailingzero));
label("LABEL",point(0),UnFill(1mm));
attach(legend(),truepoint(E),20E,UnFill);
A legend can have multiple entries per line:
import graph;
size(8cm,6cm,IgnoreAspect);
attach(legend(2),(point(S).x,truepoint(S).y),10S,UnFill);
1.0
0.5
y 0.0
−0.5
−1.0
0 0.2 0.4 0.6 0.8 1
x
sin(πx) sin(2πx)
sin(3πx) sin(4πx)
3. This example draws a graph of one array versus another (both of the same size) using
custom tick locations and a smaller font size for the tick labels on the y axis.
import graph;
size(200,150,IgnoreAspect);
real[] x={0,1,2,3};
real[] y=x^2;
draw(graph(x,y),red);
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,
RightTicks(Label(fontsize(8pt)),new real[]{0,4,9}));
Chapter 8: Base modules 115
y
4
0
0 1 2 3
x
4. This example shows how to graph columns of data read from a file.
import graph;
size(200,150,IgnoreAspect);
file in=input("filegraph.dat").line();
real[][] a=in;
a=transpose(a);
real[] x=a[0];
real[] y=a[1];
draw(graph(x,y),red);
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks);
y 1
0
50 70 90 110
x
5. The next example draws two graphs of an array of coordinate pairs, using frame align-
ment and data markers. In the left-hand graph, the markers, constructed with
marker marker(path g, markroutine markroutine=marknodes,
pen p=currentpen, filltype filltype=NoFill,
bool above=true);
Chapter 8: Base modules 116
using the path unitcircle (see [filltype], page 53), are drawn below each node. Any
frame can be converted to a marker, using
marker marker(frame f, markroutine markroutine=marknodes,
bool above=true);
In the right-hand graph, the unit n-sided regular polygon polygon(int n) and
the unit n-point cyclic cross cross(int n, bool round=true, real r=0) (where
r is an optional “inner” radius) are used to build a custom marker frame. Here
markuniform(bool centered=false, int n, bool rotated=false) adds this frame
at n uniformly spaced points along the arclength of the path, optionally rotated by the
angle of the local tangent to the path (if centered is true, the frames will be centered
within n evenly spaced arclength intervals). Alternatively, one can use markroutine
marknodes to request that the marks be placed at each Bezier node of the path, or
markroutine markuniform(pair z(real t), real a, real b, int n) to place marks
at points z(t) for n evenly spaced values of t in [a,b].
These markers are predefined:
marker[] Mark={
marker(scale(circlescale)*unitcircle),
marker(polygon(3)),marker(polygon(4)),
marker(polygon(5)),marker(invert*polygon(3)),
marker(cross(4)),marker(cross(6)),marker(diamond),marker(plus);
};
marker[] MarkFill={
marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
marker(polygon(4),Fill),marker(polygon(5),Fill),
marker(invert*polygon(3),Fill),marker(diamond,Fill)
};
The example also illustrates the errorbar routines:
void errorbars(picture pic=currentpicture, pair[] z, pair[] dp,
pair[] dm={}, bool[] cond={}, pen p=currentpen,
real size=0);
picture pic;
real xsize=200, ysize=140;
size(pic,xsize,ysize,IgnoreAspect);
pair[] f={(5,5),(50,20),(90,90)};
Chapter 8: Base modules 117
pair[] df={(0,0),(5,7),(0,5)};
errorbars(pic,f,df,red);
draw(pic,graph(pic,f),"legend",
marker(scale(0.8mm)*unitcircle,red,FillDraw(blue),above=false));
scale(pic,true);
xaxis(pic,"$x$",BottomTop,LeftTicks);
yaxis(pic,"$y$",LeftRight,RightTicks);
add(pic,legend(pic),point(pic,NW),20SE,UnFill);
picture pic2;
size(pic2,xsize,ysize,IgnoreAspect);
frame mark;
filldraw(mark,scale(0.8mm)*polygon(6),green,green);
draw(mark,scale(0.8mm)*cross(6),blue);
draw(pic2,graph(pic2,f),marker(mark,markuniform(5)));
scale(pic2,true);
xaxis(pic2,"$x$",BottomTop,LeftTicks);
yaxis(pic2,"$y$",LeftRight,RightTicks);
yequals(pic2,55.0,red+Dotted);
xequals(pic2,70.0,red+Dotted);
100 100
80 80
legend
60 60
y y
40 40
20 20
0 0
0 20 40 60 80 100 0 20 40 60 80 100
x x
size(200,100,IgnoreAspect);
markroutine marks() {
return new void(picture pic=currentpicture, frame f, path g) {
path p=scale(1mm)*unitcircle;
for(int i=0; i <= length(g); ++i) {
pair z=point(g,i);
frame f;
if(i % 4 == 0) {
fill(f,p);
add(pic,f,z);
} else {
if(z.y > 50) {
pic.add(new void(frame F, transform t) {
path q=shift(t*z)*p;
unfill(F,q);
draw(F,q);
});
} else {
draw(f,p);
add(pic,f,z);
}
}
}
};
}
pair[] f={(5,5),(40,20),(55,51),(90,30)};
draw(graph(f),marker(marks()));
scale(true);
Chapter 8: Base modules 119
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks);
60
40
y
20
0
0 20 40 60 80 100
x
size(400,150,IgnoreAspect);
real[] x=sequence(12);
real[] y=sin(2pi*x/12);
scale(false);
string[] month={"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
draw(graph(x,y),red,MarkFill[0]);
xaxis(BottomTop,LeftTicks(new string(real x) {
return month[round(x % 12)];}));
yaxis("$y$",LeftRight,RightTicks(4));
0.5
y 0
−0.5
−1
Jan Mar May Jul Sep Nov
size(0,200);
draw(graph(x,y,0,1));
//limits((0,-1),(1,0),Crop);
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks(trailingzero));
1.0
0.5
y 0.0
−0.5
−1.0
−1 0 1
x
The function
guide graphwithderiv(pair f(real), pair fprime(real), real a, real b,
int n=ngraph#10);
Chapter 8: Base modules 121
can be used to construct the graph of the parametric function f on [a,b] with the
control points of the n Bezier segments determined by the specified derivative fprime:
unitsize(2cm);
import graph;
pair F(real t) {
return (1.3*t,-4.5*t^2+3.0*t+1.0);
}
pair Fprime(real t) {
return (1.3,-9.0*t+3.0);
}
path g=graphwithderiv(F,Fprime,0,0.9,4);
dot(g,red);
draw(g,arrow=Arrow(TeXHead));
The next example illustrates how one can extract a common axis scaling factor.
import graph;
axiscoverage=0.9;
size(200,IgnoreAspect);
real[] x={-1e-11,1e-11};
real[] y={0,1e6};
real xscale=round(log10(max(x)));
real yscale=round(log10(max(y)))-1;
draw(graph(x*10^(-xscale),y*10^(-yscale)),red);
xaxis("$x/10^{"+(string) xscale+"}$",BottomTop,LeftTicks);
yaxis("$y/10^{"+(string) yscale+"}$",LeftRight,RightTicks(trailingzero));
Chapter 8: Base modules 122
10
9
8
7
6
y/105
5
4
3
2
1
0
−1 −0.5 0 0.5 1
x/10−11
Axis scaling can be requested and/or automatic selection of the axis limits can be
inhibited with one of these scale routines:
void scale(picture pic=currentpicture, scaleT x, scaleT y);
size(200,200,IgnoreAspect);
scale(Log,Log);
draw(graph(f,0.1,10));
//limits((1,0.1),(10,0.5),Crop);
dot(Label("(3,5)",align=S),Scale((3,5)));
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$y$",LeftRight,RightTicks);
101
(3,5)
y 100
10−1 −1
10 100 101
x
import graph;
size(200,200,IgnoreAspect);
scale(Log,Log);
draw(graph(f,0.1,10),red);
pen thin=linewidth(0.5*linewidth());
xaxis("$x$",BottomTop,LeftTicks(begin=false,end=false,extend=true,
ptick=thin));
yaxis("$y$",LeftRight,RightTicks(begin=false,end=false,extend=true,
ptick=thin));
Chapter 8: Base modules 124
101
y 100
10−1 −1
10 100 101
x
One can also specify custom tick locations and formats for logarithmic axes:
import graph;
size(300,175,IgnoreAspect);
scale(Log,Log);
draw(graph(identity,5,20));
xlimits(5,20);
ylimits(1,100);
xaxis("$M/M_\odot$",BottomTop,LeftTicks(DefaultFormat,
new real[] {6,10,12,14,16,18}));
yaxis("$\nu_{\rm upp}$ [Hz]",LeftRight,RightTicks(DefaultFormat));
100
νupp [Hz]
10
1
6 10 12 14 16 18
M/M⊙
scaleT yscale=scaleT(log2,pow2,logarithmic=true);
scale(Linear,yscale);
draw(graph(f,-4,4));
yaxis("$y$",ymin=1,ymax=f(5),RightTicks(Label(Fill(white))),EndArrow);
xaxis("$x$",xmin=-5,xmax=5,LeftTicks,EndArrow);
y
24
23
22
21
20
−5 0 5
x
Here is an example of "broken" linear x and logarithmic y axes that omit the segments
[3,8] and [100,1000], respectively. In the case of a logarithmic axis, the break endpoints
are automatically rounded to the nearest integral power of the base.
import graph;
size(200,150,IgnoreAspect);
scale(Broken(a,b),BrokenLog(c,d));
real[] x={1,2,4,6,10};
real[] y=x^4;
draw(graph(x,y),red,MarkFill[0]);
xaxis("$x$",BottomTop,LeftTicks(Break(a,b)));
yaxis("$y$",LeftRight,RightTicks(Break(c,d)));
label(rotate(90)*Break,(a,point(S).y));
label(rotate(90)*Break,(a,point(N).y));
label(Break,(point(W).x,ScaleY(c)));
label(Break,(point(E).x,ScaleY(c)));
104 ≈
≈ ≈
y
101
100
≈
2 10
x
size(10cm,5cm,IgnoreAspect);
scale(Log,Log);
draw(graph(ampl,0.01,10));
ylimits(0.001,100);
Chapter 8: Base modules 127
xaxis("$\omega\tau_0$",BottomTop,LeftTicks);
yaxis("$|G(\omega\tau_0)|$",Left,RightTicks);
102 1.5
101 1.0
Arg G/π
|G(ωτ0 )|
100 0.5
10−1 (1,0) 0.0
10−2 −0.5
10−3 −2 −1.0
10 10−1 100 101
ωτ0
size(9cm,6cm,IgnoreAspect);
string data="secondaryaxis.csv";
file in=input(data).line().csv();
string[] titlelabel=in;
string[] columnlabel=in;
real[][] a=in;
a=transpose(a);
real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
real[] susceptibleM=a[5], exposed=a[6], infectiousM=a[7];
scale(true);
Chapter 8: Base modules 128
xaxis("Time ($\tau$)",BottomTop,LeftTicks);
yaxis(Left,RightTicks);
add(secondary);
label(shift(5mm*N)*"Proportion of crows",point(NW),E);
Proportion of crows
0.9 100
0.7
0.5 10−1
0.3
0.1 10−2
10 11 12 13 14 15
Time (τ )
size(400,200,IgnoreAspect);
int n=10000;
real[] a=new real[n];
for(int i=0; i < n; ++i) a[i]=Gaussrand();
draw(graph(Gaussian,min(a),max(a)),blue);
histogram(a,min(a),max(a),N,normalize=true,low=0,lightred,black,bars=true);
Chapter 8: Base modules 129
xaxis("$x$",BottomTop,LeftTicks);
yaxis("$dP/dx$",LeftRight,RightTicks(trailingzero));
0.4
0.3
dP/dx
0.2
0.1
0.0
−3 −2 −1 0 1 2 3
x
11. Here is an example of reading column data in from a file and a least-squares fit, using
the stats module.
size(400,200,IgnoreAspect);
import graph;
import stats;
file fin=input("leastsquares.dat").line();
real[][] a=fin;
a=transpose(a);
real first=100;
real step=50;
real last=700;
scale(Log(true),Linear(true));
real[] T,xi,dxi;
T.push(first);
xi.push(L.m);
dxi.push(L.dm);
}
draw(graph(T,xi),blue);
errorbars(T,xi,dxi,red);
crop();
ylimits(0);
xaxis("$T$",BottomTop,LeftTicks);
yaxis("$\xi$",LeftRight,RightTicks);
Chapter 8: Base modules 131
0 2
10 103
T
12. Here is an example that illustrates the general axis routine.
import graph;
size(0,100);
path g=ellipse((0,0),1,2);
scale(true);
axis(Label("C",align=10W),g,LeftTicks(endlabel=false,8,end=false),
ticklocate(0,360,new real(real v) {
path h=(0,0)--max(abs(max(g)),abs(min(g)))*dir(v);
return intersect(g,h)[0];}));
90
135 45
C 180 0
225 315
270
13. To draw a vector field of n arrows evenly spaced along the arclength of a path, use the
routine
picture vectorfield(path vector(real), path g, int n, bool truesize=false,
pen p=currentpen, arrowbar arrow=Arrow);
as illustrated in this simple example of a flow field:
import graph;
defaultpen(1.0);
Chapter 8: Base modules 132
size(0,150,IgnoreAspect);
real arrowsize=4mm;
real arrowlength=2arrowsize;
real epsilon=0.5;
path g=graph(f,epsilon,1/epsilon);
int n=3;
draw(g);
xaxis("$x$");
yaxis("$y$");
add(vectorfield(vector(W,W),g,n,true));
add(vectorfield(vector(NE,NW),(0,0)--(point(E).x,0),n,true));
add(vectorfield(vector(NE,NE),(0,0)--(0,point(N).y),n,true));
14. To draw a vector field of nx×ny arrows in box(a,b), use the routine
picture vectorfield(path vector(pair), pair a, pair b,
int nx=nmesh, int ny=nx, bool truesize=false,
real maxlength=truesize ? 0 : maxlength(a,b,nx,ny),
Chapter 8: Base modules 133
pair a=(0,0);
pair b=(2pi,2pi);
add(vectorfield(vector,a,b));
15. The following scientific graphs, which illustrate many features of Asymptote’s graphics
routines, were generated from the examples diatom.asy and westnile.asy, using the
comma-separated data in diatom.csv and westnile.csv.
Chapter 8: Base modules 134
A B C
g)
in
tz
ue
(K
g
in
s
e
os
tz
g
st
to ria
in
ue
R
cy
he
tz
K
)
w
ei
ue
s auc
n
h)
ll
no
or
K
sa
ot
en . v
lm
it
ru
as
a
K
(R
m
(G
/e
on var
H
si
ri
a
si
a
is
ea
ra
le
os
cr ina
os
ut
el
tr
ne
ul
rm
p.
in
c
u
vi
cc
te
ri pu
m
sp
m
ot
fo
flo
s
ila ca
ei
os
cf
s
ra
la
on
he
er
ag a
el
a
ei
ri
ri
ri
nt
oe
oc
on
os
lla
ila
ila
na
et
ac
i
be
er
ag
ag
no
ha
ch
ul
st
Ta
Fr
Fr
Fr
A
C
A
A
A
0 2000
1998
1996 1994
1992 1990
1988
1986
1984 1982
100 1980
1978
sediment depth (cm)
1972
1970
1965
200
1961
1950
300 1940 1942
1920
1915 1910
1888
400 1763
1726
25 50 25 50 25 50 20 40 25 50 20 40 20 40 10 8
% 5 4
1.0
0.9 1. Estimate
proportion of
Susceptible bird survival
0.8 3. Determine
birds surviving
0.7 desired bird
at end of season
survival for
0.6 next season
0.5 2. Read off
4. Calculate initial
0.4 required mosquito
0.3 proportional abundance
reduction in
0.2 mosquitoes
0.1
0.0
0 10 M2 20 M1 30 40
Initial no. of mosquitoes per bird (SM0 /NB0 )
Chapter 8: Base modules 135
8.28 palette
Asymptote can also generate color density images and palettes. The following palettes are
predefined in palette.asy:
pen[] Grayscale(int NColors=256)
a grayscale palette;
pen[] Rainbow(int NColors=32766)
a rainbow spectrum;
pen[] BWRainbow(int NColors=32761)
a rainbow spectrum tapering off to black/white at the ends;
pen[] BWRainbow2(int NColors=32761)
a double rainbow palette tapering off to black/white at the ends, with a linearly
scaled intensity.
pen[] Wheel(int NColors=32766)
a full color wheel palette;
pen[] Gradient(int NColors=256 ... pen[] p)
a palette varying linearly over the specified array of pens, using NColors in each
interpolation interval;
The function cmyk(pen[] Palette) may be used to convert any of these palettes to the
CMYK colorspace.
A color density plot using palette palette can be generated from a function f(x,y) and
added to a picture pic:
bounds image(picture pic=currentpicture, real f(real, real),
range range=Full, pair initial, pair final,
int nx=ngraph, int ny=nx, pen[] palette, int divs=0,
bool antialias=false)
The function f will be sampled at nx and ny evenly spaced points over a rectangle
defined by the points initial and final, respecting the current graphical scaling of pic.
The color space is scaled according to the z axis scaling (see [automatic scaling], page 122).
If divs > 1, the palette is quantized to divs − 1 values. A bounds structure for the function
values is returned:
struct bounds {
real min;
real max;
// Possible tick intervals:
int[] divisor;
}
This information can be used for generating an optional palette bar. The palette color
space corresponds to a range of values specified by the argument range, which can be Full,
Automatic, or an explicit range Range(real min, real max). (The type range is defined
in palette.asy.) Here Full specifies a range varying from the minimum to maximum
values of the function over the sampling interval, while Automatic selects "nice" limits.
The examples fillcontour.asy and imagecontour.asy illustrate how level sets (contour
lines) can be drawn on a color density plot (see Section 8.36 [contour], page 164).
Chapter 8: Base modules 136
A color density plot can also be generated from an explicit real[][] array data:
bounds image(picture pic=currentpicture, real[][] f, range range=Full,
pair initial, pair final, pen[] palette, int divs=0,
bool transpose=(initial.x < final.x && initial.y < final.y),
bool copy=true, bool antialias=false);
If the initial point is to the left and below the final point, by default the array indices are
interpreted according to the Cartesian convention (first index: x, second index: y) rather
than the usual matrix convention (first index: −y, second index: x).
To construct an image from an array of irregularly spaced points and an array of values
f at these points, use one of the routines
bounds image(picture pic=currentpicture, pair[] z, real[] f,
range range=Full, pen[] palette)
bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
range range=Full, pen[] palette)
An optionally labelled palette bar may be generated with the routine
void palette(picture pic=currentpicture, Label L="", bounds bounds,
pair initial, pair final, axis axis=Right, pen[] palette,
pen p=currentpen, paletteticks ticks=PaletteTicks,
bool copy=true, bool antialias=false);
The color space of palette is taken to be over bounds bounds with scaling given by the
z scaling of pic. The palette orientation is specified by axis, which may be one of Right,
Left, Top, or Bottom. The bar is drawn over the rectangle from initial to final. The
argument paletteticks is a special tick type (see [ticks], page 107) that takes the following
arguments:
paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
bool beginlabel=true, bool endlabel=true,
int N=0, int n=0, real Step=0, real step=0,
pen pTick=nullpen, pen ptick=nullpen);
The image and palette bar can be fit to a frame and added and optionally aligned to a
picture at the desired location:
size(12cm,12cm);
import graph;
import palette;
int n=256;
real ninv=2pi/n;
real[][] v=new real[n][n];
pen[] Palette=BWRainbow();
Chapter 8: Base modules 137
picture bar;
bounds range=image(v,(0,0),(1,1),Palette);
palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette,
PaletteTicks("$%+#.1f$"));
add(bar.fit(),point(E),30E);
+1.0
+0.8
+0.6
+0.4
+0.2
0.0 A
−0.2
−0.4
−0.6
−0.8
−1.0
size(10cm,10cm,IgnoreAspect);
scale(Linear,Log,Log);
pen[] Palette=BWRainbow();
bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette);
xaxis("$x$",BottomTop,LeftTicks,above=true);
yaxis("$y$",LeftRight,RightTicks,above=true);
Chapter 8: Base modules 138
palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette,
PaletteTicks(ptick=linewidth(0.5*linewidth())));
f (x, y)
10−3 10−2 10−1 100 101 102
102
y 101
100
0 20 40 60 80 100
x
One can also draw an image directly from a two-dimensional pen array or a function pen
f(int, int):
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);
as illustrated in the following examples:
size(200);
import palette;
int n=256;
real ninv=2pi/n;
pen[][] v=new pen[n][n];
Chapter 8: Base modules 139
image(v,(0,0),(1,1));
import palette;
size(200);
pair pws(pair z) {
pair w=(z+exp(pi*I/5)/0.9)/(1+z/0.9*exp(-pi*I/5));
return exp(w)*(w^3-0.5*I);
}
int N=512;
pair a=(-1,-1);
pair b=(0.5,0.5);
real dx=(b-a).x/N;
real dy=(b-a).y/N;
image(f,N,N,(0,0),(300,300),antialias=true);
For convenience, the module palette also defines functions that may be used to con-
struct a pen array from a given function and palette:
pen[] palette(real[] f, pen[] palette);
pen[][] palette(real[][] f, pen[] palette);
8.29 three
This module fully extends the notion of guides and paths in Asymptote to three dimensions.
It introduces the new types guide3, path3, and surface. Guides in three dimensions are
specified with the same syntax as in two dimensions except that triples (x,y,z) are used
in place of pairs (x,y) for the nodes and direction specifiers. This generalization of John
Hobby’s spline algorithm is shape-invariant under three-dimensional rotation, scaling, and
shifting, and reduces in the planar case to the two-dimensional algorithm used in Asymptote,
MetaPost, and MetaFont [see J. C. Bowman, Proceedings in Applied Mathematics and
Mechanics, 7:1, 2010021-2010022 (2007)].
For example, a unit circle in the XY plane may be filled and drawn like this:
import three;
size(100);
path3 g=(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle;
draw(g);
draw(O--Z,red+dashed,Arrow3);
Chapter 8: Base modules 141
draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
dot(g,red);
size(100,0);
path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
draw(g);
draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
dot(g,red);
The parameters nu and nv specify the number of subdivisions for drawing optional mesh
lines for each Bezier patch. The optional name parameter is used as a prefix for naming
the surface patches in the PRC model tree. Here material is a structure defined in three_
light.asy:
struct material {
pen[] p; // diffusepen,emissivepen,specularpen
real opacity;
real shininess;
real metallic;
real fresnel0;
}
These material properties are used to implement physically based rendering (PBR) using
light properties defined in plain_prethree.asy and three_light.asy:
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 Headlamp=light(gray(0.8),specular=gray(0.7),
specularfactor=3,dir(42,48));
currentlight=Headlamp;
light nolight;
The currentlight.background (or background member of the specified light) can be
used to set the background color for 2D (or 3D) images. The default background is white for
HTML images and transparent for all other formats. One can request a completely transparent
background for 3D WebGL images with currentlight.background=black+opacity(0.0);
render
A function render() may be assigned to the optional render parameter allows one to
pass specialized rendering options to the surface drawing routines, via arguments such as:
bool tessellate; // use tessellated mesh to store straight patches
real margin; // shrink amount for rendered OpenGL viewport, in bp.
bool partnames; // assign part name indices to compound objects
bool defaultnames; // assign default names to unnamed objects
interaction interaction; // billboard interaction mode
Chapter 8: Base modules 143
along with the rendering parameters for the legacy PRC format described in three.asy.
Asymptote also supports image-based lighting with the setting settings.ibl=true.
This uses pre-rendered EXR images from the directory specified by -imageDir (which de-
faults to ibl) or, for WebGL rendering, the URL specified by -imageURL (which defaults to
https://vectorgraphics.gitlab.io/asymptote/ibl). Additional rendered images can
be generated on an NVIDIA GPU using the reflect program in the cudareflect subdirec-
tory of the Asymptote source directory.
Sample Bezier surfaces are contained in the example files BezierSurface.asy,
teapot.asy, teapotIBL.asy, and parametricsurface.asy.
The structure render contains specialized rendering options documented at the begin-
ning of module three.
The examples elevation.asy and sphericalharmonic.asy illustrate how to
draw a surface with patch-dependent colors. The examples vertexshading.asy and
smoothelevation.asy illustrate vertex-dependent colors, which are supported by
Asymptote’s native OpenGL/WebGL renderers and the two-dimensional vector output format
(settings.render=0). Since the legacy PRC output format does not support vertex
shading of Bezier surfaces, PRC patches are shaded with the mean of the four vertex colors.
A surface can be constructed from a cyclic path3 with the constructor
surface surface(path3 external, triple[] internal=new triple[],
pen[] colors=new pen[], bool3 planar=default);
and then filled:
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);
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 plane can be
constructed from a two-dimensional cyclic path g with the constructor
surface surface(path p, triple plane(pair)=XYplane);
and then filled:
draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red);
Planar Bezier surfaces patches are constructed using Orest Shardt’s bezulate routine,
which decomposes (possibly nonsimply connected) regions bounded (according to the
zerowinding fill rule) by simple cyclic paths (intersecting only at the endpoints) into
subregions bounded by cyclic paths of length 4 or less.
A more efficient routine also exists for drawing tessellations composed of many 3D tri-
angles, with specified vertices, and optional normals or vertex colors:
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);
Here, the triple array v lists the (typically distinct) vertices, while the array vi contains
integer arrays of length 3 containing the indices of the elements in v that form the vertices of
Chapter 8: Base modules 144
each triangle. Similarly, the arguments n and ni contain optional normal data and p and pi
contain optional pen vertex data. If more than one normal or pen is specified for a vertex,
the last one is used. An example of this tessellation facility is given in triangles.asy.
Arbitrary thick three-dimensional curves and line caps (which the OpenGL standard does
not require implementations to provide) are constructed with
tube tube(path3 p, real width, render render=defaultrender);
this returns a tube structure representing a tube of diameter width centered approximately
on g. The tube structure consists of a surface s and the actual tube center, path3 center.
Drawing thick lines as tubes can be slow to render, especially with the Adobe Reader ren-
derer. The setting thick=false can be used to disable this feature and force all lines to be
drawn with linewidth(0) (one pixel wide, regardless of the resolution). By default, mesh
and contour lines in three-dimensions are always drawn thin, unless an explicit line width
is given in the pen parameter or the setting thin is set to false. The pens thin() and
thick() defined in plain_pens.asy can also be used to override these defaults for specific
draw commands.
There are six choices for viewing 3D Asymptote output:
1. Use the native Asymptote adaptive OpenGL-based renderer (with the command-line
option -V and the default settings outformat="" and render=-1). On UNIX systems
with graphics support for multisampling, the sample width can be controlled with the
setting multisample. The ratio of physical to logical screen pixels can be specified with
the setting devicepixelratio. An initial screen position can be specified with the pair
setting position, where negative values are interpreted as relative to the corresponding
maximum screen dimension. The default settings
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"};
bind the mouse buttons as follows:
• Left: rotate
• Shift Left: zoom
• Ctrl Left: shift viewport
• Alt Left: pan
• Wheel Up: zoom in
• Wheel Down: zoom out
• Right: zoom
• Shift Right: rotate about the X axis
• Ctrl Right: rotate about the Y axis
• Alt Right: rotate about the Z axis
The keyboard bindings are:
• h: home
Chapter 8: Base modules 145
• f: toggle fitscreen
• x: spin about the X axis
• y: spin about the Y axis
• z: spin about the Z axis
• s: stop spinning
• m: rendering mode (solid/patch/mesh)
• e: export
• c: show camera parameters
• p: play animation
• r: reverse animation
• : step animation
• +: expand
• =: expand
• >: expand
• -: shrink
• : shrink
• <: shrink
• q: exit
• Ctrl-q: exit
2. Generate WebGL interactive vector graphics output with the the command-line option
and -f html (or the setting outformat="html"). The resulting 3D HTML file can then
be viewed directly in any modern desktop or mobile browser, or even embedded within
another web page:
<iframe src="logo3.html" width="561" height="321" frameborder="0">
</iframe>
Normally, WebGL files generated by Asymptote are dynamically remeshed to fit the
browser window dimensions. However, the setting absolute=true can be used to force
the image to be rendered at its designed size (accounting for multiple device pixels per
css pixel).
For specialized applications, the setting keys=true can be used to generate an identi-
fying key immediately before the WebGL code for each generated object. The default
key, the "line:column" of the associated function call of the top-level source code, can
be overwritten by adding KEY="x" as the first argument of the function call, where x
represents user-supplied text.
The interactive WebGL files produced by Asymptote use the default mouse and (many
of the same) key bindings as the OpenGL renderer. Zooming via the mouse wheel of a
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 ESC key is pressed.
By default, viewing the 3D HTML files generated by Asymptote requires network access
to download the AsyGL rendering library, which is normally cached by the browser for
future use. However, the setting offline=true can be used to embed this small (about
48kB) library within a stand-alone HTML file that can be viewed offline.
Chapter 8: Base modules 146
3. Render the scene to a specified rasterized format outformat at the resolution of n pixels
per bp, as specified by the setting render=n. A negative value of n is interpreted as
|2n| for EPS and PDF formats and |n| for other formats. The default value of render
is -1. By default, the scene is internally rendered at twice the specified resolution; this
can be disabled by setting antialias=1. High resolution rendering is done by tiling
the image. If your graphics card allows it, the rendering can be made more efficient
by increasing the maximum tile size maxtile to your screen dimensions (indicated by
maxtile=(0,0). If your video card generates unwanted black stripes in the output,
try setting the horizontal and vertical components of maxtiles to something less than
your screen dimensions. The tile size is also limited by the setting maxviewport,
which restricts the maximum width and height of the viewport. Some graphics drivers
support batch mode (-noV) rendering in an iconified window; this can be enabled with
the setting iconify=true.
4. Embed the 3D legacy PRC format in a PDF file and view the resulting PDF file with
version 9.0 or later of Adobe Reader. This requires settings.outformat="pdf" and
settings.prc=true, which can be specified by the command-line options -f pdf and
-f prc, put in the Asymptote configuration file (see [configuration file], page 177), or
specified in the script before module three (or graph3) is imported. The media9 LaTeX
package is also required (see Section 8.19 [embed], page 103). The example 100d.asy
illustrates how one can generate a list of predefined views (see 100d.views). A station-
ary preview image with a resolution of n pixels per bp can be embedded with the setting
render=n; this allows the file to be viewed with other PDF viewers. Alternatively, the
file externalprc.tex illustrates how the resulting PRC and rendered image files can be
extracted and processed in a separate LaTeX file. However, see Chapter 7 [LaTeX us-
age], page 92, for an easier way to embed three-dimensional Asymptote pictures within
LaTeX. For specialized applications where only the raw PRC file is required, specify
settings.outformat="prc". The PRC specification is available from https://web.
archive.org/web/20081204104459/http://livedocs.adobe.com/acrobat_sdk/9/
Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/
5. Output a V3D portable compressed vector graphics file using settings.outformat="v3d",
which can be viewed with an external viewer or converted to an alternate 3D format
using the Python pyv3d library. V3D content can be automatically embedded within
a PDF file using the options settings.outformat="pdf" and settings.v3d=true.
Alternatively, a V3D file file.v3d may be manually embedded within a PDF file
using the media9 LaTeX package:
\includemedia[noplaybutton,width=100pt,height=200pt]{}{file.v3d}%
An online Javascript-based V3D-aware PDF viewer is available at https://github.
com/vectorgraphics/pdfv3dReader.
The V3D specification and the pyv3d library are available at https://github.com/
vectorgraphics/v3d. A V3D file file.v3d may be imported and viewed by Asymptote
either by specifying file.v3d on the command line
asy -V file.v3d
or using the v3d module and importv3d function in interactive mode (or within an
Asymptote file):
import v3d;
Chapter 8: Base modules 147
importv3d("file.v3d");
6. Project the scene to a two-dimensional vector (EPS or PDF) format with render=0.
Only limited support for hidden surface removal, lighting, and transparency is available
with this approach (see [PostScript3D], page 153).
Automatic picture sizing in three dimensions is accomplished with double deferred draw-
ing. The maximal desired dimensions of the scene in each of the three dimensions can
optionally be specified with the routine
void size3(picture pic=currentpicture, real x, real y=x, real z=y,
bool keepAspect=pic.keepAspect);
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 size parameters. The global pair viewportmargin may be used to add horizontal
and vertical margins to the viewport dimensions. Alternatively, a minimum viewportsize
may be specified. A 3D picture pic can be explicitly fit to a 3D frame by calling
frame pic.fit3(projection P=currentprojection);
and then added to picture dest about position with
void add(picture dest=currentpicture, frame src, triple position=(0,0,0));
For convenience, the three module defines O=(0,0,0), X=(1,0,0), Y=(0,1,0), and
Z=(0,0,1), along with a unitcircle in the XY plane:
path3 unitcircle3=X..Y..-X..-Y..cycle;
A general (approximate) circle can be drawn perpendicular to the direction normal with
the routine
path3 circle(triple c, real r, triple normal=Z);
A circular arc centered at c with radius r from c+r*dir(theta1,phi1) to
c+r*dir(theta2,phi2), drawing counterclockwise relative to the normal vector
cross(dir(theta1,phi1),dir(theta2,phi2)) if theta2 > theta1 or if theta2 ==
theta1 and phi2 >= phi1, can be constructed with
path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
triple normal=O);
The normal must be explicitly specified if c and the endpoints are colinear. If r < 0,
the complementary arc of radius |r| is constructed. For convenience, an arc centered at c
from triple v1 to v2 (assuming |v2-c|=|v1-c|) in the direction CCW (counter-clockwise)
or CW (clockwise) may also be constructed with
path3 arc(triple c, triple v1, triple v2, triple normal=O,
bool direction=CCW);
When high accuracy is needed, the routines Circle and Arc defined in graph3 may be used
instead. See [GaussianSurface], page 158, for an example of a three-dimensional circular
arc.
The representation O--O+u--O+u+v--O+v--cycle of the plane passing through point O
with normal cross(u,v) is returned by
path3 plane(triple u, triple v, triple O=O);
Chapter 8: Base modules 148
A three-dimensional box with opposite vertices at triples v1 and v2 may be drawn with
the function
path3[] box(triple v1, triple v2);
For example, a unit box is predefined as
path3[] unitbox=box(O,(1,1,1));
Asymptote also provides optimized definitions for the three-dimensional paths
unitsquare3 and unitcircle3, along with the surfaces unitdisk, unitplane,
unitcube, unitcylinder, unitcone, unitsolidcone, unitfrustum(real t1, real t2),
unitsphere, and unithemisphere.
These projections to two dimensions are predefined:
oblique
oblique(real angle)
The point (x,y,z) is projected to (x-0.5z,y-0.5z). If an optional real ar-
gument is given, the negative z axis is drawn at this angle in degrees. The
projection obliqueZ is a synonym for oblique.
obliqueX
obliqueX(real angle)
The point (x,y,z) is projected to (y-0.5x,z-0.5x). If an optional real argu-
ment is given, the negative x axis is drawn at this angle in degrees.
obliqueY
obliqueY(real angle)
The point (x,y,z) is projected to (x+0.5y,z+0.5y). If an optional real argu-
ment is given, the positive y axis is drawn at this angle in degrees.
orthographic(triple camera, triple up=Z, triple target=O,
real zoom=1, pair viewportshift=0, bool showtarget=true,
bool center=true)
This projects from three to two dimensions using the view as seen at a point
infinitely far away in the direction unit(camera), orienting the camera so that,
if possible, the vector up points upwards. Parallel lines are projected to parallel
lines. The bounding volume is expanded to include target if showtarget=true.
If center=true, the target will be adjusted to the center of the bounding vol-
ume.
orthographic(real x, real y, real z, triple up=Z, triple target=O,
real zoom=1, pair viewportshift=0, bool showtarget=true,
bool center=true)
This is equivalent to
orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,center)
The routine
triple camera(real alpha, real beta);
can be used to compute the camera position with the x axis below the horizontal
at angle alpha, the y axis below the horizontal at angle beta, and the z axis
up.
Chapter 8: Base modules 149
projection[][] SixViewsUS={{null,TopView},
{LeftView,FrontView,RightView,BackView},
{null,BottomView}};
projection[][] ThreeViewsFR={{RightView,FrontView},
{null,TopView}};
projection[][] SixViewsFR={{null,BottomView},
Chapter 8: Base modules 150
{RightView,FrontView,LeftView,BackView},
{null,TopView}};
projection[][] ThreeViews={{FrontView,TopView,RightView}};
projection[][] SixViews={{FrontView,TopView,RightView},
{BackView,BottomView,LeftView}};
When not multiplied on the left by a transform3, three-dimensional TEX Labels are
drawn as Bezier surfaces directly on the projection plane:
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)
The optional name parameter is used as a prefix for naming the label patches in the PRC
model tree. The default interaction is Billboard, which means that labels are rotated
interactively so that they always face the camera. The interaction Embedded means that
the label interacts as a normal 3D surface, as illustrated in the example billboard.asy.
Alternatively, a label can be transformed from the XY plane by an explicit transform3 or
mapped to a specified two-dimensional plane with the predefined transform3 types XY, YZ,
ZX, YX, ZY, ZX. There are also modified versions of these transforms that take an optional
argument projection P=currentprojection that rotate and/or flip the label so that it is
more readable from the initial viewpoint.
A transform3 that projects in the direction dir onto the plane with normal n through
point O is returned by
transform3 planeproject(triple n, triple O=O, triple dir=n);
One can use
triple normal(path3 p);
to find the unit normal vector to a planar three-dimensional path p. As illustrated in the
example planeproject.asy, a transform3 that projects in the direction dir onto the plane
defined by a planar path p is returned by
transform3 planeproject(path3 p, triple dir=normal(p));
The functions
surface extrude(path p, triple axis=Z);
surface extrude(Label L, triple axis=Z);
return the surface obtained by extruding path p or Label L along axis.
Three-dimensional versions of the path functions length, size, point, dir, accel,
radius, precontrol, postcontrol, arclength, arctime, reverse, subpath, intersect,
intersections, intersectionpoint, intersectionpoints, min, max, cyclic, and
straight are also defined.
The routine
real[] intersect(path3 p, surface s, real fuzz=-1);
returns a real array of length 3 containing the intersection times, if any, of a path p with a
surface s. The routine
real[][] intersections(path3 p, surface s, real fuzz=-1);
returns all (unless there are infinitely many) intersection times of a path p with a surface s
as a sorted array of real arrays of length 3, and
triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);
Chapter 8: Base modules 152
returns the corresponding intersection points. Here, the computations are performed to the
absolute error specified by fuzz, or if fuzz < 0, to machine precision. The routine
real orient(triple a, triple b, triple c, triple d);
is a numerically robust computation of dot(cross(a-d,b-d),c-d), which is the determi-
nant
|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|
The result is negative (positive) if a, b, c appear in counterclockwise (clockwise) order
when viewed from d or zero if all four points are coplanar.
The routine
real insphere(triple a, triple b, triple c, triple d, triple e);
returns a positive (negative) value if e lies inside (outside) the sphere passing through points
a,b,c,d oriented so that dot(cross(a-d,b-d),c-d) is positive, or zero if all five points
are cospherical. The value returned is the determinant
|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|
Here is an example showing all five guide3 connectors:
import graph3;
size(200);
currentprojection=orthographic(500,-500,500);
path3 p=z[0]..z[1]---z[2]::{Y}z[3]
&z[3]..z[4]--z[5]::{Y}z[6]
&z[6]::z[7]---z[8]..{Y}z[9];
draw(p,grey+linewidth(4mm),currentlight);
xaxis3(Label(XY()*"$x$",align=-3Y),red,above=true);
yaxis3(Label(XY()*"$y$",align=-3X),red,above=true);
Chapter 8: Base modules 153
Three-dimensional versions of bars or arrows can be drawn with one of the specifiers
None, Blank, BeginBar3, EndBar3 (or equivalently Bar3), Bars3, BeginArrow3, MidArrow3,
EndArrow3 (or equivalently Arrow3), Arrows3, BeginArcArrow3, EndArcArrow3 (or equiv-
alently ArcArrow3), MidArcArrow3, and ArcArrows3. Three-dimensional bars accept the
optional arguments (real size=0, triple dir=O). If size=O, the default bar length is
used; if dir=O, the bar is drawn perpendicular to the path and the initial viewing direc-
tion. The predefined three-dimensional arrowhead styles are DefaultHead3, HookHead3,
TeXHead3. Versions of the two-dimensional arrowheads lifted to three-dimensional space
and aligned according to the initial viewpoint (or an optionally specified normal vec-
tor) are also defined: DefaultHead2(triple normal=O), HookHead2(triple normal=O),
TeXHead2(triple normal=O). These are illustrated in the example arrows3.asy.
Module three also defines the three-dimensional margins NoMargin3, BeginMargin3,
EndMargin3, Margin3, Margins3, BeginPenMargin2, EndPenMargin2, PenMargin2,
PenMargins2, BeginPenMargin3, EndPenMargin3, PenMargin3, PenMargins3,
BeginDotMargin3, EndDotMargin3, DotMargin3, DotMargins3, Margin3, and
TrueMargin3.
The routine
void pixel(picture pic=currentpicture, triple v, pen p=currentpen,
real width=1);
can be used to draw on picture pic a pixel of width width at position v using pen p.
Further three-dimensional examples are provided in the files near_earth.asy,
conicurv.asy, and (in the animations subdirectory) cube.asy.
Limited support for projected vector graphics (effectively three-dimensional nonrendered
PostScript) is available with the setting render=0. This currently only works for piecewise
planar surfaces, such as those produced by the parametric surface routines in the graph3
module. Surfaces produced by the solids module will also be properly rendered if the
parameter nslices is sufficiently large.
In the module bsp, hidden surface removal of planar pictures is implemented using a
binary space partition and picture clipping. A planar path is first converted to a structure
face derived from picture. A face may be given to a two-dimensional drawing routine
in place of any picture argument. An array of such faces may then be drawn, removing
hidden surfaces:
void add(picture pic=currentpicture, face[] faces,
projection P=currentprojection);
Labels may be projected to two dimensions, using projection P, onto the plane passing
through point O with normal cross(u,v) by multiplying it on the left by the transform
Chapter 8: Base modules 154
Here is an example that shows how a binary space partition may be used to draw a
two-dimensional vector graphics projection of three orthogonal intersecting planes:
size(6cm,0);
import bsp;
real u=2.5;
real v=1;
currentprojection=oblique;
path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
path3 l=rotate(90,Z)*rotate(90,Y)*y;
path3 g=rotate(90,X)*rotate(90,Y)*y;
face[] faces;
filldraw(faces.push(y),project(y),yellow);
filldraw(faces.push(l),project(l),lightgrey);
filldraw(faces.push(g),project(g),green);
add(faces);
8.30 obj
This module allows one to construct surfaces from simple obj files, as illustrated in the
example files galleon.asy and triceratops.asy.
Chapter 8: Base modules 155
8.31 graph3
This module implements three-dimensional versions of the functions in graph.asy. To draw
an x axis in three dimensions, use the routine
void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
real xmin=-infinity, real xmax=infinity, pen p=currentpen,
ticks3 ticks=NoTicks3, arrowbar3 arrow=None,
margin3 margin=NoMargin3, bool above=false,
projection P=currentprojection);
Analogous routines yaxis and zaxis can be used to draw y and z axes in three dimensions.
There is also a routine for drawing all three axis:
void axes3(picture pic=currentpicture,
Label xlabel="", Label ylabel="", Label zlabel="",
bool extend=false,
triple min=(-infinity,-infinity,-infinity),
triple max=(infinity,infinity,infinity),
pen p=currentpen, arrowbar3 arrow=None,
margin3 margin=NoMargin3, projection P=currentprojection);
The predefined three-dimensional axis types are
axis YZEquals(real y, real z, triple align=O, bool extend=false);
axis XZEquals(real x, real z, triple align=O, bool extend=false);
axis XYEquals(real x, real y, triple align=O, bool extend=false);
axis YZZero(triple align=O, bool extend=false);
axis XZZero(triple align=O, bool extend=false);
axis XYZero(triple align=O, bool extend=false);
axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false);
The optional align parameter to these routines can be used to specify the default axis
and tick label alignments. The Bounds axis accepts two type parameters, each of which
must be one of Min, Max, or Both. These parameters specify which of the four possible
three-dimensional bounding box edges should be drawn.
The three-dimensional tick options are NoTicks3, InTicks, OutTicks, and InOutTicks.
These specify the tick directions for the Bounds axis type; other axis types inherit the
direction that would be used for the Bounds(Min,Min) axis.
Here is an example of a helix and bounding box axes with ticks and axis labels, using
orthographic projection:
import graph3;
size(0,200);
size3(200,IgnoreAspect);
currentprojection=orthographic(4,6,3);
draw(p,Arrow3);
scale(true);
xaxis3(XZ()*"$x$",Bounds,red,InTicks(Label,2,2));
yaxis3(YZ()*"$y$",Bounds,red,InTicks(beginlabel=false,Label,2,2));
zaxis3(XZ()*"$z$",Bounds,red,InTicks);
import graph3;
size(0,200);
size3(200,IgnoreAspect);
currentprojection=perspective(dir(75,20));
scale(Linear,Linear,Log);
xaxis3("$x$",0,1,red,OutTicks(2,2));
yaxis3("$y$",0,1,red,OutTicks(2,2));
zaxis3("$z$",1,30,red,OutTicks(beginlabel=false));
Chapter 8: Base modules 157
size(0,100);
path3 g=yscale3(2)*unitcircle3;
currentprojection=perspective(10,10,10);
axis(Label("C",position=0,align=15X),g,InTicks(endlabel=false,8,end=false),
ticklocate(0,360,new real(real v) {
path3 h=O--max(abs(max(g)),abs(min(g)))*dir(90,v);
return intersect(g,h)[0];},
new triple(real t) {return cross(dir(g,t),Z);}));
Surface plots of matrices and functions over the region box(a,b) in the XY plane are
also implemented:
surface surface(real[][] f, pair a, pair b, bool[][] cond={});
surface surface(real[][] f, pair a, pair b, splinetype xsplinetype,
splinetype ysplinetype=xsplinetype, bool[][] cond={});
surface surface(real[][] f, real[] x, real[] y,
splinetype xsplinetype=null, splinetype ysplinetype=xsplinetype,
bool[][] cond={})
Chapter 8: Base modules 158
import graph3;
size(200,0);
currentprojection=perspective(10,8,4);
draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle);
draw(arc(0.12Z,0.2,90,60,90,25),ArcArrow3);
surface s=surface(f,(-1,-1),(1,1),nx=5,Spline);
xaxis3(Label("$x$"),red,Arrow3);
yaxis3(Label("$y$"),red,Arrow3);
zaxis3(XYZero(extend=true),red,Arrow3);
Chapter 8: Base modules 159
draw(s,lightgray,meshpen=black+thick(),nolight,render(merge=true));
label("$O$",O,-Z+Y,red);
A mesh can be drawn without surface filling by specifying nullpen for the surfacepen.
A vector field of nu×nv arrows on a parametric surface f over box(a,b) can be drawn
with the routine
picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b,
int nu=nmesh, int nv=nu, bool truesize=false,
real maxlength=truesize ? 0 : maxlength(f,a,b,nu,nv),
bool cond(pair z)=null, pen p=currentpen,
arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
as illustrated in the examples vectorfield3.asy and vectorfieldsphere.asy.
8.32 grid3
This module, contributed by Philippe Ivaldi, can be used for drawing 3D grids. Here is an
example (further examples can be found in grid3.asy and at https://web.archive.org/
web/20201130113133/http://www.piprime.fr/files/asymptote/grid3/):
import grid3;
size(8cm,0,IgnoreAspect);
currentprojection=orthographic(0.5,1,0.5);
limits((-2,-2,1),(0,2,100));
grid3(XYZgrid);
xaxis3(Label("$x$",position=EndPoint,align=S),Bounds(Min,Min),
OutTicks());
yaxis3(Label("$y$",position=EndPoint,align=S),Bounds(Min,Min),OutTicks());
Chapter 8: Base modules 160
zaxis3(Label("$z$",position=EndPoint,align=(-1,0.5)),Bounds(Min,Min),
OutTicks(beginlabel=false));
8.33 solids
This solid geometry module defines a structure revolution that can be used to fill and
draw surfaces of revolution. The following example uses it to display the outline of a
circular cylinder of radius 1 with axis O--1.5unit(Y+Z) with perspective projection:
import solids;
size(0,100);
revolution r=cylinder(O,1,1.5,Y+Z);
draw(r,heavygreen);
Chapter 8: Base modules 161
8.34 tube
This module extends the tube surfaces constructed in three_arrows.asy to arbitrary cross
sections, colors, and spine transformations. The routine
surface tube(path3 g, coloredpath section,
transform T(real)=new transform(real t) {return identity();},
real corner=1, real relstep=0);
draws a tube along g with cross section section, after applying the transformation T(t)
at point(g,t). The parameter corner controls the number of elementary tubes at the
angular points of g. A nonzero value of relstep specifies a fixed relative time step (in
the sense of relpoint(g,t)) to use in constructing elementary tubes along g. The type
coloredpath is a generalization of path to which a path can be cast:
struct coloredpath
{
path p;
pen[] pens(real);
int colortype=coloredSegments;
}
Here p defines the cross section and the method pens(real t) returns an array of pens
(interpreted as a cyclic array) used for shading the tube patches at relpoint(g,t). If
colortype=coloredSegments, the tube patches are filled as if each segment of the section
was colored with the pen returned by pens(t), whereas if colortype=coloredNodes, the
tube components are vertex shaded as if the nodes of the section were colored.
A coloredpath can be constructed with one of the routines:
coloredpath coloredpath(path p, pen[] pens(real),
int colortype=coloredSegments);
coloredpath coloredpath(path p, pen[] pens=new pen[] {currentpen},
int colortype=coloredSegments);
coloredpath coloredpath(path p, pen pen(real));
In the second case, the pens are independent of the relative time. In the third case, the
array of pens contains only one pen, which depends of the relative time.
Chapter 8: Base modules 162
The casting of path to coloredpath allows the use of a path instead of a coloredpath;
in this case the shading behavior is the default shading behavior for a surface.
An example of tube is provided in the file trefoilknot.asy. Further examples can
be found at https://web.archive.org/web/20201130113133/http://www.piprime.fr/
files/asymptote/tube.
8.35 flowchart
This module provides routines for drawing flowcharts. The primary structure is a block,
which represents a single block on the flowchart. The following eight functions return a
position on the appropriate edge of the block, given picture transform t:
pair block.top(transform t=identity());
pair block.left(transform t=identity());
pair block.right(transform t=identity());
pair block.bottom(transform t=identity());
pair block.topleft(transform t=identity());
pair block.topright(transform t=identity());
pair block.bottomleft(transform t=identity());
pair block.bottomright(transform t=identity());
To obtain an arbitrary position along the boundary of the block in user coordinates, use:
pair block.position(real x, transform t=identity());
The center of the block in user coordinates is stored in block.center and the block size in
PostScript coordinates is given by block.size.
A frame containing the block is returned by
frame block.draw(pen p=currentpen);
The following block generation routines accept a Label, string, or frame for their object
argument:
rectangular block with an optional header (and padding dx around header and body):
block rectangle(object header, object body, pair center=(0,0),
pen headerpen=mediumgray, pen bodypen=invisible,
pen drawpen=currentpen,
real dx=3, real minheaderwidth=minblockwidth,
real minheaderheight=minblockwidth,
real minbodywidth=minblockheight,
real minbodyheight=minblockheight);
block rectangle(object body, pair center=(0,0),
pen fillpen=invisible, pen drawpen=currentpen,
real dx=3, real minwidth=minblockwidth,
real minheight=minblockheight);
parallelogram block:
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);
Chapter 8: Base modules 163
diamond-shaped block:
block diamond(object body, pair center=(0,0),
pen fillpen=invisible, pen drawpen=currentpen,
real ds=5, real dw=1,
real height=20, real minwidth=minblockwidth,
real minheight=minblockheight);
circular block:
block circle(object body, pair center=(0,0), pen fillpen=invisible,
pen drawpen=currentpen, real dr=3,
real mindiameter=mincirclediameter);
rectangular block with rounded corners:
block roundrectangle(object body, pair center=(0,0),
pen fillpen=invisible, pen drawpen=currentpen,
real ds=5, real dw=0, real minwidth=minblockwidth,
real minheight=minblockheight);
rectangular block with beveled edges:
block bevel(object body, pair center=(0,0), pen fillpen=invisible,
pen drawpen=currentpen, real dh=5, real dw=5,
real minwidth=minblockwidth, real minheight=minblockheight);
To draw paths joining the pairs in point with right-angled lines, use the routine:
path path(pair point[] ... flowdir dir[]);
The entries in dir identify whether successive segments between the pairs specified by point
should be drawn in the Horizontal or Vertical direction.
Here is a simple flowchart example (see also the example controlsystem.asy):
size(0,300);
import flowchart;
block block1=rectangle(Label("Example",magenta),
pack(Label("Start:",heavygreen),"",Label("$A:=0$",blue),
"$B:=1$"),(-0.5,3),palegreen,paleblue,red);
block block2=diamond(Label("Choice?",blue),(0,2),palegreen,red);
block block3=roundrectangle("Do something",(-1,1));
block block4=bevel("Don't do something",(1,1));
block block5=circle("End",(0,0));
draw(block1);
draw(block2);
draw(block3);
draw(block4);
draw(block5);
// draw(pic,block1.right(t)--block2.top(t));
block1--Right--Down--Arrow--block2;
block2--Label("Yes",0.5,NW)--Left--Down--Arrow--block3;
block2--Right--Label("No",0.5,NE)--Down--Arrow--block4;
block4--Down--Left--Arrow--block5;
block3--Down--Right--Arrow--block5;
});
Example
Start:
A := 0
B := 1
Yes No
Choice?
End
8.36 contour
This module draws contour lines. To construct contours corresponding to the values in a
real array c for a function f on box(a,b), use the routine
guide[][] contour(real f(real, real), pair a, pair b,
real[] c, int nx=ngraph, int ny=nx,
interpolate join=operator --, int subsample=1);
The integers nx and ny define the resolution. The default resolution, ngraph x ngraph
(here ngraph defaults to 100) can be increased for greater accuracy. The default interpo-
lation operator is operator -- (linear). Spline interpolation (operator ..) may produce
smoother contours but it can also lead to overshooting. The subsample parameter indicates
the number of interior points that should be used to sample contours within each 1 x 1 box;
the default value of 1 is usually sufficient.
Chapter 8: Base modules 165
The next example draws and labels multiple contours for the function z = x2 − y 2 with
the resolution 100 x 100, using a dashed pen for negative contours and a solid pen for
positive (and zero) contours:
import contour;
size(200);
draw(Labels,contour(f,(-1,-1),(1,1),c),p);
-0.3
0.3 -0.4
0.2
-0.5
-0.1 -0.2
0.4
0.1
0.1
0.4
-0.1 -0.2
-0.5
0.2
-0.4 0.3
-0.3
The next examples illustrates how contour lines can be drawn on color density images,
with and without palette quantization:
import graph;
import palette;
import contour;
size(10cm,10cm);
pair a=(0,0);
pair b=(2pi,2pi);
int N=200;
int Divs=10;
int divs=1;
int n=Divs*divs;
Chapter 8: Base modules 167
defaultpen(1bp);
pen Tickpen=black;
pen tickpen=gray+0.5*linewidth(currentpen);
pen[] Palette=quantize(BWRainbow(),n);
bounds range=image(f,Automatic,a,b,3N,Palette,n);
// Major contours
real[] Cvals=uniform(range.min,range.max,Divs);
draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin);
xaxis("$x$",BottomTop,LeftTicks,above=true);
yaxis("$y$",LeftRight,RightTicks,above=true);
palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette,
PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen));
+1.0
6
+0.8
5 +0.6
+0.4
4
+0.2
f (x, y)
y 0.0
3
−0.2
2 −0.4
−0.6
1
−0.8
0 −1.0
0 1 2 3 4 5 6
x
import graph;
import palette;
import contour;
size(10cm,10cm);
Chapter 8: Base modules 168
pair a=(0,0);
pair b=(2pi,2pi);
int N=200;
int Divs=10;
int divs=1;
defaultpen(1bp);
pen Tickpen=black;
pen tickpen=gray+0.5*linewidth(currentpen);
pen[] Palette=BWRainbow();
bounds range=image(f,Automatic,a,b,N,Palette);
// Major contours
real[] Cvals=uniform(range.min,range.max,Divs);
draw(contour(f,a,b,Cvals,N,operator --),Tickpen+squarecap+beveljoin);
xaxis("$x$",BottomTop,LeftTicks,above=true);
yaxis("$y$",LeftRight,RightTicks,above=true);
palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette,
PaletteTicks("$%+#0.1f$",N=Divs,n=divs,Tickpen,tickpen));
Chapter 8: Base modules 169
+1.0
6
+0.8
5 +0.6
+0.4
4
+0.2
f (x, y)
y 0.0
3
−0.2
2 −0.4
−0.6
1
−0.8
0 −1.0
0 1 2 3 4 5 6
x
Finally, here is an example that illustrates the construction of contours from irregularly
spaced data:
import contour;
size(200);
int n=100;
srand(1);
In the above example, the contours of irregularly spaced data are constructed by first
creating a triangular mesh from an array z of pairs:
size(200);
int np=100;
pair[] points;
int[][] trn=triangulate(points);
The example Gouraudcontour.asy illustrates how to produce color density images over
such irregular triangular meshes. Asymptote uses a robust version of Paul Bourke’s Delau-
nay triangulation algorithm based on the public-domain exact arithmetic predicates written
by Jonathan Shewchuk.
8.37 contour3
This module draws surfaces described as the null space of real-valued functions of (x, y, z)
or real[][][] matrices. Its usage is illustrated in the example file magnetic.asy.
8.38 smoothcontour3
This module, written by Charles Staats, draws implicitly defined surfaces with smooth
appearance. The purpose of this module is similar to that of contour3: given a real-valued
function f (x, y, z), construct the surface described by the equation f (x, y, z) = 0. The
smoothcontour3 module generally produces nicer results than contour3, but takes longer
to compile. Additionally, the algorithm assumes that the function and the surface are both
smooth; if they are not, then contour3 may be a better choice.
To construct the null surface of a function f(triple) or ff(real,real,real) over
box(a,b), use the routine
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);
Chapter 8: Base modules 172
The optional parameter overlapedges attempts to compensate for an artifact that can
cause the renderer to “see through” the boundary between patches. Although it defaults
to false, it should usually be set to true. The example genustwo.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 https://github.com/charlesstaats/
smoothcontour3.
8.39 slopefield
To draw a slope field for the differential equation dy/dx = f (x, y) (or dy/dx = f (x)), use:
Here, the points a and b are the lower left and upper right corners of the rectangle in which
the slope field is to be drawn, nx and ny are the respective number of ticks in the x and
y directions, tickfactor is the fraction of the minimum cell dimension to use for drawing
ticks, and p is the pen to use for drawing the slope fields. The return value is a picture that
can be added to currentpicture via the add(picture) command.
The function
takes a point (c) and a slope field-defining function f and returns, as a path, the curve
passing through that point. The points a and b represent the rectangular boundaries over
which the curve is interpolated.
Both slopefield and curve alternatively accept a function real f(real) that depends
on x only, as seen in this example:
import slopefield;
size(200);
8.40 ode
The ode module, illustrated in the example odetest.asy, implements a number of explicit
numerical integration schemes for ordinary differential equations.
174
9 Command-line options
Type asy -h to see the full list of command-line options supported by Asymptote:
Usage: ../asy [options] [file ...]
A PostScript offset may be specified as a pair (in bp units) with the -O option:
asy -O 0,0 file
The default offset is zero. The pair aligndir specifies an optional direction on the boundary
of the page (mapped to the rectangle [-1,1]×[-1,1]) to which the picture should be aligned;
the default value (0,0) species center alignment.
The -c (command) option may be used to execute arbitrary Asymptote code on the
command line as a string. It is not necessary to terminate the string with a semicolon.
Multiple -c options are executed in the order they are given. For example
asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
produces the output
4
0.841470984807897
and draws a unitsquare of size 100.
The -u (user) option may be used to specify arbitrary Asymptote settings on the com-
mand line as a string. It is not necessary to terminate the string with a semicolon. Multiple
-u options are executed in the order they are given. Command-line code like -u x=sqrt(2)
can be executed within a module like this:
real x;
usersetting();
write(x);
When the -l (listvariables) option is used with file arguments, only global functions
and variables defined in the specified file(s) are listed.
Additional debugging output is produced with each additional -v option:
-v Display top-level module and final output file names.
-vv Also display imported and included module names and final LaTeX and dvips
processing information.
-vvv Also output LaTeX bidirectional pipe diagnostics.
-vvvv Also output knot guide solver diagnostics.
-vvvvv Also output Asymptote traceback diagnostics.
179
10 Interactive mode
Interactive mode is entered by executing the command asy with no file arguments. When
the -multiline option is disabled (the default), each line must be a complete Asymptote
statement (unless explicitly continued by a final backslash character \); it is not necessary
to terminate input lines with a semicolon. If one assigns settings.multiline=true, inter-
active code can be entered over multiple lines; in this mode, the automatic termination of
interactive input lines by a semicolon is inhibited. Multiline mode is useful for cutting and
pasting Asymptote code directly into the interactive input buffer.
Interactive mode can be conveniently used as a calculator: expressions entered at the
interactive prompt (for which a corresponding write function exists) are automatically
evaluated and written to stdout. 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 %
in the next line input at the prompt. For example:
> 2+3
5
> %*4
20
> 1/%
0.05
> sin(%)
0.0499791692706783
> currentpicture
<picture currentpicture>
> %.size(200,0)
>
The % symbol, when used as a variable, is shorthand for the identifier 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:
help view the manual;
erase erase currentpicture;
reset reset the Asymptote environment to its initial state, except for changes to
the settings module (see [settings], page 177), the current directory (see [cd],
page 59), and breakpoints (see Chapter 16 [Debugger], page 186);
input FILE
does an interactive reset, followed by the command include FILE. If the
file name FILE contains nonalphanumeric characters, enclose it with quota-
tion marks. A trailing semi-colon followed by optional Asymptote commands
may be entered on the same line.
quit exit interactive mode (exit is a synonym; the abbreviation q is also accepted
unless there exists a top-level variable named q). A history of the most recent
1000 (this number can be changed with the historylines configuration vari-
able) previous commands will be retained in the file .asy/history in the user’s
Chapter 10: Interactive mode 180
12 Command-Line Interface
Asymptote code may be sent to the http://asymptote.ualberta.ca server directly from
the command line
• SVG output:
curl --data-binary 'import venn;' 'asymptote.ualberta.ca:10007?f=svg' |
display -
• HTML output:
curl --data-binary @/usr/local/share/doc/asymptote/examples/Klein.asy
'asymptote.ualberta.ca:10007' -o Klein.html
• V3D output:
curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=v3d'
-o teapot.v3d
• PDF output with rendered bitmap at 2 pixels per bp:
curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf'
-o teapot.pdf
• PDF output with rendered bitmap at 4 pixels per bp:
curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&render=4'
-o teapot.pdf
• PRC output:
curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&prc'
-o teapot.pdf
• PRC output with rendered preview bitmap at 4 pixels per bp:
curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&prc&render=4'
-o teapot.pdf
The source code for the command-line interface is available at https://github.com/
vectorgraphics/asymptote-http-server.
183
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection '("asy" "-lsp"))
:activation-fn (lsp-activate-on "asymptote")
:major-modes '(asy-mode)
:server-id 'asyls
)
)
• Launch emacs and execute
M-x lsp
184
14 PostScript to Asymptote
The excellent PostScript editor pstoedit (version 3.50 or later; available from https://
sourceforge.net/projects/pstoedit/) includes an Asymptote backend. Unlike virtu-
ally all other pstoedit backends, this driver includes native clipping, even-odd fill rule,
PostScript subpath, and full image support. Here is an example:
asy -V /usr/local/share/doc/asymptote/examples/venn.asy
pstoedit -f asy venn.eps test.asy
asy -V test
If the line widths aren’t quite correct, try giving pstoedit the -dis option. If the fonts
aren’t typeset correctly, try giving pstoedit the -dt option.
185
15 Help
A list of frequently asked questions (FAQ) is maintained at
https://asymptote.sourceforge.io/FAQ
Questions on installing and using Asymptote that are not addressed in the FAQ should be
sent to the Asymptote forum:
https://sourceforge.net/p/asymptote/discussion/409349
Including an example that illustrates what you are trying to do will help you get useful
feedback. LaTeX problems can often be diagnosed with the -vv or -vvv command-line
options. Contributions in the form of patches or Asymptote modules can be posted here:
https://sourceforge.net/p/asymptote/patches
To receive announcements of upcoming releases, please subscribe to Asymptote at
https://sourceforge.net/projects/asymptote/
If you find a bug in Asymptote, please check (if possible) whether the bug is still present in
the latest git developmental code (see Section 2.8 [Git], page 8) before submitting a bug
report. New bugs can be reported at
https://github.com/vectorgraphics/asymptote/issues
To see if the bug has already been fixed, check bugs with Status Closed and recent lines in
https://asymptote.sourceforge.io/ChangeLog
Asymptote can be configured with the optional GNU library libsigsegv, available
from https://www.gnu.org/software/libsigsegv/, which allows one to distinguish user-
generated Asymptote stack overflows (see [stack overflow], page 70) from true segmentation
faults (due to internal C++ programming errors; please submit the Asymptote code that
generates such segmentation faults along with your bug report).
186
16 Debugger
Asymptote now includes a line-based (as opposed to code-based) debugger that can assist
the user in following flow control. To set a break point in file file at line line, use the
command
void stop(string file, int line, code s=quote{});
The optional argument s may be used to conditionally set the variable ignore in plain_
debugger.asy to true. For example, the first 10 instances of this breakpoint will be ignored
(the variable int count=0 is defined in plain_debugger.asy):
stop("test",2,quote{ignore=(++count <= 10);});
To set a break point in file file at the first line containing the string text, use
void stop(string file, string text, code s=quote{});
To list all breakpoints, use:
void breakpoints();
To clear a breakpoint, use:
void clear(string file, int line);
To clear all breakpoints, use:
void clear();
The following commands may be entered at the debugging prompt:
h help;
c continue execution;
i step to the next instruction;
s step to the next executable line;
n step to the next executable line in the current file;
f step to the next file;
r return to the file associated with the most recent breakpoint;
t toggle tracing (-vvvvv) mode;
q quit debugging and end execution;
x exit the debugger and run to completion.
Arbitrary Asymptote code may also be entered at the debugging prompt; however, since
the debugger is implemented with eval, currently only top-level (global) variables can be
displayed or modified.
The debugging prompt may be entered manually with the call
void breakpoint(code s=quote{});
187
17 Acknowledgments
Financial support for the development of Asymptote was generously provided by the Natural
Sciences and Engineering Research Council of Canada, the Pacific Institute for Mathemat-
ical Sciences, and the University of Alberta Faculty of Science.
We also would like to acknowledge the previous work of John D. Hobby, author of the
program MetaPost that inspired the development of Asymptote, and Donald E. Knuth,
author of TEX and MetaFont (on which MetaPost is based).
The authors of Asymptote are Andy Hammerlindl, John Bowman, and Tom Prince.
Sean Healy designed the Asymptote logo. Other contributors include Orest Shardt, Jesse
Frohlich, Michail Vidiassov, Charles Staats, Philippe Ivaldi, Olivier Guibé, Radoslav Mari-
nov, Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, Mar-
tin Wiebusch, Stefan Knorr, Supakorn “Jamie” Rassameemasmuang, Jacob Skitsko, Joseph
Chaumont, and Oliver Cheng. Pedram Emami developed the Asymptote Web Application
hosted at http://asymptote.ualberta.ca:
https://github.com/vectorgraphics/asymptoteWebApplication
188
Index
! :
! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
!= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64, 66 :: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
# <
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
< . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
<= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
%
% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66, 179
%= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 =
== . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64, 66
&
& . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25, 67 >
&& . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
>= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
*
* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41, 66
** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 ?
*= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
+
+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41, 66 ^
++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 ^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66, 67
+= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 ^= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
^^ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
–
- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
-- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13, 67
|
--- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
-= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 || . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
-c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
-l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
-u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
-V . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 10
2
2D graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
.
.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3
.asy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3D graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
3D grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
3D PostScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
/
/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
/= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Index 189
A asinh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
a4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Aspect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
abort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 assert. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27, 28, 74 assignment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
abs2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27, 28 asy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32, 86
absolute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 145 asy-mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
accel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 151 asy.vim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
access. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 asygl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 asyinclude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
aCos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Asymptote Web Application . . . . . . . . . . . . . . . . . . . . . 1
acos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 asymptote.sty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
acosh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 asymptote.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
add . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55, 147 ASYMPTOTE_CONFIG . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
addViews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 atan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
adjust. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 aTan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Ai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 atan2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Ai_deriv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 atanh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Airy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 atleast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64, 78 attach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56, 92, 113
Align . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 autoadjust . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
aligndir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 autoimport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
all . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 automatic scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Allow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 autounravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
and . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 axialshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 axis . . . . . . . . . . . . . . . . . . . . . . . . . . . 128, 131, 156, 157
angle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 azimuth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
animate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 61, 103
animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
annotate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 B
antialias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145, 177 babel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
append . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 76 background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
arc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 147 background color. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Arc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 BackView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
ArcArrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
ArcArrow3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Bar3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
ArcArrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Bars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
ArcArrows3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Bars3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
arclength . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36, 151 barsize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
arcpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 base modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
arctime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36, 151 basealign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 baseline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
arithmetic operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 batch mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 77 beep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
array iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 BeginArcArrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 BeginArcArrow3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Arrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 BeginArrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
arrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15, 21 BeginArrow3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
arrow keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 181 BeginBar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Arrow3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 BeginBar3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
arrowbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 BeginDotMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
arrowhead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 BeginDotMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Arrows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 BeginMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
arrows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 BeginMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Arrows3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 BeginPenMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 BeginPenMargin2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
ascii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 BeginPenMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
asin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 BeginPoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
aSin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Bessel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Index 190
expi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27, 29 G
explicit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 gamma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
explicit casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Gaussrand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
expm1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
exponential integral . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 getc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
extendcap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 getint. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37, 104 getpair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
external . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 getreal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
extrude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 getstring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
E . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 74 gettriple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
globalwrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 61
F glOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145, 177
GNU Scientific Library . . . . . . . . . . . . . . . . . . . . . . . . . 74
fabs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 gouraudshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
face . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Gradient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
factorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 gradient shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Fedora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
feynman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 graph3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
fft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 graphic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21, 177
FFTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 graphical user interface . . . . . . . . . . . . . . . . . . . . . . . 181
file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 186 graphwithderiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 gray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 grayscale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
FillDraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Grayscale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
filldraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47, 123
filloutside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 grid3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
fillrule . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 gs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
filltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 gsl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
find . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30, 78 GSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
findall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 gsOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
firstcut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 GUI installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
fit3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 GUI usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
fixedscaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
floor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 guide3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
flowchart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
flush . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 60
fmod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46, 47 H
font encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 hatch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
fontcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Headlamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
fontsize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 height. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179, 185, 186
format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 177 Hermite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
forum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Hermite(splinetype splinetype . . . . . . . . . . . . . 105
frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 hex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 42
freshnel0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 hexadecimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 41
from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 hidden surface removal . . . . . . . . . . . . . . . . . . . . . . . . 153
FrontView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 histogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
function declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61, 179
function shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 historylines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Function shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 HookHead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69, 74 HookHead3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
functionshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Horizontal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
htmlviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
htmlviewerOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
hyperrefOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Index 193
hypot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
I J
i_scaled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 J . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
ibl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Japanese . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
iconify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
identity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51, 74, 80
identity4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 K
if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 k_scaled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
IgnoreAspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Kate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135, 136 KDE editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
image-based lighting . . . . . . . . . . . . . . . . . . . . . . . . . . 143 keepAspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52, 92
ImageMagick . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 103, 177 keyboard bindings: . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
implicit casts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
implicit linear solver . . . . . . . . . . . . . . . . . . . . . . 104 keyword-only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
implicit scaling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
implicitsurface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 K . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
import. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Korean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
importv3d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
inches. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
incircle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 L
include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 20, 151
including images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17, 20, 110
increasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 labelmargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
inf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 labelpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
inheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 labelpath3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
initialized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 labelx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 labely . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
inline. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Landscape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
InOutTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 language context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 179 language server protocol . . . . . . . . . . . . . . . . . . . . . . 183
input encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 lastcut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30, 76 lasy-mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
inside. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 latex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
insphere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 LATEX NFSS fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
inst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 LaTeX usage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
installation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 latexmk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 latitude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
integer division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 latticeshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
integral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
integrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 leastsquares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99, 129
interactive mode . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 179 Left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
interior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 LeftRight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
interp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 LeftSide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
interpolate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 LeftTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107, 109
intersect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36, 97, 151 LeftView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
intersectionpoint . . . . . . . . . . . . . . . . . . . 37, 97, 151 legend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15, 17, 113
intersectionpoints . . . . . . . . . . . . . . . . . . . . . . 37, 151 Legendre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
intersections . . . . . . . . . . . . . . . . . . . . . . . . 36, 37, 151 length . . . . . . . . . . . . . . . . . . 27, 28, 30, 34, 40, 76, 151
InTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 letter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
intMax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 lexorder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
intMin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 libcurl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
inverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50, 81 libm routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
invert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 libsigsegv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70, 185
invisible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 light. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
isnan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Index 194
M
MacOS X binary distributions . . . . . . . . . . . . . . . . . . . . . 3 N
MacOS X configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
magick. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 61, 103, 177 named arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
makepen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 nan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77, 101 natural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Margin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63, 77
Margin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 newframe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Margins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 newl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
margins. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 newpage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Margins3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 newton. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
mark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 next . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
markangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 nobasealign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
marker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 NoFill. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 noglobalread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
marknodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 nolight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
markuniform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 NoMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
mask . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 NoMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 none . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 None . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
mathematical functions . . . . . . . . . . . . . . . . . . . . . . . . 74 normal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38, 51, 79, 151 nosafe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
maxbound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28, 29 notaknot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
maxtile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
maxtimes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
maxviewport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 NoTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
metallic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 NoTicks3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
MetaPost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
MetaPost ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 nullpen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 53, 54
MetaPost cutafter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
MetaPost cutbefore . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Index 195
O pdflatex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
obj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 pdfreloadOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 pdfviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
oblique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 pdfviewerOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
obliqueX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 PDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
obliqueY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 pen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
obliqueZ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 PenMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
ode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 PenMargin2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
offset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43, 177 PenMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
OmitTick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 PenMargins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
OmitTickInterval . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 PenMargins2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
OmitTickIntervals . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 PenMargins3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
opacity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47, 142 periodic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
OpenGL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 perpendicular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
operator +(...string[] a). . . . . . . . . . . . . . . . . . . . 31 physically based rendering . . . . . . . . . . . . . . . . . 142
operator -- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
operator .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 picture alignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
operator answer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 picture.add . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
operator cast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 picture.addPoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
operator ecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 picture.calculateTransform. . . . . . . . . . . . . . . . . . 53
operator init . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61, 64 picture.fit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 picture.scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 piecewisestraight . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
orient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28, 152 pixel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
orientation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Pl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
orthographic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 plain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 planar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
outformat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 plane. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
outprefix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 planeproject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 177 point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 40, 151
OutTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 polar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
overloading functions. . . . . . . . . . . . . . . . . . . . . . . . . . . 70 polargraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
overwrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 pop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Portrait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142, 144
P postcontrol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 151
postfix operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
pack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
postscript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
packing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
PostScript fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
pad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
PostScript subpath . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 27
pow10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
prc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
paperheight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
papertype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 precontrol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 151
paperwidth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 prefix operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
parallelogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 private . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
parametric surface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
parametrized curve . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 pstoedit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
partialsum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 psviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
patch-dependent colors . . . . . . . . . . . . . . . . . . . . . . . . 143 psviewerOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 33, 141, 163 pt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
path markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 public. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
path[]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
path3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140, 141 P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47, 99 Python usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
PBR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Index 196
Q roundcap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
quadraticroots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 roundedpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
quarticroots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 roundjoin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
quick reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 roundrectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
quit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10, 179, 186 RPM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
quote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 runtime imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
quotient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Russian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
R S
RadialShade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 safe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
radialshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 save . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
RadialShadeDraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 saveline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
radians . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21, 122
radius . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35, 151 scale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43, 51, 122, 150
Rainbow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 scale3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
rand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 scaled graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
randMax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 schur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 scientific graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 scroll. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
reading string arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 search. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
readline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 search paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Seascape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
realDigits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 secondary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
realEpsilon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 secondaryX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
realMax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 secondaryY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
realMin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 seconds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
realmult . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 seek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
realschur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 seekeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 segmentation fault . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 self operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
reflect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Relative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 177
relpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 sgn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
reltime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
remainder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
rename. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51, 150
render . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141, 144, 177 shiftless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 shininess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
resetdefaultpen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 shipout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
rest arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 showtarget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
restore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Si . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
restricted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 signedint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 SimpleHead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
reverse . . . . . . . . . . . . . . . . . . . . . . . . 30, 36, 40, 77, 151 simplex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
rewind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 simplex2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
rfind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 simpson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
rgb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 sin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Riemann zeta function . . . . . . . . . . . . . . . . . . . . . . . . . 74 Sin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Right. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 single precision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
RightSide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 singleint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
RightTicks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107, 109 singlereal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
RightView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 sinh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Rotate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 SixViews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
rotate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 SixViewsFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Rotate(pair z) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 SixViewsUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
round . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 size . . . . . . . . . . . . . . . . . . . . . . 11, 34, 40, 52, 151, 177
Index 197
size3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 T
Slant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
slant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 tab completion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
slice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 tanh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
slide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 target . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
slope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 tell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
slopefield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
smoothcontour3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 tension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25, 140
sncndn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 tensionSpecifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
solid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 tensor product shading . . . . . . . . . . . . . . . . . . . . . . . . . 19
solids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 tensorshade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 tessellation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 tex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57, 177
specular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 TEX fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
specularfactor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 TEX string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
specularpen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 texcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Spline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105, 157 TeXHead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
split . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 TeXHead3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
sqrt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 texpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 22
squarecap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 texpreamble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
texreset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
srand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
textbook graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
stack overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70, 185
tgz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
static. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
thick. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
stats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
thin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
stdin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
stdout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 three. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
step . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 ThreeViews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
stickframe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 ThreeViewsFR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
stop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 ThreeViewsUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Straight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 tick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
straight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34, 151 Ticks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107, 109
strftime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 32 ticks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29, 31 tildeframe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
stroke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18, 20 tile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
strokepath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 tilings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
strptime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 32, 97
struct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Top . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
subpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36, 151 TopView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
subpictures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 trace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
substr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 trailingzero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50, 151
superpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 transform3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Suppress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
SuppressQuiet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 transparent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
surface . . . . . . . . . . . . . . . . . . . . . . . . 141, 143, 157, 158 transpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
SVG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32, 177 trembling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
syzygy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 triangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
triangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
triangulate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
tridiagonal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
trigonometric integrals . . . . . . . . . . . . . . . . . . . . . . . . . 74
triple. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
TrueMargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Index 198
TrueMargin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 W
tube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 161 warn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 WebGL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
type1cm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 whatever . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 69 Wheel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
wheel mouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
U White. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
U3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 white-space string delimiter mode . . . . . . . . . . . . . . 81
undefined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
UnFill. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 windingnumber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
unfill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
uniform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59, 82
uninstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 W . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
unique. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27, 29
unitbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13, 148 X
unitcircle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13, 147 xasy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
unitrand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 xaxis3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
unitsize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 52 xdr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
UNIX binary distributions . . . . . . . . . . . . . . . . . . . . . . 3 xelatex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
unpacking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 xequals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
unravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 XEquals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 xlimits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
update. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
UpsideDown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
XOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
xpart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28, 29
usepackage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
xscale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
user coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
xscale3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
user-defined operators . . . . . . . . . . . . . . . . . . . . . . . . . . 67
xtick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33, 69
XY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150, 151
usleep. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
XYEquals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
XYZero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
XZEquals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
V XZero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
v3d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 XZZero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
variable initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Y
vectorfield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131, 132 yaxis3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
vectorfield3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74, 147
vectorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 YEquals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
verbatim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
yequals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
vertex-dependent colors . . . . . . . . . . . . . . . . . . . . . . . 143
ylimits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Vertical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
ypart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28, 29
Viewport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
yscale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
viewportheight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
yscale3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
viewportmargin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
ytick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
viewportsize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
YX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
viewportwidth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
YZ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
views. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
YZEquals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
vim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
YZero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
virtual functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
YZZero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
void . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Index 199
Z zeroTransform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
zerowinding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
zaxis3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 zeta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
zero_Ai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 zpart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
zero_Ai_deriv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 zscale3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
zero_Bi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
zero_Bi_deriv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 ZX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
zero_J. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 ZY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151