说实话关于四元数这一节真的是不好懂,因为里面涉及到好多数学知识,单说推出来的公式就有很多。不怕大家笑话,对于四元数的学习我足足花了两天的时间,包括整理出这篇文章。在前面一章我写到了“变换”,这也是总结的学习笔记。我发现,写博客真是的是一个好多学习方法,加上之前一个博士师兄告诉我,要想好好的学习一本书或者一门技术,那么以此将学习笔记或者经验写成博客专栏是一种有效的方法。现在我要坚持这种方式,给自己留下学习过程中的足迹,也给大家分享一下。欢迎大家指出其中的不足,谢谢!

四元数是表示旋转的另一种数学形式,使用四元数可以节省存储空间,其之间的连接运算需要的算术运算更少,在产生平滑的三维动画时,用四元数更容易进行修改。

四元数集合,在数学上被称为哈密顿四元数环(ring of Hamiltonian quaternions),用H表示,可以理解为四维空间向量,空间中的元素q可以表示为:

q = (x,y,z,w) = w + xi +yj + zk;

也可以用实数和向量的形式进行表示,即:

q = w + v;其中w是实数部分,v是v(x,y,z)。

四元数集合是复数集合的自然扩展。四元数的乘法服从分配率,并且虚部i,j,k之间满足一下关系:

四元数式的乘法不满足交换律,因此在进行乘法运算时要注意顺序。两个四元数q1 = w1 + x1i + y1j + z1k和q2 = w2 + x2i + y2j+z2k的乘积q1q2为:

用数量-向量的形式,则q1=s1+v1和q2=s2+v2的乘积表达式为:

四元数也有共轭,比如一个四元数为 q = s+v,那么它的共轭为q’ = s-v。而qq’=||q||2 = q2.

非零的四元数的逆,记作q-1,所以。

重点来了,下面;来说一下四元数的旋转

三维空间的旋转可以理解为R3到自身的映射函数φ。由于φ代表旋转,所以它必须包含长度,角度,旋转方向等信息。

如果有则长度保持不变。

如果对任意两个点p1和p2

则从原点到两个点p1和p2的连线所形成 夹角保持不变。

如果  

则手向性也保持不变。

如果满足条件φ(s+v) = s+φ(v),则函数φ可以扩展为H到自身的映射,这样就将(4)式改写为

如果将p1和p2看做是数量部分为零的四元数,根据,就可以将(5),(6)式合并成一个等式,在该等式中可以保持角度和手向性不变,等式如下:

满足(7)是的函数φ称为是同态的。

该类函数φ可以用公式(8)表示:

其中q为一个非零的四元数,且满足,因此可以表示旋转的集合。证明过程如下:

首先证明φq的长度保持不变,因为

其次,φq是同态的,因为

四元数与旋转的关系

假设向量P绕一任意旋转轴的单位向量A(xa,ya,za)旋转θ角,如下图所示:

我们可以将P看作为没有实数部分的四元数xi+yj+zk,设q = s+v,则q-1 = s-v。

那么φq(P) = qPq-1就等于(s+v)P(s-v)。即计算过程如下所示:

由于则(11)等于:

设v = tA,则上式可以改写为:

将(13)与绕任意轴旋转的公式P’ = PcosΘ + (A x P)sinΘ + A(A.P)(1-cosΘ),可以推出

则可以得到:

带入q = s+v得到:

推广一下来讲:

对于四元数q的任意数量乘积表示的都是相同的旋转,因为:

两个四元数q1和q2的乘积也可以表示一个旋转。乘积q1q2表示现已q2,后以q1进行旋转。因为:

可以将多个四元数结合起来,形成一系列旋转的一个四元数。将两个四元数相乘需要做16次乘法和加法运算,而两个3×3矩阵相乘就需要做27次类似的操作。因此对物体进行多次旋转时,应用四元数可以获得较高的计算效率。

