Al aplicar la fórmula clásica para el ángulo entre dos vectores:
se encuentra que, para ángulos muy pequeños / agudos, hay una pérdida de precisión y el resultado no es exacto. Como se explica en esta respuesta de Stack Overflow , una solución es usar el arcotangente en su lugar:
Y esto de hecho da mejores resultados. Sin embargo, me pregunto si esto daría malos resultados para ángulos muy cercanos a . Es el caso? Si es así, ¿hay alguna fórmula para calcular ángulos con precisión sin verificar la tolerancia dentro de una rama?if
algorithms
precision
numerical-limitations
astrojuanlu
fuente
fuente
Respuestas:
( He probado este enfoque antes, y recuerdo que funcionó correctamente, pero no lo he probado específicamente para esta pregunta ) .
Por lo que puedo decir, ambos y puede sufrir una cancelación catastrófica si son casi paralelas / perpendiculares; atan2 no puede darle una buena precisión si alguna de las entradas está desactivada.∥v1×v2∥ v1⋅v2
Comience reformulando el problema como encontrar el ángulo de un triángulo con longitudes laterales,y(todos estos se calculan con precisión en aritmética de coma flotante). Hay una variante bien conocida de la fórmula de Heron debido a Kahan ( Area calcular mal y ángulos de una aguja similar a Triangle ), que le permite calcular el área y el ángulo (entre y ) de un triángulo especificado por sus longitudes de los lados, y hacerlo numéricamente estable. Debido a que la reducción a este subproblema también es precisa, este enfoque debería funcionar para entradas arbitrarias.a=|v1| b=|v2| c=|v1−v2| a b
Citando de ese documento (ver p.3), suponiendo , Todos los paréntesis aquí se colocan cuidadosamente, y son importantes; si te encuentras tomando la raíz cuadrada de un número negativo, las longitudes laterales de entrada no son las longitudes laterales de un triángulo.a≥b
Hay una explicación de cómo funciona esto, incluidos ejemplos de valores para los que fallan otras fórmulas, en el artículo de Kahan. Su primera fórmula para es en la página 4.α C′′
La razón principal por la que sugiero la fórmula de Kahan Heron es porque es una primitiva muy agradable: muchas preguntas de geometría plana potencialmente complicadas se pueden reducir a encontrar el área / ángulo de un triángulo arbitrario, por lo que si puede reducir su problema a eso, hay es una fórmula estable y agradable, y no hay necesidad de inventar algo por su cuenta.
Editar Siguiendo el comentario de Stefano, hice un diagrama de error relativo para , ( código ). Las dos líneas son los errores relativos para y , van a lo largo del eje horizontal. Parece que funciona.v1=(1,0) v2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
fuente
La respuesta eficiente a esta pregunta es, no sorprendentemente, en otra nota de Velvel Kahan :
donde uso como el ángulo formado por con el eje horizontal. (Es posible que deba cambiar el orden de los argumentos en algunos idiomas).arctan(x,y) (x,y)
(Di una demostración de Mathematica de la fórmula de Kahan aquí ).
fuente
ATAN2(Y, X)