Saltar al contenido

Forma directa de calcular el ángulo en el sentido de las agujas del reloj entre 2 vectores

Este artículo fue aprobado por nuestros expertos así garantizamos la veracidad de este ensayo.

Solución:

caso 2D

Así como el producto escalar es proporcional al coseno del ángulo, el determinante es proporcional a su seno. Entonces puedes calcular el ángulo así:

dot = x1*x2 + y1*y2      # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2      # determinant
angle = atan2(det, dot)  # atan2(y, x) or atan2(sin, cos)

La orientación de este ángulo coincide con la del sistema de coordenadas. En un sistema de coordenadas zurdo, es decir X apuntando a la derecha y y hacia abajo como es común en los gráficos por computadora, esto significará que obtendrá un signo positivo para los ángulos en el sentido de las agujas del reloj. Si la orientación del sistema de coordenadas es matemática con y hacia arriba, obtienes ángulos en sentido contrario a las manecillas del reloj como es la convención en matemáticas. Cambiar el orden de las entradas cambiará el signo, por lo que si no está satisfecho con los signos, simplemente cambie las entradas.

caso 3D

En 3D, dos vectores colocados arbitrariamente definen su propio eje de rotación, perpendicular a ambos. Ese eje de rotación no viene con una orientación fija, lo que significa que tampoco puede fijar de manera única la dirección del ángulo de rotación. Una convención común es dejar que los ángulos sean siempre positivos y orientar el eje de tal manera que encaje en un ángulo positivo. En este caso, el producto escalar de los vectores normalizados es suficiente para calcular los ángulos.

dot = x1*x2 + y1*y2 + z1*z2    #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))

Plano incrustado en 3D

Un caso especial es el caso en el que sus vectores no se colocan arbitrariamente, sino que se encuentran dentro de un plano con un vector normal conocido norte. Entonces el eje de rotación estará en la dirección norte también, y la orientación de norte fijará una orientación para ese eje. En este caso, puede adaptar el cálculo 2D anterior, incluido norte en el determinante para hacer su tamaño 3×3.

dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)

Una condición para que esto funcione es que el vector normal norte tiene unidad de longitud. Si no, tendrás que normalizarlo.

Como triple producto

Este determinante también podría expresarse como el producto triple, como señaló @Excrubulent en una edición sugerida.

det = n · (v1 × v2)

Esto podría ser más fácil de implementar en algunas API y brinda una perspectiva diferente de lo que está sucediendo aquí: el producto cruzado es proporcional al seno del ángulo y estará perpendicular al plano, por lo tanto, será un múltiplo de norte. Por lo tanto, el producto punto básicamente medirá la longitud de ese vector, pero con el signo correcto adjunto.

Para calcular el ángulo solo necesita llamar atan2(v1.s_cross(v2), v1.dot(v2)) para el caso 2D. Donde s_cross es el análogo escalar de la producción cruzada (área firmada del paralelogramo). Para el caso 2D, sería producción de cuña. Para el caso 3D, debe definir la rotación en el sentido de las agujas del reloj porque desde un lado del plano en el sentido de las agujas del reloj hay una dirección, desde el otro lado del plano hay otra dirección =)

Editar: este es el ángulo en sentido contrario a las agujas del reloj, el ángulo en el sentido de las agujas del reloj es justo opuesto

Esta respuesta es la misma que la de MvG, pero la explica de manera diferente (es el resultado de mis esfuerzos para tratar de entender por qué funciona la solución de MvG). Lo estoy publicando en la remota posibilidad de que otros lo encuentren útil.

El ángulo antihorario theta desde x para ycon respecto al punto de vista de su dado normal n (||n|| = 1), es dado por

atan2( punto(n, cruz(x,y)), punto(x,y) )

(1) = atan2( ||x|| ||y|| sen(theta), ||x|| ||y|| cos(theta) )

(2) = atan2( sin(theta), cos(theta) )

(3) = ángulo en sentido antihorario entre el eje x y el vector (cos(theta), sin(theta))

(4) = theta

donde ||x|| denota la magnitud de x.

El paso (1) sigue al señalar que

cruz(x,y) = ||x|| ||y|| pecado (theta) n,

y entonces

punto(n, cruz(x,y))

= punto(n, ||x|| ||y|| sin(theta) n)

= ||x|| ||y|| pecado(theta) punto(n, n)

que es igual

||x|| ||y|| pecado (theta)

Si ||n|| = 1.

El paso (2) se deriva de la definición de atan2señalando que atan2(cy, cx) = atan2(y,x)donde c es un escalar. El paso (3) se deriva de la definición de atan2. El paso (4) se sigue de las definiciones geométricas de cos y sin.

Recuerda dar visibilidad a este post si te valió la pena.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *