Autor Wątek: Jak obliczyć miarę kąta z jego sinusa  (Przeczytany 6590 razy)

Offline Moriquendi

  • Użytkownik

# Styczeń 27, 2011, 22:50:00
Hej,

Próbuję obliczyć kąt w pewnym trójkącie, żebym mógł obrócić o ten kąt jakiś obiekt w grze.
Mam podane wszystkie współrzędne punktów trójkąta.

Wpadłem na pomysł żeby obliczyć to z dwóch wzorów na pole trójkąta.
Najpierw z wektorów:
P = 1/2*(u_1*v_2 - u_2*v_1);

Z drugiego wzoru (P=a*b*sin alpha) wyliczam sinusa kąta

Sin alpha = P/ (a*b)

Mam więc sinusa....Teraz tylko zastanawiam się jak z tego kąta wydobyć kąt :P
Jest moża jakaś biblioteka, która to za mnie zrobi?

Offline Mr. Spam

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

Offline Liosan

  • Redaktor

# Styczeń 27, 2011, 22:52:15
arc sin - arcus sinus, funkcja kołowa.

Liosan

Offline Witek9002

  • Użytkownik

# Styczeń 27, 2011, 23:24:49
Pierwsza uwaga:
Cytuj
Z drugiego wzoru (P=a*b*sin alpha) wyliczam sinusa kąta
Jeśli a i b to boki trójkąta, a alpha to kąt między nimi, to masz zły wzór. Musisz podzielić to jeszcze przez 2:
P = 0.5 a * b * sin(alpha)
Cytuj
Jest moża jakaś biblioteka, która to za mnie zrobi?
Bibliteka standardowa ma tą funkcję (arcsin, jak wspomniał Liosan).

Btw. Ten kąt można jeszcze inaczej obliczyć. Załóżmy, że chcesz policzyć kąt przy wierzchołku A:
1. Liczysz wektor AB = B - A
2. Liczysz wektor AC = C - A
3. Normalizujesz je.
4. szukany kąt = arccos(AC dot AB), gdzie dot, to iloczyn skalarny

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 28, 2011, 01:04:35
Cytuj
Próbuję obliczyć kąt w pewnym trójkącie, żebym mógł obrócić o ten kąt jakiś obiekt w grze.
Mam podane wszystkie współrzędne punktów trójkąta.
Nie wiem, po co chcesz liczyć ten kąt, jak można prościej (i szybciej) policzyć z tego macierz obrotu.

Załóżmy, że chodzi o kąt przy wierzchołku A. Algorytm jest prosty:
- wyznaczasz współrzędne wektora AB,
- normalizujesz te współrzędne,
- wyznaczasz wektor prostopadły (zamiana współrzędnych ze sobą i zmiana znaku jednej z nich),
- składasz te dwa wektory w macierz 2x2 - skoro są one znormalizowane i prostopadłe, wychodzi z tego macierz ortonormalna, a więc macierz obrotu o kąt kierunku wektora AB,
- w ten sam sposób wyznaczasz macierz obrotu dla wektora AC,
- wyznaczasz macierz odwrotną do macierzy wektora AC (na odwrotność macierzy 2x2 jest banalny wzór, tym bardziej że jest to macierz ortonormalna, więc jej wyznacznik wynosi 1),
- mnożysz macierz AB przez odwrotność macierzy AC

W wyniku dostajesz macierz obrotu o różnicę kątów kierunku wektorów AB i AC, czyli masz wszystko co potrzebne do obracania obiektów.


A tak swoją drogą, to skoro masz sinusa, to po co Ci kąty? Ze wzoru na zależność sin i cos wyznaczasz cosinusa i masz już wszystko, by obracać obiekty (do samego obrotu nie potrzebujemy kątów, ale właśnie sin i cos). Jedyny problem w tym, że z samego sinusa nie powiesz, czy kąt jest ostry czy rozwarty.

