CS 3723/3721
Programming Languages
Postscript
The star Example


The star Example:

This example uses rotate and translate in a clever way to draw a five-sided star. On the left below is the basic code for the example, while the code on the right shows the actions of this code in a step-by-step way. (See also the Blue book (PDF, 847k) for a discussion of this example on pages 51-53.)

The five pictures above give the output of the right-hand Postscript program (although it arranges these vertically on one page). These pictures show the progress of constructing the star, without the "fill" part. Thus the pictures show the result after drawing 1 line, 2 lines, 3 lines, 4 lines, and 5 lines. In order to enable this, the right-hand program does not use a final "closepath", but instead draws the 5th line explicitly. (This results in a final corner that is not pointed, as you can see from the rightmost diagram.)

Each line in turn is drawn from the origin to the point (72,0), that is, 1 inch along the x-axis. Then the origin is moved to the new final point, and the axes are rotated by -144 degrees, that is, 144 degrees clockwise, which is the way Postscript handles angles. In each case the new axes are show after the move of the origin to the end of the line just drawn, and after the rotation.

star.ps Display version of star.ps

/starside {
  72 0 lineto %add line to path
  currentpoint translate %move origin
  -144 rotate
} def %rotate coord. sys.

/star {
  currentpoint translate
  4 {starside} repeat
  closepath
  3 setlinewidth stroke
} def

100 100 moveto
star
showpage
/Mulberry {0.34 0.90 0 0.02 setcmykcolor} def
/starside {
  72 0 lineto %add line to path
  currentpoint translate %move origin
  -144 rotate
} def %rotate coord. sys.

/star { %stack: x ( # of times to repeat)
  currentpoint translate
  {starside} repeat % uses the parameter
  % no closepath; explicitly closes
  3 setlinewidth stroke
} def

/coords {
  /Times-Bold findfont 16 scalefont setfont
  1 setlinewidth
  Mulberry
  0 0 moveto 50 0 rlineto stroke
  50 0 moveto (x) show
  0 0 moveto 0 50 rlineto stroke
  0 50 moveto (y) show
  20 50 moveto
  (Step: ) show 
  % Tricky string conversion, blue book, p 71
  /nstr 3 string def % buffer for result
  i nstr cvs show % cvs "writes" i into nstr
  0 setgray % black again
} def

5 -1 1 { % 5, 4, 3, 2, 1
  /i exch def % save loop variable
  gsave
    0 5 i sub 160 mul translate
    100 100 moveto
    i star
    coords
  grestore
} for

showpage
Result: star0.pdf Result: star6.pdf

Successive stages in drawing 5 sides of a star
Side 1 Side 2 Side 3 Side 4 Side 5


The Blue Book's star Example:

The Blue book has the same example as above, but with an extra fill 0f the star:

star.ps (from Blue book)

/starside {
  72 0 lineto %add line to path
  currentpoint translate %move origin
  -144 rotate
} def %rotate coord. sys.

/star {
  currentpoint translate
  4 {starside} repeat
  closepath
  gsave
     0.4 setgray
     fill
  grestore
  3 setlinewidth stroke
} def

100 100 moveto
star
showpage

In the program above, just before the gsave, the current path is the star, and the current color is black (by default). Inside the gsave-grestore, the color is changed to gray, and the current path is "used up" with a fill command. After the grestore, the color is restored to black, and the path is restored to the star. In this way you can use a path twice without creating it twice.