四元数与旋转的关系,unity验证

先介绍一下四元数与旋转的关系,之后在Unity中进行仿真看是否和理论一致。

四元数

先介绍一下四元数的概念:
首先四元数的定义与复数非常相似:
复数的定义为:
z = a + b i z=a+bi z=a+bi
其中: i 2 = − 1 , a 、 b ∈ R i^2=-1,a、b\in\mathbb{R} i2=1,abR
我们对四元数的定义为:
q = a + b i + c j + d k q=a+bi+cj+dk q=a+bi+cj+dk
其中: i 2 = j 2 = k 2 = i j k = − 1 , a 、 b 、 c 、 d ∈ R i^2=j^2=k^2=ijk=-1,a、b、c、d\in\mathbb{R} i2=j2=k2=ijk=1,abcdR
这里的四元数仅仅只是这样定义的,只需要记住四元数的定义和他的几个性质即可。理解旋转不需要理解四元数在高维空间的意义,也不需要知道四元数的其他性质。
同时我们也采用另一种方式(向量、矩阵)的形式来存储四元数。
比如 q = [ s , v ] . ( v = [ x , y , z ] , s , x , y , z ∈ R ) q=[s,\mathbf v].(\mathbf v=[x,y,z],s,x,y,z\in\mathbb{R}) q=[s,v].(v=[x,y,z],s,x,y,zR)
其中s,x,y,z分别对应我们的a,b,c,d

四元数的性质

四元数的加法和减法

四元数的加法和减法与复数的加法与减法类似:
加法:
q 1 = a 1 + b 1 i + c 1 j + d 1 k q_1=a_1+b_1i+c_1j+d_1k q1=a1+b1i+c1j+d1k
q 2 = a 2 + b 2 i + c 2 j + d 2 k q_2=a_2+b_2i+c_2j+d_2k q2=a2+b2i+c2j+d2k
q 1 + q 2 = ( a 1 + a 2 ) + ( b 1 + b 2 ) i + ( c 1 + c 2 ) j + ( d 1 + d 2 ) k q_1+q_2=(a_1+a_2)+(b_1+b_2)i+(c_1+c_2)j+(d_1+d_2)k q1+q2=(a1+a2)+(b1+b2)i+(c1+c2)j+(d1+d2)k
可以看到我们的四元数的加法和减法是符合各分量相加的,减法同理:
q 1 = a 1 + b 1 i + c 1 j + d 1 k q_1=a_1+b_1i+c_1j+d_1k q1=a1+b1i+c1j+d1k
q 2 = a 2 + b 2 i + c 2 j + d 2 k q_2=a_2+b_2i+c_2j+d_2k q2=a2+b2i+c2j+d2k
q 1 − q 2 = ( a 1 − a 2 ) + ( b 1 − b 2 ) i + ( c 1 − c 2 ) j + ( d 1 − d 2 ) k q_1-q_2=(a_1-a_2)+(b_1-b_2)i+(c_1-c_2)j+(d_1-d_2)k q1q2=(a1a2)+(b1b2)i+(c1c2)j+(d1d2)k
根据四元数的第二种表示形式,我们有:
q 1 = [ s 1 , t 1 ] , q 2 = [ s 2 , t 2 ] q_1=[s_1,\mathbf t_1],q_2=[s_2,\mathbf t_2] q1=[s1,t1],q2=[s2,t2]
则有:
q 1 ± q 2 = [ s 1 ± s 2 , t 1 ± t 2 ] q_1 \pm q_2=[s_1 \pm s_2,\mathbf t_1 \pm \mathbf t_2] q1±q2=[s1±s2,t1±t2]

四元数的乘法

四元数的乘法是比较特殊的,首先四元数的乘法不遵循交换律。
我们先推导一下四元数的乘积,以及他的表示:
q 1 = a 1 + b 1 i + c 1 j + d 1 k q_1=a_1+b_1i+c_1j+d_1k q1=a1+b1i+c1j+d1k
q 2 = a 2 + b 2 i + c 2 j + d 2 k q_2=a_2+b_2i+c_2j+d_2k q2=a2+b2i+c2j+d2k
q 1 q 2 = ( a 1 + b 1 i + c 1 j + d 1 k ) ∗ ( a 2 + b 2 i + c 2 j + d 2 k ) = a 1 a 2 + a 1 b 2 i + a 1 c 2 j + a 1 d 2 k + a 2 b 1 i + b 1 b 2 i 2 + b 1 c 2 i j + b 1 d 2 i k + a 2 c 1 j + b 2 c 1 j i + c 1 c 2 j 2 + c 1 d 2 j k + a 2 d 1 k + b 2 d 1 k i + c 2 d 1 k j + d 1 d 2 k 2 q_1q_2=(a_1+b_1i+c_1j+d_1k)* (a_2+b_2i+c_2j+d_2k)\\=a_1a_2+a_1b_2i+a_1c_2j+a_1d_2k\\+a_2b_1i+b_1b_2i^2+b_1c_2ij+b_1d_2ik\\+a_2c_1j+b_2c_1ji+c_1c_2j^2+c_1d_2jk\\+a_2d_1k+b_2d_1ki+c_2d_1kj+d_1d_2k^2 q1q2=(a1+b1i+c1j+d1k)(a2+b2i+c2j+d2k)=a1a2+a1b2i+a1c2j+a1d2k+a2b1i+b1b2i2+b1c2ij+b1d2ik+a2c1j+b2c1ji+c1c2j2+c1d2jk+a2d1k+b2d1ki+c2d1kj+d1d2k2
此处的推导要注意顺序因为例如: i j ≠ j i ij\not=ji ij=ji
我们根据 i 2 = j 2 = k 2 = i j k = − 1 i^2=j^2=k^2=ijk=-1 i2=j2=k2=ijk=1
可以推导出:
i 2 = j 2 = k 2 = − 1 i j = k j k = i i k = − j i^2=j^2=k^2=-1\\ij=k\\jk=i\\ik=-j i2=j2=k2=1ij=kjk=iik=j
因此我们可以化简:
q 1 q 2 = a 1 a 2 − b 1 b 2 − c 1 c 2 − d 1 d 2 + ( a 1 b 2 + a 2 b 1 + c 1 d 2 − c 2 d 1 ) i + ( a 1 c 2 − b 1 d 2 + a 2 c 1 + b 2 d 1 ) j + ( a 1 d 2 + b 1 c 2 − b 2 c 1 + a 2 d 1 ) k q_1q_2=a_1a_2-b_1b_2-c_1c_2-d_1d_2\\+(a_1b_2+a_2b_1+c_1d_2-c_2d_1)i\\+(a_1c_2-b_1d_2+a_2c_1+b_2d_1)j\\+(a_1d_2+b_1c_2-b_2c_1+a_2d_1)k q1q2=a1a2b1b2c1c2d1d2+(a1b2+a2b1+c1d2c2d1)i+(a1c2b1d2+a2c1+b2d1)j+(a1d2+b1c2b2c1+a2d1)k
经过整理有:
= ( a 1 a 2 − b 1 b 2 − c 1 c 2 − d 1 d 2 ) + ( b 1 a 2 + a 1 b 2 − d 1 c 2 + c 1 d 2 ) i + ( c 1 a 2 + d 1 b 2 + a 1 c 2 − b 1 d 2 ) j + ( d 1 a 2 − c 1 b 2 + b 1 c 2 + a 1 d 2 ) k =(a_1a_2-b_1b_2-c_1c_2-d_1d_2)\\+(b_1a_2+a_1b_2-d_1c_2+c_1d_2)i\\+(c_1a_2+d_1b_2+a_1c_2-b_1d_2)j\\+(d_1a_2-c_1b_2+b_1c_2+a_1d_2)k =(a1a2b1b2c1c2d1d2)+(b1a2+a1b2d1c2+c1d2)i+(c1a2+d1b2+a1c2b1d2)j+(d1a2c1b2+b1c2+a1d2)k
我们可以将上述的式子看成是矩阵相乘的形式。(这里不再赘述)
同时我们推导一下四元数的一些性质如下:
我们如果将上文的分量作为向量则有:
v = [ b 1 , c 1 , d 1 ] , u = [ b 2 , c 2 , d 2 ] \mathbf v=[b_1,c_1,d_1],\mathbf u=[b_2,c_2,d_2] v=[b1,c1,d1],u=[b2,c2,d2]
那么我们可以推导出来
v ⋅ u = b 1 b 2 + c 1 c 2 + d 1 d 2 \mathbf v \cdot \mathbf u=b_1b_2+c_1c_2+d_1d_2 vu=b1b2+c1c2+d1d2
同时我们也有
v × u = ( c 1 d 2 − d 1 c 2 ) i − ( b 1 d 2 − d 1 b 2 ) j + ( b 1 c 2 − c 1 b 2 ) k \mathbf v \times \mathbf u=(c_1d_2-d_1c_2)i-(b_1d_2-d_1b_2)j+(b_1c_2-c_1b_2)k v×u=(c1d2d1c2)i(b1d2d1b2)j+(b1c2c1b2)k
则我们可以将其写成:
q 1 q 2 = [ a 1 a 2 − v ⋅ u , a 1 u + a 2 v + v × u ] q_1q_2=[a_1a_2-\mathbf v \cdot \mathbf u,a_1 \mathbf u+a_2 \mathbf v+\mathbf v \times \mathbf u] q1q2=[a1a2vu,a1u+a2v+v×u]
这个就是四元数的乘积的另一种表示形式。

