Postscript code for epicycloid?
February 19, 2006 7:51 PM   Subscribe

I want a true vector-based (i.e., not merely a series of thousands of line segments) Postscript or Illustrator file of an epicycloid where a=5, b=2.

This is the image I'm after. The equations for an epicycloid a=5,b=2 work out to [x=7cos(θ)-2cos(7θ/2), y=7sin(θ)-2sin(7θ/2)], θ=0..4π.

I have no problem creating this in Grapher or Matlab or Maple or what have you using that equation, but if I try to export an EPS file, what I get is essentially a high resolution bitmap — a list of thousands of straight lines that make a facsimile of the shape if it's not enlarged too much.

Does anyone have enough of a command of Postscript to actually write up the code that would generate the true vector representation? Is that even possible in postscript?
posted by dmd to Science & Nature (20 answers total)
I haven't written PostScript by hand in well over a decade, and I'm sorry I'm far too rusty (to the point of having pretty much forgotten the language) to just whip out the code, but in answer to your second question it most certainly could be done in hand-coded PostScript.
posted by majick at 8:02 PM on February 19, 2006

I would think if you do it in MATLAB, create the figure large enough, and then export as .EPS, that should work?
posted by virga at 9:25 PM on February 19, 2006

PostScript cubics are made up of a pair of cubic parametric equations. (See PDF page 579 in the red book.) This will not be expressive enough to produce the "true vector representation" in a single curve. You will have to add multiple curve segments together to make your path, being careful to make the approximation detailed enough that the difference cannot be seen at your output resolution. I would think it would be much easier to do the same thing with line segments.
posted by grouse at 4:54 AM on February 20, 2006

Best answer: This seemed like fun so I did it for some reason:

/pi 3.1415926535 def
/a 5 def
/b 2 def
/initial 0 def
/increment 0.1 def
/inch {72 mul} def
/limit 300 pi mul def

/xcoord { % theta
dup % theta theta
cos a b add mul % theta (a+b)*cos(theta)
exch % (a+b)*cos(theta) theta
a b add b div mul cos b mul % (a+b)*cos(theta) b*cos(((a+b)/b)*theta)
} def

/ycoord { % theta
sin a b add mul
exch a b add b div mul sin b mul
} def

/coords { % theta
% (theta) == dup ==
dup xcoord % (x) == dup ==
exch ycoord % (y) == dup ==
} def

3 inch 3 inch translate
0.25 inch 0.25 inch scale

initial coords moveto

initial increment limit {
coords lineto
} for

0.01 setlinewidth


Sorry for loss of indentation. Decrease /increment to taste.
posted by grouse at 5:54 AM on February 20, 2006 [1 favorite]

there's svg code here (source) [self links] that you can use. it uses bezier curves to approximate the arcs (you said you wanted "true vector based" - i don't know of a vector format that uses arbitrary functions directly; at some point you have to translate to line segments, either straight or curved; using curves means it looks smooth even with few segments, giving faster rendering). the image itself will only be visible if you have svg support (recent firefox; possibly the adobe plugin for ie).
posted by andrew cooke at 7:01 AM on February 20, 2006

(sorry, just realised you specifically want ps. you might find a translator somewhere, or just lift the equations i use from the source)
posted by andrew cooke at 7:03 AM on February 20, 2006

(and, i should add, it's not svg directly, but javascript that generates svg. i'll shut up now.)
posted by andrew cooke at 7:06 AM on February 20, 2006

Response by poster: Grouse, that's awesome.

It looks like Illustrator/Photoshop are too dumb to understand the pure mathematical beauty of such a solution, though.

I do in fact need something that I'll be able to work with in Illustrator - I want to be able to work along the path defined by this curve.
posted by dmd at 7:17 AM on February 20, 2006

Response by poster: Oh - I just noticed fandango_matt's file, which seems to work!

fandango_matt, can you tell me how you created that file?

Grouse's file is only 35 lines long, so I'm easily able to understand what's going on in it, whereas yours is 7114 lines long. It doesn't seem to contain long lists of line segments, so I trust that somewhere in there it's either doing some math or declaring some curves, but I can't find it among all the thousands of lines of postscript errata.
posted by dmd at 7:26 AM on February 20, 2006

