Digamos que tienes esto:
P1 = (x=2, y=50)
P2 = (x=9, y=40)
P3 = (x=5, y=20)
Suponga que P1
es el punto central de un círculo. Siempre es el mismo. Quiero el ángulo que está formado por P2
y P3
, o en otras palabras, el ángulo que está al lado P1
. El ángulo interior para ser precisos. Siempre será un ángulo agudo, menos de -90 grados.
Pensé: Hombre, eso es simple geometría matemática. Pero he buscado una fórmula durante alrededor de 6 horas, y solo encuentro personas que hablan de cosas complicadas de la NASA como arccos y productos escalares vectoriales. Mi cabeza se siente como si estuviera en un refrigerador.
¿Algunos gurús de las matemáticas que piensan que esto es un problema simple? No creo que el lenguaje de programación importe aquí, pero para aquellos que creen que sí lo es: java y aim-c. Lo necesito para ambos, pero no lo he etiquetado para estos.
Se vuelve muy simple si lo piensa como dos vectores, uno del punto P1 al P2 y otro del P1 al P3
entonces:
a = (p1.x - p2.x, p1.y - p2.y)
b = (p1.x - p3.x, p1.y - p3.y)
Luego puede invertir la fórmula del producto escalar:
para obtener el ángulo:
Recuerde que solo significa: a1 * b1 + a2 * b2 (solo 2 dimensiones aquí ...)
fuente
La mejor manera de lidiar con el cálculo de ángulos es usar
atan2(y, x)
que dado un puntox, y
devuelve el ángulo desde ese punto y elX+
eje con respecto al origen.Dado que el cálculo es
es decir, básicamente traduces los dos puntos por
-P1
(en otras palabras, traduces todo para queP1
termine en el origen) y luego consideras la diferencia de los ángulos absolutos deP3
y deP2
.La ventaja de
atan2
es que está representado el círculo completo (puede obtener cualquier número entre -π y π) donde, en cambioacos
, debe manejar varios casos dependiendo de los signos para calcular el resultado correcto.El único punto singular para
atan2
es(0, 0)
... lo que significa que ambosP2
yP3
deben ser diferentes,P1
ya que en ese caso no tiene sentido hablar de un ángulo.fuente
atan2
es exactamente lo que se necesita para este problema, pero parece que la mayoría de las personas que llegan a esta pregunta simplemente no pueden leer o no pueden entender por qué lasacos
soluciones basadas en datos son malas. Afortunadamente para mí, dejé la fase de "alguien está equivocado en Internet" ( xkcd.com/386 ) hace muchos años y no voy a comenzar una pelea por defender lo obvio :-)Permítanme darles un ejemplo en JavaScript, he luchado mucho con eso:
Bonificación: ejemplo con HTML5-canvas
fuente
sqrt
y elevando al cuadrado. Vea mi respuesta aquí (escrita en Ruby), o en esta demostración actualizada (JavaScript).Básicamente, lo que tienes son dos vectores, un vector de P1 a P2 y otro de P1 a P3. Entonces, todo lo que necesita es una fórmula para calcular el ángulo entre dos vectores.
Eche un vistazo aquí para obtener una buena explicación y la fórmula.
fuente
Si está pensando en P1 como el centro de un círculo, está pensando demasiado complicado. Tienes un triángulo simple, por lo que tu problema se puede resolver con la ley de los cosenos . No hay necesidad de ninguna transformación de coordenadas polares o algo por el estilo. Digamos que las distancias son P1-P2 = A, P2-P3 = B y P3-P1 = C:
Todo lo que necesita hacer es calcular la longitud de las distancias A, B y C.Estas están fácilmente disponibles en las coordenadas xey de sus puntos y el teorema de Pitágoras
fuente
P1-P2 = A
no debe leerse como "Para calcular A, reste P2 de P1", sino como "Estoy definiendo A como la distancia de P1 a P2", que luego se puede calcular usando la segunda ecuación. Solo quería definir una abreviatura de las distancias, para hacer las ecuaciones más legibles.Me encontré con un problema similar recientemente, solo necesitaba diferenciar entre ángulos positivos y negativos. En caso de que esto sea útil para alguien, recomiendo el fragmento de código que tomé de esta lista de correo sobre cómo detectar la rotación sobre un evento táctil para Android:
fuente
Solución geométrica muy simple con explicación
Hace unos días, tuve el mismo problema y tuve que sentarme con el libro de matemáticas. Resolví el problema combinando y simplificando algunas fórmulas básicas.
Consideremos esta figura-
Queremos saber ϴ , por lo que primero debemos averiguar α y β . Ahora, para cualquier línea recta
Sea- A = (ax, ay) , B = (bx, by) y O = (ox, oy) . Entonces, para la línea OA -
Del mismo modo, para la línea OB -
Ahora, lo necesitamos
ϴ = β - α
. En trigonometría tenemos una fórmula:Después de reemplazar el valor de
tan α
(de eqn-2) ytan b
(de eqn-3) en eqn-4, y aplicar la simplificación obtenemos-Entonces,
¡Eso es!
Ahora, tome la siguiente figura:
Este método C # o Java calcula el ángulo ( ϴ ) -
fuente
En Objective-C puedes hacer esto
O leer más aquí
fuente
Mencionaste un ángulo con signo (-90). En muchas aplicaciones, los ángulos pueden tener signos (positivos y negativos, consulte http://en.wikipedia.org/wiki/Angle ). Si los puntos son (digamos) P2 (1,0), P1 (0,0), P3 (0,1) entonces el ángulo P3-P1-P2 es convencionalmente positivo (PI / 2) mientras que el ángulo P2-P1- P3 es negativo. El uso de las longitudes de los lados no distinguirá entre + y - por lo que, si esto importa, deberá usar vectores o una función como Math.atan2 (a, b).
Los ángulos también pueden extenderse más allá de 2 * PI y aunque esto no es relevante para la pregunta actual, fue lo suficientemente importante que escribí mi propia clase de Ángulo (también para asegurarme de que los grados y los radianes no se mezclaran). Las preguntas sobre si el ángulo1 es menor que el ángulo2 depende fundamentalmente de cómo se definen los ángulos. También puede ser importante decidir si una línea (-1,0) (0,0) (1,0) se representa como Math.PI o -Math.PI
fuente
Recientemente, yo también tengo el mismo problema ... En Delphi es muy similar a Objective-C.
fuente
Aquí hay un método de C # para devolver el ángulo (0-360) en sentido antihorario desde la horizontal para un punto en un círculo.
Saludos, Paul
fuente
fuente
Hay una respuesta simple para esto usando matemáticas de la escuela secundaria.
Digamos que tienes 3 puntos
Para obtener el ángulo del punto A al B
angle = atan2(A.x - B.x, B.y - A.y)
Para obtener el ángulo del punto B al C
angle2 = atan2(B.x - C.x, C.y - B.y)
Acabo de usar este código en el proyecto reciente que hice, cambie la B a P1 ... también puede eliminar el "180 +" si lo desea
fuente
bueno, las otras respuestas parecen cubrir todo lo requerido, así que me gustaría agregar esto si estás usando JMonkeyEngine:
Vector3f.angleBetween(otherVector)
ya que eso es lo que vine a buscar aquí :)
fuente
}
fuente