Bezier curve with control points within the curve

一曲冷凌霜 提交于 2019-12-11 18:46:36

问题


Please see the image below. This path object is created using 4 Bezier curve on each side. Currently I am facing a problem when I try to get bounds of this path object created using cubic brazier curves. As you can see top and bottom sides have control point away from the curve which makes bounds totally inaccurate.

So my question is is it possible to create a jigsaw puzzle piece like in the image having all control points on or at the level of the curve. ( That is creating a curve and perfect mirror of it, all points within the bounds of the curve)


回答1:


Don't calculate the bounds by using the control points, then. At least if you need tight bounds and don't want a quick check for potential visibility in a given clipping rectangle. This awesome site can help a lot with common Bézier curve calculations, including bounding box.

Alternatively, switch to splines where the control points are on the curve, but then you could end up with the opposite effect where the curve extends beyond the bounds imposed by its control points.




回答2:


You can easily convert your BEZIER cubic control points into Interpolation cubic. Just by reversing this:

  • BEZIER vs. interpolation cubic

so:

/*                              bezier = interpol
1  |                           (    x0)=X1;
t  |                  (3.0*x1)-(3.0*x0)=(0.5*(X2-X0));
tt |         (3.0*x2)-(6.0*x1)+(3.0*x0)=(3.0*(X2-X1))-(X2-X0)-(0.5*(X3-X1));
ttt|(    x3)-(3.0*x2)+(3.0*x1)-(    x0)=(0.5*(X2-X0))+(0.5*(X3-X1))+(2.0*(-X2+X1));
1  |                           (    y0)=Y1;
t  |                  (3.0*y1)-(3.0*y0)=(0.5*(Y2-Y0));
tt |         (3.0*y2)-(6.0*y1)+(3.0*y0)=(3.0*(Y2-Y1))-(Y2-Y0)-(0.5*(Y3-Y1));
ttt|(    y3)-(3.0*y2)+(3.0*y1)-(    y0)=(0.5*(Y2-Y0))+(0.5*(Y3-Y1))+(2.0*(-Y2+Y1));
*/

// input: x0,y0,..x3,y3 ... Bezier control points
// output: X0,Y0,..X3,Y3  ... interpolation control points
    double x0,y0,x1,y1,x2,y2,x3,y3,m=1.0/9.0;
    X0=x0-(x1-x0)/m; Y0=y0-(y1-y0)/m;
    X1=x0;           Y1=y0;
    X2=x3;           Y2=y3;
    X3=x3+(x3-x2)/m; Y3=y3+(y3-y2)/m;

Hope I did not make any algebraic mistake. This will move all control points into your curves directly while the shape will be unchanged. Beware that for BBOX computation you should only use (X1,Y1) and (X2,Y2) as the used parameter t=<0,1> is interpolating between them !!!.

But even this can provide inaccuracy as you can have some extremes without control point. In case even that is a problem (The BBOX is a bit smaller than should) you can re-sample your shape to set of points (for example 10 per cubic) on the curve with some step (0.1) and do the BBOX from those points. That will be much more precise but slower of coarse...




回答3:


One property of Bezier curves is that as you split them, the distance between the smooth curve and the CVs shrinks.

So, one way to fix those CVs on the top and bottom is to split the related Bezier into two Beziers using the De Casteljau algorithm.

You could even do this algorithmically:

  • Find tight bounding box and CV-based bounding box.
  • If the difference is greater than your tolerance, find the max/min CVs and their related Bezier curves
  • Split all of the related Bezier curves into two Bezier curves each
  • Repeat

Eventually you'll hit your tolerance. You might have a lot of Beziers by then though if you have a very tight tolerance or tricky data.



来源:https://stackoverflow.com/questions/46466288/bezier-curve-with-control-points-within-the-curve

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