Offline Moriquendi

  • Użytkownik

# Styczeń 28, 2011, 23:19:35
Próbowałem z tym polem, ale coś nie wychodzi :/

   //wektory
   int x_1, y_1;
   double dlugosc_1;
   
   int x_2, y_2;
   double dlugosc_2;
   
   x_1 = Point_1.x - pos_x;   //Współrzędne wektora AB
   y_1 = Point_1.y - pos_y;
   
   dlugosc_1 = sqrt(pow(x_1,2) + pow(y_1,2));  //długość wektora AB
   
   x_2 = Point_2.x - pos_x;  //Wspolrzedne wektora AC
   y_2 = Point_2.y - pos_y;
   dlugosc_2 = sqrt(pow(x_2,2) + pow(y_2,2)); //dlugosc AC
   
   //Obliczamy pole trojkata
   float pole;
   if(x_1 * y_2 >= x_2 * y_1)
   pole = 0.5*(x_1 * y_2 - x_2 * y_1);
   else
   pole = 0.5*(x_2 * y_1 - x_1 * y_2);
   

   double sinus = pole/(0.5*dlugosc_1*dlugosc_2);
   
   double kat = asin(sinus);
   
   //Obraca korbke (zamienia radiany na stopnie)
   obiekt.rotation += 180*kat/3.14;

Co prawda obiekt się obraca, ale dosyć dziwnie....
Na początku obraca się za wolno (powinien obrócić się o 90, a obraza się o 45), potem całkiem dziwnie już to wygląda....

Nie wiem, może to za mała dokładność? Różnica we współrzędnych między punktami B i C to jakiś 1-3 px...


@Krzysiek, być może twój sposób jest lepszy....ale macierze...inne pojęcia o których nic nie wiem... Potrzebne mi jest coś na poziom 2 liceum :-)

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Styczeń 29, 2011, 19:48:11
Cytuj
Potrzebne mi jest coś na poziom 2 liceum :-)
To odstaw całe programowanie - to też nie jest poziom 2 klasy typowego liceum. ;)

Offline Armageddon

  • Użytkownik

# Styczeń 29, 2011, 21:16:46
To odstaw całe programowanie - to też nie jest poziom 2 klasy typowego liceum. ;)
Trochę masz racji, ale też nie przesadzajmy. Sam jestem w 3 klasie liceum na matematyce i informatyce rozszerzonej to też bym tego nie zrobił. To wcale nie jest proste zadanie nawet dla dobrego ucznia z liceum.
Zauważyłem taką modę wśród lepiej wykształconych(tzn. po studiach albo w trakcie), że Ci skoro oni wiedzą to inni też muszą(nie ważne ile lat mają, do jakiej szkoły uczęszczają itd.). Jakby nie patrzeć, żeby programować nie potrzeba potrafić wspaniale całej analizy matematycznej, nie potrzeba mieć zgłębionej stereometrii w każdym calu. Szczególnie, że lekcje w szkole z matematyki nie wprowadzają specjalnie w tym kierunku. Dobrze mieć jakieś pojęcie, ale nie każdy jest asem matematycznym i geniuszem a też może sobie po programować.

Wiem, teraz pojawią się pewnie głosy typu: "Jak tego nie potrafisz to po co się za to zabierasz", "Najpierw się naucz matematyki a potem zacznij programować" itp.
Ale zrozumcie, naprawdę dla niektórych opanować taką dużą ilość materiału to naprawdę problem. Zakuwanie matematyki nie należy do najciekawszych zajęć, ale jak się programuje grafikę i odrazu widzi efekty to od razu robi się przyjemnie.

Przepraszam za możliwy nieład myślowy i składniowy, ale pisałem to na kilka razy.

Pozdrawiam ;)

Offline Kos

  • Użytkownik
    • kos.gd

# Styczeń 29, 2011, 21:38:24
@up - nie zgadzam się. Widziałem u ludzi nieraz podejście "chcę umieć X, ale nie chcę uczyć się X" i zawsze zgrzytałem zębami na sam widok.

Jeśli ktoś chce programować zagadnienia geometryczne i nie zna geometrii, to dlaczego się jej po prostu nie nauczyć, by poczuć się w niej swobodnie? Po kolei, po kolei!

Klasa w liceum nie ma znaczenia... skoro się chce programować (czyli robić coś, czego w liceach zwykle nie ma, albo jest prowizoryczne), to trzeba być gotowym, że mogą być potrzebne po drodze jeszcze inne umiejętności, których w liceum też nie ma.

Offline Adam7

  • Użytkownik
    • warsztat.gd

# Styczeń 29, 2011, 21:44:40
Zakuwanie matematyki nie należy do najciekawszych zajęć,
Co, zakuwanie matematyki (bez sensu) ją trzeba zrozumieć a nie zakuwać.

Offline Armageddon

  • Użytkownik

# Styczeń 29, 2011, 23:10:52
@up - nie zgadzam się. Widziałem u ludzi nieraz podejście "chcę umieć X, ale nie chcę uczyć się X" i zawsze zgrzytałem zębami na sam widok.

True.

Jeśli ktoś chce programować zagadnienia geometryczne i nie zna geometrii, to dlaczego się jej po prostu nie nauczyć, by poczuć się w niej swobodnie? Po kolei, po kolei!

Mimo wszystko, fajniej się uczy jak się widzi od razu efekty w programie. Z czystą geometrią trochę ciężej(yupi! potrafię znaleźć znaleźć kąt trójkąta x wiedząc, że jest trójkątem). A jak się zobaczy swojego pierwszego mesh'a to już coś ;)

Cytuj
Co, zakuwanie matematyki (bez sensu) ją trzeba zrozumieć a nie zakuwać.

No tak, ale zrozumienie matematyki wymaga zrobienia X zadań(te X zależy od rozwiązującego), co jak wcześniej wspomniałem, nie zawsze jest super ciekawe ;)

Offline Xirdus

  • Redaktor
    • @Xirdus

# Styczeń 29, 2011, 23:18:31
No tak, ale zrozumienie matematyki wymaga zrobienia X zadań(te X zależy od rozwiązującego)
Jak ze wszystkim. Ale u niektórych owe X jest bliskie lub równe zeru.

Offline Armageddon

  • Użytkownik

# Styczeń 29, 2011, 23:56:15
Jak ze wszystkim. Ale u niektórych owe X jest bliskie lub równe zeru.
Hehe, szkoda, że tych niektórych jest tak mało. Inaczej by nie było takiej paniki o obowiązkową maturę z matematyki :)

Offline Xirdus

  • Redaktor
    • @Xirdus

# Styczeń 30, 2011, 00:39:12
Inaczej by nie było takiej paniki o obowiązkową maturę z matematyki :)
Pamiętaj, że tutaj jest forum programistów, a nie ludzi z ogólniaka o profilu ogólnym ;)

Offline Moriquendi

  • Użytkownik

# Styczeń 30, 2011, 12:22:20
Cytuj
1. Liczysz wektor AB = B - A
2. Liczysz wektor AC = C - A
3. Normalizujesz je.

Co znaczy 'normalizować'?

Edit:
Nie wiem czy dobrze w wikipedi wyczytałem.
Chodzi o to, żeby wydłużyć/skrócić wektor żeby miał długość  =1?
« Ostatnia zmiana: Styczeń 30, 2011, 12:24:16 wysłana przez Moriquendi »

Offline Adam27

  • Użytkownik

# Styczeń 30, 2011, 12:28:10
Co znaczy 'normalizować'?

Edit:
Nie wiem czy dobrze w wikipedi wyczytałem.
Chodzi o to, żeby wydłużyć/skrócić wektor żeby miał długość  =1?

Tak, to właśnie jest normalizacja.