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 四元数的理解的主要内容,如果未能解决你的问题,请参考以下文章