22 Sep 2004 raph   » (Master)

Curves

haruspex, nomis: it's great having this discussion with people who care about curves and the UI's for editing them.

haruspex wrote:

The fact is, any geometrical figure - ellipse, circle, parabola - is irrelevant to the problem of fitting a natural, drawn curve. Pure geometric shapes (with the exception of straight lines) rarely occur in a letter outline, so I disregard them as modelling test cases. Instead, I ask, how well can this primitive deal with a pre-mathematical, natural curve, as might have come from the designer's hand? How awkward is the translation? (Your curve continuity arguments are relevant theoretical ammunition here I think, although my assessments are usually subjective, not objective.)

Absolutely. I wasn't trying to say that an ellipse had any special status as a smooth curve, or that its simple mathematical representation has any relevance to the question of smoothness. However, I do believe it is an example of a smooth curve.

That said, I could probably have come up with a better example, for example, an "S" curve. Whatever curve primitive you use has to interpolate between a fairly tight negative curvature on one side and a roughly equal positive curvature on the other, with an inflection point somewhere near the middle. Obviously, some fonts have smooth S curves, and others don't. Cubic Beziers are actually pretty good at making an S curve, in my opinion. Certainly, it's not uncommon in professional fonts to see a single Bezier traverse from a vertical tangent in the upper left corner to another vertical tangent in the lower right.

And here, I believe, circular segments don't necessarily do a good job. If you try to do it in two or three arcs, you'll be able to see the knots pretty clearly. The S in Computer Modern has three, and suffers badly from it in my opinion.

The UI makes a pretty big difference when designing with circular arcs, too. Most of the masters I've seen from Bitstream have the centers of the circular arcs explicitly drawn. If you draw the main slope of the S with, say, eight arcs, then the centers should describe a fairly continuous path in and of themselves. In the hands of a master designer, I'm sure that using one circular arc for every 15 to 30 degrees of the original curve can lead to some of the cleanest, smoothest curves you can imagine. But if you don't do a good job visualizing the radii of curvature, and put the tool in novice hands, my guess is that you'll see bad curves.

To sum, cubic Beziers do a good job fitting smooth curves, such as the main body of an S, but it's also very easy to draw unsmooth curves. Circular arcs take more primitives to fit the same curves, but, at least with good discipline and a good UI for visualizing curvature, result in much more reliably smooth curves.

I think the Cornu spiral has a good chance of combining the best of both primitives. A single Cornu spiral segment can make a pretty darn good S all by itself. Conversely, I'm hoping that any unsmoothness that results from drawing a curve from curvature-continuous Cornu spiral segments was placed there deliberately, or at the very least, should be obvious to a moderately trained eye just from looking at the control points. [this last property is related to the property I mentioned last time of maintaining smoothness when the control points are perturbed, but is expressed more in terms of user experience than math.] I don't believe any other geometric primitive can come close to claiming all these properties.

nomis asked what a UI for Cornu spiral curves might look like. While there are no doubt many ways to do it, my first cut is going to look something like this. Basically, you just put down a series of on-curve points. Math fills in the rest. I like to keep things simple.

nomis also wrote:

The point I am trying to make: I don't think that the fundamental primitive is that important. It is the way we present it to the user that makes the difference.

I very much agree that the UI is important, more important even than the choice of primitive, but I still feel there's a strong case to be made for a primitive which yields very good results with a small number of control points.

That having said: Cornu splines obviously will be approximated with e.g. beziers at some point, so we are actually talking about user interface here... :-)

Not surprisingly, one of the first things I've implemented is a converter from Cornu segments to quadratic Beziers, but that transformation is not as inevitable as you might think. The killer advantages of Beziers are ease of affine transformation and subdivision (using De Casteljau), the latter of which is especially nice for rendering. That said, the Cornu spiral is remarkably well behaved for being a "special function", and it's probably not anywhere nearly as painful as you might think to work directly in the space of the Cornu parameters. The key property is that the motion along arclength goes at a constant rate with respect to the parameter; with Beziers, it's not hard to set up curves for which this motion goes through or near zero, which results in numerically fairly tricky curves. Also, two cubic Beziers can intersect at up to nine points, while I think it may be true that two Cornu spiral segments each traversing no more than 180 degrees of arc intersect at no more than two points.

Also, thanks for the kind feedback on FontFocus! Your eyes are sharp - it does indeed work in the X direction (on vertical stems) but not in the Y direction (on horizontals). In general, having an uneven baseline or x-height line is a pretty serious artifact, while subtly distorting widths and spacing isn't. It might still be worth playing around with, though, especially for non-latin scripts.

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!