样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)

贝塞尔曲线插值与B样条插值

前言: 这篇是“样条曲线”的接续,前面主要集中在了理论部分,这篇文章主要内容是贝塞尔曲线与B样条是如何应用到插值中的。

前篇:样条曲线

文章目录

  • 贝塞尔曲线插值与B样条插值
    • 0. 插值问题
    • 1. 贝塞尔曲线插值
      • 1.1 曲线的数学描述
      • 1.2 曲线插值
      • 1.3 代码实现
    • 2. B样条插值
      • 2.1 数学表达和一些补充
      • 2.2 曲线插值
        • 2.2.1 三次 clamped B-样条
        • 2.2.2 B样条插值方程的获取
        • 2.2.3 方程求解,确定样条曲线
      • 3. 代码实现(挖坑)
    • 3. 三次样条插值
    • 4. 总结

0. 插值问题

问题是一切发展的动力。还是从问题出发,考虑怎么通过数学手段解决问题。

对于插值问题,就是已知一些离散点,插值出一些新的点,使得所有点形成一条光滑曲线。

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第1张图片

如已知六个点 P 0 , P 1 , ⋯   , P 5 P_0,P_1,\cdots,P_5 P0,P1,,P5 ,如图红色点 ( 1 , 1 ) , ( 3 , 6 ) , ( 6 , 3 ) , ( 8 , 0 ) , ( 11 , 6 ) , ( 12 , 12 ) (1,1),(3,6),(6,3),(8,0),(11,6),(12,12) (1,1),(3,6),(6,3),(8,0),(11,6),(12,12) ,如何通过插值生成类似于图中蓝色光滑曲线,而非僵硬的绿色多线段。

1. 贝塞尔曲线插值

1.1 曲线的数学描述

依据前篇的数学描述,假设一共 n + 1 n+1 n+1 个控制点 P 0 , P 1 , ⋯   , P n P_0,P_1,\cdots,P_n P0,P1,,Pn ,这 n + 1 n+1 n+1 个点可以确定一条 n n n 次贝塞尔曲线。可以用如下式计算曲线上任意点坐标
B ( t ) = ∑ i = 0 n C n i ( 1 − t ) n − i t i P i B(t) = \sum\limits_{i=0}^n C_n^i(1-t)^{n-i}t^i P_i B(t)=i=0nCni(1t)nitiPi
特别的,有几个常用贝塞尔曲线

二次贝塞尔曲线
B ( t ) = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 ,       t ∈ [ 0 , 1 ] B(t) = (1-t)^2P_0 + 2t(1-t)P_1 + t^2 P_2, \ \ \ \ \ t\in[0,1] B(t)=(1t)2P0+2t(1t)P1+t2P2,     t[0,1]
三次贝塞尔曲线
B ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 B(t) = (1-t)^3P_0 + 3t(1-t)^2P_1 + 3t^2(1-t)P_2 + t^3P_3 B(t)=(1t)3P0+3t(1t)2P1+3t2(1t)P2+t3P3

1.2 曲线插值

这里以最常用的三次贝塞尔曲线为例,探究其插值应用。

对于贝塞尔曲线,有三个要点:

  • 其是通过控制点来生成的,控制点不全在最终曲线上。
  • 控制点首末的两点是最终曲线的端点(意味着首末控制点会在最终曲线上),且各自与相邻点的连线同最终曲线相切。
  • 两个贝塞尔曲线如果平滑连接,则需要连接点与其左右相邻两端点共线。

基于要点2,可以在把两个已知点作为三次贝塞尔曲线的两个端点 P 0 , P 3 P_0,P_3 P0,P3,然后想办法再指定两个控制点 P 2 , P 3 P_2,P_3 P2,P3 即可。

且控制点设定要满足贝塞尔曲线相连时平滑。

总结一下就是:

  • 在两点中生成贝塞尔曲线,且这两个点作为三次贝塞尔曲线的两个端点。
  • 再确定额外两个控制点,控制点设定满足两相邻的贝塞尔曲线连接点和其连接点左右控制点共线。

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第2张图片

如上图是由两个贝塞尔曲线组成的一条平滑曲线,经过点 P 1 , P 2 , P 3 P_1,P_2,P_3 P1,P2,P3 ,且 P 1 , P 2 P_1,P_2 P1,P2 是第一条三次贝塞尔曲线的两端点, P 2 , P 3 P_2,P_3 P2,P3 是第二条三次贝塞尔曲线的两端点。我们需要的是每个贝塞尔曲线再设定两个控制点即可。

最简单直接的思路就是列方程,解方程。如上,两条贝塞尔曲线,一共四个未知点(控制点),需要四个方程。

  • 令其连接点满足 c 1 c^1 c1 连续,也即 P 1 2 , P 2 , P 2 1 P_1^2,P_2,P_2^1 P12,P2,P21 共线。此处有一个方程。

  • 对连接点处 c 2 c^2 c2 连续也加以考虑。此处也有一个方程。

    还差两个方程。限制两端点即可。比如二阶导为某一定值,或三阶导为某一定值。诸如此类,这一点在后面会有详细描述。B样条中,简单的三次样条中都有详细描述。

这种思路原理直接且简单,不再用代码实现。无非就是列方程、解方程的问题。这一点在B样条中有详细类似的过程,但比这复杂的多。

下面详细描述一种有趣的解决方案:

最重要的一点是满足 P 1 2 , P 2 , P 2 1 P_1^2,P_2,P_2^1 P12,P2,P21 三点共线,所以只要关注 P 1 2 , P 2 1 P_1^2,P_2^1 P12,P21 的设定即可,因为 P 1 1 , P 2 2 P_1^1,P_2^2 P11,P22 可以依据同样的规则设定。解决方案如下, P 1 2 , P 2 1 P_1^2,P_2^1 P12,P21 肯定不是凭空产生,需要依赖于已有的一些点。而其中可依赖的点有 P 1 , P 2 , P 3 P_1,P_2,P_3 P1,P2,P3

第一种思路可以在 P 1 , P 2 P_1,P_2 P1,P2 连线上,控制一个比例因子生成一点,同样 P 2 , P 3 P_2,P_3 P2,P3 连线上亦如是。如上图中的蓝色两点,然后连接两点形成一条线段,平移线段,使其通过 P 2 P_2 P2 ,平移后的两点就是我们需要的 P 1 2 , P 2 1 P_1^2,P_2^1 P12,P21

