The following is a sample application, written in C, that invokes
libplot
operations to draw vector graphics. It draws an
intricate and beautiful path (Bill Gosper's "C" curve, discussed
as Item #135 in HAKMEM, MIT Artificial Intelligence Laboratory
Memo #239, 1972). As the numeric constant MAXORDER
(here
equal to 12) is increased, the path will take on the shape of a
curly letter "C", which is the envelope of a myriad of epicyclic
octagons.
#include <stdio.h> #include <plot.h> #define MAXORDER 12 void draw_c_curve (double dx, double dy, int order) { if (order >= MAXORDER) pl_fcontrel (dx, dy); /* continue path along (dx, dy) */ else { draw_c_curve (0.5 * (dx - dy), 0.5 * (dx + dy), order + 1); draw_c_curve (0.5 * (dx + dy), 0.5 * (dy - dx), order + 1); } } int main () { int handle; /* set a Plotter parameter */ pl_parampl ("PAGESIZE", "letter"); /* create a Postscript Plotter that writes to standard output */ if ((handle = pl_newpl ("ps", stdin, stdout, stderr)) < 0) { fprintf (stderr, "Couldn't create Plotter\n"); return 1; } pl_selectpl (handle); /* select the Plotter for use */ if (pl_openpl () < 0) /* open Plotter */ { fprintf (stderr, "Couldn't open Plotter\n"); return 1; } pl_fspace (0.0, 0.0, 1000.0, 1000.0); /* specify user coor system */ pl_flinewidth (0.25); /* line thickness in user coordinates */ pl_pencolorname ("red"); /* path will be drawn in red */ pl_erase (); /* erase Plotter's graphics display */ pl_fmove (600.0, 300.0); /* position the graphics cursor */ draw_c_curve (0.0, 400.0, 0); if (pl_closepl () < 0) /* close Plotter */ { fprintf (stderr, "Couldn't close Plotter\n"); return 1; } pl_selectpl (0); /* select default Plotter */ if (pl_deletepl (handle) < 0) /* delete Plotter we used */ { fprintf (stderr, "Couldn't delete Plotter\n"); return 1; } return 0; }
As you can see, this application begins by calling the pl_newpl
function to create a Postscript Plotter. The Postscript Plotter will
produce output for a US letter-sized page, though any other standard
page size, e.g., "a4", could be substituted. This would be arranged by
altering the call to pl_parampl
. The PAGESIZE
parameter
is one of several Plotter parameters that an application programmer may
set by calling pl_parampl
. For a complete list, see section Device driver parameters.
After the Plotter is created, the application selects it for use,
opens it, and draws the "C" curve recursively. The drawing of
the curve is accomplished by calling the pl_fmove
function to
position the Plotter's graphics cursor, and then calling
draw_c_curve
. This subroutine repeatedly calls
pl_fcontrel
. The pl_fcontrel
function continues a path by
adding a line segment to it. The endpoint of each line segment is
specified in relative coordinates, i.e., as an offset from the previous
cursor position. After the "C" curve is drawn, the Plotter is
closed. A Postscript file is written to standard output when
pl_deletepl
is called to delete the Plotter.
Specifying "pnm", "gif", "ai", "fig", "pcl", "hpgl", "tek", or "meta" as
the first argument in the call to pl_newpl
, instead of "ps",
would yield a Plotter that would write graphics to standard output in
the specified format, instead of Postscript. The PAGESIZE
parameter is relevant to the "ai", "fig", "pcl", and "hpgl" output
formats, but is ignored for the others. Specifying "meta" as the
Plotter type may be useful if you wish to avoid recompilation for
different output devices. Graphics metafile output may be piped to the
plot
utility and converted to any other supported output format,
or displayed in an X window. See section The plot
Program.
If "X" were specified as the first argument of pl_newpl
, the
curve would be drawn in a popped-up X window, and the output stream
argument would be ignored. Which X Window System display the window
would pop up on would be determined by the DISPLAY
parameter,
or if that parameter were not set, by the DISPLAY
environment
variable. The size of the X window would be determined by the
BITMAPSIZE
parameter, or if that parameter were not set, by the
BITMAPSIZE
environment variable. The default value is "570x570".
For the "pnm" and "gif" Plotter types, the interpretation of
BITMAPSIZE
is similar.
You could also specify "Xdrawable" as the Plotter type. For you to make
this work, you would need to know a bit about X Window System
programming. You would need to create at least one X drawable
(i.e., window or a pixmap), and by invoking the pl_parampl
function before newpl
is called, set it as the value of the
parameter XDRAWABLE_DRAWABLE1
or XDRAWABLE_DRAWABLE2
. For
the parameters that affect X Drawable Plotters, see section Device driver parameters.
The following is another sample application, written in C, that invokes
libplot
operations to draw vector graphics. It draws a
spiral consisting of elliptically boxed text strings, each of which
reads "GNU libplot!". This figure will be sent to standard output in
Postscript format.
#include <stdio.h> #include <plot.h> #include <math.h> #define SIZE 100.0 /* nominal size of user coordinate frame */ #define EXPAND 2.2 /* expansion factor for elliptical box */ void draw_boxed_string (char *s, double size, double angle) { double true_size, width; pl_ftextangle (angle); /* text inclination angle (degrees) */ true_size = pl_ffontsize (size); /* choose font size */ width = pl_flabelwidth (s); /* compute width of text string */ pl_fellipserel (0.0, 0.0, /* draw surrounding ellipse */ EXPAND * 0.5 * width, EXPAND * 0.5 * true_size, angle); pl_alabel ('c', 'c', s); /* draw centered text string */ } int main() { int handle, i; /* set a Plotter parameter */ pl_parampl ("PAGESIZE", "letter"); /* create a Postscript Plotter that writes to standard output */ if ((handle = pl_newpl ("ps", stdin, stdout, stderr)) < 0) { fprintf (stderr, "Couldn't create Plotter\n"); return 1; } pl_selectpl (handle); /* select the Plotter for use */ if (pl_openpl () < 0) /* open Plotter */ { fprintf (stderr, "Couldn't open Plotter\n"); return 1; } pl_fspace (-(SIZE), -(SIZE), SIZE, SIZE); /* spec. user coor system */ pl_pencolorname ("blue"); /* pen color will be blue */ pl_fillcolorname ("white"); pl_filltype (1); /* ellipses will be filled with white */ pl_fontname ("NewCenturySchlbk-Roman"); /* choose a Postscript font */ for (i = 80; i > 1; i--) /* loop through angles */ { double theta, radius; theta = 0.5 * (double)i; /* theta is in radians */ radius = SIZE / pow (theta, 0.35); /* this yields a spiral */ pl_fmove (radius * cos (theta), radius * sin (theta)); draw_boxed_string ("GNU libplot!", 0.04 * radius, (180.0 * theta / M_PI) - 90.0); } if (pl_closepl () < 0) /* close Plotter */ { fprintf (stderr, "Couldn't close Plotter\n"); return 1; } pl_selectpl (0); if (pl_deletepl (handle) < 0) /* delete Plotter we used */ { fprintf (stderr, "Couldn't delete Plotter\n"); return 1; } return 0; }
This example shows what is involved in plotting a text string or text
strings. First, the desired font must be retrieved. A font is
fully specified by calling pl_fontname
, pl_fontsize
, and
pl_textangle
, or their floating point counterparts
pl_ffontname
, pl_ffontsize
, and pl_ftextangle
.
Since these three functions may be called in any order, each of them
returns the size of the font that it selects, as a convenience to the
programmer. This may differ slightly from the size specified in the
most recent call to pl_fontsize
or pl_ffontsize
, since
many Plotters have only a limited repertory of fonts. The above example
plots each text string in the "NewCenturySchlbk-Roman" font, which is
available on Postscript Plotters. See section Available text fonts.
If you replace "ps" by "X" in the call to pl_newpl
, an X
Plotter rather than a Postscript Plotter will be used, and the spiral
will be drawn in a popped-up X window. If your X display does
not support the "NewCenturySchlbk-Roman" font, you may substitute any
other scalable font, such as the widely available
"utopia-medium-r-normal". For the format of font names, see section Available text fonts for the X Window System. If the X Plotter is unable to retrieve the font
you specify, it will first attempt to use a default scalable font
("Helvetica"), and if that fails, use a default Hershey vector font
("HersheySerif") instead. Hershey fonts are constructed from line
segments, so each built-in Hershey font is available on all types of
Plotter.
If you are using an older (pre-X11R6) X Window System display, you will find that retrieving a scalable font is a time-consuming operation. The above example may run slowly on some older X displays, since a new font must be retrieved before each text string is drawn. That is because each text string has a different angle of inclination. It is possible to retrieve individual characters from an X11R6 display, rather than retrieving an entire rasterized font. If this feature is available, the X Plotter will automatically take advantage of it to save time.
Go to the first, previous, next, last section, table of contents.