如何将一个四元数变换成等价的3×3旋转矩阵的形式呢?

首先将改写成矩阵的形式

将四元数q改写成四维向量q = (w,x,y,z),那么w = s,x = tAx,y = tAy,z = tAz。因为A是单位向量,所以x2+y2+z2 = t2A2 = t2

则上式等价于:

因为q是单位四元数,满足w2+ x2+y2+z2 =1,所以可以得到:

则四元数的旋转矩阵Rq的公式如下:

球型线性插值

因为四元数是用向量表示的,所以很适合做插值运算。在产生一个物体动画过程中,在产生位于两个预先计算的关键帧之间的中间过渡定位时,插值非常有用。

最简单的差值类型是线性插值。对于两个四元数q1和q2,线性插值后得到的四元数q(t)为:

当t在[0,1]范围内取值时,函数q(t)在连接q1和q2的线段上平滑变化。如下图所示:

q(t)并不保持q1和q2的单位长度,但可以使用下面的函数在任意点位置对q(t)进行重新规格化:

这样就可以用该函数描绘位于q1和q2间的过渡弧线。在上图中,它将弧描绘成四维单位超球面的二维截面。

尽管线性插值很有效,但是q(t)并没有以恒定的速率描绘q1和q2间的过渡弧线,这就是线性插值的弊端。下图关于cos-1(q(t).q1)的图形表明,q1和q2之间的角度变化速率在端点t = 0 和 t = 1时相对较慢,而在t = 1/2时最快。

我们希望找到一个函数q(t),用它对四元数q1和q2进行插值时,会保持其单位长度不变并且以恒定的速率扫过位于q1和q2之间的夹角。如果q1和q2的夹角为θ,那么这个函数将会产生一个四元数,该四元数在q(t)和q1的形成一个夹角θt,这里t在0到1之间取值。

如下图(a),(b):四元数q(t)位于连接q1和q2的弧上,与q1的形成一个夹角θt,与q2构成夹角θ(1-t)。可以将q(t)写成:

其中a(t)和b(t)分别表示q(t)在q1和q2方向上的分量的长度。

我们可以构造相似三角形来确定长度a(t),q1到以原点和q2为端点的线段的垂直距离为||q1||sinθ,而q(t)到该线段的垂直距离为||q1||sinθ(1-t)。根据相似三角形,可以得到以下关系式:

由于||q1|| = 1,||q(t)|| = 1,可以将上式化简为:

同理可以得到:

这时可以将球型线性插值函数q(t)定义为:

θ角为

因为四元数q和-q表示相同的旋转,所以在旋转四元数q1和q2的正负号时一般要满足q1.q2>=0,这样也可以保证以最短路径的方式进行插值。

