Unity 四元数与欧拉角的相互转换及推导

懒惰的我终于也要写第一篇博客啦~由于需求需要在控制台中对unity的四元数与欧拉角进行相互转换 而网上的文章大多没有推导过程 并且坐标系或欧拉角的旋转顺序与unity不一致 所以自己动笔算了算 在此记录一下~
首先感谢这个小姐姐的这篇文章。以及文章中的以下四个链接给予我的启发
1. Euler To Quaternion
2.Quaternion To Euler
3.AngleAxis To Quaternion
4.Quaternion To AngleAxis

注:本文建立在对欧拉角和四元数概念了解透彻的基础上所做的纯数学推导 若对概念不清可先看上面小姐姐的文章~

废话结束进入正题

先说结论

定义unity中的欧拉角为e = (X,Y,Z)
四元数为Q = (x,y,z,w) = w+ix+jy+kz

欧拉角→四元数:

w = c 1 c 2 c 3 + s 1 s 2 s 3 x = s 1 s 2 c 3 + c 1 c 2 s 3 y = s 1 c 2 c 3 − c 1 s 2 s 3 z = c 1 s 2 c 3 − s 1 c 2 s 3 \begin{array}{l} w = c_1c_2c_3 + s_1s_2s_3\\ x = s_1s_2c_3 + c_1c_2s_3\\ y = s_1c_2c_3 - c_1s_2s_3\\ z = c_1s_2c_3 - s_1c_2s_3\end{array} w=c1c2c3+s1s2s3x=s1s2c3+c1c2s3y=s1c2c3c1s2s3z=c1s2c3s1c2s3
其中:
s 1 = s i n ( Y / 2 ) c 1 = c o s ( Y / 2 ) s 2 = s i n ( Z / 2 ) c 2 = c o s ( Z / 2 ) s 3 = s i n ( X / 2 ) c 3 = c o s ( X / 2 ) \begin{array}{l} s_1 = sin(Y/2)\\ c_1 = cos(Y/2)\\ s_2= sin(Z/2)\\ c_2 = cos(Z/2)\\ s_3 = sin(X/2)\\ c_3 = cos(X/2)\end{array} s1=sin(Y/2)c1=cos(Y/2)s2=sin(Z/2)c2=cos(Z/2)s3=sin(X/2)c3=cos(X/2)

四元数→欧拉角:
X = a s i n ( 2 w x − 2 y z ) Y = a t a n 2 ( 2 w y + 2 x z , 1 − 2 x 2 − 2 y 2 ) Z = a t a n 2 ( 2 w z + 2 x y , 1 − 2 x 2 − 2 z 2 ) \begin{array}{l} X = asin(2wx-2yz)\\ Y = atan2(2wy+2xz,1-2x^2-2y^2)\\ Z = atan2(2wz+2xy,1-2x^2-2z^2)\end{array} X=asin(2wx2yz)Y=atan2(2wy+2xz,12x22y2)Z=atan2(2wz+2xy,12x22z2)

推导

欧拉角→四元数

首先由轴角到四元数公式 q = ( ( x , y , z ) s i n θ 2 , c o s θ 2 ) q = ((x,y,z)sin\frac{\theta}{2},cos\frac{\theta}{2}) q=((x,y,z)sin2θ,cos2θ) 得绕三个轴旋转的四元数分别为
Q X = c 3 + i s 3 Q Y = c 1 + j s 1 Q Z = c 2 + k s 2 \begin{array}{l} Q_X = c_3+is_3\\ Q_Y = c_1+js_1\\ Q_Z = c_2+ks_2 \end{array} QX=c3+is3QY=c1+js1QZ=c2+ks2

