[ Home ]

Postscript Programs

Did you know that Postscript is a powerful programming language? Just a few lines are sufficient to generate fascinating images.

Sierpinski Gasket

%!PS
45 120 translate
0 1 511{0 1 511{2 copy and 0 eq{2 copy .3 0 360 arc fill}if pop}for pop}for
showpage
[ sierpinski.ps ]

Spiral With the Golden Angle

%!PS
297 421 translate
0 .1 400{dup dup sqrt 4 div 0 360 arc fill 137.50775 rotate}for
showpage
[ spiral.ps ]

Penrose Tiling

%!PS
/L/S/W/T/M/+/Z/F[{for}{exch def}{add}{rmoveto}{l + sin mul}{Z -14.2001
1 12}{25 mul/r Z/l Z r 0 T r 90 T}{1 S rlineto}]{def}forall{Z 72 72
360}/I W{/a W{/b I{/i I 2 div{/m I moveto i m +/j I{/l Z j l + b m T a
0 T sub m sin div .2 + floor .3 + S M}F i 0 0 j L M L stroke}F}F}F}F
showpage
[ penrose.ps ]

IFS Fractal Generator

Iterated Function System fractals are generated by a set of affine transformations. An affine transformation is a linear transformation together with a translation.

One way to draw such fractals is the following:
Start at any point. Pick a random transformation in the set and apply it to the point. This defines a new point. Repeat the same procedure with the new point and so on. Draw all points after a few steps needed for convergence.

This fractal generator uses another technique. First it approximates the convex hull of the fractal. Then it applies all transformations in the set recursively. At the deepest recursions, the convex hull approximation is transformed and drawn.

The whole fractal generator is encapsulated in one function which calls save and restore in order to not interfere with other code. This is important if you want to use my fractal generator in your own Postscript applications. I release this code to the public domain so you don't need to worry about copyright issues.

The Fractal Generator

%IFS fractal generator released to the public domain
%Arguments: bbox_x1  bbox_y1  bbox_x2  bbox_y2  transform_matrix_array
%           convex-hull_resolution(positive integer)  coarseness
/ifs{save 8 1 roll/D{def}def/C{bind D}D/F{forall}D/X{cvx}D<</E/exch/O
/pop/U/dup/G/get/u/put/M/matrix/+/add/-/sub/*/mul/./div/Y/copy/I/index
/t/translate/o/roll/Q/itransform/S{E D}>>{X D}F U */k S 4 */N S/n N 1
- D/V[0 1 n{[E -1e8 E 360 N . * U cos E sin]}for]D /T S[T{[E M Y/m S[0
3]{m E 2 Y G 1 - u}F 0 0 m Q]}F]{1/f S[E{/p S T{/m S[p{}F m
transform]}F}F]{/p S V{/v S v{}F E p{* E}F +/s S s - -1e-8 le{v 0 s
u/f 0 D}if}F}F[V n G{}F V{{}F[[6 4 2 8 6 9 7]{I}F 0 0]Q]7 1 o 6 3 o O
O O}F O O O]f 0 ne{exit}if}loop 0 N 4 . cvi n{V E G 0 G}for[/h/g/f/e/P
/d/c/b/a]{S}F/A{-.5 * E .5 * +}D/B{neg A}D a c B b d B t c a A e g B
. d b A f h B . 2 Y gt{E}if O U scale g e A h f A t/l[P {{}F/lineto
X}F]U 2/moveto X u X C/p[T{1[/I/M/concatmatrix/r]{X}F}F/O X]X C/r{U{}F
O O 4 1 o * 3 1 o * - abs k ge/p load{m setmatrix concat l closepath
fill}ifelse}C/m M currentmatrix D M identmatrix r restore}def

Calling It — an Example

%the Sierpinski triangle
50 50 545 792 %bounding box for the fractal
[  %IFS-transformations
    [0.5 0 0 0.5  0.866 -0.5]
    [0.5 0 0 0.5  0.0    1.0]
    [0.5 0 0 0.5 -0.866 -0.5]
]
6    % = n. The convex hull is approximated with a 4n-gon.
.002 %coarseness - the scale ratio of the smallest structures to the whole
ifs  %calls the fractal generator
showpage
[ ifs.ps ] containing another two examples

Weird Stuff

There are some strange features of Postscript. Don't expect this to work under all environments, and don't expect your printer to display a filesystem!

The File Lister

%!PS
/Courier findfont 10 scalefont setfont/y 740 def(*){y 80 lt{showpage/y
740 def}if 80 y moveto show/y y 11 sub def} 400 string filenameforall
showpage
[ ls.ps ]

Updated September 2009