Autor Wątek: Celownik i obracajaca sie wieza, 2d widok z gory...  (Przeczytany 4193 razy)

Offline siwy

  • Użytkownik

# Czerwiec 15, 2006, 11:08:29
Problem z celowaniem i obracaniem wiezyczki...

Chcialem zrobic cos takiego ze mam widok od gory i widze wiezyczke np. na srodku ekranu i tam gdzie wskarze kursorem tam ma sie obrocic.. Nie wiem czy dobrze sie do tego bralem bo probowalem przeliczac wspolzedne x1 i y1 oraz x2 i y2 tak by otrzymac a. ze y=ax+b.. a- to nachylenie prostej.. ale jakos mi nie wychodzi..
Chce zrobic obracajaca sie wiezyczke w kierunku gdzie wskarze celownikiem i linie strzalow po ktorej maja leciec pociski.. Nie wiem jak do konca wyprowadzic wzory tych funkcji :((

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline empitness

  • Użytkownik
    • portfolio

# Czerwiec 15, 2006, 12:16:25
Hmmm, ostatnio miałem podobny problem, ale wystąpił w trochę innej sytuacji. Mianowicie miałem sprite'a statku kosmicznego, skierowanego przodem do góry (pod kątem 90 st. do podłoża). Musiałem obliczyć podobnie jak u Ciebie kąt, o który obrócić należałoby statek, aby jego środek był skierowany bezpośrednio w stronę kursora.

Ja zrealizowałem to za pomocą funkcji trygonometrycznych, gdyż takie rozwiązanie wydawało mi się najprostsze. Zrobiłem to w ten sposób, że odległość myszki od środku statku w obu osiach potraktowałem jako boki trójkąta prostokątnego. Mając odległość w osi X i osi Y myszki od statku (wyprowadzoną z prostych zależności typu 'Xlen = MousePosX - ShipPosX; Ylen = MousePosY - ShipPosY;' i ewentualnego przemnożenia otrzymanej wartości przez -1) obliczyłem stosunek długości tychże "boków", i wysłałem je jako argument do funkcji atan, odwrotnej dla tan.

Wszystko sprowadziło się więc do obliczenia stosunku odpowiednich dla danej funkcji trygonometrycznej boków tymczasowego trójkąta, i wysłanie tego stosunku do odpowiedniej funkcji odwrotnej. Na koniec należało oczywiście zamenić otrzymaną wartość w radianach na stopnie, ze wzoru:
deg = rad * (180 / PI)

Zdaję sobie sprawę, że moje zawiłe tłumaczenie mogło Ci bardziej zamieszać, niż pomóc, więc zamieszczam dodatkowo screena z realizacji tych obliczeń i czekam na ewentualne pytania, na które w miarę możliwości postaram się odpowiedzieć :)


Offline siwy

  • Użytkownik

# Czerwiec 15, 2006, 13:01:40
empitness dzieki za odpowiedz... zeczywiscie dobry pomysl :)).. ja probowalem z funkcja liniowom ale glupoty wychodzily :D:D... a z ta trygonometria to ladnie latwo i co najwazniejsze dobrze :D a szybko ?... A co mnie tam to tylko gra 2d :P

Offline mi-ku

  • Użytkownik
    • miku DevBlog

# Czerwiec 15, 2006, 13:18:09
ja myślę że sposób empitnessa jest bardzo szybki, na pewno szybszy niż z wykorzystaniem sinusa lub cosinusa w których trzeba by było obliczać pierwiastek kwadratowy i jeszcze kombinować z ćwiartkami. Tylko po co przeliczać kąt z wartości w radianach?

Offline empitness

  • Użytkownik
    • portfolio

# Czerwiec 15, 2006, 13:51:43
To zależy do czego się go potrzebuje... Po prostu ja potrzebowałem go jako argument dla funkcji odpowiedzialnej za obrazania surface'ów z biblioteki SDL_gfx, która to przyjmuje go właśnie w stopniach, a nie radianach., stąd to przeliczanie. Ale faktycznie, nie zawsze jest to konieczne, za bardzo się zasugerowałem moim konkretnym przypadkiem. :)

Offline siwy

  • Użytkownik

# Czerwiec 15, 2006, 16:15:28
Zrobilem to w koncu tak !

double tgAB=(nX/nY);
double alfa=atan(tgAB);
float angle=-alfa*(180/PI*100000);