纯四元数

对于一个纯四元数(只有虚部的四元数)来说,我们可以将其与三维世界一一对应,即我们的x,y,z坐标对应的正是i,j,k的数值。
这时对我们两个纯虚数来说:
v = [ 0 , v ] , u = [ 0 , u ] v=[0,\mathbf v],u=[0,\mathbf u] v=[0,v],u=[0,u]
则我们有根据上文可以推导:
v u = [ − v ⋅ u , v × u ] vu=[-\mathbf v \cdot \mathbf u,\mathbf v \times \mathbf u] vu=[vu,v×u]

四元数的逆、共轭

四元数的逆

我们规定 q − 1 q^{-1} q1 q q q的逆,因此我们可以规定有:
q q − 1 = q − 1 q = 1 ( q ≠ 0 ) qq^{-1}=q^{-1}q=1(q\not = 0) qq1=q1q=1(q=0)
这里要注意左乘与右乘的区别。

四元数的共轭

我们规定 q ∗ q^{*} q q q q的共轭。
其中假设: q = a + b i + c j + d k q=a+bi+cj+dk q=a+bi+cj+dk q ∗ = a − b i − c j − d k q^{*}=a-bi-cj-dk q=abicjdk
因此根据四元数的另一种定义形式我们有:
q = [ a , v ] q ∗ = [ a , − v ] q=[a,\mathbf v]\\q^{*}=[a,-\mathbf v] q=[a,v]q=[a,v]

四元数共轭的性质

q ∗ q = [ a 2 − v ⋅ v , a v + a ( − v ) − v × v ] = [ a 2 + v ⋅ v , 0 ] = ∣ q ∣ 2 q^{*}q=[a^2-\mathbf v \cdot \mathbf v,a\mathbf v+a(-\mathbf v)-\mathbf v \times \mathbf v]\\=[a^2+\mathbf v \cdot \mathbf v,0]=|q|^2 qq=[a2vv,av+a(v)v×v]=[a2+vv,0]=q2
四元数共轭的乘法是满足交换律的:
q ∗ q = q q ∗ q^{*}q=qq^{*} qq=qq
当四元数是一个单位四元数的时候,会有好性质如下:
q q ∗ = 1 q − 1 q q ∗ = q − 1 q ∗ = q − 1 qq^{*}=1\\q^{-1}qq^{*}=q^{-1}\\q*=q^{-1} qq=1q1qq=q1q=q1

旋转

