简体   繁体   English

贝塞尔曲线与曲线内的控制点

[英]Bezier curve with control points within the curve

Please see the image below. 请参见下图。 下图 This path object is created using 4 Bezier curve on each side. 使用每侧的4个贝塞尔曲线创建此路径对象。 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) (即在曲线的边界内创建所有曲线和完美的镜像)

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 . 这个很棒的网站可以为常见的Bézier曲线计算(包括边界框)提供很多帮助。

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. 或者,切换到样条曲线上控制点在曲线上的位置,但是您可能会得到相反的效果,即曲线超出了控制点所施加的边界。

You can easily convert your BEZIER cubic control points into Interpolation cubic. 您可以轻松地将BEZIER三次控制点转换为插值三次。 Just by reversing this: 只需反转一下:

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 !!!. 请注意,对于BBOX计算,您仅应使用(X1,Y1)(X2,Y2)因为所使用的参数t=<0,1>在它们之间进行插值!!!!

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. 万一这是个问题(BBOX比应有的要小一些),您可以使用一些步长( 0.1 )重新采样形状以设置曲线上的点集(例如,每立方10个),然后从这些点进行BBOX点。 That will be much more precise but slower of coarse... 那将更加精确,但粗略地会慢一些。

One property of Bezier curves is that as you split them, the distance between the smooth curve and the CVs shrinks. 贝塞尔曲线的一个特性是,当您分割它们时,平滑曲线和CV之间的距离会缩小。

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. 因此,一种在顶部和底部固定这些CV的方法是使用De Casteljau算法将相关的贝塞尔曲线拆分为两个贝塞尔曲线。

You could even do this algorithmically: 您甚至可以通过算法执行此操作:

  • Find tight bounding box and CV-based bounding box. 查找紧密边界框和基于CV的边界框。
  • If the difference is greater than your tolerance, find the max/min CVs and their related Bezier curves 如果差异大于公差,则找到最大/最小CV及其相关的贝塞尔曲线
  • Split all of the related Bezier curves into two Bezier curves each 将所有相关的Bezier曲线分别分成两条Bezier曲线
  • 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. 如果您的容忍度非常高或数据比较棘手,那么到那时您可能会有很多贝塞尔曲线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM