網上有很多四元數相關的文章。
但當你看完這些後。再看着下面這樣的代碼,你能快速回過神來麼?
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
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和百度。
另外,程式設計中還經常用到歐拉角和矩陣的轉換。
這三個的特點。
矩陣運算的資料相對來說比較直覺,容易調試和診斷。但資料存儲量大,特别是旋轉的時候,會浪費很多空間。
歐拉角儲存小,但有萬向鎖,并且插值不夠平滑。
四中繼資料量介于二者之間。但插值容易。
在骨骼動畫中,可以在檔案中存儲歐拉角,加載後将旋轉資料轉換為四元數。最後動畫計算時統一采用矩陣運算。
要說的東西很多,一言難盡。今天就到這裡吧。
簡介:09年入行,喜歡遊戲和程式設計,對3d遊戲和引擎尤其感興趣。
版權聲明:本文版權歸作者和部落格園共有,歡迎轉載。轉載必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
轉載:http://www.cnblogs.com/geniusalex/archive/2010/12/19/1910879.html