彻底搞懂四元数
来源:互联网 发布:淘宝店铺ip地址怎么查 编辑:程序博客网 时间:2024/05/18 18:45
提要
旋转的表达方式有很多种,有欧拉角,旋转矩阵,轴角,四元素等等,今天要学习的就是游戏开发中最常用的四元素。
从欧拉角和轴向角到四元数
在讲四元素之前,我们先来看下简单的欧拉角和轴向角。
欧拉角使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用roll,pitch,yaw来表示这些分量的旋转值。需要注意的是,这里的旋转是针对世界坐标系说的,这意味着第一次的旋转不会影响第二、三次的转轴。
欧拉角容易出现的问题是 1)不易在任意方向的旋转轴插值; 2)万向节死锁;3)旋转的次序无法确定。
轴角用一个以单位矢量定义的旋转角,再加上一个标量定义的旋转角来表示旋转。通常的表示[x,y,z,theta],前面三个表示轴,最后一个表示角度。表示非常直观,也很紧凑。
轴角最大的一个局限就是不能进行简单的插值,此外,轴角形式的旋转不能直接施于点或矢量,必转换为矩阵或者四元素。
四元素感觉上就是轴角的进化,也是使用一个3维向量表示转轴和一个角度分量表示绕此转轴的旋转角度,即(x,y,z,w), 其中
其中(ax,ay,az)表示轴的矢量,theta表示绕此轴的旋转角度。四元数中的每个数都是经过“处理”的轴和角,轴角描述的“四元组”并不是一个空间下的东西,首先(ax,ay,az)是一个3维坐标下的矢量,而theta则是级坐标下的角度,简单的将他们组合到一起并不能保证他们插值结果的稳定性,因为他们无法归一化,所以不能保证最终插值后得到的矢量长度(经过旋转变换后两点之间的距离)相等,而四元数在是在一个统一的4维空间中,方便归一化来插值,又能方便的得到轴、角这样用于3D图像的信息数据,所以用四元数再合适不过了。相比于矩阵,四元素也只要存储4个浮点数,优势很明显。
四元素的相关计算
乘法
给定两个四元数p和q,分别代表旋转P和Q,则乘积pq表示两个旋转的合成(即旋转了Q之后再旋转P),并不是用加法。四元数的乘法定义如下,利用简单的分配律就是了:
q1 * q2 =
(w1*w2 - x1*x2 - y1*y2 - z1*z2) +
(w1*x2 + x1*w2 + y1*z2 - z1*y2) i +
(w1*y2 - x1*z2 + y1*w2 + z1*x2) j +
(w1*z2 + x1*y2 - y1*x2 + z1*w2) k
由于q = w + x i + y j + z k中可以分为纯量w与向量x i + y j + z k,所以为了方便表示,将q表示为(S, V),其中S表示纯量w,V表示向量x i + y j + z k,所以四元数乘法又可以表示为:
q1 * q2 = (S1 + V1)*(S2 + V2) = S1*S2 - V1.V2 + V1XV2 + S1*V2 + S2*V1
求模
N(q) = |q| = x2 + y2 + z2 + w2
单位化
Normalize( q ) = q/ | q | = q / (x2 + y2 + z2 + w2)
求共轭
q*=(-x, -y, -z, w)
求逆
对于向量逆的定义, q-1 =q*/|q|2
对于单位四元素,分母为1,q-1 = q* =(-x, -y, -z, w)
用四元数旋转矢量
给定一个矢量v,再给定一个旋转的单位四元素q,让v旋转q。
首先将v改写成四元素的形式v = (x, y ,z, 0), 接下来要旋转v须用q前乘以矢量v,再后乘以q-1。
v‘ = qvq-1
当然用后面乘以共轭的q也是一样的,因为都是单位四元素。
对于旋转多个四元数,比如 R=R1R2R3. 则
注意顺序。
四元数的线性插值和球面线性插值
四元素的可以方便地进行插值是四元素最大的优势。线性插值最为简单,效率也很高。给定两个旋转四元素qa和qb代表旋转A和旋转B,找到旋转A到旋转B之间的 t 的旋转:
注意这里的 t 实际上是是沿弦上走了t,而不是在球面上走t,这样就会导致当 t 以恒定速度改变时,角度的变化并非恒定.
为了解决这个问题,就出现了球面线性插值。给定四元素q和q,
其中theta是两个四元素的夹角,
四元数的各种转换
四元素转欧拉角
欧拉角转四元素
四元素转旋转矩阵
参考
游戏引擎架构 第四章
Computer Graphics: 四元數與旋轉 - http://openhome.cc/Gossip/ComputerGraphics/QuaternionsRotate.htm
Quaternion(四元数)和旋转以及Yaw, pitch, roll 的含义 - - http://www.wy182000.com/2012/07/17/quaternion%E5%9B%9B%E5%85%83%E6%95%B0%E5%92%8C%E6%97%8B%E8%BD%AC%E4%BB%A5%E5%8F%8Ayaw-pitch-roll-%E7%9A%84%E5%90%AB%E4%B9%89/
- 彻底搞懂四元数
- 彻底搞懂四元数
- 彻底搞懂四元数
- 彻底搬家!
- 彻底鄙视
- 要彻底
- 彻底搞懂红黑树
- 彻底搞懂红黑树
- Oracle:彻底结束会话 ,彻底解锁
- 彻底封杀Ping漏洞
- 彻底删除oracle8.17
- 如何彻底删除Oracle
- 彻底删除“我的文档”
- 彻底明白javaIO (转)
- 彻底放弃inno setup
- 彻底破解Dotfuscator
- 彻底破解 Dotfuscator
- 如何彻底删除Oracle
- Android studio常量表达式的错误
- Android:ScrollView起始位置不是最顶部
- CI持续集成系统 jira + jenkins + gerrit
- codeforces 754D Fedor and coupons【优先队列+贪心*好题】
- Android AOP之路四 编译时注解详细讲解
- 彻底搞懂四元数
- Leetcode
- centos上部署kubernetes集群
- 堆排序原理及算法实现(Java)
- JQuery中$.ajax()方法参数详解
- 关于this kernel requires an x86-64 cpu but only detected an i686 cpu unable to boot please use a kern
- savon调用WebService服务
- acm之路
- 图的深搜