Вычисление угла между трехмерным объектом и точкой

У меня есть 3D-объект в DirectX11 с вектором положения и углом поворота для направления, на которое он смотрит (он вращается только вокруг оси Y).

D3DXVECTOR3 m_position;
float       m_angle;

Если бы я затем хотел повернуть объект, чтобы он столкнулся с чем-то, то мне нужно было бы найти угол между направлением, на которое он смотрит, и направлением, которому он должен быть направлен, используя точечное произведение на двух нормализованных векторах.

Проблема, с которой я сталкиваюсь, заключается в том, как я нахожу направление, в котором объект в настоящее время обращен, только с помощью его положения и угла. Что у меня сейчас есть:

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

Кто-нибудь знает, как я получаю вектор для текущего направления, на которое он смотрит, из значений, которые у меня есть, или мне нужно переписать его, чтобы я следил за вектором направления объекта?

РЕДАКТИРОВАТЬ: изменено «COS» на «ACOS».

РЕШЕНИЕ (при участии пользователя 2802841):

// 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;

0

Решение

Если вы сохраняете ориентацию как угол, вы должны принять какую-либо ориентацию по умолчанию, когда угол равен 0, выразить эту ориентацию по умолчанию как вектор (например, (1.0, 0.0, 0.0), если вы принимаете направление x + по умолчанию), затем поверните этот вектор на ваши угловые градусы (либо непосредственно с грехом / cos или с помощью матрицы вращения, созданной один из D3DXMatrixRotation * функции) и результирующий вектор будет вашим текущим направлением.

РЕДАКТИРОВАТЬ:

В ответ на ваш комментарий вы можете определить направление вращения как это. Что в вашем случае означает что-то вроде (не проверено):

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

куда normal скорее всего, это вектор (0, 1, 0) (потому что вы сказали, что ваши объекты вращаются вокруг оси Y).

1

Другие решения

если, как вы говорите, 0 градусов == (0,0,1) вы можете использовать:

normDirection = (sin (угол), 0, cos (угол))

потому что вращение всегда вокруг оси у.

Вам придется изменить знак греха (угол) в зависимости от вашей системы (левша или правша).

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector