Bezier和B样条曲线
前置知识请参考: 插值与拟合
问题
已知若干点,如何得到通过这些点的一条光滑曲线?
古代工匠的解决方法:把富有弹性的细长木条用压铁固定在样点上,在其他地方让它自由弯曲,且在结点处具有连续的曲率,然后沿木条画下曲线,成为样条曲线
样条曲线的意义
普通的多项式插值法,如Lagrange插值,存在Runge现象,即当多项式次数较高时存在稳定性、大幅度震荡等问题。可以使用分段低阶多项式来替代,这就是样条的思想。
Bezier 曲线
1962年,由法国数学家Pierre Bézier提出
例:三个控制点确定的二次Bezier曲线
P x = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 P_{x}=(1-t)^{2} P_{0}+2 t(1-t) P_{1}+t^{2} P_{2} Px=(1−t)2P0+2t(1−t)P1+t2P2
性质
- 可计算性
n 阶 贝 塞 尔 曲 线 B n ( t ) 可 以 由 前 n 个 点 决 定 的 n − 1 次 贝 塞 尔 曲 线 B n − 1 ( t ∣ P 0 , ⋯ , P n − 1 ) 与 后 n 个 点 决 定 的 n − 1 次 贝 塞 尔 曲 线 B n − 1 ( t ∣ P 1 , ⋯ , P n ) 线 性 组 合 递 推 而 来 , 即 B n ( t ∣ P 0 , P 1 , ⋯ , P n ) = ( 1 − t ) B n − 1 ( t ∣ P 0 , P 1 , ⋯ , P n − 1 ) + t B n − 1 ( t ∣ P 1 , P 2 , ⋯ , P n ) \mathrm{n} 阶贝塞尔曲线 B^{n}(t) 可以由前 \mathrm{n} 个点决定的 \mathrm{n}-1 次贝塞尔曲线 B^{n-1}\left(t \mid P_{0}, \cdots, P_{n-1}\right) 与 后 \mathrm{n} 个 点决定的 \mathrm{n}-1 次贝塞尔曲线 B^{n-1}\left(t \mid P_{1}, \cdots, P_{n}\right) 线性组合递推而来,\\即 B^{n}\left(t \mid P_{0}, P_{1}, \cdots, P_{n}\right)=(1-t) B^{n-1}\left(t \mid P_{0}, P_{1}, \cdots, P_{n-1}\right)+t B^{n-1}\left(t \mid P_{1}, P_{2}, \cdots, P_{n}\right) n阶贝塞尔曲线Bn(t)可以由前n个点决定的n−1次贝塞尔曲线Bn−1(t∣P0,⋯,Pn−1)与后n个点决定的n−1次贝塞尔曲线Bn−1(t∣P1,⋯,Pn)线性组合递推而来,即Bn(t∣P0,P1,⋯,Pn)=(1−t)Bn−1(t∣P0,P1,⋯,Pn−1)+tBn−1(t∣P1,P2,⋯,Pn)
- Bezier曲线是B样条曲线的特例
- 曲线总是通过第一个和最后一个点
- 曲线在始点处的切线落在前两个控制的连线上,曲线在终点处的切线落在最后两个控制点的连线上
缺点
- Bezier曲线幂次 = 控制点个数 - 1,控制点越多,需要的计算也越复杂。实际中常使用分段低幂次的Bezier曲线,如三次Bezier曲线。如果使用这种方法,保持曲线一次光滑(每个点左右导数相等)的条件是连接点和其两侧的控制点共线。
- 改变其中任何一个点,整条曲线都会随之改变
实际应用
Photoshop 中的钢笔工具,实际上是三次Bezier曲线
B样条曲线
1972年,de Boor与Cox分别独立提出了计算B样条基函数的公式,称之为de Boor-Cox公式。在此之前,计算B样条基函数大多用差分方法计算,数值上可能不稳定。
Bezier和B样条曲线均有其矩阵表示形式。
优点
- B样条多项式的次数可独立于控制点数目(有一定限制)(注意这点区别于Bezier曲线);
- B样条允许局部控制曲线或曲面。
几个概念
-
控制点(control points):
等价于Bezier曲线中的控制点
-
节点(knots):
跟控制点没有关系,人为划分的,目的是将曲线划分为若干部分,各部分间相互影响又有一定独立性。节点个数一般多于控制点。
实际应用中一般是先给出节点,可以通过节点解算控制点。见https://zhuanlan.zhihu.com/p/110465025
例子:
根据节点的取法进行分类:
- 均匀 B 样条:节点均匀分布
- 准均匀 B 样条:在开始和结束处的节点可重复,中间节点均匀分布 ( 如果要B样条经过起始点和终止点,请使用准均匀)
- 非均匀 B 样条:节点非均匀分布
其他
- Bezier和B样条曲线均由控制点定义,但不会经过其控制点
- B样条和三次样条曲线的区别:类似于Lagrange插值和Newton插值的区别;本质上是一种东西,只是形式不同而已
- 给定区间上的所有样条函数组成一个线性空间,B样条基函数是该线性空间的一组基函数
python相关函数
import scipy.interpolate as spi
spi.interp1d
spi.splrep
spi.splev
参考资料
https://www.bilibili.com/video/BV1cW411a7yB?from=search&seid=4588310070627013461&spm_id_from=333.337.0.0
https://www.bilibili.com/video/BV1uK4y1M7M1?from=search&seid=4588310070627013461&spm_id_from=333.337.0.0
https://zhuanlan.zhihu.com/p/110465025