第二种思路可以直接在 P 1 , P 3 P_1,P_3 P1,P3 连线上直接根据某特定比例因此生成两点,按照同样的平移步骤,平移后的该两点当作控制点。当然比例因此可以根据先验信息,比如参考线 P 1 P 2 P_1P_2 P1P2 和线 P 2 , P 3 P_2,P_3 P2,P3 长度比的数值。等等。

1.3 代码实现

import numpy as np
import matplotlib.pyplot as plt

def getInterpolationPoints(controlPoints, tList):
	n = len(controlPoints)-1
	interPoints = []
	for t in tList:
		Bt = np.zeros(2, np.float64)
		for i in range(len(controlPoints)):
			Bt = Bt + comb(n,i) * np.power(1-t,n-i) * np.power(t,i) * np.array(controlPoints[i])
		interPoints.append(list(Bt))

	return interPoints


def getControlPointList(pointsArray, k1=-1, k2=1):
	points = np.array(pointsArray)
	index = points.shape[0] - 2

	res = []
	for i in range(index):
		tmp = points[i:i+3]
		p1 = tmp[0]
		p2 = tmp[1]
		p3 = tmp[2]

		if k1 == -1:
			l1 = np.sqrt(np.sum((p1-p2)**2))
			l2 = np.sqrt(np.sum((p2-p3)**2))
			k1 = l1/(l1+l2)
			k2 = l2/(l1+l2)

		p01 = k1*p1 + (1-k1)*p2
		p02 = (1-k2)*p2 + k2*p3
		p00 = k2*p01 + (1-k2)*p02
		
		sub = p2 - p00
		p12 = p01 + sub
		p21 = p02 + sub

		res.append(p12)
		res.append(p21)
	pFirst = points[0] + 0.1*(res[0] - points[0])
	pEnd = points[-1] + 0.1*(res[-1] - points[-1])
	res.insert(0,pFirst)
	res.append(pEnd)

	return np.array(res)

if __name__ == '__main__':
	points = [[1,1],[3,6],[6,3],[8,0],[11,6],[12,12]]
	controlP = getControlPointList(points)
	l = len(points) - 1
	figure = plt.figure()
	t = np.linspace(0,1,50)
	for i in range(l):
		p = np.array([points[i], controlP[2*i], controlP[2*i+1], points[i+1]])
		interPoints = getInterpolationPoints(p, t)
		x = np.array(interPoints)[:,0]
		y = np.array(interPoints)[:,1]
		plt.plot(x,y)
	plt.scatter(np.array(points)[:,0],np.array(points)[:,1],color='gray')
	plt.show()

结果

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第3张图片

分析

结果如预期一样,不会特别好,但可以确定该种方法是可行的。结果受比例因子 k 1 , k 2 k1,k2 k1,k2 影响很大,受原始点(型值点)的密度、趋势变化影响。

观察也知,该想法对于没有明显趋势反转(凸曲线变为凹曲线)的点效果还行,但对于转折点,效果不太行。分析其原因,是在起初分析时,使用的图是便没有考虑这种情况。如下,

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第4张图片

而该问题的本质原因,是因为该思路只限制了连接点处 c 1 c^1 c1 连续,而对 c 2 c^2 c2 连续没有考虑,所以就出现了结果图中连接点确实看起来很平滑,但后面的过渡不太好。这也侧面说明了插值问题中 c 2 c^2 c2 连续对于平滑是很重要的。

2. B样条插值

2.1 数学表达和一些补充

具体推导见前篇:样条曲线

