🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.postscript
1 messages
1 total messages Started by Lee Choquette Wed, 03 Feb 1988 02:09
Escher's Fish.ps: Draws interlocking, endless fish
#6853
Author: Lee Choquette
Date: Wed, 03 Feb 1988 02:09
291 lines
8168 bytes
This PostScript program comes from our freely distributed Macintosh
software library.  It draws interlocking stylized fish:  four large ones
in the center, growing continually smaller toward the edges.

----
Lee Choquette				u-lchoqu@ug.utah.edu
University of Utah Computer Center	utah-gr!utah-ug!u-lchoqu
MEB 3440				Choquette@UTAHCCA.Bitnet
Salt Lake City, UT  84112-1180		(801) 581-8504

	"All right, all right, we're not all programmed for perfection,
	 you know."

% "Square Limit" drawing by M. C. Escher
% Functions derived by Peter Henderson
% Paper in 1982 Conference on LISP and Functional Programming
% Coding by Michael Parsons, Sept. 1985
% Translation to PostScript for Sun CRT by Peter Bumbulis, July 1986
% Adaptation for Apple LaserWriter by Price Collins, Jan. 1988

% corner defines one corner of the picture at level n
/corner
  { dup 0 le
      {   pop        { }       { }        { } u quartet }
      { 1 sub dup corner exch side dup 90 rot u quartet }
    ifelse
  } def

% cycle combines 4 copies of image each rotated by 90 degrees
/cycle
  { dup 270 rot
    dup 180 rot
    dup 90 rot
    quartet
  } def

% fish gives a border to produce the final drawing
/fish
  { squarelimit exec
    newpath  
      0 0 moveto
      0 1 lineto
      1 1 lineto
      1 0 lineto
    closepath
    stroke
  } def

% flip inverts the image
/flip
  { .5 .5 translate
    1 -1 scale
    -.5 -.5 translate
  } def

% nonet arranges 9 images in equal sized squares to form 1 image
/nonet
  { 9 -1 roll 1 3 div 0  1  zoom
    9 -1 roll 1 3 div .5 1  zoom
    9 -1 roll 1 3 div 1  1  zoom
    9 -1 roll 1 3 div 0  .5 zoom
    9 -1 roll 1 3 div .5 .5 zoom
    9 -1 roll 1 3 div 1  .5 zoom
    9 -1 roll 1 3 div 0  0  zoom
    9 -1 roll 1 3 div .5 0  zoom
    9 -1 roll 1 3 div 1  0  zoom
    9 { exec } /repeat cvx 12 array astore cvx
  } def

% quadcorner forms 1 quarter of the image at level n.
/quadcorner
  { dup corner
    exch side
    dup dup
    90 rot
    dup u
    exch t
    90 rot
    dup 3 1 roll
    { q }
    90 rot
    nonet
  } def

% quartet combines 4 images, 1 in each quadrant, to produce 1 image
/quartet
  { 4 -1 roll 1 2 div 0 1 zoom
    4 -1 roll 1 2 div 1 1 zoom
    4 -1 roll 1 2 div 0 0 zoom
    4 -1 roll 1 2 div 1 0 zoom
    4 { exec } /repeat cvx 7 array astore cvx
  } def

% rot rotates image by the radians anti-clockwise about the image center
/rotcode
  { gsave
     .5 .5 translate
      rotate
      -.5 -.5 translate
      exec
    grestore
  } def
/rot { /rotcode cvx 3 array astore cvx } def

% side defines one side of the picture at level n
/side
  { dup 0 le
      {   pop  { } dup t 90 rot t quartet }
      { 1 sub side dup t 90 rot t quartet }
    ifelse
  } def

% squarelimit produces the fish drawing
/squarelimit { quadcorner cycle } def

% zoom scales an image up or down with one fixed point
/zoomcode
  { gsave
      2 copy neg exch neg exch 5 2 roll translate
      dup scale translate
      exec
    grestore
  } def
/zoom { /zoomcode cvx 5 array astore cvx } def

