Vamos dizer que você tem isso:
P1 = (x=2, y=50)
P2 = (x=9, y=40)
P3 = (x=5, y=20)
Suponha que esse P1
seja o ponto central de um círculo. É sempre a mesma coisa. Eu quero o ângulo que é composto por P2
e P3
, ou em outras palavras, o ângulo que está próximo P1
. O ângulo interno para ser preciso. Sempre será um ângulo agudo, portanto menor que -90 graus.
Eu pensei: Cara, isso é matemática simples em geometria. Mas tenho procurado uma fórmula há cerca de 6 horas e só encontro pessoas falando sobre coisas complicadas da NASA, como arccos e produtos escalares vetoriais. Minha cabeça parece que está na geladeira.
Alguns gurus da matemática aqui que pensam que este é um problema simples? Eu não acho que a linguagem de programação seja importante aqui, mas para quem pensa que é: java e objetivo-c. Preciso disso para ambos, mas não o etiquetei para estes.
Fica muito simples se você pensar em dois vetores, um do ponto P1 ao P2 e outro do P1 ao P3
então:
a = (p1.x - p2.x, p1.y - p2.y)
b = (p1.x - p3.x, p1.y - p3.y)
Você pode inverter a fórmula do produto escalar:
para obter o ângulo:
Lembre-se de que apenas significa: a1 * b1 + a2 * b2 (apenas duas dimensões aqui ...)
fonte
A melhor maneira de lidar com a computação em ângulo é usar
atan2(y, x)
que, dado um ponto,x, y
retorne o ângulo desse ponto e oX+
eixo em relação à origem.Dado que o cálculo é
ou seja, você basicamente traduz os dois pontos por
-P1
(em outras palavras, você traduz tudo para queP1
acabe na origem) e depois considera a diferença dos ângulos absolutos deP3
e deP2
.A vantagem
atan2
disso é que o círculo completo é representado (você pode obter qualquer número entre -π e π) onde, em vez disso,acos
é necessário lidar com vários casos, dependendo dos sinais para calcular o resultado correto.O único ponto singular para
atan2
é(0, 0)
... significando que ambosP2
eP3
devem ser diferentes,P1
como nesse caso, não faz sentido falar sobre um ângulo.fonte
atan2
é exatamente o que é necessário para esse problema, mas parece que a maioria das pessoas que chega a essa pergunta simplesmente não consegue ler ou não consegue entender por que asacos
soluções baseadas são ruins. Por sorte o suficiente para me deixei a "alguém está errado na internet" ( xkcd.com/386 fase) há muitos anos e eu não estou indo para começar uma luta para defender o óbvio :-)Deixe-me dar um exemplo em JavaScript, lutei muito com isso:
Bônus: exemplo com tela HTML5
fonte
sqrt
e esquadrinhando. Veja minha resposta aqui (escrita em Ruby) ou nesta demonstração atualizada (JavaScript).Basicamente, o que você tem são dois vetores, um vetor de P1 a P2 e outro de P1 a P3. Então, tudo o que você precisa é de uma fórmula para calcular o ângulo entre dois vetores.
Dê uma olhada aqui para uma boa explicação e a fórmula.
fonte
Se você está pensando em P1 como o centro de um círculo, está pensando muito complicado. Você tem um triângulo simples, portanto seu problema é solucionável pela lei dos cossenos . Não há necessidade de qualquer transformação de coordenadas polares ou algo assim. Digamos que as distâncias sejam P1-P2 = A, P2-P3 = B e P3-P1 = C:
Tudo o que você precisa fazer é calcular o comprimento das distâncias A, B e C. Essas são facilmente disponíveis nas coordenadas x e y dos seus pontos e no teorema de Pitágoras
fonte
P1-P2 = A
não deve ser lida como "Para calcular A, subtraia P2 de P1", mas como "Estou definindo A como a distância de P1 a P2", que pode ser calculada usando a segunda equação. Eu só queria definir uma abreviação para as distâncias, para tornar as equações mais legíveis.Encontrei recentemente um problema semelhante, mas precisava diferenciar entre ângulos positivos e negativos. Caso isso seja útil a alguém, recomendo o trecho de código que peguei nesta lista de e-mails sobre a detecção de rotação em um evento de toque para Android:
fonte
Solução geométrica muito simples com explicação
Poucos dias atrás, um caiu no mesmo problema e teve que se sentar com o livro de matemática. Resolvi o problema combinando e simplificando algumas fórmulas básicas.
Vamos considerar esta figura-
Queremos saber ϴ , então precisamos descobrir α e β primeiro. Agora, para qualquer linha reta
Seja A = (ax, ay) , B = (bx, by) e O = (boi, oy) . Então, para a linha OA -
Da mesma forma, para a linha OB -
Agora precisamos
ϴ = β - α
. Na trigonometria, temos uma fórmulaApós substituir o valor de
tan α
(do eqn-2) etan b
(do eqn-3) no eqn-4, e aplicar a simplificação, obtemosAssim,
É isso!
Agora, veja a figura a seguir:
Esse método C # ou Java calcula o ângulo ( ϴ ) -
fonte
No Objective-C, você poderia fazer isso
Ou leia mais aqui
fonte
Você mencionou um ângulo assinado (-90). Em muitas aplicações, os ângulos podem ter sinais (positivos e negativos, consulte http://en.wikipedia.org/wiki/Angle ). Se os pontos são (digamos) P2 (1,0), P1 (0,0), P3 (0,1), então o ângulo P3-P1-P2 é convencionalmente positivo (PI / 2), enquanto o ângulo P2-P1- P3 é negativo. O uso dos comprimentos dos lados não fará distinção entre + e - portanto, se isso for importante, você precisará usar vetores ou uma função como Math.atan2 (a, b).
Os ângulos também podem se estender além de 2 * PI e, embora isso não seja relevante para a pergunta atual, era suficientemente importante que eu escrevesse minha própria classe Angle (também para garantir que graus e radianos não se misturassem). As perguntas sobre se o ângulo1 é menor que o ângulo2 dependem criticamente de como os ângulos são definidos. Também pode ser importante decidir se uma linha (-1,0) (0,0) (1,0) é representada como Math.PI ou -Math.PI
fonte
Recentemente, eu também tenho o mesmo problema ... No Delphi, é muito semelhante ao Objective-C.
fonte
Aqui está um método C # para retornar o ângulo (0-360) no sentido anti-horário da horizontal para um ponto em um círculo.
Cheers, Paul
fonte
fonte
existe uma resposta simples para isso usando matemática do ensino médio.
Digamos que você tenha 3 pontos
Para obter ângulo do ponto A a B
angle = atan2(A.x - B.x, B.y - A.y)
Para obter ângulo do ponto B a C
angle2 = atan2(B.x - C.x, C.y - B.y)
Acabei de usar esse código no projeto recente que fiz, altere B para P1. Você também pode remover o "180 +" se quiser
fonte
bem, as outras respostas parecem cobrir tudo o necessário, então eu gostaria de adicionar isso se você estiver usando o JMonkeyEngine:
Vector3f.angleBetween(otherVector)
como é isso que eu vim aqui procurando :)
fonte
}
fonte