Unity3D 四元数的理解

Posted 暗光之痕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D 四元数的理解相关的知识,希望对你有一定的参考价值。

环境:Unity2018.3 语言:C#

 

总起:

本文主要参考《3D数学基础:图形与游戏开发》这本书。

 

四元数的理解:

复数

首先我来考虑复数轴i,i的定义为i^2=-1。

 

按照旋转的角度来理解的话,从1变换到-1,1实际上是旋转了180度到了-1。那么旋转90度呢?这个时候实际上就旋转到了复数轴上了,我们便用i来表示这个轴。

 

在2维空间中事情比较简单。

 

设点p为(x, y),以复数的概念来看即为x+yi。如果旋转θ度,则引入另一个复数q=(cosθ, sinθ)。两者相乘得到旋转之后的点:

 

p’= pq = (x+yi)(cosθ +isinθ)

 

没有三元数

在3维空间中简单的增加一个维度并不能达到想要的效果:

 

j轴垂直于实数轴,那么肯定有j^2=-1,问题是ij的结果是什么?

 

我们很容易想到是-1,但是如果ij=-1,结合i^2=-1,说明i=j,实际上j这个新轴是不存在的。

 

四元数

这个时候我们就需要假设一个新的轴k,使得ij=k,同时k^2=-1。

 

得到i^2=j^2=k^2=-1。

 

我们可以想象i、j、k之间相互垂直组成3维空间,而实数跟他们分别垂直,可以想象出是单独拿出来的一条线。

 

ij=k,ji=-k;

jk=i,kj=-i;

ki=j,ik=-j.

 

我们得到了以上结论,注意实数轴和复数轴的转换跟复数空间中的不一样,因为1*i直接到了复数空间的i轴,而不是一个新轴。

 

这个结论其实很有意思,类似于我们以前学到的叉乘,同时可以用右手定则确定两个虚轴相乘的结果。

 

最终我们得到由3个虚部组成的四元数[w, (x, y, z)]为 w + xi + yj + zk。

 

从轴角对的角度来看,一次旋转实际上可以表示为一个轴n和旋转角度θ组成,四元数可由该轴角对来表示为[cos(θ/2) sin(θ/2)n]。

 

即[cos(θ/2) sin(θ/2)nx sin(θ/2)ny sin(θ/2)nz]。

 

对比

四元数很难理解,但是我们为什么要用它呢?因为相比于其他两种方式,有无可替代的优势。

 

旋转矩阵,计算机图形学中,我们一直在学习矩阵,最方便解决旋转的方式当然就是矩阵,并且矩阵的逆就是反角位移。

 

缺点是占用空间大,用了9个数;并且旋转矩阵是病态的,有效数字只有3个,但却需要6个数字去限制它们,很容易出现计算、采样不精确的情况下,产生非法的旋转矩阵。

 

第二种方式是欧拉角,欧拉角非常直观,甚至如果我们的游戏只需要一个到两个轴,完全可以使用欧拉角来处理问题。

 

但是欧拉角最大的问题是在插值的时候,可能会以我们相反的方向绕一圈进行插值;然后就是万向死锁,这个不做展开,只需要知道有这么一个底层问题。

 

四元数相比而言,最大的优势就是能提供平滑的插值,同时能快速连接多个四元数,很轻松的求出四元数的逆。

 

下一篇文章,我们结合Unity中四元数的实现,来具体讨论一下四元数的用处。

 

个人:

工程上代码写了许久,很累,学习最多的还是沟通和代码风格,技术上的进步比较少,所以最近想着把数学渲染什么的过一遍。

以上是关于Unity3D 四元数的理解的主要内容,如果未能解决你的问题,请参考以下文章

使用四元数的Unity3D相对偏移对象旋转

四元数

四元数quaternion

四元数法

四元数运动学笔记旋转的雅克比矩阵

Unity3D 控制物体旋转详解 —— 自身绕轴旋转缓慢旋转鼠标控制旋转欧拉数和四元数的关系