PostScript Animations



PostScript is an excellent programming language for creating animations of search processes and eventually showing solutions. The core idea is to use a PostScript viewer like GhostScript and its interactive execution mode to continuously update the display via PostScript instructions that we emit.

Using PostScript ensures that your animations and graphs are scalable, portable and of very high typesetting quality. PostScript is also a lot of fun and very flexible.

In addition, if you use PostScript for creating animations, you can also easily embed the resulting graphs in other documents.

Examples of PostScript animations: In the following, we explain the general principle underlying these animations.

1. Designing your mini-language


First, think about the mini-language that you want to use to describe the small individual steps of your animation.

For example, in many scheduling tasks, you want to show the placement of individual items on a common roster or time-table. In such examples, you first define custom PostScript procedures that let you: You want to think in abstract positions, not in pixel positions. Typically, the abstract positions will be indicated by one or two natural numbers that denote a particular time slot or board field.

In PostScript terminology, you want to think in user space coordinates, not in device space. See the PostScript Language Reference for more information:

Coordinates specified in a PostScript program refer to locations within a coordinate system that always bears the same relationship to the current page, regardless of the output device on which printing or displaying will be done. This coordinate system is called user space.

For example, to clear a square at an abstract position indicated by two coordinates on the operand stack, you can define:

/cs { gsave translate 1 setgray 0 0 1 1 rectfill grestore } bind def

and use it like:

5 7 cs

in the code that emits animation steps.

As another example, to show a given letter at an indicated position, you can define:

/sl { gsave translate 0.5 0.28 translate dup stringwidth pop -2 div 0 moveto
0 setgray /Palatino-Roman 0.8 selectfont show grestore } bind def

and use it like:

(x) 5 3 sl

User-defined procedures allow for very concise and simple instructions to show individual steps of the animation.

2. Scaling the coordinate system

In default user space of PostScript, the length of a unit is 1/72 inch (ca. 0.35mm). The default user space provides a consistent, dependable initial setting for PostScript programs.

You can use operators like translate, rotate and scale to modify user space to better suit your application. For example, to scale user space by a factor of 50, use:

50 dup scale

at the beginning of your PostScript definitions. We have already seen applications of translate in the previous snippets. Notice also the use of gsave and grestore to save and restore the graphics state, so that the user space is only changed temporarily to conveniently perform a particular drawing operation.

3. Invoking GhostScript

Once you have defined your mini-language for a particular animation task in terms of PostScript procedures, you save your definitions to a file, say preface.ps. You can load this file from within a PostScript interpreter with the PostScript operator run:

run executes the contents of the specified file. In other words, it interprets the characters in that file as a PostScript program. When run encounters end-of-file or terminates for some other reason (for example, execution of the stop operator), it closes the file.

For example, you can run load the definitions contained in preface.ps with:

(preface.ps) run

Note that this requires the use of the -dNOSAFER option of GhostScript.

To prepare GhostScript for running animations, invoke it as:

gs -dNOSAFER -dNOPROMPT -q

GhostScript then reads PostScript instructions from standard input, updating the display continuously. Using this feature, you can show a real-time animation of your program states by piping the PostScript instructions your program emits to GhostScript:

./your_program | gs -dNOSAFER -dNOPROMPT -q

The first instruction your program should generate is:

(preface.ps) run

as explained above. After that, your program simply emits instructions of your mini-language for showing individual steps of the animation. For example, the stream of output may look like:

(preface.ps) run
0 0 cs
(a) 7 8 sl
(b) 3 7 sl
3 7 cs
(c) 3 7 sl

etc., allocating some letters to certain positions and removing them according to the allocation or search strategy you use in your program.

4. Further GhostScript options

Further useful command line options of GhostScript are:

-gnumber1xnumber2 This lets you specify the width and height of the GhostScript window. Example: -g500x200.
-rnumber This lets you set a resolution to scale the graphical output according to the device resolution. Example: -r100.

In fact, for the situation described above, you can invoke GhostScript also with preface.ps specified directly on the command line:

./your_program | gs -dNOSAFER -dNOPROMPT -q preface.ps

However, the way outlined above (i.e., including "(preface.ps) run" in the emitted instructions) makes the PostScript output self-contained: You can you can then also write it to a file and view it later, again using the -dNOSAFER option.

To determine bounding boxes on resulting graphs, it is useful to use the bbox output device of GhostScript. Append showpage to the emitted instructions, and invoke GhstScript with:

./your_program | gs -dNOSAFER -sDEVICE=bbox -q -

This shows you the smallest BoundingBox containing all graphical elements.


Acknowledgments: I first saw the idea of using PostScript for animations in the excellent Prolog teaching environment GUPU, created by Ulrich Neumerkel. Thank you!



Main page