| www.delorie.com/gnu/docs/plotutils/plotutils_55.html | search |
![]() Buy GNU books! | |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You may use GNU libplot to produce vector graphics animations on
any Plotter that does real-time plotting (i.e., an X, X
Drawable, ReGIS, 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 ()
{
plPlotter *plotter;
plPlotterParams *plotter_params;
int i = 0, j;
/* set Plotter parameters */
plotter_params = pl_newplparams ();
pl_setplparam (plotter_params, "BITMAPSIZE", "300x150");
pl_setplparam (plotter_params, "VANISH_ON_DELETE", "yes");
pl_setplparam (plotter_params, "USE_DOUBLE_BUFFERING", "yes");
/* create an X Plotter with the specified parameters */
if ((plotter = pl_newpl_r ("X", stdin, stdout, stderr,
plotter_params)) == NULL)
{
fprintf (stderr, "Couldn't create Plotter\n");
return 1;
}
if (pl_openpl_r (plotter) < 0) /* open Plotter */
{
fprintf (stderr, "Couldn't open Plotter\n");
return 1;
}
pl_fspace_r (plotter,
-0.5, -0.5, 299.5, 149.5); /* set user coor system */
pl_linewidth_r (plotter, 8); /* set line thickness */
pl_filltype_r (plotter, 1); /* objects will be filled */
pl_bgcolorname_r (plotter, "saddle brown"); /* set background color */
for (j = 0; j < 300; j++)
{
pl_erase_r (plotter); /* erase window */
pl_pencolorname_r (plotter, "red"); /* use red pen */
pl_fillcolorname_r (plotter, "cyan"); /* use cyan filling */
pl_ellipse_r (plotter, i, 75, 35, 50, i); /* draw an ellipse */
pl_colorname_r (plotter, "black"); /* use black pen and filling */
pl_circle_r (plotter, i, 75, 12); /* draw a circle [the pupil] */
i = (i + 2) % 300; /* shift rightwards */
}
if (pl_closepl_r (plotter) < 0) /* close Plotter */
{
fprintf (stderr, "Couldn't close Plotter\n");
return 1;
}
if (pl_deletepl_r (plotter) < 0) /* delete Plotter */
{
fprintf (stderr, "Couldn't delete Plotter\n");
return 1;
}
return 0;
}
|
As you can see, this application begins by calling pl_setplparam
several times to set Plotter parameters, and then calls
pl_newpl_r 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_r 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_r 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_r is called, the window pops up, and the animation
begins. In the body of the for loop there is a call to
pl_erase_r, 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 positions of the objects that are plotted in the animation are
expressed in terms of user coordinates, not pixel coordinates. But the
call to pl_fspace_r defines user and pixel coordinates to be
effectively the same. User coordinates are chosen so that the lower
left corner of the rectangle mapped to the X window is
(-0.5,-0.5) and the upper right corner is (299.5,149.5).
Since this agrees with the window size, individual pixels may be
addressed in terms of integer user coordinates. For example,
pl_point_r(plotter,299,149) would set the pixel in the upper
right 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()
{
plPlotter *plotter;
plPlotterParams *plotter_params;
int angle = 0;
/* set Plotter parameters */
plotter_params = pl_newplparams ();
pl_setplparam (plotter_params, "BITMAPSIZE", "300x300");
pl_setplparam (plotter_params, "USE_DOUBLE_BUFFERING", "yes");
pl_setplparam (plotter_params, "BG_COLOR", "blue");
/* create an X Plotter with the specified parameters */
plotter = pl_newpl_r ("X", stdin, stdout, stderr, plotter_params);
/* open X Plotter, initialize coordinates, pen, and font */
pl_openpl_r (plotter);
pl_fspace_r (plotter, 0.0, 0.0, 1.0, 1.0); /* use normalized coors */
pl_pencolorname_r (plotter, "white");
pl_ffontsize_r (plotter, 1.0);
pl_fontname_r (plotter, "NewCenturySchlbk-Roman");
pl_fmove_r (plotter, 0.5, 0.5); /* move to center */
while (1) /* loop endlessly */
{
pl_erase_r (plotter);
pl_textangle_r (plotter, angle++); /* set new rotation angle */
pl_alabel_r (plotter, 'c', 'c', "A"); /* draw a centered `A' */
}
pl_closepl_r (plotter); /* close Plotter */
pl_deletepl_r (plotter); /* delete Plotter */
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 A.3 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.
If you are writing an application that performs a lengthy sequence of
drawing operations on an X Plotter, you may find it useful to set
the Plotter parameter X_AUTO_FLUSH to "no". By default, an X
Plotter flushes all graphics to its X Window System display after
each drawing operation. This flushing ensures that graphics are visible
to the user immediately after they are drawn. However, it sometimes
considerably slows down the rendering process. For additional details
on Plotter parameters, see 9.5 Plotter parameters.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| webmaster donations bookstore | delorie software privacy |
| Copyright © 2003 by The Free Software Foundation | Updated Jun 2003 |