对于 n+1 个控制点 P 0 , P 1 , ⋯   , P n P_0,P_1,\cdots,P_n P0,P1,,Pn ,有一个包含 m+1 个节点的列表(或节点向量) t 0 , t 1 , ⋯   , t m {t_0,t_1,\cdots,t_{m}} t0,t1,,tm ,其 k 次B样条曲线表达式为(且m=n+k+1)
P ( t ) = ∑ i = 0 n B i , k ( t )   P i P(t) = \sum\limits_{i=0}^n B_{i,k}(t)\ P_i P(t)=i=0nBi,k(t) Pi
其中 B i , k ( t ) B_{i,k}(t) Bi,k(t) 称为 k 次 B 样条基函数,也叫调和函数。且 B i , k ( t ) B_{i,k}(t) Bi,k(t) 满足如下递推式(de Boor递推式
k = 0 ,      B i , 0 ( t ) = { 0 ,      t ∈ [ t i , t i + 1 ] 1 ,          O t h e r w i s e k > 0 ,      B i , k ( t ) = t − t i t i + k − t i B i , k − 1 ( t ) + t i + k + 1 − t t i + k + 1 − t i + 1 B i + 1 , k − 1 ( t ) k = 0,\ \ \ \ B_{i,0}(t) = \left\{ \begin{matrix} 0, \ \ \ \ t\in[t_i,t_i+1] \\ 1, \ \ \ \ \ \ \ \ Otherwise \end{matrix} \right.\\ k > 0,\ \ \ \ B_{i,k}(t) = \frac{t-t_i}{t_{i+k}-t_i} B_{i,k-1}(t) + \frac{t_{i+k+1}-t}{t_{i+k+1}-t_{i+1}} B_{i+1,k-1}(t) k=0,    Bi,0(t)={0,    t[ti,ti+1]1,        Otherwisek>0,    Bi,k(t)=ti+ktittiBi,k1(t)+ti+k+1ti+1ti+k+1tBi+1,k1(t)

前篇中在尝试各种节点列表时,得到了很多结果,但对结果总结分析较少,以下是一些非常重要的小总结和补充

  • 前篇实例中许多曲线看起来很奇怪,是因为没有考虑定义域,也即由基函数完全支持的部分。该定义域在前篇中有提到,是 [ t k , t n + 1 ]    o r    [ t k , t m − k ] [t_k,t_{n+1}]\ \ or\ \ [t_k,t_{m-k}] [tk,tn+1]  or  [tk,tmk] ,这点十分重要。在考虑定义域的情况下,曲线平滑且不会显示地很奇怪。

    定义域是依赖于节点列表的,值得一提的是,如果想要较广定义域 [ t k , t n + 1 ] [t_k,t_{n+1}] [tk,tn+1],从式子上来看,至少有两种思路

    • 使得定义域内 t 区间数量尽量多,这种情况在节点均匀分布时可用,别的情况可能没用。即 k k k 尽量小, n + 1 n+1 n+1 尽量大,也即 m − ( n + 1 ) m-(n+1) m(n+1) 尽量小, n + 1 n+1 n+1 尽量大。也即 m m m 与 n+1 尽量接近,n+1 尽量大。换句话说,节点个数尽量多,控制点数与节点数接近。

      使用该方法重新设定节点列表绘制前篇中第一个实例曲线
      c o n t r o l P o n t s = [ [ 50 , 50 ] , [ 100 , 300 ] , [ 300 , 100 ] , [ 380 , 200 ] , [ 400 , 600 ] ] k n o t s = { 0 , 1 20 , 2 20 , 8 20 , 14 20 , 19 20 , 1 , 1 } n = 4 , m = 7 , k = 2 d o m a i n = [ t 3 , t 5 ] = [ 2 20 , 19 20 ] controlPonts = [[50,50], [100,300], [300,100], [380,200], [400,600]]\\ knots = \{0,\frac{1}{20},\frac{2}{20},\frac{8}{20},\frac{14}{20},\frac{19}{20},1,1\} \\ n=4,m=7,k=2 \\ domain = [t_3,t_5] = [\frac{2}{20},\frac{19}{20}] controlPonts=[[50,50],[100,300],[300,100],[380,200],[400,600]]knots={0,201,202,208,2014,2019,1,1}n=4,m=7,k=2domain=[t3,t5]=[202,2019]
      定义域已经几乎包括了所有区间,最终定义域内曲线如下

      样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第5张图片

      曲线没有包含全部,但 [ 2 20 , 19 20 ] [\frac{2}{20},\frac{19}{20}] [202,2019] 也几乎包含全部了。Excellent!

    • 使得定义域内 t 区间跨度大,其实严格来说就是我们要解决的问题本质,第一种思路只是实现第二种的一种解决方案。跨度大,也即 t n + 1 − t k t_{n+1} - t_k tn+1tk 尽量大。如果 m , n , k m,n,k m,n,k 确定的情况下,如何确保呢。可以改变节点列表中的 t 的分布。我们需要的是区间 [ t k , t m − k ] [t_k,t_{m-k}] [tk,tmk] ,如果前 k+1 个 t 数据全部设为 0,而第 m-k 个 t 之后的数据全部设为 1。那么区间 [ t k , t m − k ] [t_k,t_{m-k}] [tk,tmk] 跨度不就是 [ 0 , 1 ] [0,1] [0,1] 嘛,也就是整个曲线嘛,很棒的想法。从曲线的角度来看,此时就是我们绘制出的整个曲线。就没有之前绘图中出现的奇奇怪怪的曲线变化了。

      使用该方法重新设定节点列表绘制前篇中第一个实例曲线
      c o n t r o l P o n t s = [ [ 50 , 50 ] , [ 100 , 300 ] , [ 300 , 100 ] , [ 380 , 200 ] , [ 400 , 600 ] ] k n o t s = { 0 , 0 , 0 , 0 , 1 2 , 1 , 1 , 1 , 1 } n = 4 , m = 8 , k = 3 d o m a i n = [ 0 , 1 ] controlPonts = [[50,50], [100,300], [300,100], [380,200], [400,600]]\\ knots = \{0,0,0,0,\frac{1}{2},1,1,1,1\} \\ n=4,m=8,k=3 \\ domain = [0,1] controlPonts=[[50,50],[100,300],[300,100],[380,200],[400,600]]knots={0,0,0,0,21,1,1,1,1}n=4,m=8,k=3domain=[0,1]
      样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第6张图片

      不再有奇怪的点,生成的曲线也十分"完美"。

    第二种思路极其重要,如果 [ t k , t m − k ] [t_k,t_{m-k}] [tk,tmk] 区间内节点又均匀分布,该样条曲线也被称作为准均匀样条。在首末两端设定一定数量的 0,1 的方法在样条曲线中极其常见,因为它确实很实用啊。

  • 前篇中也提到了一个有趣且及其重要的现象,即 当节点列表中首末两端 0,1 重复 k+1次时,那么生成的样条曲线首末两端同贝塞尔曲线一样,都是实际原始点(型值点)的首末两点。该样条曲线也有个特定的名字,叫 clamped B-spline curves 。结合上面第二种思路提到的内容,我们得到的样条曲线也就是整条曲线。

  • 其中还有一个 Wrapping 问题,即,使得生成曲线形成闭环。待用到时再探究和总结(挖坑)。

2.2 曲线插值

贝塞尔曲线中应用插值时提到了生成曲线端点为数据点(型值点)的重要性,该特点是实现插值的基础,或者说是实现两点间插值的基础。幸运的是,B样条中有一种样条满足这样的条件,即上述的 clamped B-spline。需要节点首末的 0 , 1 0,1 0,1 重复 k + 1 k+1 k+1 次。

我们常用三次的样条插值,下面就以三次样条插值为例,对其进行详细分析。

2.2.1 三次 clamped B-样条

对于三次 camped B-样条,有以下要点

  • 次数 k
    k = 3 k = 3 k=3

  • 型值点个数 n + 1 n+1 n+1 与 节点个数 m + 1 m+1 m+1 满足

m = n + k + 1    ⇒    m − n = 4 m = n + k + 1\ \ \Rightarrow\ \ m - n = 4 m=n+k+1    mn=4

  • camped 情况下,节点 t 0 , t 1 , ⋯   , t m t_0,t_1,\cdots,t_m t0,t1,,tm 满足
    { t 0 = t 1 = t 2 = t 3 = 0 t 4 , t 5 , ⋯   , t n ∈ [ 0 , 1 ] t n + 1 = t n + 2 = t n + 3 = t n + 4 = 1 \left\{ \begin{matrix} \begin{aligned} &t_0 = t_1 = t_2 = t_3 = 0 \\ &t_4,t_5,\cdots,t_{n} \in [0,1] \\ &t_{n+1} = t_{n+2} = t_{n+3} = t_{n+4} = 1 \end{aligned} \end{matrix} \right. t0=t1=t2=t3=0t4,t5,,tn[0,1]tn+1=tn+2=tn+3=tn+4=1
    特别地,如果使用准均匀样条,即 t 4 , t 5 , ⋯   , t n t_4,t_5,\cdots,t_n t4,t5,,tn 均匀分布(当然也可以使用别的分布方法),即有
    t 4 = 4 − 3 n + 1 − k = 1 n − 2 t 5 = 5 − 3 n − 2 = 2 n − 2 ⋯ t j = j − 3 n − 2 ⋯ t n = n − 3 n − 2 \begin{aligned} &t_4 = \frac{4-3}{n+1-k} = \frac{1}{n-2}\\ &t_5 = \frac{5-3}{n-2} = \frac{2}{n-2} \\ &\cdots \\ &t_j = \frac{j-3}{n-2} \\ &\cdots \\ &t_n = \frac{n-3}{n-2} \end{aligned} t4=n+1k43=n21t5=n253=n22tj=n2j3tn=n2n3

为了形象展示,使用之前类似图表来表示

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第7张图片

注意,其中橙色标注的区间为 [ 0 , 0 ] o r [ 1 , 1 ] [0,0] or [1,1] [0,0]or[1,1] 长度为 0,另,又因为其不在定义域内,我们不作计算,也即,其 0 次 基函数值始终记为 0。假设我们计算定义域内某区间 [ t j , t j + 1 ] [t_j,t_{j+1}] [tj,tj+1] 的曲线,按照前篇介绍的递推计算公式,0 次基函数 b j , 0 = 1 b_{j,0} = 1 bj,0=1 其余为 0 ,正如上表所示。

我们要得到 n+1 个点的权重,即 B 0 , 3 , B 1 , 3 , ⋯   , B n , 3 B_{0,3},B_{1,3},\cdots,B_{n,3} B0,3,B1,3,,Bn,3 ,由上我们知道,对于一段区间(如 [ t j , t j + 1 ] [t_j,t_{j+1}] [tj,tj+1]),三次基函数只会有四个非零值,分别为 B j , 3 , B j − 1 , 3 , B j − 2 , 3 , B j − 3 , 3 B_{j,3},B_{j-1,3},B_{j-2,3},B_{j-3,3} Bj,3,Bj1,3,Bj2,3,Bj3,3

如前篇所述,递推公式为
b j , k ( t ) = t − t j t j + k − t j   b j , k − 1 ( t ) + t j + k + 1 − t t j + k + 1 − t j + 1   b j + 1 , k − 1 ( t ) b_{j,k}(t) = \frac{t-t_j}{t_{j+k}-t_j}\ b_{j,k-1}(t)+\frac{t_{j+k+1}-t}{t_{j+k+1}-t_{j+1}}\ b_{j+1,k-1}(t) bj,k(t)=tj+ktjttj bj,k1(t)+tj+k+1tj+1tj+k+1t bj+1,k1(t)

四个权重求解具体如下,当 t ∈ [ j , j + 1 ] t\in[j,j+1] t[j,j+1]

  • 0 次 基函数有一个非零 b j , 0 b_{j,0} bj,0

    b j , 0 = 1 b_{j,0}=1 bj,0=1

  • 1 次 基函数有两个非零 b j , 1 , b j − 1 , 1 b_{j,1},b_{j-1,1} bj,1,bj1,1

    b j , 1 ( t ) = t − t j t j + 1 − t j   b j , 0 ( t ) + t j + 2 − t t j + 2 − t j + 1   b j + 1 , 0 ( t ) = t − t j t j + 1 − t j \begin{aligned} b_{j,1}(t) & = \frac{t-t_j}{t_{j+1}-t_j}\ b_{j,0}(t)+\frac{t_{j+2}-t}{t_{j+2}-t_{j+1}}\ b_{j+1,0}(t) \\ & = \frac{t-t_j}{t_{j+1}-t_j} \end{aligned} bj,1(t)=tj+1tjttj bj,0(t)+tj+2tj+1tj+2t bj+1,0(t)=tj+1tjttj

    b j − 1 , 1 ( t ) = t − t j − 1 t j − t j − 1   b j − 1 , 0 ( t ) + t j + 1 − t t j + 1 − t j   b j , 0 ( t ) = t j + 1 − t t j + 1 − t j \begin{aligned} b_{j-1,1}(t) & = \frac{t-t_{j-1}}{t_{j}-t_{j-1}}\ b_{j-1,0}(t)+\frac{t_{j+1}-t}{t_{j+1}-t_{j}}\ b_{j,0}(t) \\ & = \frac{t_{j+1}-t}{t_{j+1}-t_{j}} \end{aligned} bj1,1(t)=tjtj1ttj1 bj1,0(t)+tj+1tjtj+1t bj,0(t)=tj+1tjtj+1t

  • 2 次 基函数有三个非零 b j , 2 , b j − 1 , 2 , b j − 2 , 2 b_{j,2},b_{j-1,2},b_{j-2,2} bj,2,bj1,2,bj2,2
    b j , 2 ( t ) = t − t j t j + 2 − t j   b j , 1 ( t ) + t j + 3 − t t j + 3 − t j + 1   b j + 1 , 1 ( t ) = t − t j t j + 2 − t j ⋅ t − t j t j + 1 − t j = ( t − t j ) 2 ( t j + 2 − t j ) ( t j + 1 − t j ) \begin{aligned} b_{j,2}(t) & = \frac{t-t_j}{t_{j+2}-t_j}\ b_{j,1}(t)+\frac{t_{j+3}-t}{t_{j+3}-t_{j+1}}\ b_{j+1,1}(t) \\ & = \frac{t-t_j}{t_{j+2}-t_j} \cdot \frac{t-t_j}{t_{j+1}-t_j} \\ & = \frac{(t-t_j)^2}{(t_{j+2}-t_j)(t_{j+1}-t_j)} \end{aligned} bj,2(t)=tj+2tjttj bj,1(t)+tj+3tj+1tj+3t bj+1,1(t)=tj+2tjttjtj+1tjttj=(tj+2tj)(tj+1tj)(ttj)2

    b j − 1 , 2 ( t ) = t − t j − 1 t j + 1 − t j − 1   b j − 1 , 1 ( t ) + t j + 2 − t t j + 2 − t j   b j , 1 ( t ) = t − t j − 1 t j + 1 − t j − 1 ⋅ t j + 1 − t t j + 1 − t j + t j + 2 − t t j + 2 − t j ⋅ t − t j t j + 1 − t j = ( t − t j − 1 ) ( t j + 1 − t ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) ( t − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) \begin{aligned} b_{j-1,2}(t) & = \frac{t-t_{j-1}}{t_{j+1}-t_{j-1}}\ b_{j-1,1}(t)+\frac{t_{j+2}-t}{t_{j+2}-t_{j}}\ b_{j,1}(t) \\ & = \frac{t-t_{j-1}}{t_{j+1}-t_{j-1}}\cdot \frac{t_{j+1}-t}{t_{j+1}-t_{j}} +\frac{t_{j+2}-t}{t_{j+2}-t_{j}}\cdot \frac{t-t_j}{t_{j+1}-t_j} \\ & = \frac{(t-t_{j-1})(t_{j+1}-t)}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)(t-t_j)}{(t_{j+2}-t_{j})(t_{j+1}-t_j)} \end{aligned} bj1,2(t)=tj+1tj1ttj1 bj1,1(t)+tj+2tjtj+2t bj,1(t)=tj+1tj1ttj1tj+1tjtj+1t+tj+2tjtj+2ttj+1tjttj=(tj+1tj1)(tj+1tj)(ttj1)(tj+1t)+(tj+2tj)(tj+1tj)(tj+2t)(ttj)

    b j − 2 , 2 ( t ) = t − t j − 2 t j − t j − 2   b j − 2 , 1 ( t ) + t j + 1 − t t j + 1 − t j − 1   b j − 1 , 1 ( t ) = t j + 1 − t t j + 1 − t j − 1 ⋅ t j + 1 − t t j + 1 − t j = ( t j + 1 − t ) 2 ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) \begin{aligned} b_{j-2,2}(t) & = \frac{t-t_{j-2}}{t_{j}-t_{j-2}}\ b_{j-2,1}(t)+\frac{t_{j+1}-t}{t_{j+1}-t_{j-1}}\ b_{j-1,1}(t) \\ & = \frac{t_{j+1}-t}{t_{j+1}-t_{j-1}}\cdot \frac{t_{j+1}-t}{t_{j+1}-t_{j}} \\ & = \frac{(t_{j+1}-t)^2}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} \end{aligned} bj2,2(t)=tjtj2ttj2 bj2,1(t)+tj+1tj1tj+1t bj1,1(t)=tj+1tj1tj+1ttj+1tjtj+1t=(tj+1tj1)(tj+1tj)(tj+1t)2

  • 3 次 基函数有四个非零 b j , 3 , b j − 1 , 3 , b j − 2 , 3 , b j − 3 , 3 b_{j,3},b_{j-1,3},b_{j-2,3},b_{j-3,3} bj,3,bj1,3,bj2,3,bj3,3

    b j , 3 ( t ) = t − t j t j + 3 − t j   b j , 2 ( t ) + t j + 4 − t t j + 4 − t j + 1   b j + 1 , 2 ( t ) = t − t j t j + 3 − t j ⋅ ( t − t j ) 2 ( t j + 2 − t j ) ( t j + 1 − t j ) = ( t − t j ) 3 ( t j + 3 − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) \begin{aligned} b_{j,3}(t) &= \frac{t-t_j}{t_{j+3}-t_j}\ b_{j,2}(t)+\frac{t_{j+4}-t}{t_{j+4}-t_{j+1}}\ b_{j+1,2}(t) \\ & = \frac{t-t_j}{t_{j+3}-t_j}\cdot \frac{(t-t_j)^2}{(t_{j+2}-t_j)(t_{j+1}-t_j)} \\ & = \frac{(t-t_j)^3}{(t_{j+3}-t_j)(t_{j+2}-t_j)(t_{j+1}-t_j)} \end{aligned} bj,3(t)=tj+3tjttj bj,2(t)+tj+4tj+1tj+4t bj+1,2(t)=tj+3tjttj(tj+2tj)(tj+1tj)(ttj)2=(tj+3tj)(tj+2tj)(tj+1tj)(ttj)3

    b j − 1 , 3 ( t ) = t − t j − 1 t j + 2 − t j − 1   b j − 1 , 2 ( t ) + t j + 3 − t t j + 3 − t j   b j , 2 ( t ) = t − t j − 1 t j + 2 − t j − 1 ⋅ [ ( t − t j − 1 ) ( t j + 1 − t ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) ( t − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) ] + t j + 3 − t t j + 3 − t j ⋅ ( t − t j ) 2 ( t j + 2 − t j ) ( t j + 1 − t j ) = ( t − t j − 1 ) 2 ( t j + 1 − t ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t − t j − 1 ) ( t j + 2 − t ) ( t − t j ) ( t j + 2 − t j − 1 ) ( t j + 2 − t j ) ( t j + 1 − t j ) + ( t j + 3 − t ) ( t − t j ) 2 ( t j + 3 − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) \begin{aligned} b_{j-1,3}(t) &= \frac{t-t_{j-1}}{t_{j+2}-t_{j-1}}\ b_{j-1,2}(t)+\frac{t_{j+3}-t}{t_{j+3}-t_{j}}\ b_{j,2}(t) \\ & = \frac{t-t_{j-1}}{t_{j+2}-t_{j-1}}\cdot [\frac{(t-t_{j-1})(t_{j+1}-t)}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)(t-t_j)}{(t_{j+2}-t_{j})(t_{j+1}-t_j)}] + \frac{t_{j+3}-t}{t_{j+3}-t_{j}}\cdot \frac{(t-t_j)^2}{(t_{j+2}-t_j)(t_{j+1}-t_j)} \\ & = \frac{(t-t_{j-1})^2(t_{j+1}-t)}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t-t_{j-1})(t_{j+2}-t)(t-t_j)}{(t_{j+2}-t_{j-1})(t_{j+2}-t_{j})(t_{j+1}-t_j)} + \frac{(t_{j+3}-t)(t-t_j)^2}{(t_{j+3}-t_j)(t_{j+2}-t_j)(t_{j+1}-t_j)} \end{aligned} bj1,3(t)=tj+2tj1ttj1 bj1,2(t)+tj+3tjtj+3t bj,2(t)=tj+2tj1ttj1[(tj+1tj1)(tj+1tj)(ttj1)(tj+1t)+(tj+2tj)(tj+1tj)(tj+2t)(ttj)]+tj+3tjtj+3t(tj+2tj)(tj+1tj)(ttj)2=(tj+2tj1)(tj+1tj1)(tj+1tj)(ttj1)2(tj+1t)+(tj+2tj1)(tj+2tj)(tj+1tj)(ttj1)(tj+2t)(ttj)+(tj+3tj)(tj+2tj)(tj+1tj)(tj+3t)(ttj)2

    b j − 2 , 3 ( t ) = t − t j − 2 t j + 1 − t j − 2   b j − 2 , 2 ( t ) + t j + 2 − t t j + 2 − t j − 1   b j − 1 , 2 ( t ) = t − t j − 2 t j + 1 − t j − 2 ⋅ ( t j + 1 − t ) ( t j + 1 − t ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + t j + 2 − t t j + 2 − t j − 1 ⋅ [ ( t − t j − 1 ) ( t j + 1 − t ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) ( t − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) ] = ( t − t j − 2 ) ( t j + 1 − t ) 2 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) ( t − t j − 1 ) ( t j + 1 − t ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) 2 ( t − t j ) ( t j + 2 − t j − 1 ) ( t j + 2 − t j ) ( t j + 1 − t j ) \begin{aligned} b_{j-2,3}(t) &= \frac{t-t_{j-2}}{t_{j+1}-t_{j-2}}\ b_{j-2,2}(t)+\frac{t_{j+2}-t}{t_{j+2}-t_{j-1}}\ b_{j-1,2}(t) \\ & = \frac{t-t_{j-2}}{t_{j+1}-t_{j-2}}\cdot \frac{(t_{j+1}-t)(t_{j+1}-t)}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{t_{j+2}-t}{t_{j+2}-t_{j-1}}\cdot [\frac{(t-t_{j-1})(t_{j+1}-t)}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)(t-t_j)}{(t_{j+2}-t_{j})(t_{j+1}-t_j)}] \\ & = \frac{(t-t_{j-2})(t_{j+1}-t)^2}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)(t-t_{j-1})(t_{j+1}-t)}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)^2(t-t_j)}{(t_{j+2}-t_{j-1})(t_{j+2}-t_{j})(t_{j+1}-t_j)} \end{aligned} bj2,3(t)=tj+1tj2ttj2 bj2,2(t)+tj+2tj1tj+2t bj1,2(t)=tj+1tj2ttj2(tj+1tj1)(tj+1tj)(tj+1t)(tj+1t)+tj+2tj1tj+2t[(tj+1tj1)(tj+1tj)(ttj1)(tj+1t)+(tj+2tj)(tj+1tj)(tj+2t)(ttj)]=(tj+1tj2)(tj+1tj1)(tj+1tj)(ttj2)(tj+1t)2+(tj+2tj1)(tj+1tj1)(tj+1tj)(tj+2t)(ttj1)(tj+1t)+(tj+2tj1)(tj+2tj)(tj+1tj)(tj+2t)2(ttj)

    b j − 3 , 3 ( t ) = t − t j − 3 t j − t j − 3   b j − 3 , 2 ( t ) + t j + 1 − t t j + 1 − t j − 2   b j − 2 , 2 ( t ) = t j + 1 − t t j + 1 − t j − 2 ⋅ ( t j + 1 − t ) 2 ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) = ( t j + 1 − t ) 3 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) \begin{aligned} b_{j-3,3}(t) &= \frac{t-t_{j-3}}{t_{j}-t_{j-3}}\ b_{j-3,2}(t)+\frac{t_{j+1}-t}{t_{j+1}-t_{j-2}}\ b_{j-2,2}(t) \\ &= \frac{t_{j+1}-t}{t_{j+1}-t_{j-2}}\cdot \frac{(t_{j+1}-t)^2}{(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} \\ &= \frac{(t_{j+1}-t)^3}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} \end{aligned} bj3,3(t)=tjtj3ttj3 bj3,2(t)+tj+1tj2tj+1t bj2,2(t)=tj+1tj2tj+1t(tj+1tj1)(tj+1tj)(tj+1t)2=(tj+1tj2)(tj+1tj1)(tj+1tj)(tj+1t)3

