怎样理解贝塞尔曲线,样条线和贝塞尔样条线
马克粟粟
2019年06月25日 07:54
收录于文集
共5篇

多边形建模和曲线建模是三维建模的两种主要办法。多边形建模通过调整点,线,面的相对位置,获得模型的大致形状,再添加一个表面细分修改器(Surface Subdivision Modifier),即可获得平滑效果。多边形建模的优势在于能直观地创建不规则模型。艺术家只需要不断为初始模型增加细节,从粗糙到精细,加以微调,则可不断接近所需效果。

如果模型的表面弯曲符合一定规律(如各种工业产品),多边形建模法则不是首选。人们发现,可以通过建立曲线方程,或者通过设置少数的几个控制点(Control points)的相对位置,来描述整个曲面变化,其结果会比多边形建模法更加的流畅顺滑。而通过控制点获得曲线的办法,就是贝塞尔曲线(Bezier Curve)的基本思路。贝塞尔曲线是由法国汽车工程师皮埃尔·贝塞尔(Pierre Bezier)发明,起初用于汽车车身曲面设计,后来被广泛应用到各个行业,近二十年蓬勃发展的CG产业就是受惠者之一。

绘制贝塞尔曲线,首先要确定几个控制点的相对位置,这里我们不妨先考虑二维平面上的控制点。比如现在平面上有两个控制点P0和P1,它们的坐标分别是(1,5), (5,2)。现在为这两个点建立一组以时间t为自变量的函数,t的取值范围永远在0~1之间,当t从0开始移动到1,一个活动点从P0开始逐渐移动到P1:

如果写成函数表达式,则是:

B(t) = (1-t)*P0 + t*P1

其中B(t)是活动点的坐标值,而P0或P1,代表这两个控制点的x坐标或y坐标,所以这个函数实质是两条函数:

x:B(t) = (1-t)*1 + t*5

y:  B(t) = (1-t)*5 + t*2

比如当t = 0时,点的位置刚和与P0重合;当t = 0.3 时,点的位置就是(2.2, 4.1);当t = 1时,点则与P1重合。如果做成动图,则有如下效果。这种只有两个点的情况,称为一维的贝塞尔曲线,或者线性贝塞尔曲线。

n = 1

如果场景中有三个点呢,即存在P0,P1和P2呢?那么场景中就存在两个活动点(A1和A2),它们在t = 0时,分别与P0和P1重合,当t开始变化时,A1从P0移动到P1,A2从P1移动到P2。当t = 1时,两个活动点分别到达P1和P2。如果把A1和A2连接起来,并建立第三个活动点A3,它在A1和A2之间运动。当t = 0时,A3与A1重合,当t = 1时.与A2重合,中间时间A3就在A1和A2连线上按比例移动着,那么A3的活动轨迹就是一条曲线。此时t的最高次数为2。

n = 2

当控制点逐渐增多,可以绘制出来的曲线,就更加复杂了。但无论有多少个控制点,该函数都是以t作单变量,各个活动点随着t从0变化到1,同时从各自的起始点移动到其终点。

n = 3

n = 6

只要有足够的控制点,任何曲线都可以使用贝塞尔方法绘制。这个说法听上去很美好,但是在实际的曲线设计过程中,一条复杂的贝塞尔曲线的生成是计算高成本的(computationally expensive)。试想一下,如果要设计一条经过12个固定点的曲线,最后生成的曲线方程就是12次的(t的指数的最高次数为12),那么每次微调这些控制点位置,计算机需要重新拟合这条复杂方程式,严重影响计算效率。因此,人们就想出样条线(Spline)方法来完成点的多项式拟合。

所谓的样条线就是分段多项式(Piecewise Polynomials)。而多项式,就是自变量的次数为正整数的方程式,如y = 2x + 1,就是一个线性的方程式(自变量x的次数为1次)。当然x的次数可以为所有正整数。所谓的“分段”,就是在不同的定义域区间里面,y值对应的表达式是不一样的。因此,分段多项式一般会使用下图这种方法表示。

从编辑便捷性角度看,分段多项式较单一段贝塞尔曲线有优势,因为若需要调整曲线局部,只需要调整分段多项式里面的一条式子即可,其他式子维持不变,这样计算机不需要耗费额外资源,重新计算整条12次方的曲线方程。但现在问题又来了,样条线的每个分段,是怎样的多项式呢?比如下图这12个点,我们最容易想象到的,就是点与点之间,按顺序两两相连,每个分段多项式,都是最简单线性方程。

但是这样显然是不够的,因为这样转角尖锐的效果,不能模拟高次多项式的平滑效果。于是,计算机图形学界,达到了一个共识:

样条线的每个分段多项式,使用n = 3的贝塞尔曲线(参考上面动图)

使用n = 3的贝塞尔曲线原因是要限定相邻的两个分段多项式,在交接点位置的一阶导数相等(斜率相等)和二阶导数相等(斜率的变化率相等),这里不作详细介绍。直观来看,就是让所有分段曲线能够平滑顺畅地连接起来,最终与单条的高次贝塞尔曲线在形状上没有区别。这里的每一个分段,就称为贝塞尔样条线(Bezier Spline)。各位熟悉的矢量编辑软件,如Illustrator,Coreldraw,inkscape,Gimp等,都是使用这个原理生成曲线,并可以通过每个控制点的把柄(Handles,实质也是控制点)来调整弯曲程度。

最后顺带提一下,Blender MG动画插件Animation nodes中,生成样条线有两个主要的节点,分别是Splines from Object节点和Spline from points节点。Splines from Object节点输出的是一个样条线列表(输出接口半透明)。这个节点里的所谓的Object,只能是贝塞尔曲线,该节点把这条贝塞尔曲线中的控制点按顺序两两分组,如P0和P1一组,P1和P2一组等,再分别生成样条线,最终形成样条线列表,输出到Spline output节点。它的逻辑,是把既有的单条贝塞尔曲线,转变为样条线列表。而Spline from points节点的逻辑则相反,它是通过输入控制点列表,(输出单一样条线输出接口为实心)。下面动图是根据n = 3的贝塞尔曲线公式,利用Animation nodes制作的贝塞尔曲线绘制动画。教程等马克有空时附上。