Estoy aprendiendo a usar vectores normalizados en mis juegos.
Aprendí que para conocer el ángulo entre dos vectores, puedo usar el producto punto. Esto me da un valor entre -1 y 1, donde
- 1 significa que los vectores son paralelos y están orientados en la misma dirección (el ángulo es de 180 grados).
- -1 significa que son paralelas y se enfrentan a direcciones opuestas (todavía 180 grados).
0
significa que el ángulo entre ellos es de 90 grados.
Quiero saber cómo convertir el producto escalar de dos vectores, a un ángulo real en grados. Por ejemplo, si el producto escalar de dos vectores es 0.28
, ¿cuál es el ángulo correspondiente, entre 0 y 360 grados?
2d
mathematics
vector
geometry
usuario3150201
fuente
fuente
Respuestas:
dot(A,B) = |A| * |B| * cos(angle)
que se puede reorganizar a
angle = arccos(dot(A,B) / (|A|* |B|))
.Con esta fórmula, puede encontrar el ángulo más pequeño entre los dos vectores, que estará entre 0 y 180 grados. Si lo necesita entre 0 y 360 grados, esta pregunta puede ayudarlo.
Por cierto, el ángulo entre dos vectores paralelos que apuntan en la misma dirección debería ser 0 grados, no 180.
fuente
Ampliaré un poco el comentario de TravisG y daré otra respuesta, haciendo uso del hecho de que su pregunta tenía la etiqueta "2D".
Puede obtener el ángulo entre dos vectores usando el producto de puntos, pero no puede obtener el ángulo firmado entre dos vectores que lo usan. Dicho de otra manera, si quieres girar un personaje con el tiempo hacia un punto, el producto punto te dará cuánto girar pero no en qué dirección. Sin embargo, existe otra fórmula simple que es muy útil cuando se combina con el producto de puntos. No solo tienes
dot(A,B) = |A| * |B| * cos(angle)
También puede tener otra fórmula (cuyo nombre inventé para la corrección política):
pseudoCross(A,B) = |A| * |B| * sin(angle)
donde si A = (a, b), B = (x, y), entonces pseudoCross (A, B) se define como el tercer componente del producto cruzado (a, b, 0) x (x, y, 0 ) En otras palabras:
a*x+b*y = |A| * |B| * cos(angle)
-b*x+a*y = |A| * |B| * sin(angle)
El ángulo con signo completo es entonces
angle=atanfull(-b*x+a*y,a*x+b*y)
(las funciones atanfull o atan2 lo perdonan si pasa valores no normalizados). Si A y B están normalizados, es decir, si|A|=|B|=1
, estos son simplemente:a*x+b*y = cos(angle)
-b*x+a*y = sin(angle)
Para una explicación más profunda, tenga en cuenta que las ecuaciones anteriores se pueden expresar mediante la ecuación matricial:
Sin embargo, a y b pueden expresarse como
a=cos(ang1)
,b=sin(ang1)
por algún valorang1
(noangle
). Por lo tanto, la matriz de la izquierda es una matriz de rotación que gira el vector (x, y) en la cantidad -ang1. ¡Esto es equivalente a cambiar a un marco de referencia donde el vector unitario "A" se trata como el vector / eje (1,0)! Entonces, simplemente dibujando el círculo unitario / triángulo rectángulo en este marco, puede ver por qué el vector resultante de ese producto es (cos (ángulo), sin (ángulo)).Si escribe (a, b) y (x, y) en forma polar, y aplica las fórmulas de diferencia de ángulo
cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)
ysin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)
, vuelve a expresar que los senos / cosenos están dados por este producto, ya que (lm) = ángulo. Alternativamente, esas identidades podrían usarse para ver por qué el producto lineal dado anteriormente rota un vector.Todas estas identidades significan que rara vez necesitas ángulos. Debido a que los ángulos pueden ser extraños (radianes / grados, convenciones para seno / coseno inverso), el hecho de que se repitan cada 2 * pi, esto en realidad puede ser más útil y le ahorrará un montón de lógica "if (ang <180)", etc.
fuente