Primero encuentre la diferencia entre el punto de inicio 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 particular).
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
a continuación, calcular el ángulo (que se extiende desde el eje X positivo en P1
al eje Y positivos en P1
).
angleInDegrees = arctan(deltaY/deltaX) * 180/PI
Pero arctan
puede no ser ideal, ya que divide las diferencias de esta manera, se borrará la distinción necesaria para distinguir qué cuadrante se encuentra en el ángulo (ver más abajo). Utilice la siguiente vez si su idioma incluye una función de atan2
:
angleInDegrees = atan2(deltaY, deltaX) * 180/PI
EDITAR (22 de febrero, 2017): En general, sin embargo, llamar atan2(deltaY,deltaX)
sólo para conseguir el ángulo apropiado para cos
y sin
puede ser poco elegante. En esos casos, a menudo puede hacer lo siguiente en su lugar:
- Tratar
(deltaX, deltaY)
como vector.
- Normalice ese vector en un vector unitario. Para ello, dividir
deltaX
y deltaY
por la longitud del vector (sqrt(deltaX*deltaX+deltaY*deltaY)
), a menos que la longitud es 0.
- Después de eso,
deltaX
ahora ser el coseno del ángulo entre el vector y el eje horizontal (en la dirección de la X positiva al eje Y positivo en P1
).
- Y
deltaY
ahora será el seno de ese ángulo.
- Si la longitud del vector es 0, no tendrá un ángulo entre ella y el eje horizontal (por lo que no tendrá un seno y coseno significativos).
EDITAR (28 de febrero, 2017): Incluso sin normalizar (deltaX, deltaY)
:
- El signo de
deltaX
le indicará si el coseno se describe en el paso 3 es positivo o negativo.
- El signo de
deltaY
le dirá si el seno descrito en el paso 4 es positivo o negativo.
- Los signos de
deltaX
y deltaY
le dirá qué cuadrante el ángulo está en, en relación con el eje X positivo en P1
:
+deltaX
, +deltaY
: de 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 (proporcionados el 19 de julio, 2015 Eric Leschinski, que editó mi respuesta):
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
pasar todas las pruebas. Ver https://en.wikipedia.org/wiki/Unit_circle
Si has encontrado este y que está utilizando JavaScript es muy importante Tenga en cuenta que Math.sin y Math.¡toma radianes para que no necesites convertir el resultado en grados! Por lo tanto, ignore el bit * 180/PI. Tardé 4 horas en descubrirlo. :) – sidonaldson
¿Qué debería uno usar para calcular el ángulo a lo largo del eje vertical? – ZeMoon
@akashg: '90 - angleInDegrees'? – jbaums