上节介绍了,算是LookRotation的内部实现,这一节来介绍下unity的FromToRotation函数。
FromToRotation(from,to)这个函数主要的作用是计算将物体从一个旋转态转移到另一个旋转态的四元数,即将from旋转至to需要的四元数,与上一节不同的时,此时旋转对应欧拉角Z分量不一定为0了。
(1)FromToRotation 计算公式
主要计算思路是分别将两个方向向量归一化,两个方向向量的中间向量,即midDir = fromDir + toDir,(需要先将两个向量标准化)然后再将中间向量归一化。获取的中间向量的作用是FromToRotation的结果四元数相当于fromDir先绕中间向量旋转180度,对应旋转四元数为Q1,再绕toDir旋转180度,对应四元数为Q2,总的旋转四元数为Q,假设原本的旋转状态为A,旋转之后的状态为B,存在
Q2Q1AQ1‘Q2' = B (1)
QAQ’ = B (2)
因此Q= Q2Q1,其中根据轴角对与四元数的关系((w,x,y,z)= (Cos sita/2 , Sin sita/2 * x, Sin sita/2 * y, Sin sita/2 * z) )
Q1 = (0,midDir.x,midDir.y,midDir.z) = (0,-midDir.x,-midDir.y,-midDir.z)
Q2 = (0,toDir.x,toDir.y,toDir.z) = (0,-toDir.x,-toDir.y,-toDir.z)
通过四元数的乘法可以得到最终的公式。
需要注意的是,四元数和负四元数代表的是同一种旋转。这个在之前也有提到过。还有就是,两个方向向量需要标准化才能使得中间向量等于二者之和,同时中间向量也需要标准化,即转化为单位向量。
有一种特殊情况就是在toDir和fromDir在同一条直线上时(两个方向正好相反),需要进行一些特殊处理,因为这个时候和向量就不唯一了,为了与Unity保持一致,需要进行特殊处理。在处理时主要按照向量各分量是否为0进行分类处理,根据各分量是否为0,可以将情况分为四个大的种类,八个小的种类,主要情况如下:
(1)有三个向量分量为0
这种情况下fromDir和toDir均为零向量,可以成为非法数据,此种情况下返回(1,0,0,0)(对应(w,x,y,z))
(2)有一个分量为0
这种情况下fromDir和toDi