方位

                       方位

 表示方位的方法有三种,分别为矩阵,欧拉角,四元数表示法。

描述方位必须要有一个参照方位,如果没有参照方位,矩阵,欧拉角和四元数表示法只可以代表一种角位移

 

方位其实就是在原方位上的旋转,那怎么样确定旋转的正负方向呢?

在左手坐标系中,从旋转轴的正方向望向原点,顺时针为正方向,逆时针为负方向;在右手坐标系中则相反,即逆时针为正方向,顺时针为负方向。

 

本文使用左手坐标系。

 一。矩阵

表示角位移的矩阵其实就是旋转矩阵,此矩阵为绕某个旋转轴旋转。

图形API(如OPENGLDX都是用矩阵来表示方位)。

用矩阵表示角位移需要存放9个数(如果用4X4矩阵则是16个数),占用内存大。

 

矩阵表示法的优缺点详细说明见(p142)

二.欧拉角

欧拉角用三个数表示角位移,分别为heading, pitch, bank,这三个数都是角度值,heading表示绕物体坐标系的Y轴旋转的角度,picthX轴,bankZ轴。旋转顺序其实是无关紧要的,我们一般就按heading->pitch->bank顺序操作,本文所提到的欧拉角都是使用这种表示方法和旋转顺序。

 

由于角度描述和旋转顺序的多样性导致了表示同一方位的欧拉角表述的不唯一性,为了排除这种不唯一性,我们将headingbank限制在+180-180度之间,pitch限制在+90-90度之间。

 

欧拉角有一个有趣的问题,当pitch+90-90度时,将导致heading,bank的旋转轴相同(注意,heading,pitch,bank表示绕物体坐标系的轴,而不是原坐标系),称做万向锁,也叫做万向节。这将导致另外一种别名问题,由于heading,bank的旋转轴相同,它们可以相互抵消或相加,而最终结果是可以只用headingbank一个旋转就可以了。为此,我们规定,当picth+90-90度时,我们用heading完成竖直轴的旋转,bank定为0。万向节还导致欧拉角描述方法丢失一个自由度,这就是著名的万向节死锁问题。

 

我们设A(φ,θ,ψ) heading=φ, pitch=θ, bank=ψ的方位,Pφ)为绕Y轴旋转φ个角度, Nφ,θ)为绕X轴旋转θ个角度,Rφ,θ,ψ)为绕Z轴旋转ψ个角度。有如图的计算方式:

 

A(φ,θ,ψ) = R(φ,θ,ψ)N(φ,θ)P(φ)

 

解释为A的转换等于先绕Y轴旋转φ个角度,再绕X轴旋转θ个角度,最后绕Z轴旋转ψ个角度(从右到左的运算顺序)

 

有公式为:

 

A(δφ + φ,θ,ψ) = P(δφ)A(φ,θ,ψ)

A(φ,δθ + θ,ψ) = N(φ,δθ)A(φ,θ,ψ)

A(φ,θ,δψ + ψ) = R(φ,θ,δψ)A(φ,θ,ψ)

 

解释为物体在现有角位移(设为角位移A)上进行*转换等于在A的相应转换上加上*转换,如:物体在现有角位移A上再绕物体坐标系的Y轴旋转*个角度等于在AY轴转换中加上*个角度。在这里有个例外,当N(绕X轴的转换)为正或负90度时,我们丢失了一个旋转自由度,故上面三个等式均不成立,这就是万向节死锁的原因:当N为正或负90度时,我们不能再用原有方位+PNR转换来得出现有方位(即不能用连续的欧拉角来表示空间中连续的角位移)。

 

三.四元数

一个四元数包含一个标量和一个3D向量:

             [w, v]

              [w, ( x, y, z)]

现在我们来复习一下复数,复数包含一个实部和虚部。复数(a,b)定义为复数a+bia称为实数,b为虚数,满足i的平方等于-1。共轭复数使虚部变负。

 

四元数扩展了复数系统,它使用三个虚部i,j,k,它们的关系如下:

 

              i^2 = j^2 = k^2 = -1;

              ij = k;  ji = -k;

              jk = I;  kj = -I;

              ki = j;  ik = -j;

 

