3D数学读书笔记——四元数
本系列文章由birdlove1987编写,转载请注明出处。
文章链接: http://blog.csdn.net/zhurui_idea/article/details/25400659
什么是四元数
复数是由实数加上虚数单位 i 组成,当中
i² = -1
相似地,四元数都是由实数加上三个元素 i、j、k 组成,并且它们有例如以下的关系:
i² = j² = k² = ijk = -1
每一个四元数都是 1、i、j 和 k 的线性组合,即是四元数一般可表示为a + bi + cj + dk。
关于四元数的历史
四元数是由哈密顿在1843年爱尔兰发现的。当时他正研究扩展复数到更高的维次(复数可视为平面上的点)。他不能做到三维空间的样例,但四维则造出四元数。依据哈密顿记述,他于10月16日跟他的妻子在都柏林的皇家运河(Royal
Canal)上散步时突然想到
i² = j² = k² = ijk = -1
的方程解。之后哈密顿立马将此方程刻在附近布鲁穆桥(Brougham Bridge,现称为金雀花桥 Broom Bridge)。
不仅仅如此,哈密顿还创造了向量的内外积(大神就是大神,创造力旺盛啊-_-!)。他亦把四元数描绘成一个有序的四重实数:一个标量(a)和向量(bi + cj + dk)的组合。若两个标量部为零的四元数相乘,所得的标量部便是原来的两个向量部的标量积的负值,而向量部则为向量积的值,但它们的重要性仍有待发掘。
四元数的记法
一个四元数包括一个标量分量和一个3D向量分量。常常记标量分量为w,记向量分量为单一的v或分开的x,y,z。两种记法分别例如以下:
[w,v]
[w,(x,y,z)]
四元数的性质(当年计算机图形学考的就是这题。。呜呜呜~~)
四元数不像实数或复数那样,它的乘法是不可交换的,比如
i j = k, , j i = -k ;
j k = i , k j = -i ;
k i = j , i k = -j .
四元数是除法环的一个样例。除了没有乘法的交换律外,除法环与域是相类的。特别地,乘法的结合律仍旧存在、非零元素仍有唯一的逆元素。
负四元数
四元数能求负。做法非常直接:将每一个分量都变负。
-q = - [ w ( x y z ) ] = [ -w ( -x -y -z ) ]
= - [ w v ] = [ -w -v ]
ps:q 和 - q代表的实际角位移是同样的,因此,3D中的随意角位移都有两中不同的四元数表示方法,它们互相为负。(由于绕某个轴旋转360°物体相当于没有旋转)
单位四元数
几何上,存在两个单位四元数,它们代表没有角位移:[ 1, 0 ] 和 [ -1, 0 ]
数学上,实际仅仅有一个单位四元数 [ 1 , 0 ] 用随意四元数q乘以单位四元数,结果仍是q。数学上觉得[ -1 , 0]不是正在的单位四元数。
四元数的模、共轭和逆
四元数的模的记法和求法公式:
四元数的共轭记作 q*
,可通过让四元数的向量部分变负来获得。
四元数的逆记作,定义为四元数的共轭除以它的模。
四元数的乘法(叉乘)
四元数叉乘满足结合律,但不满足交换律。
(ab)c=a(bc)
ab≠ba
四元数乘积的模等于模的积
||pq|| = ||p|| ||q||
四元数的“差”
四元数的“差”被定义为一个方位到还有一个方位的角位移。换句话说,给定方位a和b,就能计算a旋转到b的角位移d。
四元数点乘
对于单位四元数a和b,有-1 ≤ a·b ≤ 1。通常我们仅仅关心a·b的绝对值,由于a·b=-(a·-b),所以b和-b代表同样的角位移。
四元数点乘的几何解释类似于向量点乘的几何解释。四元数点乘a·b的绝对值越大,a和b代表的角位移越相似。
四元数的对数、指数和标量乘运算
四元数求幂
对四元数求幂在3D编程中很实用,由于它能够从角位移中抽取一部分,比如四元数q代表一个角位移,如今想得到代表1/3这个角位移的四元数,能够计算q^1/3
四元数数幂的求法
在实际3D转换中我们使用这个的代码进行抽取角位移的部分
- // 四元数(输入、输出)
- float w,x,y,z;
- // 指数(输入)
- float zhishu;
- // 为了避免除零,我们这里做一个推断,由于第一个变量时cos,所以这里是.9999f
- if (fabs(w) < .9999f) {
- // 提取半角alpha
- float alpha = acos(w);
- // 计算新的alpha
- float newAlpha = alpha * exponent;
- // 计算新的w值
- w = cos(newAlpha);
- // 计算新的xyz的值
- float temp = sin(newAlpha) / sin(alpha);
- x *= temp;
- y *= temp;
- z *= temp;
- }
使用程序前应先进行单位四元数的检查,由于w=±1会导致temp的计算中出现除零的现象,假设检測出是单位四元数,直接返回原四元数就可以。
四元数插值
当今3D数学中四元数存在的理由是由于一种叫做slerp的运算,它是球面线性插值的缩写(Spherical Linear Interpolation)。slerp运算很实用,由于它能够在两个四元数间平滑插值。slerp运算避免了欧拉角插值的全部问题。
slerp是一种三元运算,这意味着它有三个操作数。前两个操作数是两个四元数,将在它们中间插值。设这两个開始和结束的四元数分别为q0和q1.差值參数设为变量 t,t 在0到1之间变化。slerp函数:slerp(q0,q1,t)
将返回q0和q1之间的插值方位。
- // 两个输入四元数
- float w0,x0,y0,z0;
- float w1,x1,y1,z1;
- // 差值变量
- float t;
- // 输出四元数
- float w,x,y,z;
- // 用点乘计算两个四元数夹角的cos值
- float cosJiao = w0*w1 + x0*x1 + y0*y1 + z0*z1;
- // 假设点乘为负,则反转一个四元数以取得短的4D弧
- if (cosJiao < 0.0f) {
- w1 = –w1;
- x1 = –x1;
- y1 = –y1;
- z1 = –z1;
- cosJiao = –cosJiao;
- }
- // 检查防止除零
- float k0, k1;
- if (cosJiao > 0.9999f) {
- // 假设很接近,就线性插值
- k0 = 1.0f–t;
- k1 = t;
- } else {
- // 利用三角公式sin²+cos²=1计算sin值
- float sinJiao = sqrt(1.0f – cosJiao*cosJiao);
- // 通过sin和cos计算角度
- float Jiao = atan2(sinJiao, cosJiao);
- // 计算分母的倒数从而避免使用除法
- float oneOverSinJiao = 1.0f / sinJiao;
- // 计算插值变量
- k0 = sin((1.0f – t) * Jiao) * oneOverSinJiao;
- k1 = sin(t * Jiao) * oneOverSinJiao;
- }
- // 插入值
- w = w0*k0 + w1*k1;
- x = x0*k0 + x1*k1;
- y = y0*k0 + y1*k1;
- z = z0*k0 + z1*k1;
嘿嘿,四元数这个地方确实有点难度。。只是3D总体都不太简单,全部好好加油!
—End—
參考文献: (1)《3D Math Primer for Graphics and Game Development》
(2) 维基百科
(3) 《计算机图形学》
3D数学读书笔记——四元数的更多相关文章
- 3D数学读书笔记——矩阵基础
本系列文章由birdlove1987编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/24975031 矩 ...
- 3D数学读书笔记——矩阵基础番外篇之线性变换
本系列文章由birdlove1987编写.转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/25102425 前面有一篇文章 ...
- 3D数学读书笔记——向量运算及在c++上的实现
本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24782661 ...
- 3D数学读书笔记——多坐标系和向量基础
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24662453 第一个知识点 ...
- 3D数学读书笔记——3D中的方位与角位移
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...
- 3D数学读书笔记——矩阵进阶
本系列文章由birdlove1987编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/25242725 最终要学习矩阵 ...
- 3D数学学习笔记——笛卡尔坐标系
本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...
- 3D数学--学习笔记(五岁以下儿童):总结一些概念(避免遗忘!)
下面是一些概念只是一个简单的解释,这里是它的一个简单的了解! 当人们谈论,我能理解有关. 1.正交投影: 投影.这意味着降维操作. 全部的点都被拉平至垂直的轴(2D)或平面(3D)上.这样的类型的投影 ...
- 【具体数学 读书笔记】1.2 Lines in the Plane
本节介绍平面划分问题,即n条直线最多把一个平面划分为几个区域(region). 问题描述: "What is the maximum number Ln of regions defined ...
随机推荐
- 栈应用之 背包问题(Python 版)
栈应用之 背包问题 背包问题描述:一个背包里可以放入重量为weight的物品,现有n件物品的集合s,其中物品的重量为别为w0,w1,...,wn-1.问题是能否从中选出若干件物品,其重量之和正好等于w ...
- java基础23 Math类和Random类
一.Math数学类 主要是提供很多数学的公式 1.1.Math类的常用方法 abs(int a):绝对值 ceil(double a):向上取整 floor(double a):向下取整 ...
- HDU 2819 Swap(行列式性质+最大匹配)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意:给你一个n*n的01矩阵,问是否可以通过任意交换整行或者整列使得正对角线上都是1. ...
- python 统计MySQL表信息
一.场景描述 线上有一台MySQL服务器,里面有几十个数据库,每个库有N多表. 现在需要将每个表的信息,统计到excel中,格式如下: 库名 表名 表说明 建表语句 db1 users 用户表 CRE ...
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) M - Unsatisfying 2-Sat
题目大意:给你 m 个式子, 问你最少再添加多少式子能使没有任何一种赋值方式使全部的式子为真. 并且在你给的式子中不能有非. 思路:根据题目给的m个式子可以建出2-Sat的图, 现在问你最少加多少个边 ...
- 007 爬虫(Scrapy库的使用)
推荐网址: http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/architecture.html 1.简介 python开发的一个快速,高层次的屏幕 ...
- RabbitMQ路由类型
关于RabbitMQ的Exchange类型 参考地址:<RabbitMQ学习系列(四): 几种Exchange 模式> github地址:https://github.com/ChenWe ...
- Python 入门之基本数据类型
为什么我要学习Python这门语言呢?其实很简单,我想拓展技术面的同时,尝试更多的方向,可能最后会不了了之,谁知道呢?有可能的话,我会向爬虫和数据分析这个方向走.所以也就开始了我的Python学习之旅 ...
- Java反射机制demo(七)—反射机制与工厂模式
Java反射机制demo(七)—反射机制与工厂模式 工厂模式 简介 工厂模式是最常用的实例化对象模式. 工厂模式的主要作用就是使用工厂方法代替new操作. 为什么要使用工厂模式?直接new不好吗? 直 ...
- 美团外卖Android Crash治理之路
Crash率是衡量一个App好坏的重要指标之一,如果你忽略了它的存在,它就会愈演愈烈,最后造成大量用户的流失,进而给公司带来无法估量的损失.本文讲述美团外卖Android客户端团队在将App的Cras ...