En un lenguaje de programación (Python, C #, etc.) necesito determinar cómo calcular el ángulo entre una línea y el eje horizontal.
Creo que una imagen describe mejor lo que quiero:
Dado (P1 x , P1 y ) y (P2 x , P2 y ), ¿cuál es la mejor manera de calcular este ángulo? El origen está en el topleft y solo se utiliza el cuadrante positivo.
c#
python
trigonometry
orlp
fuente
fuente
Respuestas:
Primero encuentre la diferencia entre el punto inicial y el punto final (aquí, esto es más un segmento de línea dirigida, no una "línea", ya que las líneas se extienden infinitamente y no comienzan en un punto en particular).
Luego calcule el ángulo (que se extiende desde el eje X positivo en
P1
el eje Y positivo enP1
).Pero
arctan
puede no ser ideal, porque dividir las diferencias de esta manera borrará la distinción necesaria para distinguir en qué cuadrante se encuentra el ángulo (ver más abajo). Utilice lo siguiente si su idioma incluye unaatan2
función:EDITAR (22 de febrero de 2017): en general, sin embargo, llamar
atan2(deltaY,deltaX)
solo para obtener el ángulo adecuadocos
ysin
puede ser poco elegante. En esos casos, a menudo puede hacer lo siguiente:(deltaX, deltaY)
como un vector.deltaX
ydeltaY
por la longitud del vector (sqrt(deltaX*deltaX+deltaY*deltaY)
), a menos que la longitud sea 0.deltaX
ahora será el coseno del ángulo entre el vector y el eje horizontal (en la dirección del eje X positivo al eje Y positivo enP1
).deltaY
ahora será el seno de ese ángulo.EDITAR (28 de febrero de 2017): incluso sin normalizar
(deltaX, deltaY)
:deltaX
le indicará si el coseno descrito en el paso 3 es positivo o negativo.deltaY
le indicará si el seno descrito en el paso 4 es positivo o negativo.deltaX
ydeltaY
le indicarán en qué cuadrante se encuentra el ángulo, en relación con el eje X positivo enP1
:+deltaX
,+deltaY
: 0 a 90 grados.-deltaX
,+deltaY
: 90 a 180 grados.-deltaX
,-deltaY
: 180 a 270 grados (-180 a -90 grados).+deltaX
,-deltaY
: 270 a 360 grados (-90 a 0 grados).Una implementación en Python usando radianes (proporcionada el 19 de julio de 2015 por Eric Leschinski, quien editó mi respuesta):
Todas las pruebas pasan. Ver https://en.wikipedia.org/wiki/Unit_circle
fuente
90 - angleInDegrees
:?Lo siento, pero estoy bastante seguro de que la respuesta de Peter es incorrecta. Tenga en cuenta que el eje y desciende por la página (común en gráficos). Como tal, el cálculo deltaY tiene que revertirse, o se obtiene la respuesta incorrecta.
Considerar:
da
Entonces, si en el ejemplo anterior, P1 es (1,1) y P2 es (2,2) [porque Y aumenta en la página], el código anterior dará 45.0 grados para el ejemplo que se muestra, lo cual es incorrecto. Cambie el orden del cálculo deltaY y funciona correctamente.
fuente
double arc = Math.atan2(mouse.y - obj.getPy(), mouse.x - obj.getPx()); degrees = Math.toDegrees(arc); if (degrees < 0) degrees += 360; else if (degrees > 360) degrees -= 360;
¡Encontré una solución en Python que funciona bien!
fuente
Teniendo en cuenta la pregunta exacta, al colocarnos en un sistema de coordenadas "especial" donde el eje positivo significa moverse hacia ABAJO (como una pantalla o una vista de interfaz), debe adaptar esta función de esta manera y las coordenadas Y negativas:
Ejemplo en Swift 2.0
Esta función da una respuesta correcta a la pregunta. La respuesta está en radianes, por lo que el uso para ver ángulos en grados es:
fuente
Basado en la referencia "Peter O". Aquí está la versión de Java
fuente
función matlab:
fuente
Una fórmula para un ángulo de 0 a 2pi.
Hay x = x2-x1 e y = y2-y1. La fórmula está funcionando para
cualquier valor de x e y. Para x = y = 0 el resultado es indefinido.
f (x, y) = pi () - pi () / 2 * (1 + signo (x)) * (1 signo (y ^ 2))
fuente
fuente
Pruebas
Para probar, dejo que la hipótesis genere casos de prueba.
fuente