我们先看一下三维空间的旋转,以四元数应用的角度来看:
四元数与旋转的关系,unity验证_第1张图片
假设一个向量 v \mathbf v v要绕 u \mathbf u u旋转 θ \theta θ度。则我们可以分解为 v / / , v ⊥ \mathbf v_{//},\mathbf v_{\bot} v//,v u \mathbf u u旋转再求和。
接下来的推导均假设 u \mathbf u u为单位向量,如果不是单位向量就单位化再进行将其作为轴进行旋转。

v / / \mathbf v_{//} v//的旋转

我们知道 v / / = ( u ⋅ v ) u \mathbf v_{//}=(\mathbf u \cdot \mathbf v)\mathbf u v//=(uv)u
并且 v / / \mathbf v_{//} v//旋转过程中并不变,
因此有: v / / ′ = v / / \mathbf v_{//}^{'}=\mathbf v_{//} v//=v//

v ⊥ \mathbf v_{\bot} v的旋转

根据上文我们有:
v ⊥ = v − v / / \mathbf v_{\bot}=\mathbf v-\mathbf v_{//} v=vv//
我们知道 v ⊥ \mathbf v_{\bot} v是在图上的圆中的,也就是 v ⊥ \mathbf v_{\bot} v绕圆旋转 θ \theta θ度。如果我们想要用一个向量来表示 v ⊥ ′ \mathbf v_{\bot}^{'} v的话我们需要构建一个单位向量通过叉乘的形式构建一个与 v ⊥ \mathbf v_{\bot} v的向量。
这个向量我们称之为: w \mathbf w w
w = u × v ⊥ \mathbf w=\mathbf u\times \mathbf v_{\bot} w=u×v
方向由右手定则确定。
如果其中的 u \mathbf u u为单位向量,那么 ∣ w ∣ = ∣ v ⊥ ∣ |\mathbf w|=|\mathbf v_{\bot}| w=v
此时如果旋转 θ \theta θ度。
则有:
v ⊥ ′ = c o s ( θ ) v ⊥ + s i n ( θ ) w = c o s ( θ ) ( v − v / / ) + s i n ( θ ) ( u × v ⊥ ) \mathbf v_{\bot}^{'}=cos(\theta)\mathbf v_{\bot}+sin(\theta)\mathbf w\\=cos(\theta)(\mathbf v- \mathbf v_{//})+sin(\theta)(\mathbf u \times \mathbf v_{\bot}) v=cos(θ)v+sin(θ)w=cos(θ)(vv//)+sin(θ)(u×v)
其中有: u × v ⊥ = u × v \mathbf u \times \mathbf v_{\bot}=\mathbf u \times \mathbf v u×v=u×v
则可以推导:
v ′ = v / / ′ + v ⊥ ′ = v / / + c o s ( θ ) ( v − v / / ) + s i n ( θ ) ( u × v ⊥ ) = c o s ( θ ) v + ( 1 − c o s ( θ ) ) ( u ⋅ v ) u + s i n ( θ ) u × v \mathbf v^{'}=\mathbf v_{//}^{'}+\mathbf v_{\bot}^{'}\\=\mathbf v_{//}+cos(\theta)(\mathbf v- \mathbf v_{//})+sin(\theta)(\mathbf u \times \mathbf v_{\bot})\\=cos(\theta)\mathbf v+(1-cos(\theta))(\mathbf u \cdot \mathbf v)\mathbf u +sin(\theta)\mathbf u \times \mathbf v v=v//+v=v//+cos(θ)(vv//)+sin(θ)(u×v)=cos(θ)v+(1cos(θ))(uv)u+sin(θ)u×v

四元数与旋转的关系

我们将上述旋转的向量转化为四元数则有:
v = [ 0 , v ] v=[0,\mathbf v] v=[0,v]
v ⊥ = [ 0 , v ⊥ ] v_{\bot}=[0,\mathbf v_{\bot}] v=[0,v]
v / / = [ 0 , v / / ] v_{//}=[0,\mathbf v_{//}] v//=[0,v//]
u = [ 0 , u ] u=[0,\mathbf u] u=[0,u]
v ′ = [ 0 , v ′ ] v^{'}=[0,\mathbf v^{'}] v=[0,v]
v ⊥ ′ = [ 0 , v ⊥ ′ ] v_{\bot}^{'}=[0,\mathbf v_{\bot}^{'}] v=[0,v]
v / / ′ = [ 0 , v / / ′ ] v_{//}^{'}=[0,\mathbf v_{//}^{'}] v//=[0,v//]
u ′ = [ 0 , u ′ ] u^{'}=[0,\mathbf u^{'}] u=[0,u]

v / / v_{//} v//的旋转

v / / = v / / ′ v_{//}=v_{//}^{'} v//=v//

v ⊥ v_{\bot} v的旋转

对于向量来说
v ⊥ ′ = c o s ( θ ) v ⊥ + s i n ( θ ) ( u × v ⊥ ) \mathbf v_{\bot}^{'}=cos(\theta)\mathbf v_{\bot}+sin(\theta)(\mathbf u \times \mathbf v_{\bot}) v=cos(θ)v+sin(θ)(u×v)
如何将上述向量的式子换为四元数呢。
其中 v ⊥ v_{\bot} v可以直接替换 v ⊥ \mathbf v_{\bot} v
对于 u × v ⊥ \mathbf u \times \mathbf v_{\bot} u×v可以由 u v ⊥ uv_{\bot} uv替换
因为我们推导过:
v u = [ − v ⋅ u , v × u ] vu=[-\mathbf v \cdot \mathbf u,\mathbf v \times \mathbf u] vu=[vu,v×u]
因为 u 、 v ⊥ \mathbf u 、\mathbf v_{\bot} uv垂直所以有 v ⋅ u = 0 \mathbf v \cdot \mathbf u=0 vu=0
因此我们可以继续推导
v ⊥ ′ = c o s ( θ ) v ⊥ + s i n ( θ ) ( u v ⊥ ) = ( c o s ( θ ) + s i n ( θ ) u ) v ⊥ v_{\bot}^{'}=cos(\theta) v_{\bot}+sin(\theta)(uv_{\bot})\\=(cos(\theta)+sin(\theta)u)v_{\bot} v=cos(θ)v+sin(θ)(uv)=(cos(θ)+sin(θ)u)v
这里我们的 q = ( c o s ( θ ) + s i n ( θ ) u ) q=(cos(\theta)+sin(\theta)u) q=(cos(θ)+sin(θ)u)就是用来旋转的四元数,但是只是对垂直与旋转轴的向量是这样的。
q = c o s ( θ ) + s i n ( θ ) u x i + s i n ( θ ) u y j + s i n ( θ ) u z k = [ c o s ( θ ) , s i n ( θ ) u ] q=cos(\theta)+sin(\theta)u_xi+sin(\theta)u_yj+sin(\theta)u_zk=[cos(\theta),sin(\theta)\mathbf u] q=cos(θ)+sin(θ)uxi+sin(θ)uyj+sin(θ)uzk=[cos(θ),sin(θ)u]

接下来我们要旋转 v \mathbf v v这个向量
继续推导有:
v ′ = v / / ′ + v ⊥ ′ = v / / + q v ⊥ v'=v_{//}^{'}+v_{\bot}^{'}=v_{//}+qv_{\bot} v=v//+v=v//+qv
我们有:
q = [ c o s ( θ ) , s i n ( θ ) u ] q=[cos(\theta),sin(\theta)\mathbf u] q=[cos(θ),sin(θ)u]
则可以证明
q 2 = [ c o s ( 2 θ ) , s i n ( 2 θ ) u ] q^2=[cos(2\theta),sin(2\theta)\mathbf u] q2=[cos(2θ),sin(2θ)u]
此处省略证明,其几何意义就是绕一个轴旋转两次 θ \theta θ与绕一个轴旋转一次 2 θ 2\theta 2θ相同。
p 2 = q p^2=q p2=q
则有
v ′ = v / / + q v ⊥ = p p − 1 v / / + p p v ⊥ = p p ∗ v / / + p p v ⊥ v'=v_{//}+qv_{\bot}\\=pp^{-1}v_{//}+ppv_{\bot}\\=pp^{*}v_{//}+ppv_{\bot} v=v//+qv=pp1v//+ppv=ppv//+ppv
这里需要证明 p ∗ v / / = v / / p ∗ p^{*}v_{//}=v_{//}p^{*} pv//=v//p p v ⊥ = v ⊥ p ∗ pv_{\bot}=v_{\bot}p^{*} pv=vp
这里省略证明。
则有
v ′ = v / / + q v ⊥ = p v / / p ∗ + p v ⊥ p ∗ = p ( v / / + v ⊥ ) p ∗ = p v p ∗ v'=v_{//}+qv_{\bot}\\=pv_{//}p^{*}+pv_{\bot}p^{*}\\=p(v_{//}+v_{\bot})p^{*}\\=pvp^{*} v=v//+qv=pv//p+pvp=p(v//+v)p=pvp
其中的 p = [ c o s ( θ / 2 ) , s i n ( θ / 2 ) u ] p=[cos(\theta/2),sin(\theta/2)\mathbf u] p=[cos(θ/2),sin(θ/2)u]
可以让一个向量绕一个轴转 θ \theta θ角度。

Unity验证

新建一个立方体,我们通过Unity带的欧拉角转四元数的方式来进行验证,涉及欧拉角的知识请搜索其他文章。
四元数与旋转的关系,unity验证_第2张图片
我们可以看到这里的初始立方体的旋转为(0,0,0)
在这里插入图片描述
这里通过控制台显示一下绕z轴旋转30度所需要的四元数
根据上述讲解需要的四元数应该是 q = [ c o s ( 15 ° ) , s i n ( 15 ° ) ( 0 , 0 , 1 ) ] q=[cos(15°),sin(15°)(0,0,1)] q=[cos(15°),sin(15°)(0,0,1)]
因此我们的 q = [ 0.966 , 0 , 0 , 0.259 ] q=[0.966,0,0,0.259] q=[0.966,0,0,0.259]
四元数与旋转的关系,unity验证_第3张图片
其中Unity中的顺序和之前我们推导的顺序不一致,最后一位才是我们的实数,经过验证是正确的。
将这个四元数施加到我们的物体上我们可以看到:
四元数与旋转的关系,unity验证_第4张图片
旋转符合推导,验证成功。

你可能感兴趣的:(unity,游戏引擎)