首页 文章

通过重用基本Bézier曲线函数绘制Bézier曲线的一部分?

提问于
浏览
12

假设我正在使用一些图形API,它允许我通过指定4个必要点来绘制贝塞尔曲线: start, end, two control points .

我可以 reuse this function 绘制'original'曲线的 x percent (通过调整控制点和终点)吗?

还是不可能?

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

  • 我需要整个东西来绘制原始的每一个n%
    具有不同颜色和/或线条样式的贝塞尔曲线

  • I 'm using Java' s用于绘制贝塞尔曲线的Path2D:

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

2 回答

  • 9

    你需要的是the De Casteljau algorithm . 这样您就可以将曲线分割成您想要的任何片段 .

    但是,因为你想建议一个稍微容易使用的配方,它会给你一个从 t0t1 的部分,其中 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) 组成的Bézier曲线 .

    请注意, t0t1 不是曲线距离的精确百分比,而是曲线参数空间 . 如果你绝对必须有距离那么事情要困难得多 . 试试这个,看看它是否能满足您的需求 .

    编辑:值得注意的是,如果 t0t1 为0或1(即您只想从一侧修剪),这些方程式会相当简单 .

    此外,关系 0 <= t0 <= t1 <= 1 并不是严格的要求 . 例如, t0 = 1t1 = 0 可用于向后弯曲"flip",或 t0 = 0t1 = 1.5 可用于将曲线延伸超过原始末端 . 但是,如果您尝试将其延伸超过 [0,1] 范围,则曲线可能与您预期的不同 .

    编辑2:在我的原始答案超过3年后,MvG在我的方程式中指出了一个错误 . 我忘记了最后一步(额外的线性插值来获得最终控制点) . 上面的等式已得到纠正 .

  • 16

    an answeranother question我刚刚包含了一些公式来计算三次曲线的一部分的控制点 . 当u = 1-t时,立方贝塞尔曲线被描述为

    B(t)= u3 P1 3u2t P2 3ut2 P3 t3 P4

    P1是曲线的起点,P4是曲线的终点 . P2和P3是控制点 .

    给定两个参数t0和t1(并且u0 =(1-t0),u1 =(1-t1)),区间[t0,t1]中的曲线部分由新控制点描述

    • Q1 = u0u0u0 P1(t0u0u0 u0t0u0 u0u0t0)P2(t0t0u0 u0t0t0 t0u0t0)P3 t0t0t0 P4

    • Q2 = u0u0u1 P1(t0u0u1 u0t0u1 u0u0t1)P2(t0t0u1 u0t0t1 t0u0t1)P3 t0t0t1 P4

    • Q3 = u0u1u1 P1(t0u1u1 u0t1u1 u0u1t1)P2(t0t1u1 u0t1t1 t0u1t1)P3 t0t1t1 P4

    • Q4 = u1u1u1 P1(t1u1u1 u1t1u1 u1u1t1)P2(t1t1u1 u1t1t1 t1u1t1)P3 t1t1t1 P4

    请注意,在带括号的表达式中,至少有一些术语是相同的并且可以组合 . 我没有这样做,因为这里所说的公式会使模式更清晰,我相信 . 您可以单独为x和y方向执行这些计算,以计算新的控制点 .

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

相关问题