一个四元数[w, (x, y, z)] 定义为复数w+xi+yj+zk

 

四元数P被解释为角位移的轴——角对方式,旋转轴n和旋转角度θ并不直接存储在四元数中,但的确是在四元数中。

              P = [cos(θ/2), sin(θ/2)n]

               = [ cos(θ/2), (sin(θ/2) x, sin(θ/2)ny, sin(θ/2)nz) ]

我们试着将旋转角度θ+360度的N数倍,旋转轴不变,不会改变P所代表的角位移,但却使P变成了-P。故任意角位移都有两种四元数的表示方法,它们互相为负。

       注:-p = [-cos(θ/2), -sin(θ/2)n]

                = [-cos(θ/2), (-sin(θ/2)nx, -sin(θ/2)ny, -sin(θ/2)nz) ]

 

[1, 0], [-1, 0]表示单位角位移, 旋转角度为0度或者360度的整数倍时没有角位移,旋转轴是无交紧要的。

 

四元数的叉乘的效果和矩阵乘法差不多。

                            [w1 v1][w2 v2] = [w1w2-v1*v2  w1v2+w2v1+v2 X v1]

 

                            (w1  x1i  y1j  z1k)(w2  x2i  y2j  z2k)

                            =    w1w2 + w1x2i + w1y2j +w1z2k +

                                  x1w2i + x1x2i2 + x1y2ij + x1z2ik +

                                  y1w2j + y1x2ji + y1y2j2 + y1z2jk +

                                  z1w2k + z1x2ki + z1y2kj + z1z2k2

                            =    w1w2 – x1x2 – y1y2 – z1z2 +

                                   (w1x2 + x1w2 + y1z2 – z1y2)i +

                                   (w1y2 + x1z2 + y1w2 – z1x2)j +

                                   (w1z2 + x1y2 + z1w2 – y1x2)k

                            =   [ w1w2 + x1x2 + y1y2 - z1z2  

( w1x2 + x1w2 + y1z2 - z1y2

                                    w1y2 + x1z2 + y1w2 - z1x2

                                    w1z2 + x1y2 +z1w2 – y1x2) ]

四元数叉乘满足结合律不满足交换律。

我们用[0, (x, y, z)] 代表三维空间中的q点,[cos(θ/2), (sin(θ/2)nx, sin(θ/2)ny, sin(θ/2)nz) ] 代表四元素p, 进行以下运算后

q1 = pqp-1

你会发现得到的结果是q点绕n轴旋转了θ度。我们试着进行多次旋转,先进行a旋转再进行b旋转得到

q1  = b(aqa-1)b-1, 由于四元数叉乘满足结合率不满足交换率,

 = (ba)q(a-1b-1), 由于a-1b-1 = (ba)-1

 =(ba) q (ba)-1

              先执行a旋转再b旋转等于ba叉乘所代表的单一旋转。

 

通过四元素的叉乘我们可以将多次旋转连接起来,不过最终得到的结果连接顺序是由后到前的。为了解决这个问题,我们可以将四元素叉乘代表旋转的标准q1 = pqp-1改为 q1 = p-1qp ,得出q1  = b-1(a-1qa)b = (ab)-1q(ab)。本文将采取这种非标准的计算方法。在本文中非特别说明,没有符号的ab代表的ab 的叉乘。

 

||P||表示四元数的模。公式:(P145), 表示角位移的四元数的模为1

四元数叉乘的模等于模的乘积:

                     ||q X p|| = ||q|| * ||p||

四元数逆的叉乘等于相反顺序的叉乘的逆:

                     q-1 X p-1 = (p X q)-1

四元数共轭和复数一样使虚部变负,记为:

q* = [w, -v]

四元数的逆等于共轭除以模,记为:

q-1 = q*/||q||

 

四元数的差

