为什么使用四元数
为了回答这个问题,先来看看一般关于旋转(面向)的描述方法-欧拉描述法。它使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用roll,pitch,yaw来表示这些分量的旋转值。需要注意的是,这里的旋转是针对世界坐标系说的,这意味着第一次的旋转不会影响第二、三次的转轴,简单的说,三角度系统无法表现任意轴的旋转,只要一开始旋转,物体本身就失去了任意轴的自主性,这也就导致了万向轴锁(Gimbal Lock)的问题。
还有一种是轴角的描述方法(即我一直以为的四元数的表示法),这种方法比欧拉描述要好,它避免了Gimbal Lock,它使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,angle),一般表示为(x,y,z,w)或者(v,w)。但这种描述法却不适合插值。
那到底什么是Gimbal Lock呢?正如前面所说,因为欧拉描述中针对x,y,z的旋转描述是世界坐标系下的值,所以当任意一轴旋转90°的时候会导致该轴同其他轴重合,此时旋转被重合的轴可能没有任何效果,这就是Gimbal Lock,这里有个例子演示了Gimbal Lock,点击这里下载。运行这个例子,使用左右箭头改变yaw为90°,此时不管是使用上下箭头还是Insert、Page Up键都无法改变Pitch,而都是改变了模型的roll。
那么轴、角的描述方法又有什么问题呢?虽然轴、角的描述解决了Gimbal Lock,但这样的描述方法会导致差值不平滑,差值结果可能跳跃,欧拉描述同样有这样的问题。
什么是四元数
四元数一般定义如下:
q=w+xi+yj+zk
其中w是实数,x,y,z是虚数,其中:
i*i=-1
j*j=-1
k*k=-1
也可以表示为:
q=[w,v]
其中v=(x,y,z)是矢量,w是标量,虽然v是矢量,但不能简单的理解为3D空间的矢量,它是4维空间中的的矢量,也是非常不容易想像的。
四元数也是可以归一化的,并且只有单位化的四元数才用来描述旋转(面向),四元数的单位化与Vector类似,
首先||q|| = Norm(q)=sqrt(w2 + x2 + y2 + z2)
因为w2 + x2 + y2 + z2=1
所以Normlize(q)=q/Norm(q)=q / sqrt(w2 + x2 + y2 + z2)
说了这么多,那么四元数与旋转到底有什么关系?我以前一直认为轴、角的描述就是四元数,如果是那样其与旋转的关系也不言而喻,但并不是这么简单,轴、角描述到四元数的转化:
w = cos(theta/2)
x = ax * sin(theta/2)
y = ay * sin(theta/2)
z = az * sin(theta/2)
其中(ax,ay,az)表示轴的矢量,theta表示绕此轴的旋转角度,为什么是这样?和轴、角描述到底有什么不同?这是因为轴角描述的“四元组”并不是一个空间下的东西,首先(ax,ay,az)是一个3维坐标下的矢量,而theta则是级坐标下的角度,简单的将他们组合到一起并不能保证他们插值结果的稳定性,因为他们无法归一化,所以不能保证最终插值后得到的矢量长度(经过旋转变换后两点之间的距离)相等,而四元数在是在一个统一的4维空间中,方便归一化来插值,又能方便的得到轴、角这样用于3D图像的信息数据,所以用四元数再合适不过了。
关于四元数的运算法则和推导这里有篇详细的文章介绍,重要的是一点,类似与Matrix的四元数的乘法是不可交换的,四元数的乘法的意义也类似于Matrix的乘法-可以将两个旋转合并,例如:
Q=Q1*Q2
表示Q的是先做Q2的旋转,再做Q1的旋转的结果,而多个四元数的旋转也是可以合并的,根据四元数乘法的定义,可以算出两个四元数做一次乘法需要16次乘法和加法,而3x3的矩阵则需要27运算,所以当有多次旋转操作时,使用四元数可以获得更高的计算效率。
为什么四元数可以避免Gimbal Lock
在欧拉描述中,之所以会产生Gimbal Lock是因为使用的三角度系统是依次、顺序变换的,如果在OGL中,代码可能这样:
glRotatef( angleX, 1, 0, 0)
glRotatef( angleY, 0, 1, 0)
glRotatef( angleZ, 0, 0, 1)
注意:以上代码是顺序执行,而使用的又是统一的世界坐标,这样当首先旋转了Y轴后,Z轴将不再是原来的Z轴,而可能变成X轴,这样针对Z的变化可能失效。
而四元数描述的旋转代码可能是这样:
TempQ = From Eula(x,y,z)
FinalQ =CameraQ * NewQ
theta, ax, ay, az = From (FinalQ)
glRotatef(theta, ax, ay, az);
其中(ax,ay,az)描述一条任意轴,theta描述了绕此任意轴旋转的角度,而所有的参数都来自于所有描述旋转的四元数做乘法之后得到的值,可以看出这样一次性的旋转不会带来问题。这里有个例子演示了使用四元数不会产生Gimbal Lock的问题。
关于插值
使用四元数的原因就是在于它非常适合插值,这是因为他是一个可以规格化的4维向量,最简单的插值算法就是线性插值,公式如:
q(t)=(1-t)q1+t q2
但这个结果是需要规格化的,否则q(t)的单位长度会发生变化,所以
q(t)=(1-t)q1+t q2 / || (1-t)q1+t q2 ||
如图:
尽管线性插值很有效,但不能以恒定的速率描述q1到q2之间的曲线,这也是其弊端,我们需要找到一种插值方法使得q1->q(t)之间的夹角θ是线性的,即θ(t)=(1-t)θ1+t*θ2,这样我们得到了球形线性插值函数q(t),如下:
q(t)=q1 * sinθ(1-t)/sinθ + q2 * sinθt/sineθ
如果使用D3D,可以直接使用D3DXQuaternionSlerp函数就可以完成这个插值过程。
- 大小: 9.9 KB
分享到:
相关推荐
四元数与旋转矩阵详细推导过程 在了解四元数(Quaternion)与三维旋转之间的关系之前,我们需要了解复数(Complex ...在下一章中,我们将会讨论四元数与旋转矩阵之间的关系,并探讨如何使用四元数来表示三维旋转。
讲述四元数和旋转矩阵之间相互转化的学术论文:首先介绍了四元数和旋转矩阵在实现向量旋转中的应用,在此基础上,根据游戏开发的实际需要,讨论了四元数和旋转矩阵之间的相互转化关系。最后,重点分析了由旋转矩阵到...
通过学习笔记的形式,Charles007对四元数及其与旋转变换的关系进行了总结,涵盖了从基本概念到运算规则,再到实际应用的多方面内容。通过这样系统的梳理,学习者可以更加深入地理解四元数在图形图像处理中的作用,...
一个单位四元数q=(cos(θ/2), sin(θ/2)u)代表绕向量u旋转θ的角度,其中u是归一化的旋转轴向量,θ是旋转角度。这种表示方式避免了万向节死锁,并且旋转可以通过四元数的乘法进行组合。 四元数的旋转运算可以应用...
总的来说,"三维旋转-四元数-万向锁介绍.zip"压缩包提供的资源旨在帮助读者深入理解三维旋转中的万向锁问题,以及如何利用四元数来克服这一难题。通过学习四元数的数学原理,以及如何在实际项目中使用它们,可以显著...
在详细解释四元数之前,本文首先介绍了复数及其与二维旋转的关系,因为复数是理解四元数性质的基础。 复数由实部和虚部组成,通常表示为a+bi的形式,其中a是实部,b是虚部,而i是虚数单位,满足i²=-1。复数的加...
四元数是数学中的一个概念,是一种抽象的代数结构,也是三维空间中旋转的另一种表示方法,它避免了欧拉角可能出现的万向锁问题。四元数包括一个实部和三个虚部,通常表示为q = (w, x, y, z),其中w是实部,x、y、z是...
四元数是一种扩展复数的数学概念,它在三维空间中的应用尤其广泛,比如在计算机图形学、机器人技术...理解四元数的结构和运算法则需要一定的抽象思维能力,但一旦掌握,就可以在各种场合下高效地使用四元数来处理问题。
代码!!!!重要!!!! 学习中关于机器人领域中四元数、欧拉角、旋转矩阵、旋转向量的相互转换关系总结,整理加深记忆。 每一个都有相互转换关系,并注释
### 欧拉角、四元数与旋转向量 #### 概述 在三维空间中,物体的旋转可以通过多种方式进行表示,其中最为常见的三种方式是:欧拉角(Euler Angles)、四元数(Quaternions)以及旋转向量(Rotation Vectors)。这三...
这篇文章的主要目的就是简单讨论一下四元数(Quaternion)与三维旋转之间的关系.简介:虽然网上四元数相关的资料有很多了,但是我好像一直没找到令我满意的,所以就想自己来写一篇.目前很多资料都使用了比较抽象的方式来...
文章Unity3D学习笔记05:四元数控制人物旋转的脚本代码
旋转矩阵R通常是3x3的形式,具有inv(R)=trans(R)的性质,即R的逆就是...本案记四元数Q[0]-Q[3],其中Q[0]与旋转的幅度有关,其余三数与旋转轴有关。本例子给出了四元数与欧拉角以及与旋转矩阵互换的代码。希望对各位有用。
旋转物体运动学是基于“标量第一单位四元数”的。 项目“SpinSpin_Quaternion_v1”与此项目类似。 项目“SpinSpin_RotationVector”与此项目类似,但基于“RotationVector”。 标量第一单位四元数定义: 标量第...
- 四元数旋转:在三维空间中,四元数可以用来表示旋转,其优点在于没有 gimbal lock(万向锁)问题。通过四元数乘法,可以实现对向量的旋转操作。 - 旋转矩阵与四元数转换:四元数工具箱提供函数将旋转矩阵转换为...
对于两个旋转四元数\( q_1 \)和\( q_2 \),它们的乘积\( q_1q_2 \)表示先执行\( q_1 \)再执行\( q_2 \)的旋转,这在处理连续旋转时非常方便。 四元数与旋转矩阵之间的转换也至关重要。给定一个单位四元数\( q = (w,...
为了更好地理解四元数与三维旋转之间的关系,先让我们从复数开始说起,因为四元数的很多性质和它们与二维旋转的关系,与复数有诸多相似之处。 复数是由实数和虚数构成的,其中虚数单位i定义为√(-1),所以任何复数z...
包含四元数的基本运算,矩阵的基本运算,四元数、欧拉角、旋转矩阵之间的相互转换
四元数的优势在于它的运算不仅避免了奇异性问题,还能在保证旋转准确的前提下,进行快速的计算,这在实时图形渲染中尤为重要。因此,在诸如OpenGL和Direct3D这样的图形学引擎和库中,四元数被广泛使用。然而,四元数...
将四元数转换为欧拉角。 请注意,不同旋转顺序的欧拉角是不同的。 此代码中使用的欧拉角旋转顺序是 z-y'-x''(偏航、俯仰、滚转)。 旋转是固有的,即沿新轴旋转。 这个定义被航空航天工程师广泛使用。 参考: ...