[WebGL入门]三十一,Quaternions(四元数)

翻译 2017年08月23日 11:43:05

注:文章译自http://wgld.org/,原作者杉本雅広(doxas)

3D编程和数学

3D编程的世界中,数学的知识是非常重要的。最具代表的就是矩阵了,不知道矩阵的话,就没办法进行坐标变换了。而其他的,向量的知识,内积・外积这些也都是不可缺少的。的确是非常烦人。
那么,这次的标题是四元数。不光是WebGL,在DirectX中也同样存在着四元数。它到底是个什么东西,使用它之后又有那些方便之处,我想很多人恐怕也没有明确的概念。这次就来说说四元数的定义以及它的简单的使用方法。这次真的是纯粹的数学话题,估计读起来会很枯燥,首先理解这篇文章的最大目的,然后慢慢往下看吧。

它到底是什么

四元数是数学中的一个概念。3D编程中和旋转相关的处理会经常使用到四元数。
四元数到底是什么,大家自己在网上搜一下,估计会出现很多很难理解的说明。比如在wikipedia中四元数的解释如下。

拥有三个虚数的超复数之一

这对大多数人来说,跟没说一样。至少我个人读了这个之后,完全不明白它的意思。
刚才也说了,四元数的定义和原理并不是本篇文章的目的。咱们只在一定程度上说一下四元数是什么,怎么用,这才是本次的重点。请在这个大前提下,继续读下去。
首先,来考虑一下。三维空间上,讲一个什么模型放进去的时候,这个模型的姿势要如何来表示呢。注意不是模型的坐标位置,是[姿势]。这里所说的姿势,是模型如何倾斜啦,模型面向什么方向啦,等等,主要是模型的各种旋转的属性。
旋转的话,使用矩阵不是也已经可以表现出来了吗!确实,矩阵是可以处理矩阵的旋转的,移动和缩放也是可以同时处理的,只是单纯的表达[姿势]的话,已经包含在里面了。
而且,使用矩阵进行旋转,可以知道X ・ Y ・ Z的各轴分别旋转了多少度,三个轴的旋转组合在一起,确实差不多已经可以表达[姿势]了。但是会稍微有些复杂,比如说面向局部坐标(0.0, 1.0, 0.0)方向的模型,将它变为面向(0.42, 0.59, 0.68)方向,那么XYZ的各轴要分别旋转多少度才合适呢。这就不是一般人的思考能力可以想象的了。
从这个观点来看[姿势],用矩阵就有些难理解了。为了表示[姿势],至少需要[旋转了多少度]和[向哪个方向旋转]这些信息。也就是说,有了这两个信息,就可以表示出旋转了。可能也不是很好理解,所有的姿势都可以通过这两个要素来表示出来。
那么,要把这两个要素很好的表示出来,就是四元数了。使用四元数,就可以表示以任意方向为轴,做任意角度的旋转。也就是说,只需要一个四元数,就可以将所有的姿势表示出来了。
估计读到这里,还是有很多人对四元数依然不是很理解。那就在接下来实际运用过程中,进一步理解吧。

四元数的表示

四元数可以表示出以[ 任意方向的轴 ]进行[ 任意角度的旋转 ]。

首先,想一下任意方向的轴。比如说在做灯光的处理的时候,为了表示光的方向,我们定义了光向量。从这一点来看,表示方向的话,用一个向量就足够了。三维空间中的向量,就可以通过X ・ Y ・ Z三个元素来表示。
接着,想一下任意的旋转角度,因为是纯粹的角度,角的度量可以用角度或者弧度来表示。
这些综合起来,构成四元数的元素,就是一个拥有三个元素的向量和一个角度。这就是四元数了。
四元数一般来说,像下面这样表示。

Q = (t; x, y, z)
只有一个元素和一个向量而已吧。就是刚才说的那样,四元数就是由向量和角度构成的。从上面的式子来看,也很容易理解吧。用难一点的语言来描述的话,上面的t叫做实数部分,向量部分的三个元素叫做虚数部分。但是,也不用太在意这些叫法。重要的是,理解了四元数可以用来表示四个元素就行了。

在实际的编程当中,如果要使用四元数,最低限度也得知道上面说的这些。而实数,虚数这些内容,想知道的话,可以自己查一下。

使用四元数的计算

接着看一下四元数的计算方法。
首先应该知道,四元数之间的乘法和矩阵一样,相乘的顺序改变的话,结果也会改变,这个一定要记住。
四元数的相乘,像下面这样进行。

>クォータニオン同士の掛け算

Q = (q; V)

R = (r; W)

QR = (qr - V ・ W; qW + rV + V × W)
上面的式子就是第一个四元数 Q 和第二个四元数 R 相乘的计算。这里出现的[ ・ ]是点积,也就是内积。[ × ]是差积,也就是外积。
这里的四元数之间的相乘处理,最终就是加算,减算,以及内积和外积的计算,计算的负荷也不大,可以进行比较告诉的处理。
理解了四元数之间的相乘,下面来看使用四元数来表示旋转。这个也一样,记住规则的话,也就没那么难了。用四元数做旋转像下面这样。
>用四元数来旋转