也即
B j , 3 ( t ) = ( t − t j ) 3 ( t j + 3 − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) B j − 1 , 3 ( t ) = ( t − t j − 1 ) 2 ( t j + 1 − t ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t − t j − 1 ) ( t j + 2 − t ) ( t − t j ) ( t j + 2 − t j − 1 ) ( t j + 2 − t j ) ( t j + 1 − t j ) + ( t j + 3 − t ) ( t − t j ) 2 ( t j + 3 − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) B j − 2 , 3 ( t ) = ( t − t j − 2 ) ( t j + 1 − t ) 2 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) ( t − t j − 1 ) ( t j + 1 − t ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t ) 2 ( t − t j ) ( t j + 2 − t j − 1 ) ( t j + 2 − t j ) ( t j + 1 − t j ) B j − 3 , 3 ( t ) = ( t j + 1 − t ) 3 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) (*) \begin{aligned} &B_{j,3}(t) = \frac{(t-t_j)^3}{(t_{j+3}-t_j)(t_{j+2}-t_j)(t_{j+1}-t_j)} \\ &B_{j-1,3}(t) = \frac{(t-t_{j-1})^2(t_{j+1}-t)}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t-t_{j-1})(t_{j+2}-t)(t-t_j)}{(t_{j+2}-t_{j-1})(t_{j+2}-t_{j})(t_{j+1}-t_j)} + \frac{(t_{j+3}-t)(t-t_j)^2}{(t_{j+3}-t_j)(t_{j+2}-t_j)(t_{j+1}-t_j)} \\ &B_{j-2,3}(t) = \frac{(t-t_{j-2})(t_{j+1}-t)^2}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)(t-t_{j-1})(t_{j+1}-t)}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t)^2(t-t_j)}{(t_{j+2}-t_{j-1})(t_{j+2}-t_{j})(t_{j+1}-t_j)} \\ &B_{j-3,3}(t) = \frac{(t_{j+1}-t)^3}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} \end{aligned} \tag{*} Bj,3(t)=(tj+3tj)(tj+2tj)(tj+1tj)(ttj)3Bj1,3(t)=(tj+2tj1)(tj+1tj1)(tj+1tj)(ttj1)2(tj+1t)+(tj+2tj1)(tj+2tj)(tj+1tj)(ttj1)(tj+2t)(ttj)+(tj+3tj)(tj+2tj)(tj+1tj)(tj+3t)(ttj)2Bj2,3(t)=(tj+1tj2)(tj+1tj1)(tj+1tj)(ttj2)(tj+1t)2+(tj+2tj1)(tj+1tj1)(tj+1tj)(tj+2t)(ttj1)(tj+1t)+(tj+2tj1)(tj+2tj)(tj+1tj)(tj+2t)2(ttj)Bj3,3(t)=(tj+1tj2)(tj+1tj1)(tj+1tj)(tj+1t)3(*)
由此,得到该区间的曲线表达式为
B ( t ) = B 0 , 3   P 0 + B 1 , 3   P 1 + ⋯ + B n , 3   P n = B j − 3 , 3 ( t )   P j − 3 + B j − 2 , 3 ( t )   P j − 2 + B j − 1 , 3 ( t )   P j − 1 + B j , 3 ( t )   P j \begin{aligned} B(t) & = B_{0,3}\ P_0 + B_{1,3}\ P_1 + \cdots + B_{n,3}\ P_n \\ & = B_{j-3,3}(t)\ P_{j-3} + B_{j-2,3}(t)\ P_{j-2} + B_{j-1,3}(t)\ P_{j-1} + B_{j,3}(t)\ P_j \end{aligned} B(t)=B0,3 P0+B1,3 P1++Bn,3 Pn=Bj3,3(t) Pj3+Bj2,3(t) Pj2+Bj1,3(t) Pj1+Bj,3(t) Pj
根据公式可知,当节点 t 0 , t 1 , ⋯   , t n t_0,t_1,\cdots,t_n t0,t1,,tn 确定后, B j , 3 , B j − 1 , 3 , B j − 2 , 3 , B j − 3 , 3 B_{j,3},B_{j-1,3},B_{j-2,3},B_{j-3,3} Bj,3,Bj1,3,Bj2,3,Bj3,3 都是关于 t 的三次函数。 B ( t ) B(t) B(t) 也随着 t ( ∈ [ 0 , 1 ] ) (\in[0,1]) [0,1] 的取值而确定,也即确定了曲线上的一系列点 B(t),正是这些点组成了样条曲线。

2.2.2 B样条插值方程的获取

clamped -B样条本身跟贝塞尔曲线很接近,当然可以考虑使用类似于上节贝塞尔曲线插值那样,在两点内依次插入 B 样条,通过某些设定确保曲线光滑。但这种方法会同上面一样很粗糙。

对于 B 样条,不同与贝塞尔曲线的一点就是,B 样条曲线有节点,而且节点可以映射到最终曲线上,节点对应坐标为 B ( t j ) B(t_j) B(tj),依据以上公式计算。而且B样条本身就是一条光滑曲线,取代于上面贝塞尔曲线的两点间逐个插值,考虑使用B样条一次性生成所需曲线,且曲线通过原始点(型值点)。

而要满足生成的 B 样条直接穿过型值点,恰好可以利用上述节点性质(即节点在曲线上的有对应点 B ( t j ) B(t_j) B(tj))。因此只需要考虑让 型值点等值于 节点对应点即可。即便这样,我们仍然有很大的参数设定自由度。

如,假设有一系列型值点中考虑其中一点 P’,我们使用三次B样条对所有型值点进行插值,让 P’ 等值于第 i 个节点对应点 B ( t j ) B(t_j) B(tj) ,即
P ‘ = B ( t i ) = B j − 3 , 3 ( t j )   P j − 3 + B j − 2 , 3 ( t j )   P j − 2 + B j − 1 , 3 ( t j )   P j − 1 + B j , 3 ( t j )   P j P‘ = B(t_i) = B_{j-3,3}(t_j)\ P_{j-3} + B_{j-2,3}(t_j)\ P_{j-2} + B_{j-1,3}(t_j)\ P_{j-1} + B_{j,3}(t_j)\ P_j P=B(ti)=Bj3,3(tj) Pj3+Bj2,3(tj) Pj2+Bj1,3(tj) Pj1+Bj,3(tj) Pj
该式中,P‘ 已知,控制点 P j − 3 , P j − 2 , P j − 1 , P j P_{j-3},P_{j-2},P{j-1},P{j} Pj3,Pj2,Pj1,Pj 都未知,第 j 个节点值 t j t_j tj 也未知,而且这些值都可以一定程度地"随意设置。

也就是说,我们有很大的自由度来通过手动设定控制点、节点分布等来满足上式。而只要满足上式,就会有生成的B样条曲线经过型值点 P’。

当然这是对一个型值点而言,考虑所有型值点的情况下,每个公式中的控制点会有重复,手动设定的自由度可能会下降,但大致感觉最终应该还是会有很多自由度。当然,可以用数学公式具体来计算说明,在此不赘述,仅为了定性说明问题。下面有详细分析求解过程。

同样以 三次B样条为例,假设已知有 l+1 个型值点为 z 0 , z 1 , ⋯   , z l z_0,z_1,\cdots,z_l z0,z1,,zl ;我们要插值生成的三次B样条参数有: n + 1 n+1 n+1 个控制点 P 0 , P 1 , ⋯   , P n P_0,P_1,\cdots,P_n P0,P1,,Pn m + 1 m+1 m+1 个节点 t 0 , t 1 , ⋯   , t m t_0,t_1,\cdots,t_m t0,t1,,tm

首先需要明确的一点是,就目前来说,目标三次样条曲线中控制点个数没限制,节点数目没限制,仅有的一个限制是
m = n + k + 1 = n + 4 (1) m = n + k + 1 = n + 4 \tag{1} m=n+k+1=n+4(1)

对于每个没有限制的点(控制点、节点)都意味着一个个的自由度。下面开始施加限制