四元数的差可以代表从一个方位到另一个方位的角位移。已知角位移a和角位移b,求它们之间的角位移t,由于方位x先旋转a再旋转t等于方位x旋转b  à at = b。我们要求出t,如果a是标量,两边同时除以a就可得出t。但我们不可以直接除以四元数,不过我们可以乘以四元数的逆以得到相同的效果。

                     a-1at = a-1b

                            [1,0] t = a-1b

                                   t= a-1b

 

四元数点乘

在本文中,点乘用*表示,叉乘用X表示

q1*q2 = [w1 v1] * [w2 v2]

              = w1*w2 + v1*v2

              = [w1 (x1 y1 z1) ] * [w2 (x2 y2 z2) ]

              = w1*w2 + x1*x2 + y1*y2 + z1*z2

像向量的点乘一样,四元数的点乘也是一个标量,且点乘结果的正负并不重要,因为

q1*q2 = - (q1* -q2)

q2-q2代表相同的角位移。

对于单位四元数a,b,有 -1 <= a*b <= 1

四元数点乘的几何意义是,点乘绝对值越大,代表这两个角位移越“相似,四元数的点乘也代表两个四元数夹角的cos值。推导过程如下:

设两个角位移ab,要求它们的夹角的cos值。四元数(角位移)自身只代表一种转换,它们的夹角是指某个方位x经过角位移a后的方位要和方位x经过角位移b后的方位相同必须经过的角位移t的旋转角度θ。四元数的差可以求出这个t = a-1b,我们要求出角度θ就不难了,因为t的实部代表cos(θ/2)。我们先求出t

                                   t= a-1b

                                    = a* xb

                                    = [wa -va][wb vb]

                                    = [wawb–(-va)*vb   wavb-wbva+vb x (-va)]

我们已经求出t的实部为wawb+va*vb,这和点乘的定义是一样的,所以我们说“四元数的点乘代表两个四元数夹角的cos值”。

四元数指数,对数,标量乘运算

对数:

              log q = log([cosЄ sinЄn])

                      = [ 0, Єn ]

指数:

              exp( q )

              exp([ 0, Єn ])  = [ cosЄ sinЄn ]

 

              exp( log(q) ) = q

标量乘:

              k[w, v] = [kw, kv]

四元数幂:

四元数能作为底数,记作 qt (不要和指数运算混淆,指数运算只接受一个四元数作为参数,而四元数求幂有两个参数 ---- 四元数和指数)。四元数求幂的意义类似于实数求幂。回忆一下,a0 = 1 a1 = aa为非零标量。当t0变到1时,at1a。四元数求幂有类似的结论:当t0变到1 qt[1, 0 ] q 。从四元数的叉乘可以证明这一结果。

这对四元数求幂非常有用,因为它可以从角位移中抽取"一部分"。例如,四元数 q 代表一个角位移,现在想要得到代表1/3这个角位移的四元数,可以这样计算: q1/3

指数超出[0, 1]范围外的几何行为和预期的一样(但有一个重要的注意事项)。例如, q2代表的角位移是 q 的两倍。假设 q 代表绕x轴顺时针旋转30度,那么 q2代表绕x轴顺时针旋转60度, q-1/3代表绕x轴逆时针旋转10度。

上面提到的注意事项是,四元数表达角位移时使用最短圆弧,不能"绕圈"。继续上面的例子, q4不是预期的绕x轴顺时针旋转240度,而是逆时针80度。显然,向一个方向旋转240度等价于向相反的方向旋转80度,都能得到正确的"最终结果"。但是,在此基础上的进一步运算,产生的就可能不是预期的结果了。例如,(q4)1/2不是 q 2,尽管我们感觉应该是这样。一般来说,凡是涉及到指数运算的代数公式,如(as)t = a(st),对四元数都不适用。

现在,我们已经理解四元数求幂可以为我们做什么了。让我们看看它的数学定义,四元数求幂定义在前一节讨论的"有用"运算上,定义如公式10.18

注意,对于标量求幂,也有类似结论:

四元数常被用于线性插值,因为四元数的线性插值是最平滑的。最著名的就是slerp插值。具体算法见(p154).

你可能感兴趣的:(算法,zk,qt,vb,360,图形)