B样条曲线的deboor算法

 众所周知,B样条曲线的通用表达式为:
C ( u ) = ∑ i = 0 n N i , p ( u ) Q i C(u)=\sum_{i=0}^n N_{i,p}(u)Q_i C(u)=i=0nNi,p(u)Qi
其中 N i , p ( u ) N_{i,p}(u) Ni,p(u)为基函数, Q i Q_i Qi为控制点。且基函数由下式递推算出:
在这里插入图片描述

 在实际使用中,如果已知所有的控制点 Q i Q_i Qi,我们希望求出参数u处的B样条值来。这种给定参数u,计算参数曲线上对应点的运算称为求值(Evaluate)操作。为了方便后续讨论,我们这里设B样条曲线有n+1个控制点,阶数为p。
 由B样条曲线的表达式可以看出来,最简单的Evaluate方法就是先由 N 0 , 0 , ⋯   , N n + p , 0 N_{0,0},\cdots,N_{n+p,0} N0,0,,Nn+p,0递推地求出基函数 N 0 , p , ⋯   , N n , p N_{0,p},\cdots,N_{n,p} N0,p,,Nn,p,然后再用公式 C ( u j ) = ∑ i = 0 n N i , p ( u ) Q i C(u_j)=\sum_{i=0}^n N_{i,p}(u)Q_i C(uj)=i=0nNi,p(u)Qi C ( u ) C(u) C(u)的值算出来,这个计算过程可以用下图理解,计算复杂度为O(n*(n+n+1))=O(np)。程序可以参考B样条值的公式计算方法
