17

假设我正在使用一些图形 API,它允许我通过指定 4 个必要点来绘制贝塞尔曲线: 开始、结束、两个控制点

我可以重复使用这个函数来绘制“原始”曲线的x%(通过调整控制点和终点)吗?

还是不可能?

不必要的信息,如果有人关心:

  • 我需要
    用不同的颜色和/或线条样式绘制原始贝塞尔曲线的每 n%
  • 我正在使用 Java 的 Path2D 绘制贝塞尔曲线:

    Path2D p = new GeneralPath();
    p.moveTo(x1, y1);
    p.curveTo(bx1, by1, bx2, by2, x2, y2);
    g2.draw(p);
    
4

2 回答 2

24

您需要的是De Casteljau 算法。这将允许您将曲线分割成您想要的任何部分。

但是,由于您只处理三次曲线,我想建议一个更容易使用的公式,它可以为您提供一个从wheret0t1where的段0 <= t0 <= t1 <= 1。这是一些伪代码:

u0 = 1.0 - t0
u1 = 1.0 - t1

qxa =  x1*u0*u0 + bx1*2*t0*u0 + bx2*t0*t0
qxb =  x1*u1*u1 + bx1*2*t1*u1 + bx2*t1*t1
qxc = bx1*u0*u0 + bx2*2*t0*u0 +  x2*t0*t0
qxd = bx1*u1*u1 + bx2*2*t1*u1 +  x2*t1*t1

qya =  y1*u0*u0 + by1*2*t0*u0 + by2*t0*t0
qyb =  y1*u1*u1 + by1*2*t1*u1 + by2*t1*t1
qyc = by1*u0*u0 + by2*2*t0*u0 +  y2*t0*t0
qyd = by1*u1*u1 + by2*2*t1*u1 +  y2*t1*t1

xa = qxa*u0 + qxc*t0
xb = qxa*u1 + qxc*t1
xc = qxb*u0 + qxd*t0
xd = qxb*u1 + qxd*t1

ya = qya*u0 + qyc*t0
yb = qya*u1 + qyc*t1
yc = qyb*u0 + qyd*t0
yd = qyb*u1 + qyd*t1

然后只需绘制由 、 和 组成(xa,ya)(xb,yb)贝塞尔(xc,yc)曲线(xd,yd)

请注意,t0t1不完全是曲线距离的百分比,而是曲线参数空间的百分比。如果您绝对必须保持距离,那么事情就会变得更加困难。试试这个,看看它是否满足您的需求。

编辑:值得注意的是,如果t0ort1为 0 或 1(即您只想从一侧修剪),这些方程式会简化很多。

此外,这种关系0 <= t0 <= t1 <= 1不是严格的要求。例如t0 = 1, 和t1 = 0可用于向后“翻转”曲线,或t0 = 0t1 = 1.5用于将曲线延伸到原始末端。但是,如果您尝试将其扩展到该[0,1]范围之外,则该曲线可能看起来与您预期的不同。

Edit2:在我最初回答 3 年多之后,MvG 指出了我的方程式中的一个错误。我忘记了最后一步(获得最终控制点的额外线性插值)。上述等式已更正。

于 2009-05-18T18:51:49.103 回答
15

回答另一个问题时,我只包含了一些公式来计算三次曲线部分的控制点。当u = 1 − t时,三次贝塞尔曲线被描述为

B( t ) = u 3 P 1 + 3 u 2 t P 2 + 3 ut 2 P 3 + t 3 P 4

P 1是曲线的起点,P 4是曲线的终点。P 2P 3是控制点。

给定两个参数t 0t 1(并且u 0 = (1 − t 0 ), u 1 = (1 − t 1 )),区间 [ t 0 , t 1 ] 中的曲线部分由下式描述新的控制点

  • Q 1 = u 0 u 0 u 0 P 1 + ( t 0 u 0 u 0 + u 0 t 0 u 0 + u 0 u 0 t 0 ) P 2 + ( t 0 t 0 u 0 + u 0 t 0 t 0 + t 0 u 0 t 0 ) P 3+ t 0 t 0 t 0 P 4
  • Q 2 = u 0 u 0 u 1 P 1 + ( t 0 u 0 u 1 + u 0 t 0 u 1 + u 0 u 0 t 1 ) P 2 + ( t 0 t 0 u 1 + u 0 t 0 t 1 + t 0 u 0 t 1 ) P 3+ t 0 t 0 t 1 P 4
  • Q 3 = u 0 u 1 u 1 P 1 + ( t 0 u 1 u 1 + u 0 t 1 u 1 + u 0 u 1 t 1 ) P 2 + ( t 0 t 1 u 1 + u 0 t 1 t 1 + t 0 u 1 t 1 ) P 3+ t 0 t 1 t 1 P 4
  • Q 4 = u 1 u 1 u 1 P 1 + ( t 1 u 1 u 1 + u 1 t 1 u 1 + u 1 u 1 t 1 ) P 2 + ( t 1 t 1 u 1 + u 1 t 1 t 1 + t 1 u 1 t 1 ) P 3+ t 1 t 1 t 1 P 4

请注意,在括号中的表达式中,至少有一些项是相等的并且可以组合。我没有这样做,因为我相信这里所说的公式会使模式更清晰。您可以简单地为xy方向独立执行这些计算来计算新的控制点。

请注意,t的参数范围的给定百分比通常不会对应于长度的相同百分比。因此,您很可能必须对曲线进行积分才能将路径长度转换回参数。或者你使用一些近似值。

于 2012-07-28T23:29:22.497 回答