Response by poster: Hmm. Now that I actually have gotten over how pretty Grouse's little file is, I realize that it's not in point of fact any different than what I had before - it's basically generating, at run time, an output containing thousands of line segments. Which, I understand, is what an output device like a printer needs, but is not what I need.

I need a vector file that I can work with in Illustrator - something that actually defines some curve paths, so I can work with those paths.
posted by dmd at 7:42 AM on February 20, 2006

Response by poster: fandango_matt, the ps file you created looks fine in postscript viewers, but seems to show up blank when Placed into Illustrator. Odd. How was it created?
posted by dmd at 7:47 AM on February 20, 2006

Response by poster: Never mind, it's showing up now. My bad.
posted by dmd at 7:49 AM on February 20, 2006

dmd, I think you should take a moment to re-read b1tr0t's comment above. Your choices are lots of lines, or lots of splines.
posted by iconjack at 7:51 AM on February 20, 2006

Response by poster: iconjack, understood.

Ok, I think this is answered to my satisfaction. fandango_matt's file has solved my practical problem (even if I don't yet understand how it was created - I definitely want to know that!), and Grouse's file has reminded me how elegant Postscript can be.

One other thing - to what extent can a spline actually faithfully describe the true curve of the epicycloid? I.e., fandango_matt's figure appears to be composed of 5 splines, each of which is defined by three points, each of which has an angle associated with it. To what extent has that actually captured the epicycloid? It looks correct to me, but is there error involved here?
posted by dmd at 8:07 AM on February 20, 2006

you don't need *lots* of splines. i found things looked ok with just two or three splines per revolution. you can see the number here (previously on askme - each black dot is a new spline.).

the splines are only an approximation. they are not exact. use a straight-line based algorithm with many small steps and compare the output - you'll see where they diverge (basically, they will agree exactly only at the points specified).
posted by andrew cooke at 8:16 AM on February 20, 2006

Have you tried Illustrator's Simplify command?

to what extent can a spline actually faithfully describe the true curve of the epicycloid?

As faithfully as a series of line segments or points can—it's still an approximation, yes? What is it that you need to do that you can't with what's been provided?
posted by grouse at 8:20 AM on February 20, 2006

As faithfully as a series of line segments or points can

for the same number of endpoints (or for the same sized file) the spline-based version is more accurate. you need a much smaller interval if you use straight line segments.
posted by andrew cooke at 8:22 AM on February 20, 2006

correction - that's correct for the same number of endpoints, but for the same size file i'm not sure it's more accurate (although it will certainly look better).
posted by andrew cooke at 8:24 AM on February 20, 2006

When working with computers in many cases, it is virtually given that nobody needs exact precision arithmetic-- all you need to do is get "close enough". For example, if you are rendering this drawing onto a screen, you can make your drawing out of many little line segments- and if you use enough of them, the result will be indistinguishable from a perfect rendering. It may be that only 100 segments is "enough" for a certain physical size and resolution, but one million segments "enough" for a larger size. At the end of the day though, the drawing always gets coverted to pixels of finitely large size, and any extra resolution (beyond a factor of maybe 1/5 the pixel size) is not useful.

For smooth curves, your function will be fit better by splines than by an equal number of segments. And with a function like your epicycloid, it takes remarkably few splines to fit it REALLY well. Offhand, I imagine that only a hundred or so splines could fit it well enough for any practical purpose.

Splines are just like line segments as they are drawn between two points, with the additional criteria that the first derivatives at each "joining point" are equal and that the second derivatives at each "joining point" are zero. So instead of having sharp corners at every join, the line segments are modified to smoothly blend into one another.

If you want to get a feel of how good splines are, look up on the internet a comparison of integrating under a curve with rectangles versus Simpson's approximation. Simpson's approximation is like a crude spline interpolation.
posted by Maxwell_Smart at 8:46 AM on February 20, 2006

Even if you do get the 'perfect' path, PostScript RIPs always convert paths to line segments on output. So no matter what you do, there will be straight line segments. PostScript's floating point mathematics are also not tremendously accurate.

It would be kind of fun to draw this figure with a bunch of signal generators and an analogue pen plotter ...
posted by scruss at 5:05 PM on February 20, 2006

« Older Mac to MSN Messenger?   |   LA Times in NYC? Newer »
This thread is closed to new comments.