Powiedzmy, że masz to:
P1 = (x=2, y=50)
P2 = (x=9, y=40)
P3 = (x=5, y=20)
Załóżmy, że P1
jest to środek koła. Jest zawsze taka sama. Chcę kąta, na który składa się P2
i P3
, innymi słowy, kąt, który jest obok P1
. A dokładniej kąt wewnętrzny. Zawsze będzie to kąt ostry, a więc mniejszy niż -90 stopni.
Pomyślałem: stary, to prosta matematyka geometrii. Ale szukałem wzoru już od około 6 godzin i znajduję ludzi, którzy mówią tylko o skomplikowanych rzeczach NASA, takich jak arccos i produkty skalarne wektorowe. Mam wrażenie, że głowa jest w lodówce.
Niektórzy guru matematyki, którzy myślą, że to prosty problem? Nie sądzę, że język programowania ma tutaj znaczenie, ale dla tych, którzy myślą, że tak: java i objective-c. Potrzebuję go do obu, ale nie oznaczyłem go dla nich.
To staje się bardzo proste, jeśli myślisz, że to dwa wektory, jeden od punktu P1 do P2 i jeden od P1 do P3
a więc:
a = (p1.x - p2.x, p1.y - p2.y)
b = (p1.x - p3.x, p1.y - p3.y)
Następnie możesz odwrócić wzór na iloczyn skalarny:
aby uzyskać kąt:
Pamiętaj, że oznacza to po prostu: a1 * b1 + a2 * b2 (tutaj tylko 2 wymiary ...)
źródło
Najlepszym sposobem radzenia sobie z obliczaniem kąta jest użycie
atan2(y, x)
tego, że dany punktx, y
zwraca kąt z tego punktu iX+
oś względem początku.Biorąc pod uwagę, że obliczenia są
tj. w zasadzie tłumaczysz dwa punkty przez
-P1
(innymi słowy tłumaczysz wszystko tak, żeP1
kończy się na początku), a następnie bierzesz pod uwagę różnicę kątów bezwzględnych ziP3
odP2
.Zaletą
atan2
jest to, że reprezentowane jest pełne koło (można uzyskać dowolną liczbę między -π a π), gdzie zamiast tegoacos
musisz obsłużyć kilka przypadków w zależności od znaków, aby obliczyć poprawny wynik.Jedynym osobliwym punktem dla
atan2
jest(0, 0)
... co oznacza, że obaP2
iP3
muszą być różne od,P1
ponieważ w tym przypadku nie ma sensu mówić o kącie.źródło
atan2
jest dokładnie tym, co jest potrzebne do rozwiązania tego problemu, ale wygląda na to, że większość ludzi docierających do tego pytania po prostu nie może czytać lub nie może zrozumieć, dlaczegoacos
rozwiązania oparte na rozwiązaniach są złe. Na szczęście wiele lat temu opuściłem fazę "ktoś się myli w internecie" ( xkcd.com/386 ) i nie zamierzam zaczynać walki o obronę oczywistego :-)Podam przykład w JavaScript, dużo z tym walczyłem:
Bonus: przykład z płótnem HTML5
źródło
sqrt
i podnosząc do kwadratu. Zobacz moją odpowiedź tutaj (napisaną w Rubim) lub w zaktualizowanej wersji demonstracyjnej (JavaScript).Zasadniczo masz dwa wektory, jeden wektor od P1 do P2 i drugi od P1 do P3. Wszystko, czego potrzebujesz, to wzór do obliczenia kąta między dwoma wektorami.
Zajrzyj tutaj, aby uzyskać dobre wyjaśnienie i wzór.
źródło
Jeśli myślisz o P1 jako środku koła, myślisz zbyt skomplikowanie. Masz prosty trójkąt, więc twój problem można rozwiązać za pomocą prawa cosinusów . Nie ma potrzeby jakiejkolwiek transformacji współrzędnych biegunowych ani czegoś podobnego. Powiedzmy, że odległości to P1-P2 = A, P2-P3 = B i P3-P1 = C:
Wszystko, co musisz zrobić, to obliczyć długość odległości A, B i C. Są one łatwo dostępne ze współrzędnych x i y punktów oraz twierdzenia Pitagorasa
źródło
P1-P2 = A
nie należy odczytywać jako „Aby obliczyć A, odejmij P2 od P1”, ale jako „Definiuję A jako odległość od P1 do P2”, którą można następnie obliczyć za pomocą drugiego równania. Chciałem tylko zdefiniować skrót dla odległości, aby równania były bardziej czytelne.Niedawno natknąłem się na podobny problem, tylko że potrzebowałem odróżnić kąt dodatni od ujemnego. Na wypadek, gdyby było to przydatne dla każdego, polecam fragment kodu, który wziąłem z tej listy mailingowej na temat wykrywania rotacji po zdarzeniu dotykowym dla Androida:
źródło
Bardzo proste rozwiązanie geometryczne z wyjaśnieniem
Kilka dni temu wpadłem w ten sam problem i musiałem siedzieć z książką do matematyki. Rozwiązałem problem, łącząc i upraszczając kilka podstawowych wzorów.
Rozważmy tę liczbę-
Chcemy wiedzieć ϴ , więc najpierw musimy znaleźć α i β . Teraz dla każdej prostej
Niech- A = (ax, ay) , B = (bx, by) i O = (ox, oy) . Więc dla linii OA -
W ten sam sposób dla linii OB -
Teraz potrzebujemy
ϴ = β - α
. W trygonometrii mamy wzórPo zastąpieniu wartości
tan α
(z równania-2) itan b
(z równania-3) w równaniu-4 i zastosowaniu uproszczenia otrzymujemy:Więc,
To jest to!
Teraz weźmy następujący rysunek-
Ta metoda C # lub Java oblicza kąt ( ϴ ) -
źródło
W Objective-C możesz to zrobić przez
Lub przeczytaj więcej tutaj
źródło
Wspomniałeś o kącie ze znakiem (-90). W wielu zastosowaniach kąty mogą mieć znaki (dodatnie i ujemne, patrz http://en.wikipedia.org/wiki/Angle ). Jeśli punkty to (powiedzmy) P2 (1,0), P1 (0,0), P3 (0,1), to kąt P3-P1-P2 jest umownie dodatni (PI / 2), podczas gdy kąt P2-P1- P3 jest ujemny. Używanie długości boków nie rozróżnia + i -, więc jeśli to ma znaczenie, będziesz musiał użyć wektorów lub funkcji takiej jak Math.atan2 (a, b).
Kąty mogą również wykraczać poza 2 * PI i chociaż nie jest to istotne dla obecnego pytania, wystarczająco ważne było, aby napisać własną klasę Angle (również po to, aby upewnić się, że stopnie i radiany nie zostaną pomieszane). Kwestia, czy kąt1 jest mniejszy niż kąt2, zależy w dużym stopniu od tego, jak definiuje się kąty. Może być również ważne, aby zdecydować, czy linia (-1,0) (0,0) (1,0) jest reprezentowana jako Math.PI czy -Math.PI
źródło
Ostatnio ja też mam ten sam problem ... W Delphi jest bardzo podobny do Objective-C.
źródło
Oto metoda C #, która zwraca kąt (0-360) przeciwnie do ruchu wskazówek zegara od poziomu dla punktu na okręgu.
Pozdrawiam, Paul
źródło
źródło
jest na to prosta odpowiedź, używając matematyki w szkole średniej.
Powiedzmy, że masz 3 punkty
Aby uzyskać kąt z punktu A do B.
angle = atan2(A.x - B.x, B.y - A.y)
Aby uzyskać kąt z punktu B do C.
angle2 = atan2(B.x - C.x, C.y - B.y)
Właśnie użyłem tego kodu w ostatnim projekcie, który zrobiłem, zmień B na P1 .. równie dobrze możesz usunąć „180 +”, jeśli chcesz
źródło
cóż, inne odpowiedzi wydają się obejmować wszystko, czego potrzeba, więc chciałbym po prostu dodać to, jeśli używasz JMonkeyEngine:
Vector3f.angleBetween(otherVector)
bo właśnie tego tu przyjechałem :)
źródło
}
źródło