if(nY<0){angle-=180;}

            glPushMatrix ();
            glRotatef (angle, 0.0f, 0.0f, 1.0f);
            glBegin (GL_TRIANGLES);
            glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (0.0f, 0.5f);
            glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.5f, 0.0f);
            glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (-0.5f, 0.0f);
            glEnd ();
            glPopMatrix ();

A tak odczytuje polozenie myszki :)

    case WM_MOUSEMOVE:
{
float mX=GET_X_LPARAM(lParam);
        float mY=GET_Y_LPARAM(lParam);
        nX=(mX/(width/2)-1);
        nY=-(mY/(height/2)-1);

        return 0;
}

A i jeszce zmienne globalne :

int width=500;             /szerokosc okna
int height=500;            /wysokosc okna

const double PI=314159;                   /liczba PI

double nX;                   /zmienne do myszki
double nY;

Offline Uszz

  • Użytkownik

# Czerwiec 15, 2006, 17:58:20
nie za duże to Twoje PI ?  ::) może zmień nazwe stałej na PRAWIE_JAK_PI ;D

Offline siwy

  • Użytkownik

# Czerwiec 16, 2006, 14:27:39
Prawie robi wielka rozniece :D:D:D:D

krychacoder

  • Gość
# Czerwiec 16, 2006, 21:48:04
Naprawdę wielką :D == 3,14159 * 10^5

//EDIT
To ludzka rzecz zrobić buga  ;)
« Ostatnia zmiana: Czerwiec 17, 2006, 11:41:23 wysłana przez krychacoder »

Offline siwy

  • Użytkownik

# Czerwiec 27, 2006, 19:42:56
jak pisze samo pi a nie pomnozona razy 10^5 to mi wychodza wyniki 0000.xxx a to mnie nie satysfakcjonuje :D

Offline TeMPOraL

  • Użytkownik
    • devBlog

# Czerwiec 27, 2006, 22:10:23
float angle=-alfa*(180/PI*100000);Może dlatego? ;) Nigdzie indziej w podanym kodzie PI nie jest użyte.
//hmm... ale przy "PI" rzędu 10^5 to wynik dzielenia powinien wyjść jeszcze mniejszy.

Dla własnego dobra trzymaj się jednak pewnych przyjętych umów, i jak zmienna nazywa się PI, to niech wynosi ok. 3.14159265358, a jak ma wynosić 314159, to niech się nazywa PI_TIMES_HUNDRED_THOUSAND albo po prostu pisz to 10000 w kodzie :)

A, i ten kod:
nX=(mX/(width/2)-1);
nY=-(mY/(height/2)-1);
wyprodukuje dzielenie przez zero, jeśli ktoś bardzo zmniejszy okno (zakładając, że WM_SIZE ma na te zmienne wpływ).

Pozdrawiam,
TeMPOraL.

Offline fofoo

  • Użytkownik
    • WebLog

# Czerwiec 28, 2006, 11:46:58
Może niewiele to wniesie do dyskusji, ale ja bym to "PI" nazwał "myPI". Zauwazyłem że taka bzdura jak dodanie do nazwy "my" może w przyszlości zaprocentować. Teraz jak widze, że coś ma przedrostek "my" to odrazu wiem o co chodzi ;)

Offline siwy

  • Użytkownik

# Czerwiec 28, 2006, 13:06:09
Może niewiele to wniesie do dyskusji, ale ja bym to "PI" nazwał "myPI". Zauwazyłem że taka bzdura jak dodanie do nazwy "my" może w przyszlości zaprocentować. Teraz jak widze, że coś ma przedrostek "my" to odrazu wiem o co chodzi ;)

sluszna uwaga dzieki fofoo..

Offline fofoo

  • Użytkownik
    • WebLog

# Czerwiec 28, 2006, 15:28:22
Jeszcze jedno 'ale' co do wytłumaczenia empitnessa. Atan przyjmuje wartosci od -pi/2 do pi/2 wiec zakres ruchu wynosi tam pi  czyli 180 stopni. Nie trzeba przypadkiem  tam sprawdzac gdzies czy np x < 0 (albo y <0)  i zmieniac wtedy zwrot obiektu o 180 stopni? Może czegos tu nie rozumiem? Jak tak to bede wdzieczny za sprostowanie.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Czerwiec 28, 2006, 15:33:00
Widzę, że już chyba wszyscy zapomnieli o takiej pożytecznej funkcji, jaką jest atan2(y,x). Podajesz współrzędne, a on Ci zwraca kąt wektora i nie trzeba bawić się samemu w żadne rozpatrywanie różnych przypadków. :)