[Rozwiązany] Problem natury matematycznej (trygonometria)

0

Hmm, potrzebuję pomocy z problemem poniżej, trygonometria to coś czego nigdy nie udało mi się ogarnąć a teraz potrzebuję tego, co poniżej.

  1. Mam punkty A, B oraz C, do każdej współrzędne x,y. Skąd wziąć kąt pomiędzy nimi?

  2. Mam element O, który posiada coś takiego jak obrót (0-360 stopni), oraz punkt A. Mam współrzędne i obrót elementu, oraz współrzędne punktu A. Jak teraz zdobyć kąt w jakim znajduje się punkt A w stosunku do elementu O? To coś jestem w sumie w stanie rozwiązać znając odpowiedź na 1. Po prostu "dorobię" sobie punkt B wysunięty o 10 jednostek do przodu od elementu - i wtedy znowu mam tak jakby punkty ABC między którymi trzeba wyznaczyć kąt.

A tu funkcja którą wyznaczam współrzędne wysunięte na X, Y od elementu uwzględniając jego rotację (może komuś się przyda do czegoś):

function getElementPositionFromVector(element, x, y)
	xx, yy = getElementPosition(element)
	rot = getElementRotation(element)
	lx = xx + math.sin (math.rad(-rot)) * x
	ly = yy + math.cos (math.rad(-rot)) * y
	return lx,ly
end

Uwaga: getElementRotation zwraca obrót odwrotnie do wskazówek zegara, czyli element odwrócony na godzinę dziewiątą ma 90 stopni obrotu, nie 270.

Z góry dzięki za pomoc

0

sin(kąt) = x, arcsin(x) = kąt

0

Kąt ABC możesz potraktować jak dwa wektory: BA i BC.
Przeczytaj http://pl.wikipedia.org/wiki/Iloczyn_skalarny (szczególnie Interpretacja geometryczna)
i użyj tych wzorów:
user image
user image

0

@[losowa nazwa] - zupełnie nie wiem o co chodzi. Wygląda jakby mi tylko kąt był potrzebny..

@__krzysiek85 - to nie na mój mój antymatematyczny mózg. Przeglądnę to jutro, ale chyba nic nie wywnioskuję ;|

0

ad 1: oblicz z pitagorasa długości boków trójkąta powstałego z połączenia ABC. Wzorem Herona obliczysz jego pole. Potem podłóż je do wzoru na pole trójkąta uwzględniającym sinus kąta, który Cie interesuje (1/2 * a * b * sin(kątaMiędzyAB)) z wyprowadzonym tym sinusem. Wartość sinusa podłóż pod arcsinusa, będziesz miał kąt.

0

@Billy pitagorasa? A skąd wiesz że to jest trójkąt prostokątny? ;]
Długości boków to akurat można policzyć od razu bo to są przecież długości wektorów AB, BC, CA ;]
Reszta rozwiązania wygląda ok.

@down mea culpa, oczywiście że tak :) Za duży skrót myślowy zrobiłeś i odniosłem wrażenie że pitagorasa chcesz do trójkąta ABC wepchnać ;)

0

... długość wektora AB, znając współrzędne A i B, liczy się jak najbardziej z pitagorasa. Gdybym zakładał, że to trójkąt prostokątny, nie sugerowałbym obliczania pola dość 'ogólnym' wzorem herona, tylko jakimś innym 'szczególnym'.

0

Użycie iloczynu skalarnego jest bardzo proste (uczą tego w liceum).

np.

A = (1,2)
B = (3,4)
C = (8,10)

wektor BA = [1-3, 2-4] = [-2,-2]
wektor BC = [8-3, 10-4]=[5,6]

