# PostScript-like drawing in Mathematica?

To illustrate by example, construct an equilateral triangle in PostScript:

0 0 moveto           %moveto origin
6 0 lineto           %construct first line segment
6 0 translate        %translate origin to current point
120 rotate           %rotate axes 120 degrees counterclockwise
6 0 lineto           %construct second line segment
closepath            %construct final line segment

Accurate and elegant.

Now concerning Mathematica, I have two questions.

1. Can a similar approach to construction be taken in Mathematica, somehow using say JoinedCurve? (Without precomputing the points.)
2. Since Mathematica includes a decent PostScript import facility, can this actual PostScript code be fed into some function to produce the path as a Mathematica graphics object?
• Have you seen AnglePath[]? BTW: once upon a time,before version 6, Mathematica had an explicit PostScript[] graphics primitive. Aug 6, 2016 at 3:57
• if you restrict yourself to such a simple example you could develop a rudimentary interpreter to convert the postscript to mathematica graphics. If your code uses def procedures and nested graphics states and such it gets unwieldy though. Aug 6, 2016 at 12:32

As J.M. notes in a comment, AnglePath allows paths to be specified in relative terms instead of absolute terms:

Graphics[
Line@AnglePath[{{60, 0°}, {60, 120°}, {60, 120°}}]
]

Note that the figure had to be closed explicitly with an extra line. We can remedy that by using JoinedCurve.

Graphics[
JoinedCurve[Line@AnglePath[{{60, 0°}, {60, 120°}}], CurveClosed->True]
]

We can emulate the Postscript code more closely by performing explicit translations and rotations, but it is not pretty:

Graphics[
{ Line[{{0, 0}, {60, 0}}]
, Translate[{##}, {60, 0}]&[
Rotate[{##}, 120°, {0, 0}]&[
Line[{{0, 0}, {60, 0}}]
, Translate[{##}, {60, 0}]&[
Rotate[{##}, 120°, {0, 0}]&[
Line[{{0, 0}, {60, 0}}]
]
]
]
]
}
]

Of course, Mathematica is well-suited to define our own domain-specific language to clean this up, but that is beyond the scope of this response.

We can get Mathematica to draw Postscript directly by adding minimal headers and footers around our code to make it an importable Encapsulated Postscript file (EPS):

$ps = "%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: -10 -10 70 70 0 0 moveto %moveto origin 60 0 lineto %construct first line segment 60 0 translate %translate origin to current point 120 rotate %rotate axes 120 degrees counterclockwise 60 0 lineto %construct second line segment closepath %construct final line segment stroke showpage %%EOF "; ImportString[$ps, "EPS"]

The generated graphics are in vector form, complete with corner caps and joins:

% // InputForm

(*
Graphics[{Thickness[0.0125],
Style[{JoinedCurve[{{{0, 2, 0}, {0, 1, 0}}}, {{{10., 9.999999999999996}, {70.,
10.}, {40.000000124354074, 61.96152429886217}}}, CurveClosed -> {1}]},
CapForm["Butt"], JoinForm[{"Miter", 10.}], Thickness[0.008838834801470012]]},
ImageSize -> {80., 80.}, PlotRange -> {{0., 80.}, {0., 80.}},
AspectRatio -> Automatic]
*)
• Unfortunately, ImportString gives a raster though. Aug 6, 2016 at 11:47
• @george2079 I'm getting a graphics object (Mma 10.3).
– Alan
Aug 6, 2016 at 13:13
• The problem with constructing the path with those translated segments is that the result is not a joined path. I did not think of trying ImportString; this is quite nice when there is a simple PostScript equivalent. But I was really looking for AnglePath; new to me, and of course not in the Graphics Objects list. So now we can Graphics[JoinedCurve[{Line[AnglePath[{0, 120 \[Degree]}]]}, CurveClosed -> True]]. Nice!
– Alan
Aug 6, 2016 at 13:45
• I incorporated your comments into the response. Thanks. Aug 7, 2016 at 3:14