【问题标题】:Split a higher order Bezier curve into many cubic curves将高阶贝塞尔曲线拆分为多条三次曲线
【发布时间】:2015-05-02 03:23:00
【问题描述】:

我需要显示贝塞尔曲线。用户通过点击显示区域选择任意点。

我实现了用这些点制作贝塞尔曲线的代码,但是对于高阶曲线,一旦阶数等于控制点的数量-1,它就不起作用了。

如何拆分这些控制点以制作代表我想要的整条曲线的三次贝塞尔曲线序列?

【问题讨论】:

  • 你似乎有两件事发生。你说“我实现了一个代码来用这些点制作贝塞尔曲线,但是对于更高的订单它不起作用”。如果您向我们展示您的代码并告诉我们输出有什么问题,也许我们可以帮助您修复它。这可能是与使用三次贝塞尔线段逼近高阶贝塞尔曲线完全不同的问题。你真正想解决哪个问题? (请注意,一般情况下,您无法找到包含完全与原始高阶曲线相同的点的一组三次线段。)
  • @robmayoff 我做的代码使用了所有的点,所以顺序会太高,行不通。因此我想分成三次曲线。不需要是完全相同的曲线,但足够好的近似值。
  • 你能解释一下为什么你认为你甚至需要分割控制点吗?你不想用三次曲线或其他东西来近似高阶曲线吗?如果您的用户放置n 点,您可以很容易地绘制相应的n 阶曲线(对要绘制的曲线上的每个点使用n+(n-1)+(n-2)+...+1 = n(n+1)/2 线性插值)

标签: c++ bezier


【解决方案1】:

我相信您可以使用adaptive methods 找到关于“绘制平滑贝塞尔曲线”的好资源,但我认为这是一个很好的简单方法(如果未优化的话):

  • 生成二项式系数。例如,一条5度曲线可以表示为:

    二项式系数是帕斯卡三角的第 n 行:

    1, 5, 10, 10, 5, 1
    
  • 在连续划分对评估点产生显着变化的位置自适应地执行递归。这发生在尖点/急弯处,需要很多点才能收敛到可接受的解决方案。例如:

    Note that ||B(a) - B(b)|| is notation for the length
    of the line between the evaluated points B(a) and B(b).
    
    Evaluate B(t) for values of t = a, b,    c,   d,    e
                                  = 0, 0.25, 0.5, 0.75, 1.
    
    Evaluate lengths of straight line segments:
        ac = ||B(a) - B(c)||
        ce = ||B(c) - B(e)||
    
        Also evaluate ab, bc, cd, de.
    
    if  ac - (ab + bc)  >  ERROR_THRESHOLD
        Split ab into two segments and split bc into two segments.
    else
        We have found a good enough approximation.
    
    Do the same as above for ce - (cd + de).
    

【讨论】:

  • 不过,作为关于可编程性的说明:如果事情变得非常昂贵甚至难以处理,你真的不能使用伯恩斯坦多项式绘制高阶曲线;所涉及的值太大而无法真正快速地融入浮点数据类型。使用线性插值结果与低阶曲线一样快,但其好处是所涉及的数字保持在初始控制坐标设置的范围内,因此您甚至可以快速计算 6 阶、10 阶或 40 阶曲线坐标并且准确。
猜你喜欢
  • 2011-03-10
  • 2016-02-28
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多