以原点为中心的轴向量 = (x, y, z)

旋转角度 = th

Q = (cos(th / 2); x * sin(th / 2), y * sin(th / 2), z * sin(th / 2))

乍一看,一定会想这是什么玩意儿?仔细看一下,其实很简单。就是X ・ Y ・ Z 的每一项,分别乘以角度的一半的正弦值。就这样,就可以表示旋转了,是不是很简单。
这里需要注意的是,向量需要正规化,千万不要使用未正规化的向量。(把一个非零向量化成与它同方向的单位向量,称为向量的正规化或单位化。)
用上面表示四元数的同样的方法,接下来来表示一个叫做共轭四元数的四元数。名字有点儿吓人,但是也不需要害怕,共轭四元数只是将四元数的X ・ Y ・ Z 的值取反。
>共轭四元数

以原点为中心的轴向量 = (x, y, z)

旋转角度 = th

Q = (cos(th / 2); x * sin(th / 2), y * sin(th / 2), z * sin(th / 2))

Q 的共轭四元数 R

R = (cos(th / 2); -x * sin(th / 2), -y * sin(th / 2), -z * sin(th / 2))
这样,表示旋转的四元数Q,和它的共轭四元数R就表示出来了。使用这两个四元数,在三维空间上的一点,沿着任意轴,任意角度进行旋转,就都可以表示出来了。计算方法如下。
>任意轴・任意角上的旋转计算

三维空间上的坐标: P = (0; x, y, z)

将P 做旋转的计算……

R * P * Q = (0; X, Y, Z)
刚才也说了,四元数之间的乘法是跟顺序有关的,要十分注意。上面的式子,大写字母的XYZ,就是沿任意轴,任意角度旋转后得到的坐标。
仔细想一下的话,只需要简单的计算,就能用四元数做一些处理了吧。

总结

好了,四元数已经了解了吧,使用四元数的方便之处还远不止这些,这次的文章,也只是让大家知道四元数是个什么东西,以及用四元数来做一些基本的计算,知道这些就足够了。
任意轴和任意角的旋转的计算方法也接触到了,像旋转那样冗长的坐标计算,也用四元数很简洁的进行了。虽然在实际程序中,如何灵活的运用是个问题,但无疑四元数是个很强大的工具。
下一次,使用四元数来写一个demo。为了方便四元数的处理,自己的库也会稍微解说一下。通过demo来接触下四元数的话,就能更加了解四元数的使用方法了。


欢迎继续关注我的博客

转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend

[WebGL入门]二十七,多纹理

多纹理进行渲染的时候应该注意的是,指定正确的纹理单位进行数据的处理,这就足够了。 其他的细节,主要是activeTexture函数和uniform1i函数的使用方法,这几个不出错的话,之后就可以在着色...

[WebGL入门]二十八,纹理参数

为了进一步提升纹理的渲染质量,来介绍一下纹理参数。通过控制纹理参数,可以很好的提升模型的渲染质量,虽然会有些比较难理解的地方,这些可以以后再考虑。 那么,WebGL中的纹理参数到底是什么呢?现在就从这...

Understanding Quaternions 中文翻译《理解四元数》

Tags: math, quaternion 原文地址:http://www.3dgep.com/understanding-quaternions/ 正文 在这篇文章中我会尝试用简...

四元数(Quaternions)

为什么使用四元数为了回答这个问题,先来看看一般关于旋转(面向)的描述方法-欧拉描述法。它使用最简单的x,y,z值来分别表示在x,y,z轴上的旋转角度,其取值为0-360(或者0-2pi),一般使用ro...

【知识】Understanding Quaternions 中文翻译《理解四元数》

转自:http://www.qiujiawei.com/understanding-quaternions/  如有侵权请告知(实在翻的不错啊,虽然作者写了未授权禁止转载可是联系方式是一个gmail。...

四元数入门(简单容易理解)

四元数常常可以在3D的书上看到。 但我的那本3D图形学书上,在没讲四元数是干什么的之前,就列了几张纸的公 式, 大概因为自己还在上高中,不知道的太多,看了半天没看懂。。。 终于,在gameres上看到...

圆点博士小四轴算法快速入门--四元数和PID图解

参考http://www.eeboard.com/bbs/thread-32321-1-1.html 飞控的算法代码一般包括下面三个部分:滤波,姿态,PID 1,滤波可以用互补滤波来实现,互补...

旋转矩阵、欧拉角、四元数比较

来源 http://www.manew.com/7461.html 旋转矩阵、欧拉角、四元数主要用于:向量的旋转、坐标系之间的转换、角位移计算、方位的平滑插值计算。 旋转矩阵、欧拉...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[WebGL入门]三十一,Quaternions(四元数)
举报原因:
原因补充:

(最多只允许输入30个字)