3D空间中,在等长度的两个交角为theta的向量v1(x1,y1,z1),v2(x2,y2,z2)之间进行球面线性插值。
不用API,自己写函数时用到。主要是理解原理
实例:
做一个行星在围绕太阳等速旋转的动画,假设只采样到旋转过程中的两个位置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。一般球面线性插值:
将一般线性插值得到的结果乘以放大系数k(t),使其长度放大到|v1|或|v2|,即得保持向量长度不变的插值:
v(t) = k(t)*(v1 + t*(v2-v1))
其中k(t) = |v1|/|v(t)|=|v1|/|v1+t*(v2-v1)|.
这样,插值向量v(t)的端点就会沿着v1,v2端点构成的圆弧行进。因为v1,v2是等长的,这个圆弧实际上是位于v1,v2构成的球面上的一段,所以又叫球面线性插值,
*****************************************************************
这个插值解决了3D空间中旋转的插值,在关键帧动画中可以用来计算两个关键帧之间的动画。但是,由于它的插值不是等角速度的,而是变速的。所以如果用来实现案例中的效果的话还需进一步处理。
*****************************************************************
***************************************
注:一般球面线性插值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
综合来看,未经过优化前,效率应该差不多。