Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a "thick" bezier curve?

I'm looking for a way to generate a polygon programatically by "thickening" a Bezier curve. Something like this:

thick bezier curve

My initial idea was to find the normals in the line, and generate the polygon from them:

Bezier normals

But the problem is that the normals can cross each other in steep curves, like this:

Bezier normals crossing each other

Are there any formulas or algorithms that generate a polygon from a bezier curve? I couldn't find any information on the internet, but perhaps I'm searching using the wrong words...

like image 929
André Wagner Avatar asked Jun 20 '14 11:06

André Wagner


4 Answers

If you want a constant thickness, this is called an offset curve and your idea of using normals is correct.

This indeed raises two difficulties:

  1. The offset curve is not exactly representable as a Bezier curve; you can use a polyline instead, or retrofit Beziers to the polyline;

  2. There are indeed cusps appearing when the radius of curvature becomes smaller than the offset width. You will have to detect the self-intersections of the polyline.

As far as I know, there is no easy solution.

For a little more info, check 38. Curve offsetting.

like image 142
Yves Daoust Avatar answered Sep 19 '22 00:09

Yves Daoust


I wrote a blog about the process to generate an offset curve: http://brunoimbrizi.com/unbox/2015/03/offset-curve/

And here's an interactive example: http://codepen.io/brunoimbrizi/pen/VYEWgY

// code is too big to post here, please see the source on codepen
like image 24
imbrizi Avatar answered Sep 22 '22 00:09

imbrizi


This is a hard problem. There are reasonable approximations like Tiller-Hanson (see my answer to this question: How to get the outline of a stroke?) but the questioner specifically raises the difficulty that 'the normals can cross each other in steep curves'; another way of looking at it is that an envelope created using normals can produce an indefinitely large number of loops, depending on how closely spaced the normals are.

A perfect solution, without self-intersections, is the envelope of the Minkowski sum of a circle and the line. I think it's impractical to get such an envelope, though: you may have to accept the intersections.

Another interesting but daunting fact is that, as Richard Kinch notes in MetaFog: Converting METAFONT Shapes to Contours, "Algebra tells us that stroking a 3rd degree polynomial curve (the ellipse approximated by Bézier curves) along a 3rd degree polynomial curve (the Bézier curve of the stroked path) results in a 6th degree envelope curve. We will have to approximate these 6th degree exact envelope curves with 3rd degree (Bezier) curves".

like image 27
Graham Asher Avatar answered Sep 22 '22 00:09

Graham Asher


Here I had the math papers about that theme.

The “Quadratic bezier offsetting with selective subdivision" covers a method to offset quadratic beziers using a criterion that set the parametric value on which the quadratic bezier is subdivided at the start in order to generate an offset approximation with other quadratic beziers segments. This method, obviously, may not be the most perfect approximation of a hypothetical “real” offset, but a fast algorithm for drawing strokes that can be performed on different quality levels by using a non recursive algorithm.

Here all the papers and examples https://microbians.com/mathcode that imbrizi use for the codepen he put in the answers.

https://codepen.io/microbians/pen/OJPmBZg

code in the link

enter image description here

like image 21
microbians Avatar answered Sep 21 '22 00:09

microbians