在这里插入图片描述
 由公式直接算值虽然简单直观,但是程序复杂度太高,所以有人又提出了一种更快速的Evaluate方法-deboor计算方法。推导过程如下((假设我们已经提前找到了要求的参数 u ∈ [ u j , u j + 1 u\in[u_j,u_{j+1} u[uj,uj+1):
C ( u ) = ∑ i = 0 n N i , p ( u ) Q i = ∑ i = j − p j N i , p ( u ) Q i = ∑ i = j − p j ( u − u i u i + p − u i N i , p − 1 ( u ) + u i + p + 1 − u u i + p + 1 − u i + 1 N i + 1 , p − 1 ( u ) ) Q i = ∑ i = j − p j u − u i u i + p − u i N i , p − 1 ( u ) Q i + ∑ i = j − p j u i + p + 1 − u u i + p + 1 − u i + 1 N i + 1 , p − 1 ( u ) Q i = ∑ i = j − p + 1 j u − u i u i + p − u i N i , p − 1 ( u ) Q i + u − u j − p u j − p + p − u j − p N j − p , p − 1 ( u ) Q j + ∑ i = j − p + 1 j u i + p − u u i + p − u i N i , p − 1 ( u ) Q i − 1 + u j + p + 1 − u u j + p + 1 − u j + 1 N j + 1 , p − 1 ( u ) Q j = ∑ i = j − p + 1 j u − u i u i + p − u i N i , p − 1 ( u ) Q i + ∑ i = j − p + 1 j u i + p − u u i + p − u i N i , p − 1 ( u ) Q i − 1 ( 因为 N j − p , p − 1 ( u ) 只在 [ u j − p , u j − p + p − 1 + 1 ) 不为 0 , N j + 1 , p − 1 ( u ) 只在 [ u j + 1 , u j + 1 + p − 1 + 1 ) 不为 0 ,而 u j ∈ [ u j , u j + 1 ) ) = ∑ i = j − p + 1 j N i , p − 1 ( u ) ( u − u i u i + p − u i Q i + u i + p − u u i + p − u i Q i − 1 ) \begin{equation}\nonumber \begin{split} C(u)&=\sum_{i=0}^n N_{i,p}(u)Q_i \\ &=\sum_{i=j-p}^{j} N_{i,p}(u)Q_i \\ &= \sum_{i=j-p}^{j} (\frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)+\frac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u))Q_i \\ &= \sum_{i=j-p}^{j}\frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)Q_i + \sum_{i=j-p}^{j}\frac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u)Q_i \\ &= \sum_{i=j-p+1}^{j}\frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)Q_i + \frac{u-u_{j-p}}{u_{j-p+p}-u_{j-p}}N_{j-p,p-1}(u)Q_j \\ &+ \sum_{i=j-p+1}^{j}\frac{u_{i+p}-u}{u_{i+p}-u_{i}}N_{i,p-1}(u)Q_{i-1} + \frac{u_{j+p+1}-u}{u_{j+p+1}-u_{j+1}}N_{j+1,p-1}(u)Q_j \\ &= \sum_{i=j-p+1}^{j}\frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)Q_i + \sum_{i=j-p+1}^{j}\frac{u_{i+p}-u}{u_{i+p}-u_{i}}N_{i,p-1}(u)Q_{i-1}\\ &(因为N_{j-p,p-1}(u)只在[u_{j-p},u_{j-p+p-1+1})不为0,\\ &N_{j+1,p-1}(u)只在[u_{j+1},u_{j+1+p-1+1})不为0,而u_j\in[u_j,u_{j+1})) \\ &=\sum_{i=j-p+1}^{j} N_{i,p-1}(u)(\frac{u-u_i}{u_{i+p}-u_i}Q_i + \frac{u_{i+p}-u}{u_{i+p}-u_{i}}Q_{i-1}) \end{split} \end{equation} C(u)=i=0nNi,p(u)Qi=i=jpjNi,p(u)Qi=i=jpj(ui+puiuuiNi,p1(u)+ui+p+1ui+1ui+p+1uNi+1,p1(u))Qi=i=jpjui+puiuuiNi,p1(u)Qi+i=jpjui+p+1ui+1ui+p+1uNi+1,p1(u)Qi=i=jp+1jui+puiuuiNi,p1(u)Qi+ujp+pujpuujpNjp,p1(u)Qj+i=jp+1jui+puiui+puNi,p1(u)Qi1+uj+p+1uj+1uj+p+1uNj+1,p1(u)Qj=i=jp+1jui+puiuuiNi,p1(u)Qi+i=jp+1jui+puiui+puNi,p1(u)Qi1(因为Njp,p1(u)只在[ujp,ujp+p1+1)不为0Nj+1,p1(u)只在[uj+1,uj+1+p1+1)不为0,而uj[uj,uj+1))=i=jp+1jNi,p1(u)(ui+puiuuiQi+ui+puiui+puQi1)
令:
Q i , k ( u ) = { Q i    k = 0 u − u i u i + p + 1 − k − u i Q i , k − 1 ( u ) + u i + p + 1 − k − u u i + p + 1 − k − u i Q i − 1 , k − 1 ( u )    k = 1 , ⋯   , p \begin{equation}\nonumber Q_{i,k}(u)=\left\{ \begin{aligned} & Q_i \ \ &k=0 \\ & \frac{u-u_i}{u_{i+p+1-k}-u_i}Q_{i,k-1}(u) + \frac{u_{i+p+1-k}-u}{u_{i+p+1-k}-u_{i}}Q_{i-1,k-1}(u) \ \ &k=1,\cdots,p \\ \end{aligned} \right. \end{equation} Qi,k(u)= Qi  ui+p+1kuiuuiQi,k1(u)+ui+p+1kuiui+p+1kuQi1,k1(u)  k=0k=1,,p
则上式可以写为:
C ( u ) = ∑ i = j − p + 1 j N i , p − 1 ( u ) Q i , 1 ( u ) = ∑ i = j − p + 1 j ( u − u i u i + p − 1 − u i N i , p − 2 ( u ) + u i + p − u u i + p − u i + 1 N i + 1 , p − 2 ( u ) ) Q i , 1 ( u ) = ∑ i = j − p + 1 j u − u i u i + p − 1 − u i N i , p − 2 ( u ) Q i , 1 ( u ) + ∑ i = j − p + 1 j u i + p − u u i + p − u i + 1 N i + 1 , p − 2 ( u ) ) Q i , 1 ( u ) = ∑ i = j − p + 2 j u − u i u i + p − 1 − u i N i , p − 2 ( u ) Q i , 1 ( u ) + u − u j − p + 1 u j − p + 1 + p − 1 − u j − p + 1 N j − p + 1 , p − 2 ( u ) Q j − p + 1 , 1 ( u ) + ∑ i = j − p + 2 j u i + p − 1 − u u i + p − 1 − u i N i , p − 2 ( u ) Q i − 1 , 1 ( u ) + u j + p − u u j + p − u j + 1 N j + 1 , p − 2 ( u ) Q j , 1 ( u ) = ∑ i = j − p + 2 j u − u i u i + p − 1 − u i N i , p − 2 ( u ) Q i , 1 ( u ) + ∑ i = j − p + 2 j u i + p − 1 − u u i + p − 1 − u i N i , p − 2 ( u ) Q i − 1 , 1 ( u ) ( 因为 N j − p + 1 , p − 2 ( u ) 只在 [ u j − p + 1 , u j − p + 1 + p − 2 + 1 ) 不为 0 , N j + 1 , p − 2 ( u ) 只在 [ u j + 1 , u j + 1 + p − 2 + 1 ) 不为 0 ,而 u j ∈ [ u j , u j + 1 ) ) = ∑ i = j − p + 2 j N i , p − 2 ( u ) ( u − u i u i + p − 1 − u i Q i , 1 ( u ) + u i + p − 1 − u u i + p − 1 − u i Q i − 1 , 1 ( u ) ) = ∑ i = j − p + 2 j N i , p − 2 ( u ) Q i , 2 ( u ) = ⋯ = ∑ i = j − p + k j N i , p − k ( u ) Q i , k ( u ) = ⋯ = ∑ i = j − p + p j N i , p − p ( u ) Q i , p ( u ) = N j , 0 ( u ) Q j , p ( u ) = Q j , p ( u ) \begin{equation}\nonumber \begin{split} C(u) &= \sum_{i=j-p+1}^{j} N_{i,p-1}(u)Q_{i,1}(u) \\ &= \sum_{i=j-p+1}^{j} (\frac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u)+\frac{u_{i+p}-u}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u))Q_{i,1}(u) \\ &= \sum_{i=j-p+1}^{j} \frac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u)Q_{i,1}(u) + \sum_{i=j-p+1}^{j}\frac{u_{i+p}-u}{u_{i+p}-u_{i+1}}N_{i+1,p-2}(u))Q_{i,1}(u) \\ &= \sum_{i=j-p+2}^{j}\frac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u)Q_{i,1}(u) \\ &+ \frac{u-u_{j-p+1}}{u_{j-p+1+p-1}-u_{j-p+1}}N_{j-p+1,p-2}(u)Q_{j-p+1,1}(u) \\ &+ \sum_{i=j-p+2}^{j}\frac{u_{i+p-1}-u}{u_{i+p-1}-u_{i}}N_{i,p-2}(u)Q_{i-1,1}(u)\\ &+ \frac{u_{j+p}-u}{u_{j+p}-u_{j+1}}N_{j+1,p-2}(u)Q_{j,1}(u) \\ &= \sum_{i=j-p+2}^{j}\frac{u-u_i}{u_{i+p-1}-u_i}N_{i,p-2}(u)Q_{i,1}(u) \\ &+ \sum_{i=j-p+2}^{j}\frac{u_{i+p-1}-u}{u_{i+p-1}-u_{i}}N_{i,p-2}(u)Q_{i-1,1}(u)\\ &(因为N_{j-p+1,p-2}(u)只在[u_{j-p+1},u_{j-p+1+p-2+1})不为0,\\ &N_{j+1,p-2}(u)只在[u_{j+1},u_{j+1+p-2+1})不为0,而u_j\in[u_j,u_{j+1})) \\ &=\sum_{i=j-p+2}^{j} N_{i,p-2}(u)(\frac{u-u_i}{u_{i+p-1}-u_i}Q_{i,1}(u) + \frac{u_{i+p-1}-u}{u_{i+p-1}-u_{i}}Q_{i-1,1}(u)) \\ &= \sum_{i=j-p+2}^{j} N_{i,p-2}(u)Q_{i,2}(u) \\ &=\cdots\\ &= \sum_{i=j-p+k}^{j} N_{i,p-k}(u)Q_{i,k}(u) \\ &=\cdots \\ &=\sum_{i=j-p+p}^{j} N_{i,p-p}(u)Q_{i,p}(u) \\ &= N_{j,0}(u)Q_{j,p}(u) \\ &= Q_{j,p}(u) \end{split} \end{equation} C(u)=i=jp+1jNi,p1(u)Qi,1(u)=i=jp+1j(ui+p1uiuuiNi,p2(u)+ui+pui+1ui+puNi+1,p2(u))Qi,1(u)=i=jp+1jui+p1uiuuiNi,p2(u)Qi,1(u)+i=jp+1jui+pui+1ui+puNi+1,p2(u))Qi,1(u)=i=jp+2jui+p1uiuuiNi,p2(u)Qi,1(u)+ujp+1+p1ujp+1uujp+1Njp+1,p2(u)Qjp+1,1(u)+i=jp+2jui+p1uiui+p1uNi,p2(u)Qi1,1(u)+uj+puj+1uj+puNj+1,p2(u)Qj,1(u)=i=jp+2jui+p1uiuuiNi,p2(u)Qi,1(u)+i=jp+2jui+p1uiui+p1uNi,p2(u)Qi1,1(u)(因为Njp+1,p2(u)只在[ujp+1,ujp+1+p2+1)不为0Nj+1,p2(u)只在[uj+1,uj+1+p2+1)不为0,而uj[uj,uj+1))=i=jp+2jNi,p2(u)(ui+p1uiuuiQi,1(u)+ui+p1uiui+p1uQi1,1(u))=i=jp+2jNi,p2(u)Qi,2(u)==i=jp+kjNi,pk(u)Qi,k(u)==i=jp+pjNi,pp(u)Qi,p(u)=Nj,0(u)Qj,p(u)=Qj,p(u)
 综上所述, C ( u ) = Q j , p ( u ) , u ∈ [ u j , u j + 1 ) C(u)=Q_{j,p}(u),u\in[u_j,u_{j+1}) C(u)=Qj,p(u),u[uj,uj+1),我们只需要算出 Q j , p ( u ) Q_{j,p}(u) Qj,p(u)就可以了,而 Q j , p ( u ) Q_{j,p}(u) Qj,p(u)的递推计算公式我们已经在上面给出了,这里再写一遍:
