Quaternion类
四元数最早是为了扩展复数应用而产生与发展起来的。然而,人们发现四元数也可以应用在计算机图形学上,作为表现旋转的可选择方法之一。
普通的复数形式可以写成xi+y,其中x是虚部,y是实部。不可思议的是i的平方等于-1,那个 -1的平方根就像你应该知道的那样,其并不存在。因此取名叫“虚数”。
假如xi + y是一个复数,那么我们可认为四元数是一组很特别的复数。四元数不只一个虚部,而是有三个。四元数的形式可写成xi + yj + zk + w,在这里i、j、k的平方都等于-1。从现在起,让我们忘记四元数中平方根的形式,其就可写成这样[w,(x y z)]。
四元数可用来表现所有形式的旋转。正如你所看到,四元数仅需要四个浮点数,所以它只是给对应的矩阵添加了第四个数而已。这个属性可有助于将你许多的旋转处理存储到文件中去(例如关键帧动画)。但你如何获取源于[w,(x y z)]的旋转呢?
答案在这,你首先需要计算你的四元数的模。四元数的模与矢量的有点相似。它可做sqrt(w2 + x2 + y2 + z2)的计算。假如平均值为1,你就得到所谓的单位四元数(正象单位矢量)。唯一的是四元数需要表现旋转,因此你必须对现有的四元数进行归一化。
四元数并不天生就具有旋转的特性,因此你还要做一些转换四元数或其它的一些必要工作。你可将存储空间的四元数转换为欧拉角或轴/角的表示法,及转换为可供OpenGL使用的矩阵。我们平常描述某个点饶某个轴旋转往往是用轴/角形式描述,例如:点P饶A轴旋转θ 度。那么描述这个旋转的四元数就定义为:Q = (c,s XA,s YA,s ZA)。其中s = sin(θ/2),c = cos(θ/2)。
A
θ
静态数据成员
零四元数
Quaternion Quaternion::ZERO(0.0,0.0,0.0,0.0);
单位四元数
Quaternion Quaternion::IDENTITY(1.0,0.0,0.0,0.0);
构造函数
带四个参数的构造函数,为w,x,y,z赋值。
Quaternion::Quaternion (Real fW, Real fX, Real fY, Real fZ)
拷贝构造函数
Quaternion::Quaternion (const Quaternion& rkQ)
成员函数
由3*3旋转矩阵生成四元数,参数是旋转矩阵。
void Quaternion::FromRotationMatrix (const Matrix3& kRot)
将四元数转换为旋转矩阵,参数是回传参数,接收得到的旋转矩阵。
void Quaternion::ToRotationMatrix (Matrix3& kRot) const
从角、轴生成四元数,参数为角和轴,即饶什么轴旋转多少度。
void Quaternion::FromAngleAxis (const Real& rfAngle,
由四元数生成轴、角表示法的角和轴。参数是引用参数,回传用途。
void Quaternion::ToAngleAxis (Real& rfAngle, Vector3& rkAxis) const
由3个向量表达的旋转矩阵生成四元数,参数是指针指向的多个向量表达的旋转矩阵(一般为3个)
void Quaternion::FromAxes (const Vector3* akAxis)
由3个向量表达的旋转矩阵生成四元数
void FromAxes (const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
由四元数生成旋转矩阵,该矩阵由指针指向的多个(3个)向量表达。
void ToAxes (Vector3* akAxis) const;
由四元数生成旋转矩阵,该矩阵由3个向量表达。
void ToAxes (Vector3& xAxis, Vector3& yAxis, Vector3& zAxis);
重载=操作符
Quaternion& operator= (const Quaternion& rkQ);
重载+操作符
Quaternion operator+ (const Quaternion& rkQ) const;
重载-操作符
Quaternion operator- (const Quaternion& rkQ) const;
重载*操作符,四元数*四元数。
Quaternion operator* (const Quaternion& rkQ) const;
重载*操作符,四元数*标量。
Quaternion operator* (Real fScalar) const;
重载*操作符,四元数*四元数。重载为友员方式。
friend Quaternion operator* (Real fScalar, const Quaternion& rkQ);
重载负号操作符
Quaternion operator- () const;
重载==操作符
bool operator== (const Quaternion& rhs) const;
四元数点乘
Real Dot (const Quaternion& rkQ) const;
四元数求模
Real Norm () const;
四元数求倒数,要求本四元数非0
Quaternion Inverse () const;
单位四元数求倒数,要求本四元数为单位四元数。
Quaternion UnitInverse () const; // apply to unit-length quaternion
求四元数的指数,即e的四元数次方
Quaternion Exp () const;
以e为底求四元数的对数
Quaternion Log () const;
用四元数旋转向量(似乎nVidia的SDK才支持)。
Vector3 operator* (const Vector3& rkVector) const;
静态成员函数,球面线性插值。参数fT为0-1的时间因子。
static Quaternion Slerp (Real fT, const Quaternion& rkP, const Quaternion& rkQ);
静态成员函数,带干扰因子的球面线性插值。参数fT为0-1的时间因子。
static Quaternion SlerpExtraSpins (Real fT, const Quaternion& rkP, const Quaternion& rkQ,
int iExtraSpins);
静态成员函数,目前不清楚用途。
static void Intermediate (const Quaternion& rkQ0,
const Quaternion& rkQ1, const Quaternion& rkQ2,
Quaternion& rka, Quaternion& rkB);
静态成员函数,样条插值(二次插值)。目的是在已知样条形状的情况下,通过插值得到平滑的目的线条。fT为0-1的时间因子。rkP和rkQ为样条的起点和终点,而rkA和为rkB插值过程中的某一线段的起点和终点(控制点连线)。
P
Q
A
B
P
Q
A
B
对AB段插值 对新的AB段插值
static Quaternion Squad (Real fT, const Quaternion& rkP,
const Quaternion& rkA, const Quaternion& rkB,
const Quaternion& rkQ);
重载输出流操作符。
inline _OgreExport friend std::ostream& operator <<
( std::ostream& o, const Quaternion& q )