J'apprends à utiliser des vecteurs normalisés dans mes jeux.
J'ai appris que pour connaître l'angle entre deux vecteurs, je peux utiliser le produit scalaire. Cela me donne une valeur entre -1 et 1, où
- 1 signifie que les vecteurs sont parallèles et font face à la même direction (l'angle est de 180 degrés).
- -1 signifie qu'ils sont parallèles et font face à des directions opposées (toujours à 180 degrés).
0
signifie que l'angle entre eux est de 90 degrés.
Je veux savoir comment convertir le produit scalaire de deux vecteurs, en un angle réel en degrés. Par exemple, si le produit scalaire de deux vecteurs est 0.28
, quel est l'angle correspondant, entre 0 et 360 degrés?
2d
mathematics
vector
geometry
user3150201
la source
la source
Réponses:
dot(A,B) = |A| * |B| * cos(angle)
qui peut être réorganisé
angle = arccos(dot(A,B) / (|A|* |B|))
.Avec cette formule, vous pouvez trouver le plus petit angle entre les deux vecteurs, qui sera compris entre 0 et 180 degrés. Si vous en avez besoin entre 0 et 360 degrés, cette question peut vous aider.
Soit dit en passant, l'angle entre deux vecteurs parallèles pointant dans la même direction devrait être de 0 degré et non de 180.
la source
Je vais développer un peu le commentaire de TravisG et donner une autre réponse, en utilisant le fait que votre question avait la balise "2D".
Vous pouvez obtenir l'angle entre deux vecteurs en utilisant le produit scalaire, mais vous ne pouvez pas obtenir l' angle signé entre deux vecteurs en l'utilisant. Autrement dit, si vous voulez tourner un personnage au fil du temps vers un point, le produit scalaire vous indiquera la distance à tourner mais pas dans quelle direction. Il existe cependant une autre formule simple qui est très utile lorsqu'elle est combinée avec le produit scalaire. Non seulement vous avez
dot(A,B) = |A| * |B| * cos(angle)
Vous pouvez également avoir une autre formule (dont j'ai inventé le nom pour le politiquement correct):
pseudoCross(A,B) = |A| * |B| * sin(angle)
où si A = (a, b), B = (x, y), alors pseudoCross (A, B) est défini comme étant le troisième composant du produit croisé (a, b, 0) x (x, y, 0 ). En d'autres termes:
a*x+b*y = |A| * |B| * cos(angle)
-b*x+a*y = |A| * |B| * sin(angle)
L'angle complet signé est alors
angle=atanfull(-b*x+a*y,a*x+b*y)
(les fonctions atanfull ou atan2 vous pardonnent si vous passez des valeurs non normalisées). Si A et B sont normalisés, c'est-à-dire si|A|=|B|=1
ce sont simplement:a*x+b*y = cos(angle)
-b*x+a*y = sin(angle)
Pour une explication plus approfondie, notez que les équations ci-dessus peuvent être exprimées par l'équation matricielle:
Mais a et b peuvent être exprimés en
a=cos(ang1)
,b=sin(ang1)
pour une certaine valeurang1
(nonangle
). Par conséquent, la matrice de gauche est une matrice de rotation qui fait tourner le vecteur (x, y) de la quantité -ang1. Cela équivaut à basculer dans un cadre de référence où le vecteur unitaire "A" est traité comme le vecteur / axe (1,0)! Donc, juste en dessinant le cercle unitaire / triangle rectangle dans ce cadre, vous pouvez voir pourquoi le vecteur résultant de ce produit est (cos (angle), sin (angle)).Si vous écrivez (a, b) et (x, y) sous forme polaire, et appliquez les formules de différence d'angle
cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)
etsin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)
, vous ré-exprimez que les sinus / cosinus sont donnés par ce produit, puisque (lm) = angle. Alternativement, ces identités pourraient être utilisées pour voir pourquoi le produit linéaire donné ci-dessus fait tourner un vecteur.Toutes ces identités signifient que vous avez rarement besoin d'angles. Parce que les angles peuvent être étranges - radian / degrés, conventions pour sinus / cosinus inverse, le fait qu'ils se répètent tous les 2 * pi - cela peut en fait être plus utile et vous faire économiser un tas de logique "if (ang <180)", etc.
la source