向量之间的插值-四元数法VS.旋转矩阵法的性能比较

问题:
3D空间中,在等长度的两个交角为theta的向量v1(x1,y1,z1),v2(x2,y2,z2)之间进行球面线性插值。html

实例:
作一个行星在围绕太阳等速旋转的动画,假设只采样到旋转过程当中的两个位置p1,p2,如今想要用软件模拟行星是怎么从p1运动到p2的。函数

思路:
1。通常线性插值:工具

咱们知道通常两个量之间进行线性插值的方法为:
v(t) = v1 + t*(v2-v1)(0<=t<=1)(由于t是一次方的,因此是线性的。)

性能

如上图所示。这里,考虑v,v1,v2是向量,由几何学的知识,v2-v1即为v1,v2组成的三角形的另一条边。由于|v1| = |v2|,因此v1 + t*(v2-v1)的长度确定小于|v1|或|v2|,当0<t<1时。获得的插值向量v(t)的端点沿着v2-v1行进。优化

***********************************************
通常线性插值因为长度发生变化,不能知足案列的要求,咱们须要保持向量长度不变的插值,即球面线性插值。
***********************************************动画

2。通常球面线性插值:3d


如上图所示,将通常线性插值获得的结果乘以放大系数k(t),使其长度放大到|v1|或|v2|,即得保持向量长度不变的插值:
v(t) = k(t)*(v1 + t*(v2-v1))htm

其中k(t) = |v1|/|v(t)|=|v1|/|v1+t*(v2-v1)|.

这样,插值向量v(t)的端点就会沿着v1,v2端点构成的圆弧行进。由于v1,v2是等长的,这个圆弧其实是位于v1,v2构成的球面上的一段,因此又叫球面线性插值,blog

*****************************************************************
这个插值解决了3D空间中旋转的插值,在关键帧动画中能够用来计算两个关键帧之间的动画。可是,因为它的插值不是等角速度的,而是变速的。因此若是用来实现案例中的效果的话还需进一步处理。
*****************************************************************get

***************************************
注:通常球面线性插值v(t)与v1的夹角theta(t)不是t的线性函数。

证实:由向量点积可得cos(theta(t)) = (v(t)*v1)/|v(t)|*|v1|,
theta(t) = arcos((v(t)*v1)/|v1|^2),由反证法,假设theat(t)为线性函数,则 theat(t) = k*t + b,又theta(0) = 0,故 b = 0,theat(t) = k*t,将t'= 2t代入得,theta(2*t) = arcos((v(2*t)*v1)/|v1|^2)并不等于 2*theta(t),因此theat(t)不多是t的线性函数。
***************************************

3。改进的球面线性插值:

要想进行等速的球面线性插值,有几个方法:

1)。用四元数工具:

变换方法:
---------------------------------------------
构造单位四元数q(cos(theta),sin(theta)*v1'),r(cos(theta),sin(theta)*v2')(v1'和v2'为单位v1,v2向量),以

及参数t(0<=t<=1),则构造四元数变换:

a.四元数 s(w,v') = r*(q-1)exp(t)*q
即为球面线性插值变换。其中,s的虚部v'即为v1'和v2'间的插值向量,乘以长度sqrt(x1^2+y1^2+z1^2)即得v1,v2间插值向量v。

b.另外一种变形形式是对四元数进行插值变换:
s(w,v') = a*q + b*r

其中a = sin(alpha*(1-t))/sin(alpha),b = sin(alpha*t))/sin(alpha), cos(alpha) = x1*y1+y1*y2+z1*z2+w1*w2.
s的虚部v'即为v1'和v2'间的插值向量,乘以长度sqrt(x1^2+y1^2+z1^2)即得v1,v2间插值向量v。

两种变换均可以。
----------------------------------------------

复杂度:

以b方法为例:时间主要花在三角函数上,四元数乘以实数只需4次乘法。cost = 1*Tat + 3*Tt + 2Td + 3*4Tm


2)。利用旋转矩阵:

变换方法:
--------------------------------------------
v = v1*Trot

其中,Trot即饶任意轴旋转的矩阵变换矩阵(见上篇:探讨:物体绕任意向量的旋转-四元数法VS.旋转矩阵法的性能比较),由于v1到v2间的插值能够当作是v1饶垂直于v1,v2组成的平面的向量的旋转,因此实际上就是个饶轴旋转的问题,不过相应参数变成:theta = t*theta,轴q(q1,q2,q3)变成向量v1Xv2/|v1Xv2| = (y1*z2-z1*y2,z1*x2-x1*z2,x1*y2-y1*x2)/sin(theta) -------------------------------------------- 复杂度: 基本和饶任意轴旋转矩阵的复杂度同样。主要是多了个向量叉积操做。 cost =2*Tt + 6*Tm + 42*Tm = 2*Tt +48*Tm 综合来看,未通过优化前,效率应该差很少。

相关文章
相关标签/搜索