długość BA = |BA| = pierwiastek((-2)2 + (-2)2)=pierwiastek(8)
długość BC = |BC| = pierwiastek((5)2 + (6)2)=pierwiastek(61)
iloczyn skalarny = BA * BC = -2 * 5 + (-2) * 6 = -22
szukany kąt = arccos(BA * BC/(|BA| * |BC|))=arccos(-22/(pierwiastek(8)*pierwiastek(61))
=arccos(-22/(pierwiastek(488)) - czyli około 3,05 radianów (około 174 stopni)

0

@Billy:
brzmi lepiej :)

AB = odl(ax,ay, bx, by)
BC = odl(bx, by, cx, cy)
CA = odl(cx, cy, ax, ay)
pole = math.sqrt(((AB+BC+CA)(AB+BC-CA)(AB-BC+CA)(-AB+BC+CA))/4)

i teraz
1/2abszukany sinus = pole
czyli
pole/szukany_sinus = 1/2
ab
czyli
1/szukany sinus = 1/2
abpole
czyli
szukany sinus = 1/ (1/2ab*pole)

tak?
bo mam wrażenie że coś pomieszałem ?

arcsinus to juz nie problem

0
dzek69 napisał(a)

(...)
pole = math.sqrt(((AB+BC+CA)(AB+BC-CA)(AB-BC+CA)(-AB+BC+CA))/4)
// p = (AB+BC+CA)/2 ; pole = math.sqrt(p(p-AB)(p-BC)(p-CA)) ; napisałem tak, bo nie chce mi się sprawdzać, czy Twoje przepisanie się z tym pokrywa

(...)
pole/szukany_sinus = 1/2ab
czyli
1/szukany sinus = 1/2abpole //... a nie (ab)/(2pole) ?
czyli
szukany sinus = 1/ (1/2
abpole) //... korygując: szukany sinus = (2pole)/(ab)

Jednak, sposób opisany przez krzyśka wydaje się 'lepszy' :], spróbuj zrobić to tak jak napisał. Ja opisałem inny sposób, bo przyznam, nie chciało mi się szukać wzoru po wektorach (a z pamięci wypadł :] ).

0

-- na dole edit!

Wynik otrzymany dzięki Billy:
62.79647064209
Wynik otrzymany dzięki __krzysiek85:
61555.984375

Nie wiem czemu drugi wyszedł taki..

metoda1 - 62.8 - rad 1.1
metoda2 - 61555.98 - rad 1074.79

Co gorsza, kąt 62,8 stopnia nie bardzo mi tu pasuje :/

Oto wynik debugowania:

AX: -1906.9853515625
AY: -1333.03125

BX: -1914.2060546875
BY: -1360.1455078125

CX: -1936.31640625
CY: -1356.1494140625
metoda1 | dlugosc AB:28.05924987793
metoda1 | dlugosc BC:22.468564987183
metoda1 | dlugosc CA:37.346488952637
metoda1 | pole:628.36041259766
metoda1 | wartosc do zarcsinusowania:1.9933677911758
metoda1 | kat w radianach po arcsin:1.0964462868521
metoda1 | kat w stopniach:62.79647064209

metoda2 | wektor AB = [7.220703125, 27.1142578125]
metoda2 | wektor BC = [-22.1103515625, -22.1103515625]
metoda2 | dlugosc wektora AB = 28.05924987793
metoda2 | dlugosc wektora BC = 22.468564987183
metoda2 | iloczyn skalarny = -759.15808105469
metoda2 | kat do arccos = -607.89910888672
metoda2 | kat po arccos w radianach = 1074.7869433911
metoda2 | kat w stopniach: 61555.984375

Nie wiem co jest nie tak w metodzie 1, w metodzie dwa chyba mi się sypnęło na iloczynie skalarnym, tak?


EDIT:
W metodzie 2 odnalazłem błąd, źle liczyłem wektor BC, wciąż szukam innej przyczyny, podążam za przykładem na konkretnych liczbach.
Swoją drogą: nie mam dostepnych funkcji arcsin i arccos - z tego co wyczytalem to tylko inwersja, wiec arccos(x) = cos(x) ^ -1, tak?

EDIT2: iloczyn skalarny mam ok..

0

Możliwe, że nie uwzględniłes w metodzie 1 poprawek, które opisałem w poście wyżej. Np. pole:

p = (28,05925+22,46856+37,34649)/2 = 43,93715
pole = sqrt(43,93715*15,8779*21,46859*6,59066) = sqrt(98259,8278) = 313,4642

co nie pokrywa się z Twoim polem w metodzie 1. Możliwe, ze błąd jest tez dalej, z wyciągnięciem szukanego sinusa (tam też robiłem wczoraj poprawkę w poście wyżej)

0

a faktycznie, nie zauważyłem poprawki na pole, teraz mi wyszło inaczej:
(bazujemy na danych z posta krzyśka, żeby nie wprowadzać zamieszania już z dużymi liczbami i uzyskać ten jego wynik jakąkolwiek metodą):

AX: 1
AY: 2
BX: 3
BY: 4
CX: 8
CY: 10
metoda1 | dlugosc AB:2.8284270763397
metoda1 | dlugosc BC:7.8102498054504
metoda1 | dlugosc CA:10.630146026611
metoda1 | pole:0.99992215633392
metoda1 | wartosc do zarcsinusowania:0.090528704226017
metoda1 | kat w radianach po arcsin:11.061322741757
metoda1 | kat w stopniach:633.51214599609

uzyskane przy pomocy:

local p = (AB+BC+CA)/2
local pole = math.sqrt(p*((p-AB)*(p-BC)*(p-CA)))

edit: na moich danych ze wczoraj wyrzuciło: pole:314.18020629883 więc jest raczej ok, coś dalej pewnie źle..

edit: wartośc do arcsin liczę tak: (edit edit edit: zreszta wrzuce do konca kod)

mysin = (2pole)/(ABBC)
kat=math.sin(mysin)^-1 -- tu w radianach
nierad = kat*180/(22/7) -- a tu juz nie

0

1.W metodzie 2 musisz mieć dwa wektory o wspólnym początku. Zatem na pewno nie możesz się posługiwać wektorami AB i BC. Nie wiem który kat chcesz wyliczyć, jeżeli przy wierzchołku B, to powinieneś skorzystać z wektorów BA i BC.
2. Gdzieś Ty wyczytał o inwersji? Jeżeli nie masz funkcji arccos(x), to możesz arccos(x) liczyć z rozwinięcia w szereg potęgowy ;-) lub metodą prób: powiedzmy, że chcesz obliczyć arccos(0,5), "zgadujesz", że wynosi 1, sprawdzasz, tzn. liczysz cos(1)=0,54... za dużo, "zgadujesz, że wynosi 1,1, sprawdzasz cos(1,1)=0,45.., za mało. Zatem arccos(0,5) jest gdzieś pomiędzy, może 1,05? cos(1,05) =0,49...
Zatem szukany arccos(0,5) leży między 1 a 1,05. I tak dalej.

0
  1. tylko je inaczej nazwałem.. (wersja na przykladzie z posta krzyska)

metoda2 | wektor AB = [-2, -2]
metoda2 | wektor BC = [5, 6]
metoda2 | dlugosc wektora AB = 2.8284270763397
metoda2 | dlugosc wektora BC = 7.8102498054504
metoda2 | iloczyn skalarny = -22
metoda2 | kat do arccos = -60.749488830566
metoda2 | kat po arccos w radianach = -2.0427129856339
metoda2 | kat w stopniach: -116.99174499512

  1. omfg.. kolejne 2h z życia na napisanie tego :P
    edit: a jednak są arcsin/arccos, po prostu sie nazywają asin acos, a w dokumentacji wcześniej jakoś mi umknęło ..
    różnica jest trochę:
    metoda1 | kat w radianach po arcsin:11.061322741757
    metoda1 | kat w radianach po arcsin:11.03109688464

edit:

OKEJ! Liczy już dobrze metodą krzyśka. Tj na jego przykładzie mi się zgodziło, teraz tylko żeby na rzeczywistych danych działało..

EDIT:
Jest tylko jeden problem: Jak rozpoznać czy kąt jest powyżej 180stopni? (zakładając że kąty liczymy zgodnie ze wskazówkami zegara?) Bo od 180 "odbija" mi w dół, nawet dobrze, bo i tak chciałem zamieniać z 360 stopni na skalę 180, ale potrzebne mi też wiedzieć właśnie ile dokładnie to było..

edit (ciekawe który to już):
wszystko rozwiązane, znalazłem jeszcze trzeci sposób na kąt, a na kąt powyżej 180 sam napisałem fixa.
troche zeszło ale mam :)

dzięki wszystkim!

0

A możesz podać ten trzeci sposób?

0
AB_ = odl(ax,ay,bx,by)
BC_ = odl(bx,by,cx,cy)
CA_ = odl(cx,cy,ax,ay)
cos = (AB_^2+BC_^2-CA_^2)/(2*AB_*BC_)
kat = math.acos(cos)
degrees = kat*180/(22/7)
return degress

1 użytkowników online, w tym zalogowanych: 0, gości: 1