'How can objects be grouped in postscript?

I made a picture in postscript, it is a collections of 6 squares. I would like to group this output as an object. yes, I know I can create a definition of a function that will out put this image. my issue is that I want to rotate this image as a group rather than modifying every coordinate. of every square that created it. Im not sure if postscript has this functionality. Scalable Vector Graphics has it, as the <g> tag. Sorry if that isn't exactly related, but its that functionality of grouping the squares together that I want to do.

The code to generate this picture is:

%!PS
%I made PS extensions executable via evince on my system
/Sq {0 0 moveto 0 100 lineto 100 100 lineto 100 0 lineto closepath} def
gsave

150 150 translate

6{
Sq 87 -50.1 translate
60 rotate
}repeat

0 0 0 setrgbcolor
closepath
1 setlinewidth
stroke

squares

I tried setting closepath outside the loop, and inside the Sqfunction, the squares are grouped lines. maybe I shouldnt close that path? I really don't know.



Solution 1:[1]

PostScript doesn't have any concept of a 'group', so you can't group objects. You could put them in a form but that's rare and in any event doesn't really do what you want.

The obvious solution as you've noted is simply to define a function which does the drawing. That's a 'group', or as close as you're going to get in PostScript.

Then you simply modify the CTM before calling the function. It's not clear exactly how you want the rotation to apply, but here's an example:

%!PS
%I made PS extensions executable via evince on my system
/Sq {0 0 moveto 0 100 lineto 100 100 lineto 100 0 lineto closepath} def

/Polygon {
  6{
    Sq 87 -50.1 translate
    60 rotate
  }repeat

  0 0 0 setrgbcolor
  1 setlinewidth
  stroke
} bind def

gsave
150 150 translate
Polygon
grestore

gsave
250 250 translate
45 rotate
Polygon
grestore

showpage

Note that rotate will rotate the CTM around the current point. In this case that means your polygon is rotated around the first vertex, if you want to rotate around the centre then you will need to calculate the co-ordinates of the centre of the polygon, move to that point, perform the rotation, then calculate the co-ordinates of the initial vertex (remembering that the CTM is now rotated!) before starting to draw the polygon.

Your original program has a few minor problems; you do a gsave without a matching grestore, so the gsave has no effect, and you leave a save state on the gstate stack. You don't need the second 'closepath' since all the subpaths are closed (again won't cause any problems in this case). Your program also doesn't execute a 'showpage' so technically a conforming PostScript interpreter will not draw anything. NeWS clones, using Display PostScript, do draw graphics primitives as they are executed.

If you use rmoveto and rlineto instead of lineto and moveto you could rewrite the code so that you didn't need to 'translate' the CTM and could simply use moveto to set the current point.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 halfer