% p, q, r and s are the data needed to draw the fish
/p
  { gsave
      flip
      .0625 .0625 scale
      newpath
       3 12 moveto  0  8 lineto
                    0 13 lineto
                    3 12 lineto
       4 12 moveto  6 16 lineto
       7 10 moveto  4 11 lineto
                    4  6 lineto
                    7 10 lineto
       8  4 moveto 16  6 lineto
       8  8 moveto 10 12 lineto
                   13 11 lineto
                   16 12 lineto
       9 10 moveto 12  9 lineto
                   16 10 lineto
      10  0 moveto 12  2 lineto
                   16  3 lineto
      10 12 moveto 11 16 lineto
                   14 14 lineto
                   16 14 lineto
      12  0 moveto 13  1 lineto
                   16  2 lineto
      14  0 moveto 16  1 lineto
      16  4 moveto 12  4 lineto
                    8  0 lineto
                    6  1 lineto
                    0  0 lineto
                    4  3 lineto
                    8  8 lineto
                   12  7 lineto
                   16  8 lineto
      stroke
    grestore
  } def

/q
  { gsave
      flip
      .0625 .0625 scale
      newpath
       0  0 moveto  0  4 lineto
                    3  3 lineto
                    5  2 lineto
                    4  0 lineto
       0  6 moveto  7  5 lineto
       2  0 moveto  3  3 lineto
       2 16 moveto  4 11 lineto
                    4  9 lineto
                    6  9 lineto
       4  9 moveto  0  8 lineto
                    0 16 lineto
                    8 16 lineto
                   10 10 lineto
                   10  7 lineto
       4 16 moveto  6 11 lineto
                    6  9 lineto
                   12  6 lineto
                   16  0 lineto
                   15  6 lineto
                   16  8 lineto
                   13 12 lineto
                   12 16 lineto
                   16 16 lineto
       5  2 moveto  7  1 lineto
                    8  0 lineto
       6  0 moveto  7  1 lineto
       6 16 moveto  8 11 lineto
       8  1 moveto 11  1 lineto
                    9  3 lineto
                    8  1 lineto
       8 11 moveto  8  8 lineto
       9  4 moveto 12  4 lineto
                   10  6 lineto
                    9  4 lineto
      10 16 moveto 14  5 lineto
      13 16 moveto 16 10 lineto
      14 16 moveto 16 12 lineto
      15 16 moveto 16 14 lineto
      stroke
    grestore
  } def

/r
  { gsave
      flip
      .0625 .0625 scale
      newpath
       0  4 moveto  1  2 lineto
       0  8 moveto  2  4 lineto
       0 12 moveto  5  6 lineto
       0 16 moveto  8  8 lineto
       1 15 moveto  4 16 lineto
       2 14 moveto  8 16 lineto
       3 13 moveto  8 14 lineto
                   12 16 lineto
       5 11 moveto 12 13 lineto
                   16 16 lineto
       6  0 moveto 11  6 lineto
                   16 10 lineto
      11  0 moveto 12  4 lineto
                   16  8 lineto
      12  4 moveto 16  0 lineto
      15  1 moveto 16  2 lineto
      14  2 moveto 16  4 lineto
      13  3 moveto 16  6 lineto
      16 12 moveto 14 10 lineto
                    8  8 lineto
                    2  4 lineto
                    0  0 lineto
      stroke
    grestore
  } def

/s
  { gsave
      flip
      .0625 .0625 scale
      newpath
       0 16 moveto  4 14 lineto
                    8 14 lineto
                   16 16 lineto
                   10 12 lineto
                    8 10 lineto
                    7  8 lineto
                    7  3 lineto
                    8  0 lineto
       0  2 moveto  7  3 lineto
       0  4 moveto  7  6 lineto
       0  6 moveto  7  8 lineto
       0  8 moveto  8 10 lineto
       0 10 moveto  7 12 lineto
       0 12 moveto  2 15 lineto
      10  0 moveto 11  6 lineto
      12  0 moveto 13  3 lineto
      12 12 moveto 12  9 lineto
                   10 10 lineto
                   12 12 lineto
      14  5 moveto 16  4 lineto
      15  7 moveto 13  3 lineto
                   16  2 lineto
      15 11 moveto 15  8 lineto
                   13  9 lineto
                   15 11 lineto
      16  6 moveto 15  7 lineto
                   16  8 lineto
      stroke
    grestore
  } def

% t is one of the basic fish rearrangements
/t { { p } { q } { r } { s } quartet } def

% u is another of the basic fish rearrangements
/u { { q } 90 rot cycle } def

% display a level 2 fish
.001 setlinewidth
0 setgray
60 150 translate
500 500 scale
2 2 fish
showpage
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads