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

Moveable, direction a wektor normalny

Object Storage Arubacloud
0 głosów
140 wizyt
pytanie zadane 25 stycznia 2017 w Matematyka, fizyka, logika przez Ehlert Ekspert (212,670 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 980 wizyt
pytanie zadane 6 grudnia 2016 w Matematyka, fizyka, logika przez Tom_Ja Dyskutant (7,970 p.)
0 głosów
2 odpowiedzi 400 wizyt
pytanie zadane 1 października 2016 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 794 wizyt
pytanie zadane 7 lutego 2017 w C i C++ przez Piotr Goździewski Nowicjusz (150 p.)

92,573 zapytań

141,423 odpowiedzi

319,648 komentarzy

61,959 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...