Next: , Previous: Transforms, Up: Programming


4.5 Frames and pictures

frame
Frames are canvases for drawing in PostScript coordinates. While working with frames directly is occasionally necessary for constructing deferred drawing routines, pictures are usually more convenient to work with. The implicit initializer for frames is newframe. The function bool empty(frame f) returns true only if the frame f is empty. The functions min(frame f) and max(frame f) return the (left,bottom) and (right,top) coordinates of the frame bounding box, respectively. The contents of frame src may be appended to frame dest with the command
     
     void add(frame dest, frame src);
or prepended with
     
     void prepend(frame dest, frame src);
A frame obtained by aligning frame f in the direction dir, in a manner analogous to the align argument of label (see label), is returned by
     
     frame align(frame f, pair dir);

picture
Pictures are high-level structures (see Structures) defined in the module plain that provide canvases for drawing in user coordinates. The default picture is called currentpicture. A new picture can be created like this:
     
     picture pic;
Anonymous pictures can be made by the expression new picture.

The size routine specifies the dimensions of the desired picture:

     
     void size(picture pic=currentpicture, real x, real y,
               bool keepAspect=Aspect);

If the x and y sizes are both 0, user coordinates will be interpreted as PostScript coordinates. In this case, the transform mapping pic to the final output frame is identity().

If exactly one of x or y is 0, no size restriction is imposed in that direction; it will be scaled the same as the other direction.

If keepAspect is set to Aspect or true, the picture will be scaled with its aspect ratio preserved such that the final width is no more than x and the final height is no more than y.

If keepAspect is set to IgnoreAspect or false, the picture will be scaled in both directions so that the final width is x and the height is y.

To ensure that each dimension is no more than size, use the routine

     
     void size(picture pic=currentpicture, real size,
               bool keepAspect=Aspect);

A picture can be fit to a frame and converted into a PostScript image by calling the function shipout:

     
     void shipout(string prefix=defaultfilename, picture pic,
                  real unitsize=0, frame preamble=patterns,
                  orientation orientation=Portrait,
                  string format="", bool wait=NoWait, bool quiet=false);
     void shipout(string prefix=defaultfilename, real unitsize=0, 
                  orientation orientation=Portrait,
                  string format="", bool wait=NoWait, bool quiet=false);
A shipout() command is added implicitly at file exit if no previous shipout commands have been executed.

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 default page orientation is Portrait. To output in landscape mode, simply replace the call to shipout() with:

     
     shipout(Landscape);

To rotate in the other direction, replace Landscape with Seascape.

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:
Fill
Fill with the pen used to draw the boundary.
Fill(pen p=nullpen)
If p is nullpen, fill with the pen used to draw the boundary; otherwise fill with pen p.


NoFill
Do not fill; draw only the boundary.


UnFill
Clip the region.


UnFill
Clip the region and surrounding margins xmargin and ymargin.


RadialShade
Fill varying radially from penc at the center of the bounding box to penr at the edge.

For example, to draw a bounding box around a picture with a 0.25 cm margin and output the resulting frame, use the command:

     
     shipout(bbox(0.25cm));
A picture may be fit to a frame with the background color of pen p with the function bbox(p,Fill).

The function

     
     pair point(picture pic=currentpicture, pair dir);
is a convenient way of determining the point on the boundary of the user-coordinate bounding box of pic in the direction dir relative to its center.

The member functions pic.min() and pic.max() calculate the PostScript bounds that picture pic would have if it were currently fit to a frame using its default size specification.

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 put=Above);
     void add(picture dest, picture src, bool group=true,
              filltype filltype=NoFill, bool put=Above);

The first example adds src to currentpicture; the second one adds src to dest. The group option specifies whether or not the graphical user interface xasy should treat all of the elements of src as a single entity (see GUI), filltype requests optional background filling or clipping, and put specifies whether to add src above or below existing objects.

There are also routines to add a picture or frame src specified in postscript coordinates to another picture about the user coordinate origin:

     
     void add(pair origin, picture dest, picture src, bool group=true,
              filltype filltype=NoFill, bool put=Above);
     void add(pair origin, picture src, bool group=true,
              filltype filltype=NoFill, bool put=Above);
     void add(pair origin=0, picture dest=currentpicture, frame src,
              bool group=true, filltype filltype=NoFill,
              bool put=Above);
     void add(pair origin=0, picture dest=currentpicture, frame src,
              pair dir, bool group=true, filltype filltype=NoFill,
              bool put=Above);

The dir 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 label). Illustrations of frame alignment can be found in the examples errorbars and image. If you want to align 3 or more subpictures, group them two at a time:

     picture pic1;
     real size=50;
     size(pic1,size);
     fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
     
     picture pic2;
     size(pic2,size);
     fill(pic2,unitcircle,green);
     
     picture pic3;
     size(pic3,size);
     fill(pic3,unitsquare,blue);
     
     picture pic;
     add(pic,pic1.fit(),N);
     add(pic,pic2.fit(),10S);
     
     add(pic.fit(),N);
     add(pic3.fit(),10S);
     
subpictures.png

Alternatively, one can use attach to automatically increase the size of picture dest to accommodate adding a frame src about the user coordinate origin:

     
     void attach(pair origin=0, picture dest=currentpicture,
                frame src, bool group=true,
                filltype filltype=NoFill, bool put=Above);
     void attach(pair origin=0, picture dest=currentpicture, frame src,
                 pair dir, bool group=true, filltype filltype=NoFill,
                 bool put=Above);

To draw or fill a box or ellipse around a label, frame, or picture, use one of the routines (the first two routines for convenience also return the boundary as a guide):

     
     guide box(frame f, Label L="", real xmargin=0,
               real ymargin=xmargin, pen p=currentpen,
               filltype filltype=NoFill, bool put=Above);
     guide ellipse(frame f, Label L="", real xmargin=0,
                   real ymargin=xmargin, pen p=currentpen,
                   filltype filltype=NoFill, bool put=Above);
     void box(picture pic=currentpicture, Label L,
              real xmargin=0, real ymargin=xmargin, pen p=currentpen,
              filltype filltype=NoFill, bool put=Above);

To erase the contents of a picture (but not the size specification), use the function

     
     void erase(picture pic=currentpicture);

To save a snapshot of currentpicture, currentpen, and currentprojection, use the function save().

To restore a snapshot of currentpicture, currentpen, and currentprojection, use the function restore().

Many further examples of picture and frame operations are provided in the base module plain.

It is possible to insert verbatim PostScript commands in a picture with the routine

     
     void postscript(picture pic=currentpicture, string s);

Verbatim TeX commands can be inserted in the intermediate LaTeX output file with the function

     
     void tex(picture pic=currentpicture, string s);

To issue a global TeX command (such as a TeX macro definition) in the TeX preamble (valid for the remainder of the top-level module) use:

     
     void texpreamble(string s);