天天看點

程式中的四元數表示法

網上有很多四元數相關的文章。

但當你看完這些後。再看着下面這樣的代碼,你能快速回過神來麼?

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