2017-02-16 10 views
-1

Я пытаюсь создать класс vector2D для своей игры, но я думаю, что получаю математику неправильно.C++ - Математика Vector2D не дает мне правильных результатов

Когда я создаю новый объект vector2d, он автоматически устанавливает свои x и y в 1, 1 в конструкторе.

Vector2D vec; 

    std::cout << " x: " << vec.GetX() << " y: " << vec.GetY() << " angle rad: " << vec.GetAngleRad() << " magnitude: " << vec.GetMagnitude() << std::endl; 



    system("pause"); 
    return 0; 

и выводит:
х: 1
у: 1
угол в радиан: 0,785398
Величина: 1,41421
(который является именно то, что я ожидал)

но проблема в том, что когда я разбираю что-либо с функцией setAngle, я получаю некоторые проводные результаты.

Например:

Vector2D vec; 

vec.SetAngleRad(3); 

std::cout << " x: " << vec.GetX() << " y: " << vec.GetY() << " angle rad: " << vec.GetAngleRad() << " magnitude: " << vec.GetMagnitude() << std::endl; 



system("pause"); 
return 0; 

Я бы ожидать, что это угол выхода в рад: 3
, но вместо этого я получаю угол в рад: 0.141593.

Это класс vector2D (я пытался комментировать свой код, чтобы вы могли видеть мои, что я думал, когда я написал):

#include "Vector2D.h" 



Vector2D::Vector2D(): 
    _x(1.0f), 
    _y(1.0f) 
{ 

} 


Vector2D::~Vector2D() 
{ 

} 

void Vector2D::SetX(float x) 
{ 
    _x = x; 
} 

float Vector2D::GetX() 
{ 
    return _x; 
} 


void Vector2D::SetY(float y) 
{ 
    _y = y; 
} 

float Vector2D::GetY() 
{ 
    return _y; 
} 


void Vector2D::SetAngleRad(float angle) 
{ 
    float hypotenuse = GetMagnitude(); 

    SetX(cos(angle) * hypotenuse); // cos of angle = x/hypotenuse 
            // so x = cos of angle * hypotenuse 

    SetY(sin(angle) * hypotenuse); //sin of angle = y/hypotenuse 
            // so y = sin of angle * hypotenuse 
} 

float Vector2D::GetAngleRad() 
{ 
    float hypotenuse = GetMagnitude(); 
    return asin(_y/hypotenuse); // if sin of angle A = y/hypotenuse 
            // then asin of y/hypotenuse = angle 
} 


void Vector2D::SetMagnitude(float magnitude) 
{ 
    float angle = GetAngleRad(); 
    float hypotenuse = GetMagnitude(); 

    SetX((cos(angle) * hypotenuse) * magnitude); // cos of angle = x/hypotenuse 
                // so cos of angle * hypotenuse = x 
                // multiplied by the new magnitude 


    SetY((sin(angle) * hypotenuse) * magnitude); //sin of angle = y/hypotenuse 
                // so sin of angle * hypotenuse = y 
                // multipied by the new magnitude 
} 

float Vector2D::GetMagnitude() 
{ 
    return sqrt((_x * _x) + (_y * _y)); // a^2 + b^2 = c^2 
              //so c = sqrt(a^2 + b^2) 
} 

Так что я действительно был бы признателен, если кто-то может объясните мне, что я делаю неправильно здесь :)

+0

Похоже, проблемы математики, не проблема программирования. Заметим, что sin (3) == sin (0.141593) и поэтому asin (sin (3)) == 0.141593 (с точностью до ошибок округления). – immibis

+0

getangle должен быть реализован с помощью atan2. В противном случае вы можете пойти не так, как надо (есть 2 квадранта, где asin (y/mag) - то же самое). –

+0

Будьте осторожны с предыдущим подчеркиванием в C++. [Часто это означает что-то.] (Http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier) ​​ – user4581301

ответ

3

чтобы получить угол в полном диапазоне круга, вы должны использовать как у и х компонентов с atan2 функции

return atan2(_y, _x); 

Примечание RESU Диапазон -Pi..Pi л и правильный отрицательный один на +2*Pi, если вам нужно диапазон 0..2*Pi

Другой вопрос: :SetMagnitude метод действительно умножает величину тока на magnitude множитель, в то время как имя предполагает, что метод должен установить его (так длина вектора 2 после применения SetMagnitude(2) будет иметь величину 4)).

Так было бы лучше, чтобы удалить *hypotenuse умножения (или изменить название метода)

+0

Отредактировано, предположительно с тем, что вы намеревались. – acraig5075

+0

@ acraig5075 Конечно :), спасибо – MBo

Смежные вопросы