Q i , k ( u ) = { Q i    k = 0 u − u i u i + p + 1 − k − u i Q i , k − 1 ( u ) + u i + p + 1 − k − u u i + p + 1 − k − u i Q i − 1 , k − 1 ( u )    k = 1 , ⋯   , p \begin{equation}\nonumber Q_{i,k}(u)=\left\{ \begin{aligned} & Q_i \ \ &k=0 \\ & \frac{u-u_i}{u_{i+p+1-k}-u_i}Q_{i,k-1}(u) + \frac{u_{i+p+1-k}-u}{u_{i+p+1-k}-u_{i}}Q_{i-1,k-1}(u) \ \ &k=1,\cdots,p \\ \end{aligned} \right. \end{equation} Qi,k(u)= Qi  ui+p+1kuiuuiQi,k1(u)+ui+p+1kuiui+p+1kuQi1,k1(u)  k=0k=1,,p
递推计算方法如下图所示,复杂度为 O ( p 2 ) O(p^2) O(p2),代码参考EvaluateDeboor
在这里插入图片描述
(由于网站要梯子,所以这里附EvaluateDeboor的代码:)

def deBoor(k: int, x: int, t, c, p: int):
    """Evaluates S(x).

    Arguments
    ---------
    k: Index of knot interval that contains x.
    x: Position.
    t: Array of knot positions, needs to be padded as described above.
    c: Array of control points.
    p: Degree of B-spline.
    """
    d = [c[j + k - p] for j in range(0, p + 1)] 

    for r in range(1, p + 1):
        for j in range(p, r - 1, -1):
            alpha = (x - t[j + k - p]) / (t[j + 1 + k - r] - t[j + k - p]) 
            d[j] = (1.0 - alpha) * d[j - 1] + alpha * d[j]

    return d[p]

参考文献:

  1. https://en.wikipedia.org/wiki/De_Boor%27s_algorithm
  2. http://www.whudj.cn/?p=535
  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值