这篇文章是看中国农大的图形学公开课的笔记, 简单介绍了贝塞尔Bezier曲线曲面和B样条B-Spline曲线曲面, 希望能够带来一个大概视角和总览. 本文同步存于我的Github仓库, 字数长度3.2k(https://github.com/ZFhuang/Study-Notes/tree/main/Content/%E4%B8%93%E9%A1%B9%E7%AC%94%E8%AE%B0/%E6%A0%B7%E6%9D%A1%E6%9B%B2%E7%BA%BF%E6%9B%B2%E9%9D%A2).
学识尚浅, 内容有错漏在所难免, 如果发现问题希望大家在评论指出.
所谓样条指的是以前设计者所用的一系列形状固定的模具, 用于拼接绘制复杂的曲线. 样条曲线这个名字形象地表达出这种用多个有规律的多项式函数拼接拟合复杂曲线的方法, 并也最常用于设计行业.
参数方程形如, 即由组成的一个有界点集, 其中t是参数, 样条曲线就常用参数方程表达, 有下面几个优势:
插值和拟合都可以被称为逼近, 但是插值必须经过所有输入点, 样条曲线属于对输入点的拟合, 不会经过所有点.
描述曲线的平滑, 最好能够:
参数连续性:
几何连续性:
两点间有无数种插值方法, 使用不同的参数方程和参数化会插值出不同的值
贝塞尔曲线, 是后面B样条曲线的一种特例, 属于几何形式的参数化曲线, 目的是输入一系列有序的控制点组成特征多边形, 然后是对特征多边形进行逼近得到光滑曲线. 公式如下
其中是伯恩斯坦基函数, 实际上是的牛顿二项式展开形式, 具体公式如下:
一次的贝塞尔曲线由两个控制点组成, 展开后相当于两点间的线性插值, 二次贝塞尔曲线相当于抛物线插值等等...
代入法: 直接用定义式来绘制, 计算复杂
递推法: 由于n次的B可由两个n-1次的B线性组合得到, 一次的贝塞尔曲线由两个控制点组成, 展开后相当于两点间的线性插值, 所以二次的贝塞尔曲线是由三个控制点, 这三个控制点按顺序连成两个线段, 各自进行对应参数的线性插值, 然后得到的两个新点连成新的线段, 在线段上同样线性插值得到. 高次的贝塞尔曲线就是不断插值得到. 写为递推式:
绘制示意图如下:
即便迭代法可以大大加快贝塞尔曲线的绘制, 但是绘制高次贝塞尔曲线仍然很大, 且由于贝塞尔曲线是由作用域在整个定义域上的大量基函数线性组合得到, 因此高次的贝塞尔曲线会由于组合过于复杂而很不稳定且难以控制, 因此实际中常常通过多个不高于4次的小段贝塞尔曲线组合得到整个曲线.
组合分段曲线要注意头尾拼接的问题, 常用的拼接需要满足连续性, 由于贝塞尔曲线曲线的起点与终点的切线和第一与倒数第一条特征线一致, 因此只要保证连接的两段贝塞尔曲线的连接点和相邻两点形成的三点共线即可.
升阶就是增加曲线控制点的数量而不改变曲线形状, 下面的定义式可以计算出可以在i处插入的新控制点的位置, 顶点越多, 形成的特征多边形就会越逼近实际曲线:
降阶则是在尽量不改变曲线形状的情况下减少控制点的数量, 这是个比较复杂的问题, 下面的递推式是一种比较简单的方法:
贝塞尔曲面实际上是贝塞尔曲线的扩展, 将特征多边形增加一个维度变为特征网格, 然后同样是利用线性组合得到所需的点. 定义式如下:
函数B仍然是伯恩斯坦基函数. 曲面由四角的四个角点和角点组成的四条边界线构成.
除了使用定义法绘制外, 常用方法同样是递推法. 曲面是曲线在不同维度上的线性组合得到的, 核心思想是依次插值每个轴, 逐步缩小范围. 以先u再v为例, 首先在每个拥有参数分割的v上, 固定v不变, 得到一串串控制点, 对这些计算贝塞尔曲线, 得到一系列对应输入u新的点. 得到的这一系列点再对参数v进行贝塞尔曲线计算, 这样迭代到只有一个点时这个点就是曲面对应的点.
实际上这个递推就是如下在定义式上加个优先级约束从而将曲面计算转为递推的曲线计算而已:
B样条曲线实际上是对贝塞尔曲线的扩展, B指Basic, 或者说贝塞尔曲线是B样条曲线的特例, B样条曲线通过一系列范围有限的基函数组合来解决贝塞尔曲线牵一发而动全身的缺点. 其定义式和贝塞尔曲线相似:
B样条曲线的核心是其基函数, 称为k阶(k-1次)基函数. 这也是有递推性的基函数, 定义如下, 这里还要注意到基函数的作用域变小了, 有限的作用域使得计算复杂度降低且更稳定:
B基函数的示意图:
如果将这个绘制出来的话, 一阶的B样条是两个节点组成的一个区间, 区间本身就是值为1的常函数. 插值的核心发生于大于1阶的时候加入的这个线性插值系数, 这个参数使得常函数被折为折线, 再形成三阶的抛物线...具体绘制的方法就是利用这个线性插值系数得到递推的点, 总体上和贝塞尔曲线的绘制是一样的.
定义式如下, 构造方法原理与贝塞尔曲面相同: