Unity中的四元数主要用于旋转变换,初识四元数时很是困惑,在查看相关博客和实践后,对四元数有了基础的认识,现将所理解的部分记录下来。
四元数本质为复数,复数最基础的印象是:
x=a+bi,a为实部,b为虚部,i为虚数单位;
四元数和这种类似,只是虚数部分为i,j,k,四元数表示为:
x=a+bi+cj+dk;
对于四元数的实部和虚部,可以这样表示:
q = ((x, y, z),w) = (v, w),其中v是向量(空间中的旋转轴和点都可以看做是向量),w是实部;
如果已知一个轴(x,y,z)和绕该轴旋转的角度θ,那么可以通过:
四元数q=((x,y,z)sin(θ/2), cos(θ/2))来表示这样一个旋转,如何计算某一点或向量执行这样一个旋转后的结果呢? (先手动计算一下)
1. 将要执行旋转的点转换成四元数形式:
p = ((a,b,c),0)=(P, 0)
2. 旋转后得到的点对应的四元数(计算而得的四元数的实部为0,虚部系数就是新的坐标)为:
p′=qpq−1
这里:q=((x,y,z)sin(θ/2),cos(θ/2))
详细计算的过程可以参考这篇博客 ,截图来自该博客
这里需要注意的是:
- 四元数分量的范围均在(-1,1之间)
- 所有用于旋转的四元数是单位四元数,模长为1
在了解以上内容后,Unity中的四元数理解起来也许就没那么头疼,这里首先需要明确的是:
Unity下的实践操作,主要使用的函数:
Quaternion.AngleAxis(angles,axis);
//给定旋转的轴和角度,生成对应的四元数,记录该旋转变换的信息
1.某一点执行旋转,旋转前:
点在Plane平面所在轴的Z正向
执行旋转:
transform.position = Quaternion.AngleAxis(angles,axis)*(transform.position-target.position)+target.position;
绕Plane所在平面的Y轴旋转90度,这里有一个transform.position-target.position的运算,是由于旋转以target为中心,而旋转后得到的结果是以target为中心进行旋转后的位置,为了得到世界空间中的正确位置,需要在加上target的世界坐标,旋转后的结果:
从控制台的输出信息可以得出Unity中的旋转正方向:
逆着旋转轴的方向看过去,沿逆时针方向旋转为旋转的正方向
2.某一局部坐标轴进行旋转:
执行旋转:
transform.rotation = Quaternion.AngleAxis(angles, axis) * transform.rotation;
这里进行旋转的对象是Plane平面自身的局部坐标系 transform.rotation 绕自己的Z轴旋转60度后,得到的旋转后的坐标系,再赋值给自己的坐标轴,相当于以自己旋转前的某一个轴将自己的局部坐标系进行了旋转(也就是整体之前的轴进行了旋转),得到的结果:
为了显示直观,使用 transform.rotation.eulerAngles 将四元数显示为欧拉角,可以从控制台的信息看出:
自身绕Z轴旋转了60度,局部坐标系发生了相应的旋转。
总结: