[comp.lang.postscript] PostScript art for the masses

hmayala@mit-amt.MEDIA.MIT.EDU (Hugo Ayala) (01/18/88)

In one of my periods of boredom around my lab I started looking
through the directories of our computer.  It was then when I stumbled
into the dubious pleasure of computer bulletin boards.  This is my
first contribution, so I don't know how the readers of this section
will receive me (I hope not to offend anyone); anyway, here it goes:

In an article who posted before somebody suggested readers to post
PostScript programs for the enjoyment of others.  Well, here is a
little program which I hope will give others a chance to decorate
their office walls with some computer generated art.  This program
generates 6 drawings which illustrate the progressions of a fractal
mountain.  The program is short, and it can be downloaded into a
PostScript printer like any normal PostScript file, however, it takes
a long time to execute.  I developed it on a Mac and tested it out on
a LaserWriter, a LPS40 and a LN03R; it worked in all three.  It
usually takes about 10 min. to print, so don't be scared if you don't
get any output for a while.

There are two parameters that can be changed to obtain different
output.  The first is the value of the variable "scl" (line 8) This
parameter limits the amount by which each line is displaced when it is
bisected by the procedure "splitline" (line 29) A value of 0.1 means
that each line can at most be displaced 10% of its total length.  The
greater the more the line can be displaced.  I've tried different
values but 0.1 seems to work best.  Feel free to experiment.  The
second parameter is the "depth" of the fractal (line 9) I haven't dare
tried a depth greater than 6.  This variable controls the number of
times that the fractal procedure is executed.  The larger this number
the more iterations the program will perform (and the longer your
printer will be tied up).  The other parameters that can be changed
are the coordinates for the anchor points.  The two arrays at the end
of the program hold the x and y coordinates of the three points which
define the original triangle.  Any three points will work.  If any one
is curious to know how the program works, let me know, I'll be happy
to describe the details of the program.

I wrote this program while learning PostScript during my free time
this summer.  I think that PostScript is a really smart solution to a
unique problem and I like it a great deal (However, you wouldn't catch
me saying this at one of our frat parties -at least while I'm still a
teenager) What I would like to know is what are people using
PostScript for.  I mean, my impression is that most of the people who
use PostScript take the output from a program (ie MacDraw) and the
fiddle with it to create interesting "effects."  Is there anyone out
there who uses PostScript in the raw?  Is most of the work just writer
drivers for other applications?

	 				hmayala@media-lab.mit.edu

------------------------------- Cut Here------------------------------------
%!
%%Title: Hugo's Fractal
%%Creator: Hugo M. Ayala'89, MIT
%%EndComments

gsave

/scl .1 def
/depth 6 def

2 setlinecap
0 setgray
1 setlinewidth

/prorand {rand 32768 div 32768 div 1 sub scl mul} def
/findrow {8 mul 7 sub sqrt 1 add 2 div truncate} def
/findindex {dup 1 sub mul 2 div 1 add} def
/findcolumn {dup findrow findindex sub} def
/findnewrow {2 mul 1 sub} def
/findnewcolumn {2 mul} def
/findarraysize {dup 1 add mul 2 div 1 add} def
/findnumoflines {dup 1 sub mul 2 div 3 mul} def
/findnumpoints {dup 1 add mul 2 div} def
/gtol {2 exch exp 1 add} def
/fixangle {dup 180 ge {180 sub} if} def
/backangle {dup 180 ge {180 sub} {180 add} ifelse} def

/splitline
{tpx btx add 2 div /mdx exch def
tpy bty add 2 div /mdy exch def
tpy bty sub tpx btx sub atan
90 add fixangle
/lineangle exch def
tpy bty sub dup mul
tpx btx sub dup mul
add sqrt /linelen exch def
prorand linelen mul dup
lineangle cos mul mdx add /mdx exch def
lineangle sin mul mdy add /mdy exch def} def

/findnewindex
{cvi /oldindex exch def
oldindex findrow cvi dup /oldrow exch def
findindex oldindex exch sub cvi /oldcolumn exch def
oldrow findnewrow cvi dup /newrow exch def findindex
oldcolumn findnewcolumn cvi dup /newcolumn exch def add
cvi /newindex exch def} def

/drawfractal
{1 1 generation gtol 1 sub findnumpoints
{cvi /topindex exch def
topindex dup findcolumn exch findrow 1 add findindex add cvi
/leftindex exch def
leftindex 1 add cvi /rightindex exch def
/tpx oldarrayx topindex get def
/tpy oldarrayy topindex get def
/btx oldarrayx leftindex get def
/bty oldarrayy leftindex get def
/mdx oldarrayx rightindex get def
/mdy oldarrayy rightindex get def
tpx tpy moveto
btx bty lineto
mdx mdy lineto
closepath stroke} for} def

/generatefractal
{1 1 depth
{/generation exch def
generation gtol findarraysize cvi dup
array /newarrayx exch def
array /newarrayy exch def
1 1 generation 1 sub gtol findnumpoints
{findnewindex
newarrayx newindex
oldarrayx oldindex get put
newarrayy newindex
oldarrayy oldindex get put} for
1 1 generation 1 sub gtol 1 sub findnumpoints
{findnewindex
newcolumn newrow 2 add findindex add cvi dup
/leftindex exch def 2 add cvi
/rightindex exch def
newcolumn newrow 1 add findindex add cvi
/mindex exch def
/tpx newarrayx newindex get def
/tpy newarrayy newindex get def
/btx newarrayx leftindex get def
/bty newarrayy leftindex get def
splitline
newarrayx mindex mdx put
newarrayy mindex mdy put
mindex 1 add cvi /mindex exch def
/btx newarrayx rightindex get def
/bty newarrayy rightindex get def
splitline
newarrayx mindex mdx put
newarrayy mindex mdy put
/mindex leftindex 1 add cvi def
/tpx newarrayx leftindex get def
/tpy newarrayy leftindex get def
splitline
newarrayx mindex mdx put
newarrayy mindex mdy put} for
/oldarrayx newarrayx def
/oldarrayy newarrayy def
7 generation sub 5 div setlinewidth
drawfractal showpage} for} def

/oldarrayx [0 540 72 72] def
/oldarrayy [0 396 720 72] def
generatefractal
grestore