由于unity欧拉角的旋转顺序为z→x→y
故该欧拉角对应的四元数应为
Q = Q Y Q X Q Z Q=Q_YQ_XQ_Z Q=QYQXQZ
分别带入得
Q = ( c 1 + j s 1 ) ( c 3 + i s 3 ) ( c 2 + k s 2 ) = ( c 1 c 3 + i c 1 s 3 + j s 1 c 3 − k s 1 s 3 ) ( c 2 + k s 2 ) = c 1 c 2 c 3 + s 1 s 2 s 3 + i ( s 1 s 2 c 3 + c 1 c 2 s 3 ) + j ( s 1 c 2 c 3 − c 1 s 2 s 3 ) + k ( c 1 s 2 c 3 − s 1 c 2 s 3 ) \begin{array}{l} Q &=(c_1+js_1)(c_3+is_3)(c_2+ks_2)\\ &=(c_1c_3+ic_1s_3+js_1c_3-ks_1s_3)(c_2+ks_2)\\ &=c_1c_2c_3+s_1s_2s_3+i(s_1s_2c_3+c_1c_2s_3)+j(s_1c_2c_3-c_1s_2s_3)+k(c_1s_2c_3-s_1c_2s_3) \end{array} Q=(c1+js1)(c3+is3)(c2+ks2)=(c1c3+ic1s3+js1c3ks1s3)(c2+ks2)=c1c2c3+s1s2s3+i(s1s2c3+c1c2s3)+j(s1c2c3c1s2s3)+k(c1s2c3s1c2s3)
得到结论
w = c 1 c 2 c 3 + s 1 s 2 s 3 x = s 1 s 2 c 3 + c 1 c 2 s 3 y = s 1 c 2 c 3 − c 1 s 2 s 3 z = c 1 s 2 c 3 − s 1 c 2 s 3 \begin{array}{l} w = c_1c_2c_3 + s_1s_2s_3\\ x = s_1s_2c_3 + c_1c_2s_3\\ y = s_1c_2c_3 - c_1s_2s_3\\ z = c_1s_2c_3 - s_1c_2s_3\end{array} w=c1c2c3+s1s2s3x=s1s2c3+c1c2s3y=s1c2c3c1s2s3z=c1s2c3s1c2s3
其中运用到了正交特性:ij=k, jk=i, ki=j

四元数→欧拉角

