贝塞尔曲线和基于贝塞尔曲线的刚体运动
贝塞尔曲线(Bezier Cruve)历史
在计算机图形学中,曲线和曲面是重要的组成部分,其中贝塞尔曲线是目前应用比较广泛的曲线之一。但是在20世纪50年代之前,要在计算机上表现出光滑的曲线是很困难的事。直到1959年,法国雪铁龙汽车公司的一个叫de Casteljau的员工提出了一种对模型网格的仿射组合进行迭代来获得光滑曲面的想法。同时,法国的另一家汽车公司-标致汽车公司的一名叫Bezier的员工,也用相同的方法得到了光滑的曲线,这就是我们讨论的贝塞尔曲线。之所以用Bezier命名曲线,是因为Bezier比de Casteljau先对外公开这个方法。但是de Casteljau的名字也被用来命名曲线的算法,这就是我们知道的de Casteljau算法。下面就来讨论贝塞尔曲线和de Casteljau算法。
曲线的幂基形式
平面几何中,多项式的图形可以用图形表示出来,比如二次多项式,这表示一条抛物线。再来看看空间中的情况,现在我们用参数t来代替x,y,z,也就是用t来表示三个坐标轴对应的位置,比如空间中的一条三次曲线就可以表示为
这里的a,b,c是常数。空间中任何一条曲线都可以写成这样的形式,其中,t的零次方,也就是1和 叫做曲线的幂基。
曲线的Bernstein基
Bezier曲线中,使用的是Bernstein基。n次多项式的Bernstein基定义如下:
其中t仍然是参数, ,这个公式看起来比较复杂,如果我们将 这个公式展开,会发现展开后的每一项都对应上面的Bernstein基。公式里的i也就表示对应的 展开后的第i项。通过公式就可以用 代替曲线的幂基。下面举个简单的例子,二次曲线的Bernstein基。由于是二次曲线,所以n=2,下面展开 得到
利用Bernstein基公式计算可以得到相同的结果。
下面来看看Bernstein基的性质。
性质1:n次Bernstein基的和等于1。有下面的等式成立:
证明上面的性质很简单,因为Bernstein基的和就是 的展开式, 是横等于1的,所以有 成立。
性质2:递归方程。Bernstein基满足下面的递归方程式。
性质4:Bernstein基的导数
性质5:
贝塞尔曲线(Bezier Curve)
了解了Bernstein基的性质后,下面来看看贝塞尔曲线是怎么定义的。有下面的定义式:
从上面的等式可以看出,一条贝塞尔曲线是由控制点和Bernstein基的线性组合构成的。 是控制点,在平上面的话就是二维的,在空间中就是三维的。如果看这个等式不是很明白的话,通过一个实际的例子就可以很清楚了解贝塞尔曲线的计算方法。例如,现在要表示一条二次贝塞尔曲线,它的三个控制点分别为 ,现在展开上面的公式,带入这三个控制点可以得到
上式中 是Bernstein基的表现形式, 是幂基的表现形式。现在就可以通过参数t的变化得到平面坐标x,y的值了。如下图
图中三个黄色的点就是控制点,红色的曲线就是通过计算得到的贝塞尔曲线。可以看到曲线都包括在由组成的封闭区域中。如果增加控制点的个数,那么曲线的次数也跟着增加。如有10个控制点的贝塞尔曲线,那么它的次数将达到9次,如下图
如果要表示更复杂的曲线,那么它的次数会更高,这个性质对表示复杂曲线来说是很不利的,次数的增加意味着计算机将会花更长的时间来处理数据。解决这个问题的方法以后会专门讨论。下面来看看贝塞尔曲线的重要性质。
性质1:End points interpolation(终点插值) ,这个性质从上面的图中也可以看出来,贝塞尔曲线的两个端点分别就是第一个控制点和最后一个控制点。
性质2:Convex hall property(凸包性质) 任何一条贝塞尔曲线都包含在由控制点组成的叫做凸包的多边形区域内。如下图
De Casteljau算法
前面介绍了贝塞尔曲线的基本概念,现在的任务就是要找到曲线上的一点。这里使用de Casteljau算法,该算法的基本思想就是在控制点之间反复迭代插值。首先任意选取控制点 和 之间的点 ,令u为0到1之间的一个数(表示比例)。那么 在 和 上的位置为 。
de Casteljau算法的基本思想也是这样的,我们在控制点上找一点 ,有了 后,u就固定了,然后再继续在控制点 和 之间,以相同的比例u找到 ,如此进行下去直到最后一个控制点 ,然后进行第二轮迭代,在 之间以相同的比例找到一点 ,如此循环下去找到 , 直到找到曲线上点为止,如上图。下面看看用代码实现的基本思路:
p:控制点,q:曲线上的点
for i = 1 to n
for j = 0 to n-i
q[i] = (1-u)q[i]+uq[i+1];
return q[0];
刚体运动轨迹和朝向
在计算机动画里,常常要用到设计物体的运动轨迹,在游戏里也一样。为了表现平滑的曲线运动,我们把贝塞尔曲线应用到设计刚体运动轨迹中来。当然贝塞尔曲线的作用远不止这些,这里只是个简单的应用。刚体的运动涉及到两个方面,一个是刚体的移动轨迹,一个是刚体的旋转。对于刚体的移动,我们只要有了曲线上的点,那么我们就得到了刚体的运动轨迹了。对于刚体的旋转,我们就需要再利用de Casteljau算法来得到在对应的t时刻物体的朝向。
刚体的移动轨迹的点我们利用上面的提到的de Casteljau算法就可以得到。我们可以利用控制点,对该算法传入控制点和u,当然u要在0和1之间。de Casteljau算法函数利用控制点,通过计算返回曲线上的点的数组。然后通过设置timer,在一秒钟内利用变换矩阵把刚体的位置移动30次,就可以得到连续的动画。或者在timer里传入控制点和u值也是一样的。
对于刚体的旋转,这里我们使用四元数。因为在这里使用四元数可以很方便的得到刚体的朝向,因为四元数可以看成一个四维的向量,对于de Casteljau算法,并不局限于三维向量,它可以扩展到n维空间,只要传入的控制点的维数固定,那么输入的点的维数也就固定了。这里一个控制点变成了四元数,它就表示t时刻刚体朝向,也就是说,刚体在经过这一个点的时候,它的朝向由这个四元数来决定。要注意的是,朝向的控制点和位移的控制点的个数不一定要一样。因为刚体的位移和朝向是没有关系的,位移的控制点个数多,说明刚体的位移轨迹复杂,但是刚体在位移的时候可以不旋转。
从上面的图中,我们可以看到刚体的运动轨迹和旋转。在右图中可以明显看到刚体朝向的改变。比如我们输入一组朝向的控制点q1.( 1.0, 0.0, 0.0, 0.0),q2( 0.7, 0.7, 0.0, 0.0),q3( 0.2, 0.7, 0.1, 0.3),q4( 0.5, 0.5, 0.5, 0.5),de Casteljau算法的返回值就表示了刚体每一时刻的朝向。而我们的控制点q1,q2,q3和q4表示刚体的4个关键朝向点。
有了这两组返回值,位移轨迹点数组和朝向数组,就可以利用这组数据构成刚体的变换矩阵。
如果用C(u)表示轨迹曲线,R(u)表示方向曲线,M(u)表示刚体运动变换矩阵,那么有:
*原创文章,转载请注明出处*