先考虑最重要的一点,即,使型值点与节点(确切说是,其在目标曲线上的点)对应,也即 z i = B ( t i ) z_i = B(t_i) zi=B(ti)。可以用如下图表示

样条曲线(下)之插值问题(贝塞尔曲线、B样条和一般样条曲线插值)_第8张图片

上图中表示了, z 0 = B ( t 0 ) , z 1 = B ( t 1 ) , ⋯   , z n = B ( t m ) z_0 = B(t_0), z_1=B(t_1), \cdots, z_n = B(t_m) z0=B(t0),z1=B(t1),,zn=B(tm),此时是最简单的对应关系,此时有 m = l m=l m=l。但此时会有个问题,因为有一个不可忽视的一点,样条曲线是有定义域的,对于三次样条,定义域为 [ t 3 , t n + 1 ] [t_3,t_{n+1}] [t3,tn+1],因此上述对应关系是有问题的,至少 z 0 z_0 z0 应该与定义域内第一个值 B ( t 3 ) B(t_3) B(t3) 对应。同样,最后一个 z l z_l zl 与 定义域内最后一个值 B ( t n + 1 ) B(t_{n+1}) B(tn+1) 对应。

上面提到了定义域的问题,一个极好的解决方案是使用 clamped B-spline

对于三次的 clamped B-样条,有
t 0 = t 1 = t 2 = t 3 = 0 t 4 , t 5 , ⋯   , t n ∈ [ 0 , 1 ] t n + 1 = t n + 2 = t n + 3 = t n + 4 = 1 t_0 = t_1 = t_2 = t_3 = 0 \\ t_4,t_5,\cdots,t_{n} \in[0,1] \\ t_{n+1} = t_{n+2} = t_{n+3} = t_{n+4} = 1 t0=t1=t2=t3=0t4,t5,,tn[0,1]tn+1=tn+2=tn+3=tn+4=1
而定义域为 [ t 3 , t n + 1 ] [t_3,t_{n+1}] [t3,tn+1] ,因此我们采用的对应关系为
t 3 ⇔ z 0 t 5 ⇔ z 1 ⋮ t n + 1 ⇔ z l t_3 \Leftrightarrow z_0 \\ t_5 \Leftrightarrow z_1 \\ \vdots \\ t_{n+1} \Leftrightarrow z_l t3z0t5z1tn+1zl
也即有
z 0 = B ( t 3 ) = B ( 0 ) ⋮ z j = B ( t j + 3 ) ⋮ z l = B ( t n + 1 ) = B ( 1 ) (2) z_0 = B(t_3) = B(0) \\ \vdots \\ z_j = B(t_{j+3}) \\ \vdots \\ z_l = B(t_{n+1})=B(1) \tag{2} z0=B(t3)=B(0)zj=B(tj+3)zl=B(tn+1)=B(1)(2)
此时, n + 1 = l + 3 n+1 = l+3 n+1=l+3 即满足 n = l + 2 n = l+2 n=l+2

