Bei Anwendung der klassischen Formel für den Winkel zwischen zwei Vektoren:
man stellt fest, dass bei sehr kleinen / spitzen Winkeln ein Präzisionsverlust auftritt und das Ergebnis nicht genau ist. Wie in dieser Antwort zum Stapelüberlauf erläutert , besteht eine Lösung darin, stattdessen den Arkustangens zu verwenden:
Und das ergibt in der Tat bessere Ergebnisse. Ich frage mich jedoch, ob dies bei Winkeln nahe \ pi / 2 zu schlechten Ergebnissen führen würde . Ist es der fall Wenn ja, gibt es eine Formel, mit der Winkel genau berechnet werden können, ohne eine Toleranz innerhalb eines if
Zweigs zu prüfen ?
algorithms
precision
numerical-limitations
Astrojuanlu
quelle
quelle
Antworten:
( Ich habe diesen Ansatz bereits getestet und erinnere mich, dass er korrekt funktioniert hat, aber ich habe ihn nicht speziell für diese Frage getestet. )
Soweit ich das beurteilen kann, sind beide und können unter einer katastrophalen Löschung leiden, wenn sie nahezu parallel / senkrecht sind - atan2 kann keine gute Genauigkeit liefern, wenn einer der Eingänge ausgeschaltet ist.v 1 ≤ v 2∥ v1× v2∥ v1⋅ v2
Beginnen Sie mit einer Neuformulierung des Problems, indem Sie den Winkel eines Dreiecks mit den Seitenlängen,und(Diese werden alle in Gleitkomma-Arithmetik genau berechnet.) Es gibt eine bekannte Variante der Heronschen Formel aufgrund von Kahan ( Fehlberechnungsfläche und Winkel eines nadelförmigen Dreiecks ), mit der Sie die Fläche und den Winkel (zwischen und ) eines Dreiecks berechnen können, die durch seine Seitenlängen angegeben sind. und dies numerisch stabil. Da die Reduktion auf dieses Unterproblem ebenfalls genau ist, sollte dieser Ansatz für beliebige Eingaben funktionieren.b = | v 2 | c = | v 1 - v 2 |a = | v1| b = | v2| c=|v1−v2| ba b
Zitiert aus diesem Artikel (siehe S.3), unter der Annahme, dass , Alle Klammern hier sind sorgfältig gesetzt, und sie sind wichtig; Wenn Sie feststellen, dass Sie die Quadratwurzel einer negativen Zahl ziehen, sind die eingegebenen Seitenlängen nicht die Seitenlängen eines Dreiecks.μ = { c - ( a - b ) , wenn b ≥ c ≥ 0 , b - ( a - c ) , wenn c > b ≥ 0 , ungültig Dreieck , sonst a n g l e = 2 arctan ( √a≥b
Wie dies funktioniert, wird in Kahans Aufsatz erklärt, einschließlich Beispielen für Werte, für die andere Formeln versagen. Ihre erste Formel für lautet auf Seite 4.α C′′
Der Hauptgrund, warum ich Kahans Herons Formel vorschlage, ist, dass sie ein sehr nettes Primitiv darstellt - viele potenziell knifflige Fragen der planaren Geometrie können auf das Finden der Fläche / des Winkels eines beliebigen Dreiecks reduziert werden eine schöne stabile Formel dafür, und es ist nicht nötig, sich selbst etwas auszudenken.
Bearbeiten Nach Stefanos Kommentar habe ich eine Darstellung des relativen Fehlers für , ( Code ) erstellt. Die zwei Linien sind die relativen Fehler für und ;, wobei entlang der horizontalen Achse verläuft. Es scheint, dass es funktioniert.v1=(1,0) v2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
quelle
Die effiziente Antwort auf diese Frage findet sich nicht allzu überraschend in einer weiteren Anmerkung von Velvel Kahan :
(Ich habe eine Mathematica Demonstration von Kahan Formel hier .)
quelle
ATAN2(Y, X)