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. A frame may be erased with the erase(frame)
routine.
The functions pair min(frame)
and pair max(frame)
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
align
, in a manner analogous to the align
argument of
label
(see label), is returned by
frame align(frame f, pair align);
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=x, 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 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
.
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.
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 orientation 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 the boundary with fillpen
;
otherwise with drawpen
. An optional margin of
xmargin
and ymargin
can be specified.
Fill
¶Fill the interior.
Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
¶If p
is nullpen
, fill with the drawing pen;
otherwise fill with pen p
. An optional margin of
xmargin
and ymargin
can be specified.
NoFill
¶Do not fill.
Draw
Draw only the boundary.
Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
¶If p
is nullpen
, draw the boundary with the drawing pen;
otherwise draw with pen p
. An optional margin of
xmargin
and ymargin
can be specified.
UnFill
¶Clip the region.
UnFill(real xmargin=0, real ymargin=xmargin)
¶Clip the region and surrounding margins xmargin
and ymargin
.
RadialShade(pen penc, pen penr)
¶Fill varying radially from penc
at the center of the bounding
box to penr
at the edge.
RadialShadeDraw(real xmargin=0, real ymargin=xmargin, pen penc,
¶pen penr, pen drawpen=nullpen)
Fill with RadialShade and draw the boundary.
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
pen p
, using the function bbox(p,Fill)
.
To pad a picture to a precise size in both directions, fit the picture to a frame using the function
frame pad(picture pic=currentpicture, real xsize=pic.xsize, real ysize=pic.ysize, filltype filltype=NoFill);
The functions
pair min(picture pic, user=false); pair max(picture pic, user=false); pair size(picture pic, user=false);
calculate the bounds that picture pic
would
have if it were currently fit to a frame using its default size specification.
If user
is false
the returned value is in
PostScript
coordinates, otherwise it is in user coordinates.
The function
pair point(picture pic=currentpicture, pair dir, bool user=true);
is a convenient way of determining the point on the bounding box of
pic
in the direction dir
relative to its center, ignoring
the contributions from fixed-size 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 Graphical User Interface), 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 label). 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 and image. 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); 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
:
void attach(picture dest=currentpicture, frame src, pair position=0, bool group=true, filltype filltype=NoFill, bool above=true); void attach(picture dest=currentpicture, frame src, pair position, pair align, bool group=true, filltype filltype=NoFill, bool above=true);
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
one of the routines
void postscript(picture pic=currentpicture, string s); void postscript(picture pic=currentpicture, string s, pair min, pair max)
Here min
and max
can be used to specify explicit bounds
associated with the resulting PostScript
code.
Verbatim TeX commands can be inserted in the intermediate
LaTeX
output file with one of the functions
void tex(picture pic=currentpicture, string s); void tex(picture pic=currentpicture, string s, pair min, pair max)
Here min
and max
can be used to specify explicit bounds
associated with the resulting TeX code.
To issue a global TeX command (such as a TeX macro definition) in the TeX preamble (valid for the remainder of the top-level module) use:
void texpreamble(string s);
The TeX environment can be reset to its initial state, clearing all macro definitions, with the function
void texreset();
The routine
void usepackage(string s, string options="");
provides a convenient abbreviation for
texpreamble("\usepackage["+options+"]{"+s+"}");
that can be used for importing LaTeX
packages.