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:
[ a,b] [x] [cos(angle)]
[-b,a] * [y] = [sin(angle)]
Sin embargo, a y b pueden expresarse como a=cos(ang1)
, b=sin(ang1)
por algún valor ang1
(no angle
). 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)
y sin(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.