You may use libplot
to produce vector graphics animations on any
Plotter that does real-time plotting (i.e., an X, X Drawable,
Tektronix, or Metafile Plotter). By definition, the `frames' in any
page of graphics are separated by invocations of erase
. So
the graphics display will be cleared after each frame. If successive
frames differ only slightly, a smooth animation will result.
The following is a sample application, written in C, that produces an animation for the X Window System. It displays a `drifting eye'. As the eye drifts across a popped-up window from left to right, it slowly rotates. After the eye has drifted across twice, the window will vanish.
#include <stdio.h> #include <plot.h> int main () { int handle, i = 0, j; /* set Plotter parameters */ pl_parampl ("BITMAPSIZE", "300x150"); pl_parampl ("VANISH_ON_DELETE", "yes"); pl_parampl ("USE_DOUBLE_BUFFERING", "yes"); /* create an X Plotter with the specified parameters */ if ((handle = pl_newpl ("X", 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_space (0, 0, 299, 149); /* specify user coordinate system */ pl_linewidth (8); /* line thickness in user coordinates */ pl_filltype (1); /* objects will be filled */ pl_bgcolorname ("saddle brown"); /* background color for the window*/ for (j = 0; j < 300; j++) { pl_erase (); /* erase window */ pl_pencolorname ("red"); /* choose red pen, with cyan filling */ pl_fillcolorname ("cyan"); pl_ellipse (i, 75, 35, 50, i); /* draw an ellipse */ pl_colorname ("black"); /* choose black pen, with black filling */ pl_circle (i, 75, 12); /* draw a circle [the pupil] */ i = (i + 2) % 300; /* shift rightwards */ } 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 pl_parampl
several times to set device driver parameters, and then calls
pl_newpl
to create an X Plotter. The X Plotter window
will have size 300x150 pixels. This window will vanish when the Plotter
is deleted. If the VANISH_ON_DELETE
parameter were not set
to "yes", the window would remain on the screen until removed by the
user (by typing `q' in it, or by clicking with a mouse).
Setting the parameter USE_DOUBLE_BUFFERING
to "yes" requests that
double buffering be used. This is very important if you wish to produce
a smooth animation, with no jerkiness. Normally, an X Plotter draws
graphics into a window in real time, and erases the window when
pl_erase
is called. But if double buffering is used, each frame
of graphics is written into an off-screen buffer, and is copied into the
window, pixel by pixel, when pl_erase
is called or the Plotter is
closed. This is a bit counterintuitive, but is exactly what is needed
for smooth animation.
After the Plotter is created, it is selected for use and opened. When
pl_openpl
is called, the window pops up, and the animation
begins. In the body of the for loop there is a call to
pl_erase
, and also a sequence of libplot
operations that
draws the eye. The pen color and fill color are changed twice with each
passage through the loop. You may wish to experiment with the animation
parameters to produce the best effects on your video hardware.
The locations of the objects that are plotted in the animation are
expressed in terms of user coordinates, not pixel coordinates. But the
call to pl_space
defines user and pixel coordinates to be
effectively the same. User coordinates are chosen so that the lower
left corner is (0,0) and the upper right corner is (299,149). Since
this agrees with the window size, individual pixels may be addressed in
terms of integer user coordinates. For example,
pl_point(299,149)
would set the pixel in the upper right hand
corner of the window to the current pen color.
The following is another sample animation, this time of a rotating letter `A'.
#include <stdio.h> #include <plot.h> int main() { int handle, angle = 0; /* set Plotter parameters */ pl_parampl ("BITMAPSIZE", "300x300"); pl_parampl ("BG_COLOR", "blue"); /* background color for window */ pl_parampl ("USE_DOUBLE_BUFFERING", "yes"); /* create an X Plotter with the specified parameters */ handle = pl_newpl ("X", stdin, stdout, stderr); pl_selectpl (handle); /* open X Plotter, initialize coordinates, pen, and font */ pl_openpl (); pl_fspace (0.0, 0.0, 1.0, 1.0); /* use normalized coordinates */ pl_pencolorname ("white"); pl_ffontsize (1.0); pl_fontname ("NewCenturySchlbk-Roman"); pl_fmove (.50,.50); /* move to center */ while (1) /* loop endlessly */ { pl_erase (); pl_textangle (angle++); /* set new rotation angle */ pl_alabel ('c', 'c', "A"); /* draw a centered `A' */ } pl_closepl(); /* close Plotter */ pl_selectpl (0); /* select default Plotter */ pl_deletepl (handle); /* delete Plotter we used */ return 0; }
This animation serves as a good test of the capabilities of an X Window System display. On a modern X11R6 display, animation will be smooth and fast. That is because X11R6 displays can rasterize individual characters from a font without rasterizing the entire font. 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"). If that too fails, it will use a default Hershey vector font ("HersheySerif") instead.
Animations that use Hershey fonts are normally faster than ones that use Postscript fonts or other X Window System fonts, since the Hershey fonts are constructed from line segments. Rasterizing line segments can be done rapidly. But if you use a scalable font such as "NewCenturySchlbk-Roman" or "utopia-medium-r-normal", you will notice that the rotation speeds up after the letter `A' has rotated through 360 degrees. That is because the `A' at angles past 360 degrees has already been rasterized.
Go to the first, previous, next, last section, table of contents.