15 Sep 2004 raph   » (Master)

haruspex wrote:

I think it's long been clear that Beziers are not a good user abstraction for curve editing - but what's wrong with circle segments between on-curve knots, as chosen by IKARUS, METAFONT, et al? I am not sure anything could be more natural. I suppose the Cornu could be seen as a French-curve style extension of circles. I think I need to write that experimental path editor I always planned, to play with these alternatives :)

What's wrong with circle segments? I'll tell you what's wrong...

But first, while circular arcs were the basis of some font formats (most notably Bitstream), they were definitely not the primitive of Metafont, and I'm not sure about Ikarus either. Metafont's primitive is the cubic Bezier, just like PostScript, but, unlike Type1 fonts, Metafont lets you do stroking with elliptical pens and constructive area geometry.

From what I've been able to learn about Ikarus, the IK file format itself just specified corner points, tangent points, and on-curve points. It was basically up to the application to figure out how to fit an actual curve to those points. Certainly, circular arcs would be one approach, but I suspect that Hermite splines may have been used as well.

Now, in order to argue which geometric primitive is best, I have to define the goals. One such goal is that it be expressive, meaning that, given an arbitrary smooth curve, I can fit it with a relatively small number of primitives (each with a relatively small number of paramters). Love or hate them, cubic Beziers are awesomely expressive.

And circular arcs do not have this property. You need quite a few of them to closely fit an ellipse, say. Take a look at some Bitstream designs -- you'll see a great many more control points than in a typical Type1 font.

I believe that curve smoothness is best defined as variation in curvature. By this metric, circular arcs are not that great; as you follow a curve, you'll have constant curvature along arcs, but a discontinuities at the joins between arcs. Of course, the more arcs you use, the less the discontinuity, but that's true of just about any primitive. Heck, you can make a decent enough outline from straight lines if you're willing to use enough.

Beziers can in fact be made to be curvature-continuous, at joins as well as the interior of the primitive. In fact, one of the central themes of John Hobby's work on Metafont was a global optimizer to choose tangents at knots to minimize curvature discontinuities (technically, for reasons of numerical stability, his algorithm zeros out the discontinuity in "mock curvature", a linear approximation to curvature, but the difference is subtle).

But Beziers are not naturally curvature continuous. In fact, my experience is that it's very difficult to design smooth Bezier curves by eyeball, especially as more control points are added. This is a subjective criterion, but I think it's possible to quantify it, as well: how well does curve smoothness hold up when you perturb the control points (or other parameters)? In general, if you start with a smooth Bezier curve, perturbation will make it worse.

This criterion is especially important when you're dealing with meta-fonts (of whatever flavor). In fact, Adobe's use of linear interpolation of cubic Bezier control points in their Multiple Master technology doesn't even guarantee tangent continuity, much less smoothness. It can be made to work well, but requires care and skill.

By these criteria, segments of the Cornu spiral are an excellent primitive. They are expressive in a way that circular arcs are not (in particular, you can cut from the central segment to make a very pretty "S" curve), while at the same time a Hobby-style global optimizer to determine the tangents can guarantee continuity of curvature across the whole curve. Variation of curvature is linear along the interior of the primitive, so you can't get wide swings there either, as you can in Beziers.

It also helps that the Cornu spiral representation is so concise - the primitive is fully determined by the endpoints and tangents at the endpoints (six degrees of freedom, as opposed to four for straight lines and eight for cubic Beziers). I believe this will help make the user interface both simple to learn and productive to use.

And I am hacking on a pattern plate editor, so if you're patient you will be able to play with it before too long.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!