使用De Boor递推算法求B样条曲线上的点

使用De Boor递推算法求B样条曲线上的点

概括说明

de Boor 算法是一种递归算法,用于计算 B 样条曲线上给定参数 u 对应的点坐标。

算法的基本思路是:

  1. 首先确定参数 u 所在的节点区间 [u_k, u_k+1]
  2. 然后取出与该节点区间相关的 p + 1 个控制点,作为初始值。
  3. 通过 p 次迭代,每次将相邻的两个点合并为一个新的点,最终得到我们想要的点坐标。

其中 p 是 B 样条曲线的阶数。

B 样条曲线有一个重要性质:在任意一个节点区间 [u_k, u_k+1] 内,曲线段只与 p + 1 个控制点相关(参考下图)。 更具体地说,对于给定的参数 u,它所在的节点区间为 [u_k, u_k+1]。根据 B 样条曲线的性质,在这个节点区间内,曲线段只与索引从 k - pk 的 p + 1个控制点相关。

根据上图,需要强调的是,对于在节点区间 [u_k, u_k+1]内的参数 u,p次B样条曲线只与索引从 k-pk 的 p + 1个控制点相关,对应 N k − p , p N_{k-p,p} Nkp,p~ N k , p N_{k,p} Nk,p非零。 同样,为了更加明确,其对应p-1次B样条曲线只与索引从 k-(p-1)k 的 p 个控制点相关,对应 N k − p + 1 , p − 1 N_{k-p+1,p-1} Nkp+1,p1~ N k , p − 1 N_{k,p-1} Nk,p1非零,比p次B样条曲线所对应的基函数个数刚好少一个。(这里理解的不够充分,可能有错误)

De Boor递推算法求B样条曲线上的点

在确定参数 u 所在的节点区间 [u_k, u_k+1]后,根据B样条曲线定义可知
P ( u ) = ∑ i = 0 n N i , p ( u ) Q i = ∑ i = k − p k N i , p ( u ) Q i P(u) = \sum_{i=0}^n N_{i,p}(u)Q_i = \sum_{i=k-p}^k N_{i,p}(u)Q_i P(u)=i=0nNi,p(u)Qi=i=kpkNi,p(u)Qi
其中, Q i Q_i Qi为B样条轨迹控制点 N i , p ( u ) N_{i,p}(u) Ni,p(u)为B样条轨迹p次基函数

