26
votes

I'm trying to create a "parrallel" bezier curve. In my attempts I've gotten close but no cigar. I'm trying to keep a solid 1px offset between the 2 curves (red,blue).

current attempt

My main goal is use a edge offseting algorythm to expand/shrink a svg path.


Solution

For anyone else who is looking for a solution, I've create a AS3 version.

http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/

4
pure conjecture, never having done this myself, but could you just copy the curve after it has been displayed as some kind of "image", and just redraw it in a new color at the preferred offset?warren
@warren It wouldn't keep a 1px offsetSean Thayne
if you draw a curve from, say, 0,0 to 2,2 to 0,2, then copy the curve into an image and redraw centered on 4,4 (instead of 2,2), would that not give a 1px offset?warren
@warren Only in some cases, it depends on the complexity of a curve. if your talking a very simple curve with small arc, then your method would work. for others thou, you'd have it intersect directly with the original lines. It all depends on how hard of a angle the curve has.Sean Thayne

4 Answers

11
votes

From wikipedia: ( http://en.wikipedia.org/wiki/B%C3%A9zier_curve )

The curve at a fixed offset from a given Bézier curve, often called an offset curve (lying "parallel" to the original curve, like the offset between rails in a railroad track), cannot be exactly formed by a Bézier curve (except in some trivial cases). However, there are heuristic methods that usually give an adequate approximation for practical purposes.

You might also see the paper indicated here: Outline of cubic bezier curve stroke

12
votes

I hope you found my math paper usefulenter image description here

Quadratic bezier offsetting with selective subdivision https://microbians.com/mathcode

7
votes

It's not possible in general to represent the offset of a cubic Bezier curve as a cubic Bezier curve (specifically, this is problematic when you have cusps or radius of curvature close to the offset distance). However, you can approximate the offset to any level of accuracy.

Try this:

  • Offset the Beziers in question (what you have already seems pretty decent)
  • Measure the difference between each original curve and corresponding offset curves. I'd try something like 10 samples and see if it works well.
  • For any offset that's outside of tolerance, subdivide (using the deCastlejau algorithm for Beziers) and iterate.

I haven't implemented an offset (because the kernels I use already have one), but this seems like something to try.

7
votes

What you ask for is called a parallel or offset curve in mathematics. The Wikipedia article (quoted above by others) on Bezier curves failed to link to the right article for "offset curve", but I've fixed that a few seconds ago. In the world of vector graphics, that same notion is called stroking the path.

In general, for cubic/Bezier curve the offset curve is a 10th order polynomial! Source: Kilgard, p. 28

If all you want to do is rasterize such offset curves, rather than compute their analytic form, you can for example look at the sources of ghostscript. You could also look at this patent application to see how NV_path_rendering does it.

If you want to covert/approximate the offset curves, then the TUG paper on MetaFog for covering METAFONT to PostScript fonts is a good reading. The METAFONT system, which predated PostScript allowed fonts to be described by the (more mathematically complex) operation of stroking, but PostScript Type 1 fonts only allow filling to be used (unlike PostScript drawings in general) for reasons of speed.

Another algorithm for approximating the offsets as (just two) Beziers (one on each side), with code in PostScript, is given in section 7 of this paper by Gernot Hoffmann. (Hat tip to someone on the OpenGL forum for finding it.)

There are in fact a lot of such algorithms. I found a 1997 survey of various algorithms for approximating offset curves. They assume the progenitor curves are Beziers or NURBS.