Ao aplicar a fórmula clássica para o ângulo entre dois vetores:
verifica-se que, para ângulos muito pequenos / agudos, há uma perda de precisão e o resultado não é exato. Conforme explicado nesta resposta de estouro de pilha , uma solução é usar o arco tangente:
E isso realmente dá melhores resultados. No entanto, gostaria de saber se isso daria resultados ruins para ângulos muito próximos de . É esse o caso? Em caso afirmativo, existe alguma fórmula para calcular com precisão ângulos sem verificar se há tolerância dentro de um if
galho?
algorithms
precision
numerical-limitations
astrojuanlu
fonte
fonte
Respostas:
( Eu testei essa abordagem antes e lembro que funcionou corretamente, mas não a testei especificamente para esta pergunta. )
Até onde eu sei, tanto e podem sofrer um cancelamento catastrófico se forem quase paralelos / perpendiculares - o atan2 não poderá fornecer boa precisão se uma das entradas estiver desativada.∥v1×v2∥ v1⋅v2
Comece reformulando o problema ao encontrar o ângulo de um triângulo com comprimentos laterais,e(todos são calculados com precisão na aritmética de ponto flutuante). Há uma variante bem conhecida de fórmula de Heron devido a Kahan ( Área miscalculating e ângulos de uma forma de agulha do triângulo ), que permite calcular a área e o ângulo (entre e ) de um triângulo especificado pelos seus comprimentos laterais, e faça isso numericamente de maneira estável. Como a redução desse subproblema também é precisa, essa abordagem deve funcionar com entradas arbitrárias.a=|v1| b=|v2| c=|v1−v2| a b
Citando esse artigo (consulte a p.3), assumindo , Todos os parênteses aqui são colocados com cuidado e são importantes; se você encontrar a raiz quadrada de um número negativo, os comprimentos dos lados de entrada não serão os comprimentos laterais de um triângulo.a≥b
Há uma explicação de como isso funciona, incluindo exemplos de valores para os quais outras fórmulas falham, no artigo de Kahan. Sua primeira fórmula para é na página 4.α C′′
A principal razão pela qual sugiro a fórmula de Kahan Heron é porque ela é uma primitiva muito boa - muitas questões de geometria planar potencialmente complicadas podem ser reduzidas para encontrar a área / ângulo de um triângulo arbitrário; portanto, se você pode reduzir seu problema a isso, existe uma boa fórmula estável para isso, e não há necessidade de criar algo por conta própria.
Editar Após o comentário de Stefano, fiz um gráfico de erro relativo para , ( código ). As duas linhas são os erros relativos de e , ao longo do eixo horizontal. Parece que funciona.v1=(1,0) v2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
fonte
A resposta eficiente a esta pergunta está, não surpreendentemente, em outra nota de Velvel Kahan :
onde eu uso como o ângulo feito por com o eixo horizontal. (Talvez você precise inverter a ordem dos argumentos em alguns idiomas.)arctan(x,y) (x,y)
(Fiz uma demonstração do Mathematica da fórmula de Kahan aqui .)
fonte
ATAN2(Y, X)