• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Moveable, direction a wektor normalny

42 Warsaw Coding Academy
0 głosów
186 wizyt
pytanie zadane 25 stycznia 2017 w Matematyka, fizyka, logika przez Ehlert Ekspert (215,010 p.)

Siema,

kończę interfejs poruszania się Moveable i przyszła pora na metodę zwracającą kierunek zwrotu postaci. Jest ich osiem mianowicie: 

enum class Direction{
   UP = 0,
   UP_RIGHT = 1,
   //...
};

Kierunek jest zwracany na podstawie wartości wektora ruchu. Jest to wektor normalny(koordynaty € <-1, 1>, długość wektora = 1 zawsze). Moje pytanie. Jak najlepiej to zrealizować?

  1. Zwracać kierunek na podstawie kąta tworzonego z osią Ox:
    float angle = std::asin(/*sinus z "trójkąta" jaki tworzy wektor*/)
    
  2. Zwracać kierunek na podstawie wartości koordynatów i ich przynależności do przedziałów:
    if (moveVector.x > std::sqrt(2)/4 && moveVec/*....*/)
       return Direction::LEFT;
    else //...
    

W przypadku przedziałów musiałbym korzystać z wielu operacji z Math więc to jest czas (ewentualnie #define). Dla kątów musiałbym jeszcze rozpatrywać znaki koordynatów. Jakieś sugestie? wink

 

 

1 odpowiedź

+1 głos
odpowiedź 26 stycznia 2017 przez niezalogowany
edycja 26 stycznia 2017
 
Najlepsza

Ja bym użył kątów. Zamiast asin skorzystałbym z acos i funkcji sgn do zdefiniowania kierunku w taki sposób.

#include <iostream>
#include <math.h>

using namespace std;

double sgn(double g)
{
    if(g>0) return 1;
    else if(g==0) return 0;
    return -1; // (g<0)
}

void kat(double x, double y) // przyjmuje skladowe wektora
{
    cout<<"( "<<x<<", "<<y<<" ) ----> fi = ";
    cout<<acos(x/sqrt(x*x+y*y))*sgn(y)*180/3.14;
    cout<<endl;
}

int main()
{
    kat(1,1);
    kat(1,0);
    kat(0,1);
    kat(0,0.01);
    kat(4,4);
    kat(4,6);
    kat(-4,6);
    kat(-4,-6);
    kat(4,-6);
    return 0;
}

Znaki współrzędnych wektora są już uwzględnione w funkcji sgn i teraz możesz sobie robić przedziały kątów od ile do ile.

komentarz 26 stycznia 2017 przez niezalogowany
edycja 26 stycznia 2017

Pojawiła się mała nieścisłość, bo nie zauważyłem jednej bardzo ważnej rzeczy:

#include <iostream>
#include <math.h>

using namespace std;

double sgn(double g)
{
    return (g>0)-(g<0);
}

void kat(double x, double y) // przyjmuje skladowe wektora
{
    cout<<"( "<<x<<", "<<y<<" ) ----> fi = ";
    cout<<acos(x/sqrt(x*x+y*y))*sgn(y)*180/3.141592653;
    cout<<endl;
}

int main()
{
    kat(1,1);
    kat(-1,1);
    kat(-1,-1);
    kat(1,-1);
    cout<<endl;
    kat(0,1);
    kat(0,-1);
    cout<<endl;
    kat(1,0);
    kat(-1,0); // sic! nie moga byc dwa zero! brak rozrozniania lewej z prawa! nie ma 180 stopni
    double x = -1, y = 0;
    cout<<"Wartosc: "<<x/sqrt(x*x+y*y)<<" - znajduje sie na granicy dziedziny arcus cosinusa (-1, 1) ale jest traktowane jako przez ta funkcje jak kat 0"<<endl;
    kat(-1,0.001);
    kat(-1,-0.001);
    cout<<endl;
return false;
}

Można to zobrazować tak: https://zapodaj.net/2dd8ff8c44f82.jpg.html

Widać, że wartość kąta 180 nie może być nigdy osiągnięta. To jest jedyny punkt, który wymaga doprecyzowania... Przykładowo np tak:

if(x/sqrt(x*x+y*y)!= -1) cout<<acos(x/sqrt(x*x+y*y))*sgn(y)*180/3.141592653;
else cout<<180<<endl;

 

komentarz 30 stycznia 2017 przez niezalogowany
Jeszcze inny sposób - atan2(y,x).

Podobne pytania

0 głosów
2 odpowiedzi 1,061 wizyt
pytanie zadane 6 grudnia 2016 w Matematyka, fizyka, logika przez Tom_Ja Dyskutant (7,970 p.)
0 głosów
2 odpowiedzi 708 wizyt
pytanie zadane 1 października 2016 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 985 wizyt
pytanie zadane 7 lutego 2017 w C i C++ przez Piotr Goździewski Nowicjusz (150 p.)

93,377 zapytań

142,379 odpowiedzi

322,526 komentarzy

62,724 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...