首先我们知道三角函数一个非常优美的特性 s i n 2 + c o s 2 = 1 sin^2+cos^2=1 sin2+cos2=1
所以有 s 1 2 + c 1 2 = s 2 2 + c 2 2 = s 3 2 + c 3 2 = 1 s_1^2+c_1^2=s_2^2+c_2^2=s_3^2+c_3^2=1 s12+c12=s22+c22=s32+c32=1
接下来我们先来计算
w x = c 1 2 c 2 2 c 3 s 3 + c 1 c 2 c 3 2 s 1 s 2 + c 1 c 2 s 1 s 2 s 3 2 + c 3 s 1 2 s 2 2 s 3 y z = − c 1 2 c 3 s 2 2 s 3 + c 1 c 2 c 3 2 s 1 s 2 + c 1 c 2 s 1 s 2 s 3 2 − c 2 2 c 3 s 1 2 s 3 w y = c 1 c 2 2 c 3 2 s 1 + c 2 c 3 s 1 2 s 2 s 3 − c 1 2 c 2 c 3 s 2 s 3 − c 1 s 1 s 2 2 s 3 2 x z = c 1 c 3 2 s 1 s 2 2 − c 2 c 3 s 1 2 s 2 s 3 + c 1 2 c 2 c 3 s 2 s 3 − c 1 c 2 2 s 1 s 3 2 w z = c 1 2 c 2 c 3 2 s 2 + c 1 c 3 s 1 s 2 2 s 3 − c 1 c 2 2 c 3 s 1 s 3 − c 2 s 1 2 s 2 s 3 2 x y = c 2 c 3 2 s 1 2 s 2 − c 1 c 3 s 1 s 2 2 s 3 + c 1 c 2 2 c 3 s 1 s 3 − c 1 2 c 2 s 2 s 3 2 \begin{array}{l} wx = c_1^2c_2^2c_3s_3+c_1c_2c_3^2s_1s_2+c_1c_2s_1s_2s_3^2+c_3s_1^2s_2^2s_3\\ yz =-c_1^2c_3s_2^2s_3+c_1c_2c_3^2s_1s_2+c_1c_2s_1s_2s_3^2-c_2^2c_3s_1^2s_3\\ wy = c_1c_2^2c_3^2s_1+c_2c_3s_1^2s_2s_3-c_1^2c_2c_3s_2s_3-c_1s_1s_2^2s_3^2\\ xz=c_1c_3^2s_1s_2^2-c_2c_3s_1^2s_2s_3+c_1^2c_2c_3s_2s_3-c_1c_2^2s_1s_3^2\\ wz = c_1^2c_2c_3^2s_2+c_1c_3s_1s_2^2s_3-c_1c_2^2c_3s_1s_3-c_2s_1^2s_2s_3^2\\ xy = c_2c_3^2s_1^2s_2-c_1c_3s_1s_2^2s_3+c_1c_2^2c_3s_1s_3-c_1^2c_2s_2s_3^2 \end{array} wx=c12c22c3s3+c1c2c32s1s2+c1c2s1s2s32+c3s12s22s3yz=c12c3s22s3+c1c2c32s1s2+c1c2s1s2s32c22c3s12s3wy=c1c22c32s1+c2c3s12s2s3c12c2c3s2s3c1s1s22s32xz=c1c32s1s22c2c3s12s2s3+c12c2c3s2s3c1c22s1s32wz=c12c2c32s2+c1c3s1s22s3c1c22c3s1s3c2s12s2s32xy=c2c32s12s2c1c3s1s22s3+c1c22c3s1s3c12c2s2s32
显然有
w x − y z = c 1 2 c 3 s 3 + s 1 2 c 3 s 3 = c 3 s 3 = s i n X 2 w y + x z = c 1 c 3 2 s 1 − c 1 s 3 2 s 1 = c 3 2 − s 3 2 2 s i n Y w z + x y = c 2 s 2 c 3 2 − c 2 s 2 s 3 2 = c 3 2 − s 3 2 2 s i n Z \begin{array}{l} wx-yz=c_1^2c_3s_3+s_1^2c_3s_3=c_3s_3=\frac{sinX}{2}\\ wy+xz=c_1c_3^2s_1-c_1s_3^2s_1=\frac{c_3^2-s_3^2}{2}sinY\\ wz+xy=c_2s_2c_3^2-c_2s_2s_3^2=\frac{c_3^2-s_3^2}{2}sinZ \end{array} wxyz=c12c3s3+s12c3s3=c3s3=2sinXwy+xz=c1c32s1c1s32s1=2c32s32sinYwz+xy=c2s2c32c2s2s32=2c32s32sinZ
由此可以首先得出 X = a s i n ( 2 w x − 2 y z ) X=asin(2wx-2yz) X=asin(2wx2yz)
然而Y和Z的算式中有个讨厌的 c 3 2 − s 3 2 c_3^2-s_3^2 c32s32所以我们需要用适当的除法来消掉它
所以我们再来计算
w 2 = c 1 2 c 2 2 c 3 2 + s 1 2 s 2 2 s 3 2 + 2 c 1 c 2 c 3 s 1 s 2 s 3 x 2 = s 1 2 s 2 2 c 3 2 + c 1 2 c 2 2 s 3 2 + 2 c 1 c 2 c 3 s 1 s 2 s 3 y 2 = s 1 2 c 2 2 c 3 2 + c 1 2 s 2 2 s 3 2 − 2 c 1 c 2 c 3 s 1 s 2 s 3 z 2 = c 1 2 s 2 2 c 3 2 + s 1 2 c 2 2 s 3 2 − 2 c 1 c 2 c 3 s 1 s 2 s 3 \begin{array}{l} w^2=c_1^2c_2^2c_3^2+s_1^2s_2^2s_3^2+2c_1c_2c_3s_1s_2s_3\\ x^2=s_1^2s_2^2c_3^2+c_1^2c_2^2s_3^2+2c_1c_2c_3s_1s_2s_3\\ y^2=s_1^2c_2^2c_3^2+c_1^2s_2^2s_3^2-2c_1c_2c_3s_1s_2s_3\\ z^2=c_1^2s_2^2c_3^2+s_1^2c_2^2s_3^2-2c_1c_2c_3s_1s_2s_3 \end{array} w2=c12c22c32+s12s22s32+2c1c2c3s1s2s3x2=s12s22c32+c12c22s32+2c1c2c3s1s2s3y2=s12c22c32+c12s22s322c1c2c3s1s2s3z2=c12s22c32+s12c22s322c1c2c3s1s2s3
所以有
w 2 − x 2 = ( c 1 2 c 2 2 − s 1 2 s 2 2 ) ( c 3 2 − s 3 2 ) y 2 − z 2 = ( s 1 2 c 2 2 − c 1 2 s 2 2 ) ( c 3 2 − s 3 2 ) \begin{array}{l} w^2-x^2=(c_1^2c_2^2-s_1^2s_2^2)(c_3^2-s_3^2)\\ y^2-z^2=(s_1^2c_2^2-c_1^2s_2^2)(c_3^2-s_3^2) \end{array} w2x2=(c12c22s12s22)(c32s32)y2z2=(s12c22c12s22)(c32s32)
所以有
w 2 − x 2 + y 2 − z 2 = ( c 2 2 − s 2 2 ) ( c 1 2 + s 1 2 ) ( c 3 2 − s 3 2 ) = c o s Z ( c 3 2 − s 3 2 ) w 2 − x 2 − ( y 2 − z 2 ) = ( c 1 2 − s 1 2 ) ( c 2 2 + s 2 2 ) ( c 3 2 − s 3 2 ) = c o s Y ( c 3 2 − s 3 2 ) \begin{array}{l} w^2-x^2+y^2-z^2=(c_2^2-s_2^2)(c_1^2+s_1^2)(c_3^2-s_3^2)=cosZ(c_3^2-s_3^2)\\ w^2-x^2-(y^2-z^2)=(c_1^2-s_1^2)(c_2^2+s_2^2)(c_3^2-s_3^2)=cosY(c_3^2-s_3^2) \end{array} w2x2+y2z2=(c22s22)(c12+s12)(c32s32)=cosZ(c32s32)w2x2(y2z2)=(c12s12)(c22+s22)(c32s32)=cosY(c32s32)
于是我们就可以愉快的相除了 得到
s i n Y c o s Y = 2 w y + 2 x z w 2 − x 2 − ( y 2 − z 2 ) s i n Z c o s Z = 2 w z + 2 x y w 2 − x 2 + y 2 − z 2 \begin{array}{l} \frac{sinY}{cosY} = \frac{2wy+2xz}{w^2-x^2-(y^2-z^2)}\\ \frac{sinZ}{cosZ} =\frac{2wz+2xy}{w^2-x^2+y^2-z^2} \end{array} cosYsinY=w2x2(y2z2)2wy+2xzcosZsinZ=w2x2+y2z22wz+2xy
因为 w 2 + x 2 + y 2 + z 2 = 1 w^2+x^2+y^2+z^2=1 w2+x2+y2+z2=1 所以可将上式化简为
s i n Y c o s Y = 2 w y + 2 x z 1 − 2 x 2 − 2 y 2 s i n Z c o s Z = 2 w z + 2 x y 1 − 2 x 2 − 2 z 2 \begin{array}{l} \frac{sinY}{cosY} = \frac{2wy+2xz}{1-2x^2-2y^2}\\ \frac{sinZ}{cosZ} = \frac{2wz+2xy}{1-2x^2-2z^2} \end{array} cosYsinY=12x22y22wy+2xzcosZsinZ=12x22z22wz+2xy
所以得到结论
X = a s i n ( 2 w x − 2 y z ) Y = a t a n 2 ( 2 w y + 2 x z , 1 − 2 x 2 − 2 y 2 ) Z = a t a n 2 ( 2 w z + 2 x y , 1 − 2 x 2 − 2 z 2 ) \begin{array}{l} X = asin(2wx-2yz)\\ Y = atan2(2wy+2xz,1-2x^2-2y^2)\\ Z = atan2(2wz+2xy,1-2x^2-2z^2)\end{array} X=asin(2wx2yz)Y=atan2(2wy+2xz,12x22y2)Z=atan2(2wz+2xy,12x22z2)
至于为什么使用atan2而不是atan 这篇文章 给出了详细的解释

以上全部推导完毕 虽然用的都是高中数学的基本知识 不过不自己动笔算一下也很难知道结果的由来啦码公式不易转载请注明出处谢谢。

你可能感兴趣的:(unity,unity)