曲线插值与拟合算法
贝赛尔曲线相关知识:https://zhuanlan.zhihu.com/p/366678047
B样条曲线相关知识:https://www.guyuehome.com/37024
https://www.bilibili.com/video/BV1Qz4y1m7dS
1.贝赛尔曲线
可知每个点的生成方式与t的关系。下图的显示的t是均匀流逝的。若把下图的黑点当作智能体在二维平面上运动,而最终的贝塞尔曲线(红色曲线)为智能体最终的行驶轨迹,我们可以看到智能体在不同的时间的速度是不相等。大致的感觉是:弯度越大时,行驶速度越慢;越平直,速度越快。
对比几组实验,发现贝塞尔曲线上第个点的速度是有差异的。但是,每个点的速度与曲线的弯度(曲率)没有直接关系,而是与控制点间距离有关。从第四组实验可以看到,四个控制点共线,曲率在每处都为零,但是速度先增大后减小,这与头两个点距离最短,中间两个点距离最大有直接关系。
在实际速度规划中,我们期望在曲率(绝对值)大的地方,以较小的行驶速度行驶;在曲率(绝对值)小的地方,以较大的行驶速度行驶,从而在效率与安全之间达到一个很好平衡。贝塞尔曲线经常被用来设计或生成无人车的行驶轨迹,要得到期望速度,得先计算各点曲率,然后再通过设计好的函数,得到最终的期望速度。这样一个过程比较绕,贝塞尔曲线的t可以当作时间以固定比例的缩放(0到1之间)的值,很自然的想法是:各时间点的速度是否与实际无人车行驶的期望速度一致呢?经过本篇实现,很遗憾的结果是,贝塞尔曲线各点上的速度与曲率没有直接关系,所以不能直接用于速度规划。
但是,我们也发现:贝塞尔曲率各点的速度与各控制点的分布(前后点的距离)有关。在设计无人车轨迹时,一般会能确定几个控制点的位置(例如起点与未端点),以及其它控制点的部分约束(例如:始未两控制点的姿态一般是确定的,这样第二个控制点与倒数第二个控制点一定分别是在始未控制方向的前与后。),因此,可以在有限维度上调整各控制点的距离来达到在中观层面控制贝塞尔曲线上各点的目的,从而直接使用。
2.B样条曲线
为什么要引入B样条曲线?
B样条是贝塞尔曲线的延申,贝塞尔曲线是B样条的基础, B样条可以看成很多组贝塞尔曲线的拼接。
贝塞尔曲线是在汽车的曲线设计种首次被提出的,汽车的外形设计十分复杂,控制点的表示方式能够简化其数学描述,将其数学化的表示出来。
还记得贝塞尔曲线的特质吗?主要的两个, 1 阶次是控制点个数减1, 2 牵一发动全身,移动一个控制点,整段曲线都会变化。
如果要用贝塞尔曲线来设计上图种的汽车造型, 那么汽车的设计简直是噩梦,形状复杂的曲线需要更多的控制点,曲线的阶次就会变得非常高。牵一发而动全身, 想改一下车屁股的造型, 移动一下控制点,结果车头的造型也被改变了。
为了克服贝塞尔曲线的以上两大缺点,B样条应运而生了。
因此B样条的两个性质就是贝塞尔的缺点反过来:1 可以指定阶次。2 移动控制点仅仅改变曲线的部分形状,而不死整体
B样条采用解决方案是贝塞尔曲线的拼接,也就是把一条曲线变为多段贝塞尔曲线的拼接。
为了是B样条曲线具备上述形式,它需要有三大要素:节点,控制点,阶次。
其中节点可认为是分隔点,将区间[u0, um]细分为节点区间。所有B-样条基函数被假设定义域在[u0, um]上。在本文中,我们经常使用u0 = 0和um = 1,所以定义域是闭区间[0,1]。
控制点和贝塞尔的一样,就是空间上决定曲线形状的点,本文中用Pi表示。
k是阶次,与贝塞尔曲线不同,k阶B样条曲线的各段轨迹由k个控制点控制而非k-1个。
B样条曲线数学定义,其中P(u)即为值u下的轨迹点值,u从0到1完成曲线绘制:
Bi,k(u)作为B样条曲线的基函数,具有以下形式(可以类比贝赛尔曲线的伯恩斯坦多项式):
这是一个递推式,可以看到基函数是关于u的函数,其他值均为常数与可递推值。
其中u的地位与贝塞尔曲线的t类似,只是贝赛尔曲线中t取[0,1]的各段是均匀的,而B样条曲线中的u在[0,1]的不同段下还具有不同的函数形式,这些分隔用常数ui表示。
这些分段就是为了实现贝塞尔曲线的拼接,而这些分隔点也就是节点。
于是整个[0,1]段被分割成了以下形式:
需要注意的是,有n+1个控制点和k阶,就需要n+k+1个分隔点。
感觉有点难以理解?没关系!我们先从B样条曲线的基函数Bi,k(u)的最特殊形式出发:
当阶次k=1时,此时的Bi,k(u)只在[ui,ui+1]处具有非零定义,即:
而当k>=2时,由于各ui均为常数,而Bi,k-1和Bi+1,k-1均为上阶值,可以被递推得到,于是所有的Bi,k(u)值便被分隔点ui和阶次k完全确定,而最后的轨迹点P(u)则是可以看做由控制点Pi、分隔点ui和阶次k共同确定,这也是我们最初提出B样条曲线需要满足的需求。
接下来我们从更高的角度再审视B样条曲线:
以一个有四个控制点的四阶B样条曲线为例,则它需要8个分隔点u0-u7,此时P(u)=P0B0,4(u)+P1B1,4(u)+P2B2,4(u)+P3B3,4(u),u∈[0,1](被8个分隔点分隔)
而B0,4(u)由递推关系可知它由B0,3(u)和B1,3(u)确定,而B0,3(u)又由B0,2(u)和B1,2(u)确定,B1,3(u)又由B2,2(u)和B1,2(u)确定,以此类推形成三角关系:即B0,4(u)完全由一阶基函数B0,1(u),B1,1(u),B2,1(u),B3,1(u)的线性组合构成,B1,4(u),B2,4(u),B3,4(u)也类似。即下图:
于是我们可以发现,作为控制点的Pi只能控制Bi,k(u)在非零域下的值,这也变相说明了B样条曲线下控制点只具有局部的控制能力。例如B0,3(u)只在[u0,u3)段非零,而在其他段由于其所有的基函数均为0,故B0,3(u)本身也为0,即P0作为控制点只有能力控制[u0,u3)段的曲线,其他阶段由于乘积为0,P0没有控制能力。
更进一步我们发现,对于任意一段节点区间[ui,ui+1),至多有k个Bi,k(u)值非零,亦即至多有k个控制点对该节点区间起控制作用,这也说明了一段节点区间内形成的曲线,应该是一段近似于k-1阶贝塞尔曲线所达到的效果。例如在3阶b样条曲线[u2,u3)内,仅有B0,3(u),B1,3(u),B2,3(u)非零,对应控制点P0,P1,P2对其起控制作用实现类似2阶贝塞尔曲线。由此我们也可以看出,B样条曲线是若干条部分贝塞尔曲线的组合。
勘误:对于open B样条,u定义域为[uk-1,un+1]
什么是open B样条呢?
事实上我们发现,对于一段u∈[0,1]的b样条曲线而言,其形成的曲线是一段闭环曲线,且其有部分段是不符合我们定义b样条曲线的意图的。之前我们提到,对于任意一段节点区间[ui,ui+1),至多有k个Bi,k(u)值非零,亦即至多有k个控制点对该节点区间起控制作用。那么什么叫至多呢?例如我们在3阶B样条曲线[u0,u1)段内时,此时仅有B0,3(u)非零,意味着在[u0,u1)段内仅有控制点P1发挥作用,而我们定义B样条曲线是为了发挥其分段贝塞尔的效果,因此,对于每一段节点区间,至少需要k个控制点,[u0,u1)段实际上是一段0阶贝塞尔,也就是从原点到P1的一条直线,这是错误定义的一段曲线,应当舍去。基于这个原理,我们可以发现当所有段均满足B样条曲线规定时,u的定义域仅为[uk-1,un+1],这样的B样条曲线我们称之为open B样条曲线。可见,如果我们要画出一条open B样条曲线,还需要满足k-1<n+1这一条件。
由此绘制的B样条曲线我们发现,它仍不符合贝塞尔曲线的部分性质,例如曲线的端点并不经过头尾的控制点,且曲线的首端切线方向和末端切线方向并不分别与第一第二,倒数第一第二的控制点组成的直线方向相同。这会导致控制上出现很多不方便的地方。故进一步,我们引入准均匀B样条曲线(clamped B样条)的概念,当一个B样条曲线的起点和终点(一般也就是0和1)呈现k次的重复度时,得到的B样条曲线即称为准均匀B样条曲线。准均匀B样条曲线兼具有B样条曲线和贝塞尔曲线的功能,即曲线的端点经过头尾的控制点,且曲线的首端切线方向和末端切线方向分别与第一第二,倒数第一第二的控制点组成的直线方向相同的同时,还能进行分段控制。准均匀B样条曲线是很常用的规划曲线。
B样条的导数:
先讲clamped B样条
既然B样条是贝塞尔曲线的扩展,那么必然要继承贝塞尔曲线一些优良的性质。贝塞尔曲线的导数还是贝塞尔, B样条的导数还是B样条。
接下来看推导公式:
因此,可知,B样条的导数还是B样条, 依然保留B样条的优良特性。
控制点减1,阶数减1,那么节点数目必然是减2. 对于clamped B样条,只要是去除第一个和最后一个节点就ok了,因此clamped B样条的求导还是clamped B样条,这个性质使其方便计算,应用广泛。