最近在unity中做一个物体跟踪另外一个的rotation做旋转,需求是需要根据一个物体的rotation跟踪另外一个物体的rotation,但是用欧拉角放缩效果不对,旋转矩阵也无法去做。最后通过四元数的方法得到了解决。
该方法的主要思路来源于参考文献[1].
1 代码
Scale =0.1f;
RotIndicatorQua = rotIndicator.transform.rotation;//跟踪此物体的rotation
string fileName = "./qua3.csv"
delatQua2 = RotIndicatorQua * Quaternion.Inverse(rotationPreQua);//计算上一帧四元数相对于当前帧四元数的delat四元数
Debug.Log("W:" + delatQua2.w);
//计算delta四元数的旋转角度。
float temp= Mathf.Min(Mathf.Max(delatQua2.w, -1.0f), 1.0f);//将w控制在-1.0-1.0之间。
angleQua = 2 * Mathf.Acos(temp);//旋转了多少角度
//计算跟踪物体四元数的旋转轴
RotIndicatorXYZ = new Vector3(delatQua2.x / Mathf.Sin(angleQua / 2), delatQua2.y / Mathf.Sin(angleQua / 2), delatQua2.z / Mathf.Sin(angleQua / 2));
if (float.IsNaN(RotIndicatorXYZ.x)) RotIndicatorXYZ.x = 0;
if (float.IsNaN(RotIndicatorXYZ.y)) RotIndicatorXYZ.y = 0;
if (float.IsNaN(RotIndicatorXYZ.z)) RotIndicatorXYZ.z = 0;
// 计算放缩后的四元数的旋转角
angleQua = angleQua * Mathf.Rad2Deg;//将弧度转为角度
angleGain = Scale * angleQua;//放缩后的角度
Debug.Log("anleQua:" + angleQua + "angleGain:" + angleGain);
angleGain = angleGain * Mathf.Deg2Rad;//角度转弧度
//计算物体帧间四元数,
rotationGain = new Quaternion(RotIndicatorXYZ.x * Mathf.Sin(angleGain / 2), RotIndicatorXYZ.y * Mathf.Sin(angleGain / 2), RotIndicatorXYZ.z * Mathf.Sin(angleGain / 2), Mathf.Cos(angleGain / 2));
if (float.IsNaN(rotationGain.x)) rotationGain.x = 0;
if (float.IsNaN(rotationGain.y)) rotationGain.y = 0;
if (float.IsNaN(rotationGain.z)) rotationGain.z = 0;
//旋转物体
globalVarScript.obj_father.transform.rotation = rotationGain * globalVarScript.obj_father.transform.rotation;
rotationPreQua = RotIndicatorQua;//记录上一帧的rot矩阵。
2 参考文献
[1].https://blog.csdn.net/tchenjiant/article/details/51485745
[2].https://blog.csdn.net/candycat1992/article/details/41254799
[3].https://eater.net/quaternions/video/intro
[4].https://www.zhihu.com/question/23005815
[5]https://www.bilibili.com/video/av33385105
[6]https://www.3dgep.com/understanding-quaternions/
[7]https://www.qiujiawei.com/understanding-quaternions/