简体   繁体   English

计算3D对象和点之间的角度

[英]Calculating the Angle Between a 3D Object and a Point

I have a 3D object in DirectX11 with a position vector and a rotation angle for the direction it's facing (it only rotates around the Y axis). 我在DirectX11中有一个3D对象,它有一个位置矢量和一个面向它的方向的旋转角度(它只围绕Y轴旋转)。

D3DXVECTOR3 m_position;
float       m_angle;

If I then wanted to rotate the object to face something then I'd need to find the angle between the direction it's facing and the direction it needs to face using the dot product on the two normalised vectors. 如果我然后想要旋转对象以面对某些东西,那么我需要找到它面对的方向与它需要面对的方向之间的角度,使用两个标准化向量上的点积。

The thing I'm having a problem with is how I find the direction the object is currently facing with just its position and the angle. 我遇到问题的是我如何找到物体当前面向的方向,只有它的位置和角度。 What I currently have is: 我现在拥有的是:

D3DXVECTOR3 normDirection, normTarget;
D3DXVec3Normalize( &normDirection, ????);
D3DXVec3Normalize( &normTarget, &(m_position-target));

// I store the values in degrees because I prefer it
float angleToRotate = D3DXToDegree( acos( D3DXVec3Dot( &normDirection, &normTarget)));

Does anyone know how I get the vector for the current direction it's facing from the values I have, or do I need to re-write it so I keep track of the object's direction vector? 有没有人知道我如何得到它所面向的当前方向的矢量,或者我是否需要重新编写它以便跟踪对象的方向向量?

EDIT: Changed 'cos' to 'acos'. 编辑:将'cos'更改为'acos'。

SOLUTION (with the assistance of user2802841): 解决方案(在user2802841的帮助下):

// assuming these are member variables
D3DXVECTOR3 m_position;
D3DXVECTOR3 m_rotation;
D3DXVECTOR3 m_direction;

// and these are local variables
D3DXVECTOR3 target;  // passed in as a parameter
D3DXVECTOR3 targetNorm;
D3DXVECTOR3 upVector;
float angleToRotate;

// find the amount to rotate by
D3DXVec3Normalize( &targetNorm, &(target-m_position));
angleToRotate = D3DXToDegree( acos( D3DXVec3Dot( &targetNorm, &m_direction)));

// calculate the up vector between the two vectors
D3DXVec3Cross( &upVector, &m_direction, &targetNorm);

// switch the angle to negative if the up vector is going down
if( upVector.y < 0)
    angleToRotate *= -1;

// add the rotation to the object's overall rotation
m_rotation.y += angleToRotate;

If you store the orientation as an angle then you must assume some kind of default orientation when angle is 0, express that default orientation as a vector (like (1.0, 0.0, 0.0) if you assume x+ direction to be the default), then rotate that vector by your angle degrees (either directly with sin/cos or by using rotation matrix created by one of the D3DXMatrixRotation* functions) and the resulting vector will be your current direction. 如果将方向存储为角度,则必须在角度为0时采用某种默认方向,将默认方向表示为向量(如果假定x +方向为默认值,则为(1.0,0.0,0.0)),然后通过角度( 直接使用sin / cos或使用由D3DXMatrixRotation *函数之一创建的旋转矩阵)旋转该向量,结果向量将是您当前的方向。

EDIT: 编辑:

In answer to your comment, you can determine rotation direction like this . 在回答您的评论时,您可以像这样确定旋转方向。 Which in your case translates to something like (untested): 在您的情况下,哪些转换为(未经测试):

D3DXVECTOR3 cross;
D3DXVec3Cross(&cross, &normDirection, &normTarget);
float dot;
D3DXVec3Dot(&dot, &cross, &normal);
if (dot < 0) {
    // angle is negative
} else {
    // angle is positive
}

Where normal is most likely a (0, 1, 0) vector (because you said your objects rotate around Y axis). normal很可能是(0,1,0)向量(因为你说你的对象围绕Y轴旋转)。

if, as you say, 0 degrees == (0,0,1) you can use: 如果,如你所说,0度==(0,0,1)你可以使用:

normDirection = ( sin( angle ), 0, cos( angle ) ) normDirection =(sin(角度),0,cos(角度))

because rotation is always around y axis. 因为旋转始终围绕y轴。

You will have to change the sign of sin(angle) depending on your system (left handed or right handed). 你必须根据你的系统(左手或右手)改变罪的标志(角度)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM