四元數,齊次座標問題及相關回答

 

我看了很多書,和文章,可是還是不知道,四元數到底有什麼用

好像她的好處就是爲了能比矩陣,在相乘的時候,運算次數少

另外,一個包含旋轉信息的四元數如何與一個向量運算得到我希望的結果?好像dx沒有提供這樣的函數啊?難道需要轉換爲矩陣再計算嗎?

D3DXQUATERNIONSlerp函數是做球體上旋轉線性插值的吧?他的最後一個參數如何使用?

q=cos(a/2) + sin(a/2)*V  角a是旋轉角度吧只要,控制一下是不是就可以達到D3DXQUATERNIONSlerp相同的效果?

旋轉的線性插值,四元數應該就是爲了這個吧,可是D3DXMatrixRotationAxis函數不是也可嗎,那還要四元數幹什麼?
-----------------------------

齊次座標:
齊次座標(x,y,z,w) 轉換爲向量(x/w,y/w,z/w) 齊次座標就是爲了可以表示無窮遠的問題吧(w趨向於0時)
D3DXVec3TransformNormal
D3DXVec3TransformCoord
D3DXVec3Transform
這3個函數有什麼區別

真的是看了很長時間書了,可能是我比較笨吧,一直由這些疑問搞不懂,還希望高手能指點一下,謝謝啦

 

你自己都說了:四元數比矩陣在相乘的時候運算次數少。在像動畫計算這樣沒幀都要做大量繞任意軸旋轉操作的應用中,四元數比矩陣可以有效降低CPU計算量。另外它可以避免萬向鎖(Gimbal)問題,你可以到Google上搜一下這個問題。
齊次座標中的w有個重要的作用是用於消除Z座標,計算投影座標影射到屏幕。
這些問題不可能幾句話說明白,最後給你推薦一本書:3D Math Primer for Graphics and Game Development,你的這兩個問題都可以在裏面找到答案,而且此書有中文版!

 

 

我看了那本書,但還是不知道爲什麼用Quaternion來表示旋轉的公式是
qPq^-1

我想可能和eigenvector,eigenvalue(特徵值,特徵向量)有關係
誰能幫我解釋一下?
謝謝

 

 

我看了很多書,和文章,可是還是不知道,四元數到底有什麼用

好像她的好處就是爲了能比矩陣,在相乘的時候,運算次數少


四元數q = (w,v),表示一個旋轉和向量。這樣的表示非常簡單,這是它的一個優點,而且可以減少一次矩陣相乘。
----------------------------------------------------------------------
另外,一個包含旋轉信息的四元數如何與一個向量運算得到我希望的結果?好像dx沒有提供這樣的函數啊?難道需要轉換爲矩陣再計算嗎?

先看看通過矩陣操作的結果吧
D3DXMatrixRotationAxis( &matRot, &m_v, angle )
D3DXVec3TransformCoord( &vNew, &m_v, &matRot );
這個是vNew向量繞m_v向量旋轉angle角度。
D3DXMatrixRotationX(&matTran,fRads);
D3DXMatrixMultiply(&m_matWorld,&matTran,&m_matWorld);
這個是是繞x軸旋轉fRads角度。
再看通過四元數的操作
D3DXQuaternionRotationYawPitchRoll (&qR, 0, fRads, 0);
D3DXMatrixRotationQuaternion (&matRot, &qR);
D3DXMatrixTranspose(&matRot,&matRot)//因爲四元數是使用右手法則的,所以需要轉置一下。
D3DXMatrixMultiply (&m_matWorld,  &m_matWorld,&matRot);
如果不轉制也行,那就
D3DXMatrixMultiply (&m_matWorld, &matRot, &m_matWorld);
顯然四元數比矩陣要少做一次乘法。
不過確實需要轉換成矩陣。

--------------------------------------------------------
D3DXQUATERNIONSlerp函數是做球體上旋轉線性插值的吧?他的最後一個參數如何使用?

q=cos(a/2) + sin(a/2)*V  角a是旋轉角度吧只要,控制一下是不是就可以達到D3DXQUATERNIONSlerp相同的效果?

旋轉的線性插值,四元數應該就是爲了這個吧,可是D3DXMatrixRotationAxis函數不是也可嗎,那還要四元數幹什麼?


