四元數與旋轉

为什么80%的码农都做不了架构师?>>>   hot3.png

在討論「四元數」之前,我們來想想對三維直角座標而言,在物體旋轉會有何影響,可以擴充三維直角座標系統的旋轉為三角度系統(Three-angle system),在Game Programming Gems中有提供這麼一段:

Quaternions do not suffer from gimbal lock. With a three-angle(roll, pitch, yaw) system, there are always certain orientations in which there is no simple change to the trhee values to represent a simple local roation. You often see this rotation having "pitched up" 90 degree when you are trying to specify a local yaw for right.


簡單的說,三角度系統無法表現任意軸的旋轉,只要一開始旋轉,物體本身即失去對任意軸的自主性。
四元數(Quaternions)為數學家Hamilton於1843年所創造的,您可能學過的是複數,例如:a + b i 這樣的數,其中i * i = -1,Hamilton創造了三維的複數,其形式為 w + x i + y j + z k,其中i、j、k的關係如下:

i2 = j2 = k2 = -1
i * j = k = -j * i
j * k = i = -k * j
k * i = j = -i * k


假設有兩個四元數:

q1 = w1 + x1 i + y1 j + z1 k
q2 = w2 + x2 i + y2 j + z2 k


四元數的加法定義如下:

q1 + q2 = (w1+w2) + (x1+x2) i + (y1+y2) j + (z1+z2) k


四元數的乘法定義如下,利用簡單的分配律就是了:

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


其中V1.V2表示向量內積,V1XV2表示向量外積。
定義四元數q = w + x i + y j +z k 的norm為:

N(q) = |q| = x2 + y2 + z2 + w2


滿足N(q) = 1的四元數集合,稱之為單位四元數(Unit quaternions)。
定義四元數定義四元數q = w + x i + y j +zk的共軛(Conjugate)為:

q* = 定義四元數q = w - x i - y j -z k = [S - V]


定義四元數的倒數為:

1/ q = q* / N(q)


說明了一些數學,您所關心的或許是,四元數與旋轉究竟有何關係,假設有一任意旋轉軸的向量A(Xa, Ya, Za)與一旋轉角度θ,如下圖所示:

可以將之轉換為四元數:

x = s * Xa
y = s * Xb
z = s * Xc
w = cos(θ/2)
s = sin(θ/2)


所以使用四元數來表示的好處是:我們可以簡單的取出旋轉軸與旋轉角度。
那麼四元數如何表示三維空間的任意軸旋轉?假設有一向量P(X, Y, Z)對著一單位四元數q作旋轉,則將P視為無純量的四元數X i + Y j + Z k,則向量的旋轉經導證如下:

Rot(P) = q p q*


四元數具有純量與向量,為了計算方便,將之以矩陣的方式來表現四元數的乘法,假設將四元數表示如下:

q = [w, x, y, z] = [S, V]


兩個四元數相乘q" = q * q'的矩陣表示法如下所示:

若令q = [S, V] = [cosθ, u*sinθ],其中u為單位向量,而令q'= [S', V']為一四元數,則經過導證,可以得出q * q' * q^(-1)會使得q'繞著u軸旋轉2θ。
由四元數的矩陣乘法與四元數的旋轉,可以導證出上面的旋轉公式可以使用以下的矩陣乘法來達成:

講了這麼多,其實就是要引出上面這個矩陣乘法,也就是說如果您要讓向量(x', y', z')(w'為0)對某個單位向量軸u(x, y, z)旋轉角度2θ,則w = cosθ,代入以上的矩陣乘法,即可得旋轉後的(x", y", z"),如果為了方便,轉換矩陣的最下列與最右行會省略不寫出來,而如下所示:

關於四元數的其它說明,您可以參考
向量外積與四元數 這篇文章。
關於旋轉的轉換矩陣導證,在Game Programming Gems第二章有詳細的說明。
關於
Gimbal lock

转载于:https://my.oschina.net/lyr/blog/61877

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463657.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩一下数组

来源:嵌入式大杂烩数组是最基本的数据结构,关于数组的面试题也屡见不鲜,本文罗列了一些常见的面试题,仅供参考。目前有以下18道题目。数组求和求数组的最大值和最小值求数组的最大值和次大值求数组中出现次数超过一半的元素求数组…

将GDB中的输出定向到文件

将所有栈信息保存到文件11中 在gdb中: set logging file 11 set logging on thread apply all bt set logging off 结束之后,在相关目录下查看11文件

不生孩子能怎么办?

你会选择不婚或者丁克的生活吗?你是否也想过未来养老的问题呢?如果想过,你对此又有什么规划呢?欢迎留言讨论!本文原创公众号:不会笑青年,授权转载请联系微信(laughyouth369),授权后&…

__attribute__((always_inline))

__attribute__((always_inline))的意思是强制内联,所有加了__attribute__((always_inline))的函数再被调用时不会被编译成函数调用而是直接扩展到调用函数体内,例子如下: define inline __attribute((always_inline))的意思就是用 inline 代…

应用程序池优化配置方案(IIS7、IIS7.5)

定义: 是将一个或多个应用程序链接到一个或多个工作进程集合的配置,该池中的应用程序与其他应用程序被工作进程边界分隔, 一、一般优化方案 1.基本设置 【1】队列长度:默认1000,将原来的队列长度65535 【2】启动32位应…

深圳的房价跌了

我很久没有关注深圳的房价了,上一篇关于深圳房价的文章好像还是几个月之前的,几个月之前,我一个同学买房,跟我咨询了下,然后就写了一篇文章。现在不要着急买房这篇文章从那个时候到现在已经一年了,前几天跟…

Springboot 使用Mybatis对postgreSQL实现CRUD

目录结构 1、创建一个springboot项目 选择Web、Mabatis、postgreSQL 2、在application中写入配置文件 1 #配置数据源 2 spring.datasource.platformpostgres 3 spring.datasource.urljdbc:postgresql://127.0.0.1:5432/postgres 4 spring.datasource.usernamepostgres 5 spring…

不得不说,这是我面过的最优秀的Linux运维!

Linux可以说是运维之“本”。无论中小企业还是大厂,现在的企业有95%甚至更多是使用Linux服务器。而对于Linux运维来说,Linux基础越扎实、会的工具越多,能解决的问题就越多,技术也能走的更远。Linux,甚至可以说是进入IT…

一个中科大「差生」的8年程序员工作总结

今年终于从大菊花厂离职了,离职前收入大概60w不到吧!在某乎属于比较差的,今天终于有空写一下自己的职场故事,也算是给自己近8年的工作做个总结复盘。近8年有些事情做对了,也有更多事情做错了,在这里记录一下…

Java IO File

#file file的一些方法,因为windows和Linux开发环境的问题,在file中最好统一用 / 输出流操作 转载于:https://www.cnblogs.com/cykfory/p/10294981.html

gtest使用例子

最近使用gtest进行单元测试,采用打桩的形式。关于gtest的详细说明就不多说了,网上的资料一大堆。主要讲解使用时的参数如何配置以及遇到的问题。下面的例子模拟是加、减、乘、除四则运算,前提是不知道加、减、乘、除四则运算是如何实现的。 …

游戏开发中的数学和物理算法(7):角度 vs 弧度

我们通常使用的笛卡尔坐标系统,角点通常在(0,0),即原点。初始边在x轴正半轴,终边与初始边成夹角。初始边逆时针旋转为正值,顺时针旋转为逆值。数学表示:角度:degreeradian*180/π 弧度:radiandegree*π/18…

一个小老板的春天

大家周末好继续之前说的采访专栏,前两天和一个做生意的朋友聊天,总结了一些内容分享给大家,觉得不错的点赞收藏起来,可能后面你自己当老板了会用到。我这个老板的名字和公司名字我就不说出来了,他现在做的是细分领域&a…

SharePoint GridView的使用2——DataSourceView的使用

首先创建一个abstract类,继承Microsoft.SharePoint.WebControls.DataTableDataSourceView。之后基于这个类可以创建多个显示不同数据的的DataSourceView,在上文的DataSource控件中有个ViewName属性,可以通过这个属性来区分不同的DataSourceVi…

我在ARM板上写的第一个驱动程序

有时大家喜欢拿电灯来当作笑谈,实际上点灯包含多内容很多,如下这篇文章就是关于嵌入式Linux点灯多技术栈,推荐给大家。摘要:搞嵌入式有两个方向,一个是嵌入式软件开发(MCU方向),另一个是嵌入式软件开发(Lin…

string、char *、char []之间的相互转换

最近工作中遇到了string、char *、char []之间的相互转换&#xff0c;今天终于抽出时间将他们之间的转换记录下来&#xff0c;使用的是CodeBlocks软件&#xff0c;编译器为GNU GCC compiler&#xff0c;下面看代码&#xff1a; #include <iostream> #include <stdio.…

C语言中匿名的最高境界

C语言中有没有见过(int [2]){19,20}或者int (*pt2)[4]的使用方法&#xff0c;字面上可能不好理解&#xff0c;这是C99之后才新增的知识点&#xff0c;名为复合型表述Compound Literals&#xff0c;一旦熟悉使用&#xff0c;便会体会到它简洁而强大的表达。什么是”复合型表述“…

codeblocks安装后提示找不到编译器

安装了自带编译器的codeblocks&#xff0c;但是打开后提示没有找到compiler&#xff0c; 经过几分钟的搜索&#xff0c;找了原因&#xff1a; 打开codeblocks&#xff0c;进入settings->compiler&#xff0c;选择如下: 然后&#xff0c;选择Toolchain executables&#xff…

一文读懂|栈溢出攻击

什么是栈简单来说&#xff0c;栈 是一种 LIFO&#xff08;Last In Frist Out&#xff0c;后进先出&#xff09; 形式的数据结构。栈一般是从高地址向低地址增长&#xff0c;并且栈支持 push&#xff08;入栈&#xff09; 和 pop&#xff08;出栈&#xff09; 两个操作。如下图所…

Sqlserver 通用存储过程(二) 联合主键

CREATEPROCP_public_ViewPage /**//**//**//* no_mIss 通用分页存储过程 2007.3.1 QQ:34813284 适用于联合主键/单主键/存在能确定唯一行列/存在能确定唯一行的多列 (用英文,隔开) 调用&#xff1a; 第一页查询时返回总记录和总页数及第一…