最近工作内容主要是四元数方面,所以在此对unity的四元数做一个总结,也防止以后自己遗忘。
在计算机图形学中,旋转的表示主要包括矩阵、四元数、欧拉角,当然还有轴角对的方式。这几种方式各有优劣,并且相互之间可以互相转化。
矩阵形式主要是计算比较方便,直接使用矩阵的乘法就可以完成旋转操作,通常情况下使用其他形式描述旋转也是转换为矩阵的形式进行计算,矩阵的缺点是需要采用九个数字记录旋转状态,占用内存过多。同时矩阵形式也不够直观。需要注意的是矩阵运算即矩阵的乘法是不可逆的,因为旋转也是不可逆的,unity世界坐标下的旋转次序是Z-X-Y;
欧拉角形式的优缺点正好和矩阵形式互补,欧拉角的优点是非常直观,直接采用三个角度的旋转角度记录旋转数据,并且占用内存空间较少,缺点是如果需要做旋转,是不可以直接使用欧拉角的运算的,一般需要转换为矩阵形式进行运算。同时由于欧拉角的旋转次序的问题,欧拉角还有一个万向节锁的问题。
四元数相对来说实现了欧拉角和矩阵的折中,四元数需要用四个元素表示旋转,同时四元数可以直接进行乘法操作,不过四元数相对来说也是不够直观,四元数可以理解为轴角对,绕某个轴旋转一定的角度,但是四个元素和旋转轴和旋转角度的关系相对复杂一些,假设旋转轴为(X,Y,Z),旋转角度为A,则对应四元数为(cos(A/2),X*SIN(A/2),Y*SIN(A/2),Z*SIN(A/2)) =(W,X,Y,Z) 。四元数还有一个好处就是可以实现旋转插值从而实现平滑旋转。
主要实现了两个函数:
(1)LookRotation 根据朝向获得四元数,使得物体面向特定的方向
(2)FromToRotation 将物体从一个特定的朝向变为另一个朝向的中间四元数
同时实现了配套的四元数与欧拉角之间的相互转换。
(1)LookRotation(dir)
此函数实现了根据朝向dir= (X,Y,Z)获取四元数,即从(0,0,1)转向(X,Y,Z)需要的四元数,注意旋转次序为ZXY,并且还有一个需要注意的点为此函数获取的四元数转化为欧拉角对应的Z角为0,所以在最终转化得来的欧拉角中Z为0
经过计算,假设欧拉角为(X,Y,Z),朝向为(x,y,z),朝向和欧拉角之间的换算公式为
X = acos(sqrt((x^2+z^2)/(x^2+y^2+z