Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Experimenting with (cubic) Bézier subdivision

elbeno, 27 February, 20081 March, 2008

As you know, a Bézier curve (here meaning specifically a cubic Bézier) is often used for drawing all kinds of things in vector graphics. It has the nice property that the endpoints and control points form a bounding box, and deCasteljau’s algorithm is a nice numerically stable way of evaluating the curve at a particular point. Of course, the same algorithm trivially gives the tangent to the curve at that point and from there it’s a hop and a skip to find the normal.

All well and good so far. The problem I wanted to tackle was that of spacing points equally along the curve (and incidentally, pushing these same points out along the normal), so that I can easily modulate a pattern (e.g. sawtooth, square wave) on to an arbitrary Bézier curve.

But there’s a slight problem with the naive method for doing this. Recall that a Bézier curve is in fact a parametric curve, specified by the parameter t which varies from 0 to 1 along the curve. The problem is that a linear increment of the parameter t does not correspond to a linear step along the curve length. For some curves, it’s not a bad approximation, but the more “curvy” the Bézier, the worse the discrepancy. This picture is a clear illustration of this problem.

bezier-subdiv-wrong

The picture shows points (and points pushed along the normal) plotted on the curve, as t increments linearly from 0 to 1. As you can see, stepping along with constant increments of the parameter t gives the wrong result. These points are not equally spaced along the curve.

So far, I have a naive “correct” solution to this problem as follows: I sample the curve at a high frequency (say 1000). Each segment between points I then treat as a straight line, and I compute the length of the curve (simply the sum of the Pythagorean distance between successive points). I can then step along the curve linearly with respect to the curve length, and recover the parameter t (to actually evaluate the curve at a given point) by a simple calculation (binary search and interpolation between nearest neighbours). The result of this approach:

bezier-subdiv

Much better.

Lisp Maths Programming

Post navigation

Previous post
Next post

Related Posts

after an hour's fiddling…

29 September, 200529 July, 2007

Got GTK+/gtkmm projects compiling under Win32. Eclipse (CDT) doesn’t really know about pkg-config. So in order to get CDT to drive the command line correctly I had to put the `pkg-config –libs gtkmm-2.4` as part of a -l directive to the linker. It doesn’t work as just a link option…

Read More

Keyboard fun

20 March, 2011

One can have hours of fun with xmodmap. Especially if one has a Symbolics keyboard. For a start, I get a “real” Meta key (not Alt) and a couple of extra modifier keys that emacs knows about: Hyper and Super. I mapped these to mod2 and mod3. Staying away from…

Read More

An algorithmic sketch: inplace_merge

13 March, 201618 March, 2016

One of the things I like to do in my spare time is study the STL algorithms. It is easy to take them for granted and easy, perhaps, to imagine that they are mostly trivial. And some are: I would think that any decent interview candidate ought to be able…

Read More

Comments (2)

  1. greatbiggary says:
    28 February, 2008 at 1:42 am

    That’s very cool. Now I’m curious to see the addition of a scratchpad area in which people can modify a bezier which you then string repeatedly along the original path, allowing people to create their own decorative line styles. I’d add a scale, and flip, each in both in U, and V to the editor, just to round out the features. Offset from the line itself would be a function of the base line’s thickness, and where in the scratch pad the sub line existed. That brings up the need to be able to move all the control points together – a so-called ‘drag’ for whole bezier.

    Now I’m rambling.

  2. elbeno says:
    28 February, 2008 at 10:11 am

    Well, I’m not actually making a drawing package. I figure Inkscape et al. have that covered. However, I do want to be able to modulate a Bézier on to a Bézier. (Or more accurately, a Bézier spline on to a Bézier spline.) Of course, c1 continuity is required too.

    But I think the first thing to do is clean this up a bit – it’s a couple of hundred lines of hacked together lisp code. I’ve also got spacing solutions for a line and a circular arc – which are trivial – which I should generalise to an elliptical arc and further generalise all three spacing mechanisms into one API. Also, my lisp is very naive – the simplest thing that could work. For example, I’m not even doing a binary search right now to recover t, because I’m using a list of points rather than an array.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes