% Postscipt implementation of an L-system
%
% Probably a reasonable introduction to PS programming too.
%
% adb@tardis.ed.ac.uk
% Ideas: Can have multiple rules by creating multiple recurse functions
% (or by making 'recurse' take an argument) eg. recurseY to include another
% rule Y at the current point.
% maxdepth controls the depth of recursion. We can't set this very high
% in this implementation since we maintain the whole stack. Example timings
% on a P133 are:
% maxdepth = 7 takes 5 secs
% maxdepth = 8 takes 13 secs
% maxdepth = 9 takes about 1m30
/maxdepth { 7 } def
%
% Variables affecting L-system drawing
%
% anglestep - how much does a "+" or "-" rotate us by?
% direction - the angle (from horizontal) we start at.
% length - the initial length of a line segment
% start-point - (0,0) is at bottom left
/anglestep 15 def
/direction 30.0 def
/length 150 def
/start_point { 0 0 } def
% Some defines to let us use more traditional rule descriptions
/START { saveposition } def
/END { restoreposition } def
/* { drawline } def
/@ { 0.7 changelength } def
/+ { turnleft } def
/- { turnright } def
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Rules
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/X { START + @ * recurse END START - @ * recurse END recurse } def
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of rules
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 'recurse' is used as part of the rule to indicate that
% X should be repeated at this point. Since we don't
% have infinite memory or time, we only recurse up to maxdepth
/increasedepth { /depth depth 1 add def } def
/decreasedepth { /depth depth 1 sub def } def
/recurse
{
depth maxdepth lt
{ increasedepth X decreasedepth } {} ifelse
} def
% Helpers - convert from angle to horizontal/vertical projection.
/angletohorz { cos } def
/angletovert { sin } def % angle of 45 give 0.707
% Actions
/drawline
{
direction angletohorz length mul
direction angletovert length mul
rlineto
} def
/turnright { /direction direction anglestep sub def } def
/turnleft { /direction direction anglestep add def } def
/saveposition { direction length currentpoint } def
/restoreposition { moveto /length exch def /direction exch def } def
/changelength { /length exch length mul def } def
%
% Start of main code
%
/depth { 0 } def
start_point moveto
X
stroke
showpage