接下来,由以下Cox-de Boor递推公式:
N i , 0 ( u ) = { 1 , if  u i ≤ u < u i + 1 0 , otherwise N i , k ( u ) = u − u i u i + k − u i N i , k − 1 ( u ) + u i + k + 1 − u u i + k + 1 − u i + 1 N i + 1 , k − 1 ( u ) \begin{aligned} N_{i,0}(u) &= \begin{cases} 1, & \text{if } u_i \leq u < u_{i+1}\\ 0, & \text{otherwise} \end{cases} \\ N_{i,k}(u) &= \frac{u - u_i}{u_{i+k} - u_i} N_{i,k-1}(u) + \frac{u_{i+k+1} - u}{u_{i+k+1} - u_{i+1}} N_{i+1,k-1}(u) \end{aligned} Ni,0(u)Ni,k(u)={1,0,if uiu<ui+1otherwise=ui+kuiuuiNi,k1(u)+ui+k+1ui+1ui+k+1uNi+1,k1(u)
带入之前的B样条曲线定义式可得:
P ( u ) = ∑ i = k − p k N i , p ( u ) Q i = ∑ i = k − p k ( 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 = k − p k u − u i u i + p − u i N i , p − 1 ( u ) Q i + ∑ i = k − p k u i + p + 1 − u u i + p + 1 − u i + 1 N i + 1 , p − 1 ( u ) Q i \begin{aligned} P(u) &= \sum_{i=k-p}^k N_{i,p}(u)Q_i \\ &= \sum_{i=k-p}^k \left( \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) \right) Q_i \\ &= \sum_{i=k-p}^k \frac{u - u_i}{u_{i+p} - u_i} N_{i,p-1}(u) Q_i + \sum_{i=k-p}^k \frac{u_{i+p+1} - u}{u_{i+p+1} - u_{i+1}} N_{i+1,p-1}(u) Q_i \end{aligned} P(u)=i=kpkNi,p(u)Qi=i=kpk(ui+puiuuiNi,p1(u)+ui+p+1ui+1ui+p+1uNi+1,p1(u))Qi=i=kpkui+puiuuiNi,p1(u)Qi+i=kpkui+p+1ui+1ui+p+1uNi+1,p1(u)Qi
这里,由于B样条曲线基函数由p次变为p-1次,根据之前结论有
N k − p , p − 1 = 0 N k + 1 , p − 1 = 0 N_{k-p,p-1}=0 \\ N_{k+1,p-1}=0 Nkp,p1=0Nk+1,p1=0

因此,对于上式结果的第一项,有
∑ i = k − p k u − u i u i + p − u i N i , p − 1 ( u ) Q i = ∑ i = k − p + 1 k u − u i u i + p − u i N i , p − 1 ( u ) Q i \sum_{i=k-p}^k \frac{u - u_i}{u_{i+p} - u_i} N_{i,p-1}(u) Q_i = \sum_{i=k-p+1}^k \frac{u - u_i}{u_{i+p} - u_i} N_{i,p-1}(u) Q_i i=kpkui+puiuuiNi,p1(u)Qi=i=kp+1kui+puiuuiNi,p1(u)Qi
对于上式结果的第二项,有
∑ i = k − p k u i + p + 1 − u u i + p + 1 − u i + 1 N i + 1 , p − 1 ( u ) Q i = ∑ i = k − p k − 1 u i + p + 1 − u u i + p + 1 − u i + 1 N i + 1 , p − 1 ( u ) Q i = ∑ i = k − p + 1 k u i + p − u u i + p − u i N i , p − 1 ( u ) Q i − 1 \begin{aligned} &\sum_{i=k-p}^k \frac{u_{i+p+1} - u}{u_{i+p+1} - u_{i+1}} N_{i+1,p-1}(u) Q_i \\ = &\sum_{i=k-p}^{k-1} \frac{u_{i+p+1} - u}{u_{i+p+1} - u_{i+1}} N_{i+1,p-1}(u) Q_i \\ = &\sum_{i=k-p+1}^k \frac{u_{i+p} - u}{u_{i+p} - u_{i}} N_{i,p-1}(u) Q_{i-1} \end{aligned} ==i=kpkui+p+1ui+1ui+p+1uNi+1,p1(u)Qii=kpk1ui+p+1ui+1ui+p+1uNi+1,p1(u)Qii=kp+1kui+puiui+puNi,p1(u)Qi1
因此,
P ( u ) = ∑ i = k − p + 1 k ( u − u i u i + p − u i Q i + u i + p − u u i + p − u i Q i − 1 ) N i , p − 1 ( u ) \begin{aligned} P(u) &= \sum_{i=k-p+1}^k \bigg( \frac{u - u_i}{u_{i+p} - u_i} Q_i + \frac{u_{i+p} - u}{u_{i+p} - u_{i}} Q_{i-1} \bigg) N_{i,p-1}(u) \end{aligned} P(u)=i=kp+1k(ui+puiuuiQi+ui+puiui+puQi1)Ni,p1(u)

Q i , 1 = u − u i u i + p − u i Q i + u i + p − u u i + p − u i Q i − 1 Q_{i,1} = \frac{u - u_i}{u_{i+p} - u_i} Q_i + \frac{u_{i+p} - u}{u_{i+p} - u_{i}} Q_{i-1} Qi,1=ui+puiuuiQi+ui+puiui+puQi1
那么,
P ( u ) = ∑ i = k − p + 1 k N i , p − 1 ( u ) Q i , 1 \begin{aligned} P(u) &= \sum_{i=k-p+1}^k N_{i,p-1}(u) Q_{i,1} \end{aligned} P(u)=i=kp+1kNi,p1(u)Qi,1
依此递推,可得
P ( u ) = ∑ i = k − p + r k N i , p − r ( u ) Q i , r \begin{aligned} P(u) &= \sum_{i=k-p+r}^k N_{i,p-r}(u) Q_{i,r} \end{aligned} P(u)=i=kp+rkNi,pr(u)Qi,r
其中,
Q i , r = u − u i u i + p + 1 − r − u i Q i , r − 1 + u i + p + 1 − r − u u i + p + 1 − r − u i Q i − 1 , r − 1 Q_{i,r} = \frac{u - u_i}{u_{i+p+1-r} - u_i} Q_{i,r-1} + \frac{u_{i+p+1-r} - u}{u_{i+p+1-r} - u_{i}} Q_{i-1,r-1} Qi,r=ui+p+1ruiuuiQi,r1+ui+p+1ruiui+p+1ruQi1,r1
如果我们记 α = u − u i u i + p + 1 − r − u i \alpha = \frac{u - u_i}{u_{i+p+1-r} - u_i} α=ui+p+1ruiuui,那么有
Q i , r = α Q i , r − 1 + ( 1 − α ) Q i − 1 , r − 1 Q_{i,r} = \alpha Q_{i,r-1} + (1-\alpha) Q_{i-1,r-1} Qi,r=αQi,r1+(1α)Qi1,r1
De Boor递推算法实际上就是通过计算权重系数 alpha进行线性插值,将相邻的两个控制点合并为一个新的控制点,通过 p 次迭代,最终即可得到我们想要的点坐标。

  • 17
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值