注意:Oa其实在OK的延长线上,上图只是为了好看才把Oa和OK分开了
算法需求如图所示:
已知空间向量OA和空间向量OB
我想算出OA向OB按某角度或者某时间移动
变成空间向量Oa的算法
先说废话:我一开始尝试了:空间平面、矩阵、四元素等等方式都能算出来,但是很繁琐。
然后发现,其实向量之间的算法完全能满足需求:
1.先求出向量AB
2.然后按某时间,某角度或者某百分比 乘以AB向量得到向量:AK
3.OA+AK=OK
4.将OK的向量归一化,乘以OA的模(长度)得到Oa
注意:Oa其实在OK的延长线上,上图只是为了好看才把Oa和OK分开了
1 osg::Vec3d rotateVector(double time, osg::Vec3d OA, osg::Vec3d OB) 2 { 3 //http://www.cnblogs.com/lyggqm/p/8820676.html 4 osg::Vec3d _Oa; 5 osg::Vec3d AB = OB - OA; 6 if (time >=0.0 && time <= 1.0) 7 AB *= time;//AK = AB*time 8 else 9 return OA; 10 osg::Vec3d OK = OA + AB; 11 OK.normalize();//因为OA,OB传入的已经是normalize的所以OK就是Oa了 12 _Oa = OK; 13 return _Oa; 14 }
算法结束
由此算法,再给出一个osg空间四元素q1转到空间四元素q2的函数吧:(与之前算法无关)
1 /// Spherical Linear Interpolation 2 /// As t goes from 0 to 1, the Quat object goes from "from" to "to" 3 /// Reference: Shoemake at SIGGRAPH 89 4 /// See also 5 /// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm 6 void Quat::slerp( value_type t, const Quat& from, const Quat& to ) 7 { 8 const double epsilon = 0.00001; 9 double omega, cosomega, sinomega, scale_from, scale_to ; 10 11 osg::Quat quatTo(to); 12 // this is a dot product 13 14 cosomega = from.asVec4() * to.asVec4(); 15 16 if ( cosomega <0.0 ) 17 { 18 cosomega = -cosomega; 19 quatTo = -to; 20 } 21 22 if( (1.0 - cosomega) > epsilon ) 23 { 24 omega= acos(cosomega) ; // 0 <= omega <= Pi (see man acos) 25 sinomega = sin(omega) ; // this sinomega should always be +ve so 26 // could try sinomega=sqrt(1-cosomega*cosomega) to avoid a sin()? 27 scale_from = sin((1.0-t)*omega)/sinomega ; 28 scale_to = sin(t*omega)/sinomega ; 29 } 30 else 31 { 32 /* -------------------------------------------------- 33 The ends of the vectors are very close 34 we can use simple linear interpolation - no need 35 to worry about the "spherical" interpolation 36 -------------------------------------------------- */ 37 scale_from = 1.0 - t ; 38 scale_to = t ; 39 } 40 41 *this = (from*scale_from) + (quatTo*scale_to); 42 43 // so that we get a Vec4 44 } 45 46 //*************以下是用法*******************/ 47 48 osg::Quat q1,q2; 49 double time;//time是0到1值 50 //.......赋值不表 51 52 q1.slerp(time, q1, q2);//q1按time百分比转到q2