Question

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).

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'.

SOLUTION (with the assistance of 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;
Was it helpful?

Solution

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.

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).

OTHER TIPS

if, as you say, 0 degrees == (0,0,1) you can use:

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

because rotation is always around y axis.

You will have to change the sign of sin(angle) depending on your system (left handed or right handed).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top