2012-03-20 122 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产品接近解决之后抽搐。

相关问题