开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天
1 概述
四元数(Quaternions)是由威廉·卢云·哈密顿(William Rowan Hamilton,1805-1865)1843年 在爱尔兰发现的数学概念,但真正应用于计算机图形学领域是在漫长的一个世纪之后。四元数是构造变换的有力工具,不过,它本身带有太多神秘的色彩,可能很多人都不了解它。
2 四元数
一个四元数由一个标量和一个矢量组成,但这个矢量不是我们通常所讨论的三维空间,而是四维空间,可以表示为[w,v]或者[w,(x,y,z)],其中,w是标量,v是矢量。
四元数同样可以表示为:
W = cos(θ/2)
X=ax*sin(θ/2)
Y -ay*sin(θ/2)
Z-az*sin(θ/2)
其中,ax、ay、az表示轴的矢量,θ表示绕此轴的旋转角度,不过,需要注意的是,θ是极坐标下的角度,简单的组合能够保证变换的稳定。当然,用轴角来描述也是可以的,只是上面的参数不能简单理解为坐标轴和角度之间的值。在使用四元数时,也可以写成轴角表示方式。
四元数存在于3D数学中有一个重要原因,它有一种slerp插值运算,slerp插值运算是一种空间的、平滑的球面线性插值,没有其他方法可以提供如此的平滑插值。插值的基本思想是基于四维空间极坐标轴下弧线插值。四元数的平滑插值在场景交互过程中发挥着重要的作用,提供了平滑的渲染过程,如场景漫游等。
在OSG中封装了一个基本类osg:Quat来描述四元数,它不仅可以简单存储四元数,而且还定义 了一系列的运算,如四元数的旋转、四元数的长度计算、四元数与向量之间的运算,重载了基本运算,还实现了slerp插值运算,例如:
void makeRotate(valye_type angle, value_type x, value_type y, value_type z) //旋转
......
value_type length()cosnt //长度计算
value_type length2()const
const Quat operator+(const Quat& rhs) const // 加法
Quat& operator+=(const Quat& rhs)
......
void sherp(value_type t, const Quat& from, const Quat& to //插值
Vec3f operator*(const Vec3f& v) // 与向量相乘
Vec3d operator*(const Vec3d& v)const
平滑的插值只能用四元数来完成,如果想用其他的形式,需要先转换为四元数,待插值完毕再转换成原格式。由于四元数非常难以理解,所以是很难直接使用的。在后面的路径动画的章节中进行路径插值时就使用了slerp 插值运算形成平滑的路径。