網上有很多四元數相關的文章。
百度百科 http://baike.baidu.com/view/319754.htm
某位的博客 http://caterpillar.onlyfun.net/Gossip/ComputerGraphics/QuaternionsRotate.htm
但當你看完這些后。再看著下面這樣的代碼,你能快速回過神來么?
class CQuaternion


{
public:
CQuaternion(const float fScalar,const Vector3& rVec)

{
mVector=rVec ;
mScalar=fScalar;
}

void FromAxisAngle (const Vector3& rAxis, const F32 Angle)

{
F32 fSin, fCos;
//取得一個弧度角的SIN COS值
SinCos( Angle*0.5f, fSin, fCos);
mVector = rAxis*fSin;
mScalar = fCos;
}
private:
float mScalar;
float mVector;
}

class CMatrix44


{
public:

enum
{ _X_,_Y_,_Z_,_W_ };
void QuaternionToMatrix(const CQuaternion& q)

{
F32 s,xs,ys,zs,wx,wy,wz,xx,xy,xz,yy,yz,zz;
s = q.Length2();
s = (s>0 ? 2.f/s : 0);

xs = q.Vect[_X_]*s; ys = q.Vect[_Y_]*s; zs = q.Vect[_Z_]*s;
wx = q.Scalar*xs; wy = q.Scalar*ys; wz = q.Scalar*zs;
xx = q.Vect[_X_]*xs; xy = q.Vect[_X_]*ys; xz = q.Vect[_X_]*zs;
yy = q.Vect[_Y_]*ys; yz = q.Vect[_Y_]*zs; zz = q.Vect[_Z_]*zs;

(*this)[0].Set(1.f-(yy+zz),xy+wz, xz-wy, 0.f); // col 0
(*this)[1].Set(xy-wz, 1.f-(xx+zz),yz+wx, 0.f); // col 1
(*this)[2].Set(xz+wy, yz-wx, 1.f-(xx+yy),0.f); // col 2
}
//忽略其它無關緊要的
//、、、、、、、
};


//========================================================
不用多說,肯定有回過神來的,也有沒有回過神來的。
正如上面那某位的博客里面講到的。

對于旋轉軸A,繞其旋轉一定的角度,則可以表示為
x = s * Xa
y = s * Xb
z = s * Xc
w = cos(θ/2)
s = sin(θ/2)
這正是我們FromAxisAngle 所做的事情。
而QuaternionToMatrix則是對應了
我想說明的是,數學庫本身并不在于代碼。而是在于數學公式,代碼僅是將其用另一種符號表示出來而已。只要仔細去看,定能明白其中的道理。
關于文中介紹的公式推導以及萬向鎖,可以GOOGLE和百度。
另外,編程中還經常用到歐拉角和矩陣的轉換。
這三個的特點。
矩陣運算的數據相對來說比較直觀,容易調試和診斷。但數據存儲量大,特別是旋轉的時候,會浪費很多空間。
歐拉角儲存小,但有萬向鎖,并且插值不夠平滑。
四元數據量介于二者之間。但插值容易。
在骨骼動畫中,可以在文件中存儲歐拉角,加載后將旋轉數據轉換為四元數。最后動畫計算時統一采用矩陣運算。
要說的東西很多,一言難盡。今天就到這里吧。