我正在尝试计算两个矢量之间的角度,以便我可以在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
}
另外需要注意的是,modelPos.x每次迭代增加0.1,因此角色在沿x轴移动时将面向对象...... 现在,当我运行程序时,在第一次迭代中一切都很好(我还没有旋转角色)。在第二次迭代中,loc_look.x值大于modelPos.x值(我使用TARGET函数中的点积计算指定的角度旋转了太多字符)。因此,在第二次迭代中,我的代码将旋转左边的字符以调整矢量的x值...
的差异如何收紧测量值,以免我的角色外观向量旋转太大?
答案 0 :(得分:4)
点积是两个向量之间角度的余弦,只有它们是单位向量。请看这个:
http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation
我看到你有一些注释掉的行:
//D3DXVec3Normalize(&loc_look, &loc_look);
但你确实需要对两个载体进行标准化。
想一想。如果向量都按常数因子缩放,则点积变大,对吧?因此进入arccos
的价值更大。但角度是一样的,所以这显然是错误的。
答案 1 :(得分:0)
您所谈论的近似值对于浮点数学来说是正常的。你需要考虑一个“epsilon”值,这样你的角色在点积接近解决后不会抽搐。