Asymptote: Reference

Asymptote (Vector Graphics Language)
Getting Started - Basics - Drawing - Labeling - Filling - Useful functions - Examples - Macros and Packages

Help - Reference - Advanced Asymptote - 3D Graphics - CSE5 Package - How to

Points

A point is associated with a cartesian coordinate pair in Asymptote. There are two useful functions that allow one to use polar coordinates as well:

 dir(theta)

returns the point (cos(theta),sin(theta)) where theta is in degrees, and

 expi(theta)

returns the complex number $e^{i\theta}$, i.e. (cos(theta),sin(theta)) where theta is measured in radians.

Paths

A path (or guide - see Variables and Data Types for the difference) in Asymptote is simply a piecewise cubic function of a parameter $t$, parameterized as $t$ ranges from $0$ to the number of nodes (say $n$) that determine the path. The most basic way to make paths is by joining points (which can be thought of as paths with length 0) or paths p, q together with one of the following operators:

p--q
p..q
p^^q

The first (--) connects the end of path p to the beginning of q with a straight line. The second (..) connects them with a Bezier cubic spline interpolation so that paths are joined smoothly. The third (^^) actually does not connect the paths at all, but rather re-parameterizes so that the two paths are treated as one. The symbol cycle connected to a path tells Asymptote to form a cyclic path by joining the endpoint with $t=n$ to that with $t=0$.

The following example includes the benefits of all three types of path joins:

unitsize(1inch);
path T,ct,tt;
T=(0,0)--(1,0)--(1/2,sqrt(3)/2)--cycle;
ct=(0,0)..(1,0)--(1/2,sqrt(3)/2)..cycle;
tt=shift(sqrt(3)/6*dir(30))*(scale(1/2)*T);
draw(T);
draw(shift(2*right)*ct);
fill(reverse(shift(4*right)*tt)^^(shift(4*right)*T),blue);

outputs: [asy] unitsize(1inch); path T,ct,tt; T=(0,0)--(1,0)--(1/2,sqrt(3)/2)--cycle; ct=(0,0)..(1,0)--(1/2,sqrt(3)/2)..cycle; tt=shift(sqrt(3)/6*dir(30))*(scale(1/2)*T); draw(T); draw(shift(2*right)*ct); fill(reverse(shift(4*right)*tt)^^(shift(4*right)*T),blue); [/asy]

Pens and Coloring

A pen is just that - the style with which Asymptote draws your paths or pictures. Pens can have various colors, dash patterns (linetypes), and linewidths. The following table gives a variety of examples of pen types and their output:

Table2.gif

We can also add pens with the + operator. For example, the command

 draw((0,0)--(100,100),orange+dashed+linewidth(1));

will produce the image

Pen14.gif

The default pen has linetype solid="", linewidth .5, and color black.

Basic drawing commands

Asymptote has four basic drawing commands: draw, fill, clip, and label. The most important of these is draw.

Draw

The function draw can take many arguments. The following is the structure of a draw command, where anything with = denotes the default value:

 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);

So with draw, you can draw path g to the picture pic along with a string label L, with pen p, etc. Of course, most of this is unnecessary for a basic diagram. The most important thing to notice is that the only non-optional argument of draw is the path g. The command draw(g); where g is a path simply draws the path on top of your current picture.

Fill

The structure of fill is much simpler than that of draw:

  void fill(picture pic=currentpicture, path g,pen p=currentpen);

This fills a cyclic path g in picture pic (see the section on Paths above) with a specified pen p (most often a color - see Pens and Coloring above). For example, the command

fill((0,0)--(0,1)--(1,1)--(1,0)--cycle,red);

where unitsize is 1 inch outputs:

Fill1.gif

Clip

The structure of clip is also simple:

 void clip(picture pic=currentpicture, path g, pen p=currentpen);

This crops a picture so that the boundary is the given path g, with fill rule p. A fill rule tells when a point is inside the boundary of the path; the default fill rule, zerowinding or fillrule(0), checks to see if the number of horizontal intersections from the point to the right is equal to the number of downward intersections with the path. Another useful fill rule is evenodd, or fillrule(1), which checks if the total number of such intersections is even.

For example, say we drew a smiley:

import graph;
unitsize(1inch);
filldraw(Circle((0,0),1),yellow,black);
fill(Circle((-.3,.4),.1),black);
fill(Circle((.3,.4),.1),black);
draw(Arc((0,0),.5,-140,-40),blue);

and we wanted to clip this to a star-shaped boundary. Then we add the lines:

path star;
star=expi(0)--(scale((3-sqrt(5))/2)*expi(pi/5))--expi(2*pi/5)--
     (scale((3-sqrt(5))/2)*expi(3*pi/5))--expi(4pi/5)--
     (scale((3-sqrt(5))/2)*expi(5*pi/5))--expi(6*pi/5)--
     (scale((3-sqrt(5))/2)*expi(7*pi/5))--expi(8*pi/5)--
     (scale((3-sqrt(5))/2)*expi(9*pi/5))--cycle;
clip(currentpicture,scale(1.7)*rotate(18)*star);
draw(scale(1.7)*rotate(18)*star);

and we get:

Clip1.gif

If we wanted to clip to a pattern in an alternating fashion, we could use the evenodd fill rule:

path zones[];
zones=(Circle((0,0),.2)^^Circle((0,0),.6)^^Circle((0,0),.8)^^Circle((0,0),1));
clip(currentpicture,zones,evenodd);

This produces:

Clip2.gif

Label

Label is used for, well, labeling your diagram.

Structure:

void label(picture pic=currentpicture, Label L, pair position,
          align align=NoAlign, pen p=nullpen, filltype filltype=NoFill);

This places a label L (usually a string, which can include LaTeX code!) at the point position, aligned by default so that the center of the label is at the position, with optional pen and filltype for its bounding box. The alignment options, however, can be very useful; any pair can be given as a direction for alignment, and the built-in alignment directions are the compass directions N, E, S, W, NE, NW, SE, SW, ENE, etc. For example, the image below:

Label1.gif

was produced by 8 double commands of the form

 label("S",(1,0),S);
 dot((1,0));

See also: Asymptote:Labeling

Pictures

The basic drawing commands all draw onto pictures, the default picture being currentpicture, which is the one that you see when you build your image. However, you can define a new picture in order to treat several drawn parts as a single object, which can be shifted and transformed as a whole relative to currentpicture. One picture (pic1) can be added to another (pic2) with the command add(pic2,pic1), and by default add(pic) simply adds pic to currentpicture. For example:

 picture pic;
 size(3cm);
 draw(pic,unitsquare);
 draw(pic,unitcircle);
 add(shift(3*right)*pic);
 draw(unitsquare);
 draw(unitcircle);

will display:

Picture1.gif

Transforms

Transforms are objects that can be applied to pairs, paths, pictures, and other transforms by the * operator. The most commonly used transforms are: Transforms.gif

Another useful transform that is not listed above:

reflect(pair a, pair b); reflects about the line a--b.

Next: Examples