使用点积来计算两个向量之间的角度
我试图计算两个向量之间的角度,以便我可以在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值的差异...
如何收紧测量值,以便我不会太大地旋转角色的外观矢量一个值?
点积是两个矢量之间角度的余弦,只有它们是单位矢量。请看到这一点:
http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation
我看到你有一些注释掉行:
//D3DXVec3Normalize(&loc_look, &loc_look);
但你确实需要正常化两种载体。
想一想。如果向量全部按一个常数因子缩放,那么点积越大,对吧?因此进入arccos
的价值更大。但角度是一样的,所以这显然是错误的。
归一化后矢量的每个值的和是否等于1?我不... – 2012-03-20 23:31:54
另外,关于你的例子** oc_look = D3DXVECTOR3(0,0,1),modelPos = D3DXVECTOR3(0,0,15)**是说这个角色是直视Z轴的?而且这个模型也是架空的?在这种情况下,角度为零。如果你只关心偏航,看起来好像更好的例子就像看着和对象在。你的“上轴”是Z轴吗? – Kaz 2012-03-20 23:34:39
不!单位矢量的**长度**是1,而不是分量的总和。如果你将自身的单位向量的点积乘以1,也就是说x * x + y * y + z * z = 1(因此sqrt(x * x + y * y + z * z)= 1)。 – Kaz 2012-03-20 23:35:17
您所说的近似值对于浮点数学来说是正常的。你需要考虑一个“epsilon”值,这样你的角色就不会在dot产品接近解决之后抽搐。
(0,0,1)和(0,0,15)是平行的,不是吗? – 2012-03-20 22:25:49
是啊...好点,但对象移动到每个迭代的权利。 look.x的值在第二次迭代时超过了modelPos.x的值,然后进行相应的调整(向左旋转)。结果是一个抖动影响(该字符重复抖动,然后重复)。 – 2012-03-20 22:28:22
我试过在“偏航”(偏航((D3DXToRadian(偏航))之前将度数转换为弧度;这可以防止抖动,但只是因为角度明显减小...外观矢量永远不会等于modePos矢量... – 2012-03-20 22:40:34