( 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|bab
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
μ=⎧⎩⎨c−(a−b),b−(a−c),invalid triangle,if b≥c≥0,if c>b≥0,otherwise
angle=2arctan(((a−b)+c)μ(a+(b+c))((a−c)+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−ϵϵ