Lors de l'application de la formule classique de l'angle entre deux vecteurs:
on constate que, pour des angles très petits / aigus, il y a une perte de précision et le résultat n'est pas précis. Comme expliqué dans cette réponse Stack Overflow , une solution consiste à utiliser l'arctangente à la place:
Et cela donne en effet de meilleurs résultats. Cependant, je me demande si cela donnerait de mauvais résultats pour des angles très proches de . Est-ce le cas? Si oui, existe-t-il une formule pour calculer avec précision les angles sans vérifier la tolérance à l'intérieur d'une if
branche?
algorithms
precision
numerical-limitations
astrojuanlu
la source
la source
Réponses:
( J'ai déjà testé cette approche et je me souviens qu'elle a fonctionné correctement, mais je ne l'ai pas testée spécifiquement pour cette question. )
Autant que je sache, les deux et peuvent souffrir d'une annulation catastrophique s'ils sont presque parallèles / perpendiculaires - atan2 ne peut pas vous donner une bonne précision si l'une des entrées est désactivée.∥v1×v2∥ v1⋅v2
Commencez par reformuler le problème en trouvant l'angle d'un triangle avec des longueurs de côté,et(ils sont tous calculés avec précision en arithmétique à virgule flottante). Il existe une variante bien connue de la formule de Heron en raison de Kahan ( zone de calcul et angles d'un triangle en forme d'aiguille ), qui vous permet de calculer la zone et l'angle (entre et ) d'un triangle spécifié par ses longueurs de côté, et le faire numériquement de manière stable. Étant donné que la réduction de ce sous-problème est également exacte, cette approche devrait fonctionner pour des entrées arbitraires.a=|v1| b=|v2| c=|v1−v2| a b
Citant cet article (voir p. 3), en supposant , Toutes les parenthèses ici sont placées avec soin, et elles comptent; si vous vous retrouvez à prendre la racine carrée d'un nombre négatif, les longueurs latérales d'entrée ne sont pas les longueurs latérales d'un triangle.a≥b
Le document de Kahan explique comment cela fonctionne, y compris des exemples de valeurs pour lesquelles d'autres formules échouent. Votre première formule pour est à la page 4.α C′′
La principale raison pour laquelle je suggère la formule de Heron de Kahan est parce qu'elle fait une très belle primitive — beaucoup de questions de géométrie planaire potentiellement délicates peuvent être réduites à trouver l'aire / l'angle d'un triangle arbitraire, donc si vous pouvez réduire votre problème à cela, il y a une belle formule stable pour cela, et il n'est pas nécessaire de trouver quelque chose par vous-même.
Modifier Suite au commentaire de Stefano, j'ai fait un tracé d'erreur relative pour , ( code ). Les deux lignes sont les erreurs relatives pour et , suivant l'axe horizontal. Il semble que ça marche.v1=(1,0) v2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
la source
La réponse efficace à cette question est, sans surprise, dans une autre note de Velvel Kahan :
où j'utilise comme l'angle fait par avec l'axe horizontal. (Vous devrez peut-être inverser l'ordre des arguments dans certaines langues.)arctan(x,y) (x,y)
(J'ai donné une démonstration Mathematica de la formule de Kahan ici .)
la source
ATAN2(Y, X)