How to generate a “thick” bezier curve?

ぐ巨炮叔叔 提交于 2019-12-04 12:59:20
Yves Daoust

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.

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

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".

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!