閱讀498 返回首頁    go 阿裏雲 go 技術社區[雲棲]


OGRE中的四元數與旋轉

想象一個物體在3D空間中移動的過程,該物體必然會涉及到旋轉。例如一個怪物,他的運動方向會改變,要改變其方向隻需要對其進行旋轉即可。

旋轉的方式大致分為三種:Euler旋轉,矩陣旋轉,以及四元數旋轉。

這裏稍微記錄下我目前對於四元數旋轉的理解。對於四元數方麵的數學,以及其原理,這裏不關心,隻需要學會如何使用即可。

無論是哪一種旋轉,物體與該物體的局部坐標係之間的相對位置,相對方位都是不會改變的。因此,在進行兩個局部旋轉(即相對於局部坐標係)時,要注意結果可能不是你預期的。

對於Euler旋轉,OGRE中為SceneNode提供了yaw, pitch, roll之類的接口。這些接口默認都是參照局部坐標係旋轉,可以通過第二個參數來指定,例如 yaw( Degree( 90 ), SceneNode::TS_WORLD );

OGRE中的Quaternion類用於四元數處理。該類(也可以說是四元數本身)有四個成員:x,y,z,w。這四個數分別代表什麼?

在OGRE論壇上我找到了一些可以讓人很容易理解的信息:

Quaternions can seem pretty daunting because of the use of 'imaginary' numbers. It's much easier to understand if you just ignore this concept completely. The basic formula for creating a quaternion from angle/axis is:


Q = cos (angle/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k(z * sin(a/2))


or

Code:


Q.w = cos (angle / 2)

Q.x = axis.x * sin (angle / 2)

Q.y = axis.y * sin (angle / 2)

Q.z = axis.z * sin (angle / 2)

稍微忽略下那些複數之類的概念,使用角度/軸的方式創建四元數的公式為:

Q = cos (angle/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k(z * sin(a/2))


對應的代碼為:

Q.w = cos (angle / 2)

Q.x = axis.x * sin (angle / 2)

Q.y = axis.y * sin (angle / 2)

Q.z = axis.z * sin (angle / 2)


再看一下OGRE中關於Quaternion的一個構造四元數的函數源代碼:

void Quaternion::FromAngleAxis (const Radian& rfAngle,

const Vector3& rkAxis)

{

// assert: axis[] is unit length

//

// The quaternion representing the rotation is

// q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)


Radian fHalfAngle ( 0.5*rfAngle );

Real fSin = Math::Sin(fHalfAngle);

w = Math::Cos(fHalfAngle);

x = fSin*rkAxis.x;

y = fSin*rkAxis.y;

z = fSin*rkAxis.z;

}


雖然可以說四元數中的w代表旋轉量,x, y, z代表對應軸,但是這也不全正確。因為我們看到,對於真正的旋轉量啊之類的數據,是需要進行有些公式變換後,才得到w, x, y, z 的。

但是,即使如此,我們還是可以這樣簡單地構造一個四元數用於旋轉:

Quaternion q( Degree( -90 ), Vector3::UNIT_X );

該構造函數第一個參數指定旋轉角度,第二個參數指定旋轉軸(可能不是),上麵的代碼就表示,饒著X軸(正X方向),旋轉-90度。將該四元數用於一個Scene Node旋轉:

sceneNode->rotate( q );

即可實現該node饒X軸旋轉-90度的效果。


再看一下OGRE tutorial中的一段代碼:

Vector3 src = mNode->getOrientation() * Vector3::UNIT_X;

Ogre::Quaternion quat = src.getRotationTo(mDirection);

mNode->rotate(quat);

SceneNode的getOrientation獲得該node的方位,用一個四元數來表示。什麼是方位?這裏我也不清楚,但是對於一個四元數,它這裏表示的是一種旋轉偏移,偏移於初始朝向。

OGRE論壇上有這麼一段話:

The reason there's no other way to convert a quaternion to a vector is because a quaternion is relative. It has no direction.

With a direction (like a vector) you could say "face north east".

But with a quaternion, you say "face 45 degrees clockwise from whatever direction you are already facing" (very simplified example). Without knowing which way the object is already facing, a quaternion is virtually meaningless with respect to orientation. So we just default it to some initial direction, like Unit Z, and make all orientations relative to that.

然後,getOrientation() * Vector3::UINT_X又會得到什麼?我可以告訴你,第一句代碼整體的作用就是獲取該物體當前麵向的方向。

最後更新:2017-04-02 04:00:24

  上一篇:go 關於CEGUI
  下一篇:go (轉載)WCHAR與CHAR的轉換