給你看一段關鍵幀動畫中的四元數插值。
// Rotation
if (pAnim->m_NumRotationKeys > 0 && !pAnim->m_vRotationKeys.empty())
{
// Loop for matching rotation key
for (j=0;j<pAnim->m_NumRotationKeys;j++)
{
if (Time < pAnim->m_vRotationKeys[j].m_Time) {
dwKey2 = j;
break;
}
}
dwKey1 = (dwKey2 == 0) ? 0 : dwKey2 - 1;
// Get difference in keys' times
DWORD dwTimeDiff = pAnim->m_vRotationKeys[dwKey2].m_Time -
pAnim->m_vRotationKeys[dwKey1].m_Time;
if(dwTimeDiff == 0)
fScalar = 0;
else// Calculate a scalar value to use
fScalar = (Time - pAnim->m_vRotationKeys[dwKey1].m_Time) / dwTimeDiff;
// slerp rotation values
D3DXQUATERNION quatRotation,q1,q2;
q1.x = -pAnim->m_vRotationKeys[dwKey1].m_quatKey.x;
q1.y = -pAnim->m_vRotationKeys[dwKey1].m_quatKey.y;
q1.z = -pAnim->m_vRotationKeys[dwKey1].m_quatKey.z;
q1.w = pAnim->m_vRotationKeys[dwKey1].m_quatKey.w;
q2.x = -pAnim->m_vRotationKeys[dwKey2].m_quatKey.x;
q2.y = -pAnim->m_vRotationKeys[dwKey2].m_quatKey.y;
q2.z = -pAnim->m_vRotationKeys[dwKey2].m_quatKey.z;
q2.w = pAnim->m_vRotationKeys[dwKey2].m_quatKey.w;
D3DXQuaternionSlerp(&quatRotation,&q1,&q2,fScalar);
// Create rotation matrix and combine with transformation
D3DXMATRIX matRotation;
D3DXMatrixRotationQuaternion(&matRotation,&quatRotation);
pAnim->m_Bone->TransformationMatrix *= matRotation;
}

D3DXQuaternionSlerp只是進行了線形插值。最後一個參數表示權值。

其他的那些函數,你看看msdn,實在不明白也沒關係,等你用到了也許就知道了,多看看別人的代碼有好處,最好自己再實做一下更好!

 

 

 

我來回答一下,表達得可能不太清楚.實在是不知道怎麼說纔好.

D3DXQUATERNIONSlerp函數最後一個參數是用來控制插值過渡速度.

D3DXQUATERNIONSlerp做的是球型插值,而D3DXMatrixRotationAxis則是線性插值.

兩種方法所得到的結果是完全不一樣的,一個是走的弧線,一個走的直線
-----------------------------

D3DXVec3TransformNormal
D3DXVec3TransformCoord
區別在於
一個是W=1,一個是W=0

要我表達清楚很難…自己試試吧

 

 

 

Quaterion 是球面空間的位移 球面空間裏的直線就是 笛卡兒座標空間裏的一段弧 對quaterion在球面空間裏進行線性插值 就相當於 在笛卡兒座標空間裏對旋轉做圓滑插值。

不記得什麼時候看過的類似的描述 也不知道記錯了沒有 不過大概的道理是對的

不用quaternion很難對旋轉做圓滑的插值, 或者說做起來比較麻煩 沒用quaterion那麼簡潔。

 

 

齊次座標系中的座標和向量都是4維的, 只不過爲了簡單一般都忽略第4維 w 直接使用3維

齊次座標系中的點 的w = 1
齊次座標系中的向量的 w = 0;

D3DXVec3TransformNormal
D3DXVec3TransformCoord

上面兩個方法的參數是3維向量 xyz, 第一個函數的參數的隱含w = 0(因爲法線是向量), 第二個函數的參數的隱含w = 1

D3DXVec3Transform 和 D3DXVec3TransformCoord的區別在於 輸出結果一個是4維的 一個是3維的
D3DXVec3TransformCoord將結果的每個分量都 除以 w 最後得出的結果是忽略了 w的 3維向量(因爲w = 1)
D3DXVec3Transform 的結果是4維的結果 w 不一定等於 1

發佈了21 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章