先引用《计算机游戏程序设计》中的一段话作为开头:
“关键帧记录了当前姿势的运动变化,例如位置和朝向。……关键帧的插值指从两个已知的关键帧中平滑地产生所有中间帧序列的过程。关键帧动画是基于时间序列的插值。”
三维浏览软件中一个常见的功能就是漫游,可以理解为一种动画。对于漫游来说,假设只有一条相机路径,那么每一帧都需要计算相机位置和相机朝向。相机位置可以通过简单的线性插值来达到要求,但是有时候急拐弯处也会产生一些很大的运动变化,因此经过通过光滑路径的方法来去除一些拐角比较大的点。不过这不是今天讨论的主题。今天讨论的主要是后一种,即相机朝向的插值。
假设在起点处,用户指定此时相机C必须朝向A点,到了路径终点的时候,相机必须朝向B点。如下图所示的一条走下楼梯的路径。如何对这之间的朝向进行平滑和连续的插值成为漫游的关键。
“对旋转量的插值,一般首先想到的是基于绕x,y,z轴的旋转的欧拉角。但实践证明,基于欧拉角的直接插值很容易导致不连续性,而且它相对于xyz轴的旋转次序不同,得到的旋转结果也不同。……四元数的旋转插值能比基于欧拉角的直接插值产生更为平滑和连续的旋转。”
这段话说明了四元数插值可以应用到我们这里。其实,四元数的球面线性插值,简写为slerp。其几何含义的解释为插值路径为四维的单位球上的较短的圆弧路径,这个圆弧是在由q,r和原点组成的平面和单位球相交的圆周上。q就是起点的朝向,r就是终点的朝向。
q r q r
具体的计算方法和代码略,在一般的几何库中都会提供。需要注意的是slerp插值方法非常适合两个四元数之间的插值,但是如果有一系列的四元数,使用slerp对四元数进行两两插值会导致插值端点出的值产生变化。
在三维软件中的另外一个应用就是缩略图的使用。在漫游浏览时,当用户到达一个满意的位置和朝向时,想记录下来,那么一般可以直接使用缩略图功能,Google Earth的地标功能与此类型。如果下次想直接到达这个地点,可以直接从当前位置“飞”过去。这里同样可以用到四元数插值。因为当前状态下,用户是已知朝向的,而目的地的朝向又是事先记录下来的。这样就可以实现快速到达目的地的平滑飞行。
评论