综上所述,根据限制,我们需要满足的关系有:

  • 需要设定样条的控制点的数目比型值点多2个,即
    n = l + 2 n = l + 2 n=l+2

  • 需要设定的节点数目比型值点多6个,即
    m = n + k + 1 = l + 2 + 3 + 1 = l + 6 m = n + k + 1 = l+2+3+1=l+6 m=n+k+1=l+2+3+1=l+6

  • 满足一系列关系式(共 l + 1 l+1 l+1 个)
    z j − 3 = B ( t j ) = B j − 3 , 3 ( t j )   P j − 3 + B j − 2 , 3 ( t j )   P j − 2 + B j − 1 , 3 ( t j )   P j − 1 + B j , 3 ( t j )   P j   ,     j = 3 , 4 , ⋯   , l + 3 z_{j-3} = B(t_j) =B_{j-3,3}(t_j)\ P_{j-3} + B_{j-2,3}(t_j)\ P_{j-2} + B_{j-1,3}(t_j)\ P_{j-1} + B_{j,3}(t_j)\ P_j\ ,\ \ \ j = 3,4,\cdots,l+3 zj3=B(tj)=Bj3,3(tj) Pj3+Bj2,3(tj) Pj2+Bj1,3(tj) Pj1+Bj,3(tj) Pj ,   j=3,4,,l+3

    且对于 B j , 3 , B j − 1 , 3 , B j − 2 , 3 , B j − 3 , 3 B_{j,3},B_{j-1,3},B_{j-2,3},B_{j-3,3} Bj,3,Bj1,3,Bj2,3,Bj3,3 ,带入(*)公式得
    B j − 3 , 3 ( t j ) = ( t j + 1 − t j ) 2 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) B j − 2 , 3 ( t j ) = ( t j − t j − 2 ) ( t j + 1 − t j ) 2 ( t j + 1 − t j − 2 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) + ( t j + 2 − t j ) ( t j − t j − 1 ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) B j − 1 , 3 ( t j ) = ( t j − t j − 1 ) 2 ( t j + 1 − t j ) ( t j + 2 − t j − 1 ) ( t j + 1 − t j − 1 ) ( t j + 1 − t j ) B j , 3 ( t j ) = ( t − t j ) 3 ( t j + 3 − t j ) ( t j + 2 − t j ) ( t j + 1 − t j ) = 0 \begin{aligned} &B_{j-3,3}(t_j) = \frac{(t_{j+1}-t_j)^2}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})} \\ &B_{j-2,3}(t_j) = \frac{(t_j-t_{j-2})(t_{j+1}-t_j)^2}{(t_{j+1}-t_{j-2})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} + \frac{(t_{j+2}-t_j)(t_j-t_{j-1})}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})} \\ &B_{j-1,3}(t_j) = \frac{(t_j-t_{j-1})^2(t_{j+1}-t_j)}{(t_{j+2}-t_{j-1})(t_{j+1}-t_{j-1})(t_{j+1}-t_{j})} \\ &B_{j,3}(t_j) = \frac{(t-t_j)^3}{(t_{j+3}-t_j)(t_{j+2}-t_j)(t_{j+1}-t_j)} = 0\\ \end{aligned} Bj3,3(tj)=(tj+1tj2)(tj+1tj1)(tj+1tj)2Bj2,3(tj)=(tj+1tj2)(tj+1tj1)(tj+1tj)(tjtj2)(tj+1tj)2+(tj+2tj1)(tj+1tj1)(tj+2tj)(tjtj1)Bj1,3(tj)=(tj+2

你可能感兴趣的:(图像处理,贝塞尔曲线,数学建模,列表,线性代数)