Maison > développement back-end > C++ > Comment puis-je calculer efficacement l'angle dans le sens des aiguilles d'une montre entre deux vecteurs dans l'espace 2D et 3D ?

Comment puis-je calculer efficacement l'angle dans le sens des aiguilles d'une montre entre deux vecteurs dans l'espace 2D et 3D ?

Patricia Arquette
Libérer: 2024-11-21 07:44:09
original
857 Les gens l'ont consulté

How can I efficiently calculate the clockwise angle between two vectors in both 2D and 3D space?

Calcul efficace des angles dans le sens des aiguilles d'une montre entre des vecteurs

Traditionnellement, le calcul de l'angle entre deux vecteurs nécessitait l'utilisation du produit scalaire, qui détermine l'angle intérieur à l'intérieur la plage de 0 à 180 degrés. Cependant, cette approche présente des défis lors de la détermination du résultat approprié entre l'angle et son complémentaire.

Existe-t-il une méthode plus directe pour calculer l'angle dans le sens des aiguilles d'une montre ?

Cas 2D

De la même manière que le produit scalaire est lié au cosinus de l'angle, le déterminant est proportionnel à son sinus. En incorporant cette relation, nous pouvons calculer l'angle comme suit :

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)
Copier après la connexion
Copier après la connexion

L'orientation de l'angle calculé s'aligne sur celle du système de coordonnées. Dans un système de coordonnées gaucher où x pointe vers la droite et y pointe vers le bas, les angles dans le sens des aiguilles d'une montre donneront des valeurs positives. À l’inverse, dans un système de coordonnées mathématiques où y pointe vers le haut, le résultat reflète les angles dans le sens inverse des aiguilles d’une montre, comme c’est l’habitude en mathématiques. L'échange de l'ordre des vecteurs d'entrée modifie le signe, offrant ainsi la possibilité de modifier le signe du résultat.

Cas 3D

En trois dimensions, les vecteurs arbitraires définissent leur propre axe de rotation perpendiculaire aux deux. Puisque cet axe n’a pas d’orientation fixe, il n’est pas possible de déterminer de manière unique la direction de l’angle de rotation. Une convention courante consiste à attribuer des angles positifs et à aligner l'axe pour s'adapter à cette convention. Dans ce contexte, le produit scalaire des vecteurs normalisés suffit pour le calcul de l'angle :

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))
Copier après la connexion
Copier après la connexion

Plan intégré en 3D

Pour les vecteurs contraints dans un plan avec une normale connue vecteur n, il y a un cas particulier à considérer. L'axe de rotation coïncide avec n et l'orientation de n fixe l'orientation de l'axe. Dans ce scénario, nous pouvons modifier le calcul 2D ci-dessus pour inclure n dans le déterminant, le transformant en une matrice 3x3 :

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)
Copier après la connexion

Pour que ce calcul soit valide, le vecteur normal n doit être normalisé à l'unité longueur.

Alternativement, le déterminant peut être exprimé sous la forme d'un produit triple :

det = n · (v1 × v2)
Copier après la connexion

Cette approche peut être plus simple à implémenter dans certaines API et donne un aperçu de la mécanique sous-jacente : le produit vectoriel est proportionnel au sinus de l'angle et est perpendiculaire au plan, ce qui signifie qu'il est un multiple de n. Le produit scalaire mesure donc essentiellement la longueur de ce vecteur avec le signe correct appliqué.

Plage 0 – 360°

La plupart des implémentations atan2 renvoient des angles dans la plage [-π, π] en radians ou [-180°, 180°] en degrés. Pour obtenir des angles positifs compris entre [0, 2π] ou [0°, 360°], la transformation suivante peut être appliquée :

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)
Copier après la connexion
Copier après la connexion

Alternativement, l'expression suivante évite la distinction des cas :

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))
Copier après la connexion
Copier après la connexion

Cette technique de correction ne se limite pas à ce problème spécifique mais peut être appliquée à tout scénario impliquant atan2.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal