Podczas stosowania klasycznej formuły kąta między dwoma wektorami:
stwierdzono, że dla bardzo małych / ostrych kątów występuje utrata precyzji, a wynik nie jest dokładny. Jak wyjaśniono w tej odpowiedzi Przepełnienie stosu , jednym rozwiązaniem jest użycie arcus tangens zamiast:
I to rzeczywiście daje lepsze wyniki. Zastanawiam się jednak, czy dałoby to złe wyniki dla kątów bardzo zbliżonych do . Czy to prawda? Jeśli tak, to czy istnieje wzór umożliwiający dokładne obliczenie kątów bez sprawdzania tolerancji wewnątrz if
gałęzi?
algorithms
precision
numerical-limitations
astrojuanlu
źródło
źródło
Odpowiedzi:
( Testowałem już to podejście i pamiętam, że zadziałało poprawnie, ale nie przetestowałem go specjalnie na to pytanie ).
O ile wiem, zarówno i .v 1 ⋅ v 2∥ v1× v2)∥ v1⋅ v2)
Zacznij od przeformułowania problemu jako znalezienia kąta trójkąta o długości boków,oraz(wszystkie są dokładnie obliczone w arytmetyce zmiennoprzecinkowej). Jest dobrze znany wariant Wzór Herona powodu Kahan ( miscalculating Obszaru oraz kąty igłą jak Triangle ), co pozwala na obliczenie powierzchni i kąt (między i ) trójkąta określonego przez jego długości bocznych, i zrób to stabilnie numerycznie. Ponieważ redukcja do tego podproblemu jest również dokładna, takie podejście powinno działać w przypadku dowolnych danych wejściowych.b = | v 2 | c = | v 1 - v 2 | a ba = | v1| b = | v2)| c = | v1- v2)| za b
Cytując z tego artykułu (patrz str. 3), zakładając, że , Wszystkie nawiasy tutaj są umieszczone ostrożnie i mają one znaczenie; jeśli okaże się, że bierzesz pierwiastek kwadratowy z liczby ujemnej, wejściowe długości boków nie są długościami boków trójkąta.μ = { c - ( a - b ) , jeśli b ≥ c ≥ 0 , b - ( a - c ) , jeśli c > b ≥ 0 , nieprawidłowy trójkąt , w przeciwnym razie a n g l e = 2 arctan ( √a≥b
W pracy Kahana wyjaśniono, jak to działa, w tym przykłady wartości, dla których inne formuły zawodzą. Twoja pierwsza formuła dla to na stronie 4.C ″α C′′
Głównym powodem, dla którego sugeruję formułę Herona Kahana, jest to, że tworzy ona bardzo przyjemną prymitywną - wiele potencjalnie trudnych pytań dotyczących geometrii płaskiej można zredukować do znalezienia pola / kąta dowolnego trójkąta, więc jeśli możesz zredukować swój problem do tego, istnieje niezła, stabilna formuła i nie ma potrzeby wymyślać czegoś na własną rękę.
Edytuj Po komentarzu Stefano, stworzyłem wykres błędu względnego dla , ( kod ). Dwie linie to błędy względne dla i , przebiegające wzdłuż osi poziomej. Wygląda na to, że działa. v 2 = ( cos θ , sinv1=(1,0) θ = ϵ θ = π / 2 - ϵ ϵv2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
źródło
Skuteczną odpowiedź na to pytanie nie jest zaskakujące w innej notatce Velvela Kahana :
gdzie używam jako kąta utworzonego przez z osią poziomą. (W niektórych językach może być konieczne odwrócenie kolejności argumentów).arctan(x,y) (x,y)
(Dałem Mathematica demonstrację wzoru Kahan jest tutaj ).
źródło
ATAN2(Y, X)