3D游戏与计算机图形学中的数学方法-四元数的更多相关文章

  1. 3D游戏与计算机图形学中的数学方法-变换

    1变换 在3D游戏的整个开发过程中,通常需要以某种方式对一系列的向量进行变换.通常用到的变换包括平移,缩放和旋转. 1.1通用变换 通常可将n x n可逆矩阵M看成是一个从坐标系到另一个坐标系的变换矩 ...

  2. 3D游戏与计算机图形学中的数学方法-点线面

    <易传·系辞上传>:”易有太极,是生两仪,两仪生四象,四象生八卦.” 借用一下古代先人们的智慧引一下本文的主题-三维图形中的点线面,在三维几何中也有一句话可以和上面的话相对应:由点成线,由 ...

  3. 3D游戏与计算机图形学中的数学方法-视截体

    视截体用来表示一个空间的范围,位于这个空间范围内的三维场景的任何物体都可以被看到. 视截体由六个平面围成,其中的四个平面与场景的边界相对应,分别被称为左,右,底,顶视截面.另外两个平面称为近视截面和远 ...

  4. Mathematics for Computer Graphics数学在计算机图形学中的应用 [转]

    最近严重感觉到数学知识的不足! http://bbs.gameres.com/showthread.asp?threadid=10509 [译]Mathematics for Computer Gra ...

  5. 3D游戏开发之UE4中的集合:TSet容器

    好久没有更新了,最近一直在老家过年,网络不通的,今天才有时间更新一集. 一.TSet<T>是什么 UE4中,除了TArray动态数组外,还提供了各种各样的模板容器.这一节,我们就介绍集合容 ...

  6. 计算机图形学中使用Turbo C++画图步骤

    一.下载安装Turbo C++ 我安装的是Turbo C++ 3.2.2.0下载链接 二.画图 1.打开Turbo C++,点击右下角start turbo C++ 2.点击file ->new ...

  7. JS中的数学方法

    1 . Math.ceil()      向上取整 2.  Math.floor()     向下取整 3. Math.round()    四舍五入取整 4.  Math.random()   生成 ...

  8. Java中的数学方法

    直接用代码 public class TestNumber { public static void main(String[] args) { float f1 = 5.4f; float f2 = ...

  9. 计算机图形学学习方法和相关书籍,做游戏,GIS,虚拟现实,三维引擎的都能够看看.

    本书參照<<图形学扫盲>> 整理的,原文内容引子: http://www.cppblog.com/lai3d/archive/2008/12/30/70796.html 前言: ...

随机推荐

  1. STORM在线业务实践-集群空闲CPU飙高问题排查(转)

    最近将公司的在线业务迁移到Storm集群上,上线后遇到低峰期CPU耗费严重的情况.在解决问题的过程中深入了解了storm的内部实现原理,并且解决了一个storm0.9-0.10版本一直存在的严重bug ...

  2. Visual Studio 中突出显示的引用

    有时候代码中处理的变量多了,看起代码来就比较的费劲,有时想看一个变量都在哪里用到了,还要一个一个的去仔细分辨. 一.VS2012本身就提供了选中提示功能 但是本身带的这个选中提示功能颜色比较浅,不过这 ...

  3. [sh]shell案例

    调用同目录下的ip.txt内容: 路径 [root@lanny ~]# pwd /root txt文件 [root@lanny ~]# cat ip.txt 10.1.1.1 10.1.1.2 10. ...

  4. ThinkPad 预装win8换win7(软激活)

    今天晚上有人叫我给他装系统,没错!这就是计算机专业的拿手技能(维修学院重装系统专业Win7系统班^-^). 一拿手上,是lenovo的ThinkPad E430型号,预装的系统是win8,由于win8 ...

  5. Qt creator 编译错误:无法解析的外部符号(命令)

    问题来自于:仅仅是在creator 中加入了一个新的DIalog类,并在main(),中实例化并show.就出现例如以下的错误: main.obj:-1: error: LNK2019: 无法解析的外 ...

  6. 告诉你38个MySQL数据库的小技巧

    无论是运维.开发.测试,还是架构师,数据库技术是一个必备加薪神器,那么,一直说学习数据库.学MySQL,到底是要学习它的哪些东西呢? 1.如何快速掌握MySQL? 培养兴趣 兴趣是最好的老师,不论学习 ...

  7. maven(3)------maven构建web项目详细步骤

    eclipse集成工具,轻松通过maven构建web项目步骤如下: 一, 右键,new -->project, 进入下一页面 二,选择"Maven Project", 点击下 ...

  8. Jmeter常见用法

    Jmeter (底层语言是Java)  单进程 Loadrunner (底层语言是C) 多进程 性能更好,更稳定 Tomcat  线程模式(与Java有关的都是单进程) lr的支持最大并发  跟lic ...

  9. ubantu 文件解压缩

    对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rar. ...

  10. cocos2d-xV3.0rc 环境搭建

    一.下载 由于www.cocos2d-x.org很难打开,不知道是不是电信的问题,所以只好在cocoschina论坛里王哲大牛的帖子里找到了一个下载链接:http://126.am/GyU7l0 帖子 ...