2012-03-20 112 views
1

我試圖計算兩個向量之間的角度,以便我可以在3D空間中的對象方向上旋轉角色。我有兩個向量(字符&對象),loc_look和modelPos分別。爲了簡單起見,我只是試圖沿着上軸旋轉...偏航。 loc_look = D3DXVECTOR3(0,0,1),modelPos = D3DXVECTOR3(0,0,15);使用點積來計算兩個向量之間的角度

我寫了這段代碼,這似乎是正確的計算。看起來,我的問題出現了,因爲我應用於角色外觀矢量(loc_look)的旋轉超過了對象位置(modelPos)的值。這裏是我的代碼:

BOOL CEntity::TARGET() 
{ 
    if(graphics.m_model->m_enemy) 
    { 
     D3DXVECTOR3 modelPos = graphics.m_model->position; 
     D3DXVec3Normalize(&modelPos, &modelPos); 

     //D3DXVec3Normalize(&loc_look, &loc_look); 
     float dot = D3DXVec3Dot(&loc_look, &modelPos); 
     float yaw = acos(dot); 
     BOOL neg = (loc_look.x > modelPos.x) ? true : false; 
     switch (neg) 
     { 
     case false: 
      Yaw(yaw); 
      return true; 
     case true: 
      Yaw(-yaw); 
      return true; 
     }   
    } 
    else 
     return false; 
} 

我旋轉用下面的代碼字符的方向矩陣:

void CEntity::CalculateOrientationMatrix(D3DXMATRIX *orientationMatrix) 

{  

D3DXMatrixRotationAxis(&rotY, &loc_up, loc_yaw); 

D3DXVec3TransformCoord(&loc_look, &loc_look, &rotY); 

D3DXVec3TransformCoord(&loc_right, &loc_right, &rotY); 


D3DXMatrixRotationAxis(&rotX, &loc_right, loc_pitch); 

D3DXVec3TransformCoord(&loc_look, &loc_look, &rotX); 

D3DXVec3TransformCoord(&loc_up, &loc_up, &rotX); 


D3DXMatrixRotationAxis(&rotZ, &loc_look, loc_roll);  

D3DXVec3TransformCoord(&loc_up, &loc_up, &rotZ); 

D3DXVec3TransformCoord(&loc_right, &loc_right, &rotZ); 

*orientationMatrix *= rotX * rotY * rotZ; 


orientationMatrix->_41 = loc_position.x; 

orientationMatrix->_42 = loc_position.y; 

orientationMatrix->_43 = loc_position.z; 


//D3DXVec3Normalize(&loc_look, &loc_look); 

SetYawPitchRoll(0,0,0); // Reset Yaw, Pitch, & Roll Amounts 

} 

而且0.1〜注意,modelPos.x增加每次迭代所以該角色會面對對象當它沿着x軸移動時...現在,當我運行程序時,在第一次迭代中一切都很好(我還沒有旋轉角色)。在第二次迭代中,loc_look.x值大於modelPos.x值(我使用TARGET函數中的點積計算所指定的角度過多地旋轉了字符)。因此,在第二次迭代中,我的代碼將旋轉左側的字符以調整向量的x值的差異...

如何收緊測量值,以便我不會太大地旋轉角色的外觀矢量一個值?

+0

(0,0,1)和(0,0,15)是平行的,不是嗎? – 2012-03-20 22:25:49

+0

是啊...好點,但對象移動到每個迭代的權利。 look.x的值在第二次迭代時超過了modelPos.x的值,然後進行相應的調整(向左旋轉)。結果是一個抖動影響(該字符重複抖動,然後重複)。 – 2012-03-20 22:28:22

+0

我試過在「偏航」(偏航((D3DXToRadian(偏航))之前將度數轉換爲弧度;這可以防止抖動,但只是因爲角度明顯減小...外觀矢量永遠不會等於modePos矢量... – 2012-03-20 22:40:34

回答

4

點積是兩個矢量之間角度的餘弦,只有它們是單位矢量。請看到這一點:

http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation

我看到你有一些註釋掉行:

//D3DXVec3Normalize(&loc_look, &loc_look); 

但你確實需要正常化兩種載體。

想一想。如果向量全部按一個常數因子縮放,那麼點積越大,對吧?因此進入arccos的價值更大。但角度是一樣的,所以這顯然是錯誤的。

+0

歸一化後矢量的每個值的和是否等於1?我不... – 2012-03-20 23:31:54

+0

另外,關於你的例子** oc_look = D3DXVECTOR3(0,0,1),modelPos = D3DXVECTOR3(0,0,15)**是說這個角色是直視Z軸的?而且這個模型也是架空的?在這種情況下,角度爲零。如果你只關心偏航,看起來好像更好的例子就像看着<1, -1, 0>和對象在<3, 4, 0>。你的「上軸」是Z軸嗎? – Kaz 2012-03-20 23:34:39

+0

不!單位矢量的**長度**是1,而不是分量的總和。如果你將自身的單位向量的點積乘以1,也就是說x * x + y * y + z * z = 1(因此sqrt(x * x + y * y + z * z)= 1)。 – Kaz 2012-03-20 23:35:17

0

您所說的近似值對於浮點數學來說是正常的。你需要考慮一個「epsilon」值,這樣你的角色就不會在dot產品接近解決之後抽搐。

相關問題