Вычисление угла между двумя векторами с использованием Dot Product - PullRequest
1 голос
/ 21 марта 2012

Я пытаюсь вычислить угол между двумя векторами, чтобы я мог повернуть символ в направлении объекта в трехмерном пространстве.У меня есть два вектора (персонаж и объект), 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 с каждой итерации, поэтому символстолкнется с объектом, когда он движется вдоль оси х ... Теперь, когда я запускаю программу, на первой итерации все в порядке (я еще не повернул символ).На второй итерации значение loc_look.x больше, чем значение modelPos.x (я слишком сильно повернул символ, используя угол, указанный в вычислениях произведения точек в функции TARGET).Поэтому на второй итерации мой код будет вращать символ влево, чтобы скорректировать разницу в значениях x векторов ...

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

Ответы [ 2 ]

4 голосов
/ 21 марта 2012

Точечное произведение - это косинус угла между двумя векторами, только если они являются единичными векторами.Пожалуйста, посмотрите это:

http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation

Я вижу, у вас есть закомментированная строка:

 //D3DXVec3Normalize(&loc_look, &loc_look); 

Но вам нужно нормализовать оба вектора.

Подумай об этом.Если все векторы масштабируются постоянным фактором, скалярное произведение становится больше, верно?И поэтому значение, входящее в arccos, больше.Но угол такой же, так что это явно неправильно.

0 голосов
/ 27 мая 2013

Аппроксимация, о которой вы говорите, является нормальной для математики с плавающей запятой. Вам необходимо ввести значение «эпсилон», чтобы ваш персонаж не дернулся после того, как скалярное произведение близко к решению.

...