atan2(y, x)
tem essa descontinuidade em 180 ° onde muda para -180 ° ..0 ° no sentido horário.
Como mapeio a faixa de valores para 0 ° ..360 °?
aqui está meu código:
CGSize deltaPoint = CGSizeMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
float swipeBearing = atan2f(deltaPoint.height, deltaPoint.width);
Estou calculando a direção de um evento de toque de deslizar considerando as duas estruturas de ponto XY startPoint
e e endPoint
. O código é para o iPhone, mas qualquer idioma que suporte serve atan2f()
.
Respostas:
fonte
(x >= 0 ? x : (2*PI + x)) * 180/PI
como em(x < 0 ? 2*PI + x : x) * 180/PI
Solução usando Módulo
Uma solução simples que abrange todos os casos.
Explicação
Positivo: 1 a 180
Se você modificar qualquer número positivo entre 1 e 180 por 360, obterá exatamente o mesmo número inserido. O modo aqui apenas garante que esses números positivos sejam retornados com o mesmo valor.
Negativo: -180 a -1
Usar o mod aqui retornará valores na faixa de 180 e 359 graus.
Casos especiais: 0 e 360
Usar mod significa que 0 é retornado, tornando esta uma solução segura de 0-359 graus.
fonte
-1 % 360 = -1
Basta adicionar 360 ° se a resposta de atan2 for menor que 0 °.
fonte
Ou se você não gosta de ramificação, apenas negue os dois parâmetros e adicione 180 ° à resposta.
(Adicionar 180 ° ao valor de retorno o coloca perfeitamente na faixa de 0-360, mas inverte o ângulo. Negar os dois parâmetros de entrada o inverte.)
fonte
@erikkallen está perto, mas não muito bem.
Isso deve funcionar em C ++: (dependendo de como o fmod é implementado, pode ser mais rápido ou mais lento do que a expressão condicional)
Alternativamente, você pode fazer isso:
uma vez que (x, y) e (-x, -y) diferem em ângulos em 180 graus.
fonte
Tenho 2 soluções que parecem funcionar para todas as combinações de xe y positivo e negativo.
1) Abuso atan2 ()
De acordo com os documentos, atan2 usa os parâmetros y e x nessa ordem. No entanto, se você os inverter, poderá fazer o seguinte:
2) Use atan2 () corretamente e converta depois
fonte
@Jason S: sua variante "fmod" não funcionará em uma implementação compatível com os padrões. O padrão C é explícito e claro (7.12.10.1, "as funções fmod"):
portanto,
é na verdade apenas uma reescrita detalhada de:
Sua terceira sugestão, no entanto, está correta.
fonte
Isso é o que eu normalmente faço:
fonte
Eu fiz uma fórmula para orientar o ângulo de 0 a 360
fonte
Uma solução alternativa é usar a função mod () definida como:
function mod(a, b) {return a - Math.floor (a / b) * b;}
Então, com a seguinte função, o ângulo entre os pontos ini (x, y) e final (x, y) é obtido. O ângulo é expresso em graus normalizados para [0, 360] graus. e Norte referenciando 360 graus.
fonte
A geosfera dos pacotes R calculará o rolamentoRhumb, que é uma linha de rolamento constante dado um ponto de origem e leste / norte. O leste e o norte devem estar em uma matriz ou vetor. O ponto de origem de uma rosa dos ventos é 0,0. O código a seguir parece resolver prontamente o problema:
fonte
-1 grau torna-se (-1 + 360) = 359 graus
-179 graus torna-se (-179 + 360) = 181 graus
fonte
Math.PI
? É o mesmo queM_PI
?Isso retornará o grau de 0 ° -360 ° no sentido anti-horário, 0 ° está nas 3 horas.
fonte
Uma fórmula para ter o intervalo de valores de 0 a 360 graus.
f (x, y) = 180-90 * (1 + sinal (x)) * (1-sinal (y ^ 2)) - 45 * (2 + sinal (x)) * sinal (y)
fonte
Aqui está um pouco de javascript. Basta inserir os valores xey.
fonte