<< Systèmes de coordonnées polaires
Chapitre 8
Rotation en trois dimensions
Si vous ne changez pas de direction,
vous risquez de finir là où vous allez.
— Lao Tseu (vers 600–531 av. J.-C.)
Ce chapitre aborde le problème difficile de la description de l’orientation d’un objet en 3D. Il aborde également les concepts étroitement liés de rotation et de déplacement angulaire. Il existe plusieurs façons différentes d’exprimer l’orientation et le déplacement angulaire en 3D. Nous abordons ici les trois méthodes les plus importantes — matrices, angles d’Euler et quaternions — ainsi que deux formes moins connues — axe-angle et carte exponentielle. Pour chaque méthode, nous définissons précisément comment fonctionne la méthode de représentation, et nous discutons des particularités, des avantages et des inconvénients de la méthode.
Différentes techniques sont nécessaires dans différentes circonstances, et chaque technique a ses avantages et ses inconvénients. Il est important de savoir non seulement comment chaque méthode fonctionne, mais aussi quelle technique est la plus appropriée pour une situation particulière et comment convertir entre les représentations.
La discussion sur l’orientation en 3D est divisée en sections comme suit :
La section 8.1 aborde les différences subtiles entre des termes tels que « orientation », « direction » et « déplacement angulaire ».
La section 8.2 décrit comment exprimer l’orientation à l’aide d’une matrice.
La section 8.3 décrit comment exprimer le déplacement angulaire à l’aide des angles d’Euler.
La section 8.4 décrit les formes axe-angle et carte exponentielle.
La section 8.5 décrit comment exprimer le déplacement angulaire à l’aide d’un quaternion.
La section 8.6 compare et contraste les différentes méthodes.
La section 8.7 explique comment convertir une orientation d’une forme à une autre.
Ce chapitre utilise abondamment les termes espace objet et espace droit. Si vous n’êtes pas familier avec ces termes, vous devriez revenir à la section 3.2, où ils ont été introduits pour la première fois.
Avant de pouvoir commencer à discuter de la façon de décrire l’orientation en 3D, définissons d’abord précisément ce que nous cherchons à décrire. Le terme orientation est lié à d’autres termes similaires, tels que
direction
déplacement angulaire
rotation.
Intuitivement, nous savons que l’« orientation » d’un objet nous dit essentiellement dans quelle direction l’objet est orienté. Cependant, l’« orientation » n’est pas exactement la même chose que la « direction ».
Par exemple, un vecteur a une direction, mais pas une orientation. La différence est que quand un vecteur pointe dans une certaine direction, on peut tordre le vecteur le long de sa longueur (voir la figure 8.1), et il n’y a pas de changement réel du vecteur, puisqu’un vecteur n’a ni épaisseur ni dimension autre que sa longueur.

Figure 8.1 Tordre un vecteur n’entraîne aucun changement appréciable du vecteur
Contrairement à un simple vecteur, considérons un objet, comme un avion à réaction, pointant dans une certaine direction. Si nous tordons l’avion (voir la figure 8.2) de la même façon que nous avons tordu le vecteur, nous allons changer l’orientation de l’avion. Dans la section 8.3, nous appelons cette composante de rotation de l’orientation d’un objet le roulis.

Figure 8.2Tordre un objet change son orientation
La différence fondamentale entre direction et orientation se voit concrètement par le fait que nous pouvons paramétrer une direction en 3D avec seulement deux nombres (les angles de coordonnées sphériques — voir la section 7.3.2), alors qu’une orientation nécessite un minimum de trois nombres (angles d’Euler — voir la section 8.3).
La section 2.4.1 a expliqué qu’il est impossible de décrire la position d’un objet en termes absolus — nous devons toujours le faire dans le contexte d’un référentiel spécifique. Lorsque nous avons étudié la relation entre « points » et « vecteurs », nous avons remarqué que spécifier une position revient en fait à spécifier une quantité de translation depuis un autre point de référence donné (généralement l’origine d’un système de coordonnées).
De la même façon, l’orientation ne peut pas être décrite en termes absolus. Tout comme une position est donnée par une translation depuis un point connu, une orientation est donnée par une rotation depuis une orientation de référence connue (souvent appelée orientation « identité » ou « de base »). La quantité de rotation est appelée déplacement angulaire. En d’autres termes, décrire une orientation est mathématiquement équivalent à décrire un déplacement angulaire.
Nous disons « mathématiquement équivalent » parce que dans ce livre, nous faisons une distinction subtile entre « orientation » et des termes comme « déplacement angulaire » et « rotation ». Il est utile de penser à un « déplacement angulaire » comme à un opérateur qui accepte une entrée et produit une sortie. Une direction de transformation particulière est implicite ; par exemple, le déplacement angulaire depuis l’ancienne orientation vers la nouvelle orientation, ou depuis l’espace droit vers l’espace objet. Un exemple de déplacement angulaire est : « Faire tourner de autour de l’axe . » C’est une action que nous pouvons effectuer sur un vecteur.
Cependant, nous rencontrons fréquemment des variables d’état et d’autres situations dans lesquelles ce cadre d’opérateur entrée/sortie n’est pas utile et une relation parent/enfant est plus naturelle. Nous avons tendance à utiliser le mot « orientation » dans ces situations. Un exemple d’orientation est : « Debout et face à l’est. » Cela décrit un état des choses.
Bien entendu, nous pouvons décrire l’orientation « debout et face à l’est » comme un déplacement angulaire en disant : « Debout, face au nord, puis faire tourner de autour de l’axe . » Cette distinction entre orientation et déplacement angulaire est similaire à la distinction entre points et vecteurs, deux autres termes qui sont équivalents mathématiquement mais pas identiques conceptuellement. Dans les deux cas, le premier terme est utilisé principalement pour décrire un état unique, et le second est principalement utilisé pour décrire une différence entre deux états. Bien entendu, ces conventions sont purement une question de préférence, mais elles peuvent être utiles.
Vous entendrez peut-être aussi le mot « attitude » pour désigner l’orientation d’un objet, surtout si cet objet est un aéronef.
Une façon de décrire l’orientation d’un espace de coordonnées en 3D est d’indiquer dans quelle direction pointent les vecteurs de base de cet espace de coordonnées (les axes , et ). Bien entendu, nous ne mesurons pas ces vecteurs dans l’espace de coordonnées que nous cherchons à décrire — par définition, ils sont , et quelle que soit l’orientation de l’espace de coordonnées. Nous devons décrire les vecteurs de base en utilisant un autre espace de coordonnées. En faisant cela, nous avons établi l’orientation relative des deux espaces de coordonnées.
Lorsque ces vecteurs de base sont utilisés pour former les lignes d’une matrice , nous avons exprimé l’orientation sous forme matricielle.1 Une autre façon de dire tout cela est que nous pouvons exprimer l’orientation relative de deux espaces de coordonnées en donnant une matrice de rotation pouvant être utilisée pour transformer des vecteurs d’un espace de coordonnées à l’autre.

Figure 8.3 Définition d’une orientation à l’aide d’une matrice
Nous avons déjà vu comment une matrice peut être utilisée pour transformer des points d’un espace de coordonnées à un autre. Dans la figure 8.3, la matrice dans le coin supérieur droit peut être utilisée pour faire pivoter des points de l’espace objet de l’avion vers l’espace droit. Nous avons extrait les lignes de cette matrice pour mettre en évidence leur relation directe avec les coordonnées des axes du corps de l’avion. La matrice de rotation contient les axes de l’objet, exprimés dans l’espace droit. Simultanément, c’est une matrice de rotation : nous pouvons multiplier des vecteurs ligne par cette matrice pour transformer ces vecteurs des coordonnées de l’espace objet en coordonnées de l’espace droit.
Une question légitime à poser est : Pourquoi la matrice contient-elle les axes du corps exprimés à l’aide des coordonnées de l’espace droit ? Pourquoi pas les axes droits exprimés dans les coordonnées de l’espace objet ? Une autre façon de formuler cela est : Pourquoi avons-nous choisi de donner une matrice de rotation qui transforme les vecteurs de l’espace objet vers l’espace droit ? Pourquoi pas de l’espace droit vers l’espace objet ?
Du point de vue mathématique, cette question est un peu absurde. Comme les matrices de rotation sont orthogonales, leur inverse est la même que leur transposée (voir la section 6.3.2). Ainsi, la décision est entièrement cosmétique.
Mais d’un point de vue pratique, à notre avis, c’est assez important. Le cœur du problème est de savoir si vous pouvez écrire du code qui est intuitif à lire et fonctionne du premier coup, ou si cela demande beaucoup de travail de déchiffrement, ou une connaissance de conventions qui ne sont pas énoncées parce qu’elles sont « évidentes » pour tout le monde sauf vous. Permettez-nous donc une brève digression pour poursuivre une réflexion commencée lorsque nous avons introduit le terme « espace droit » dans la section 3.2.4 concernant les aspects pratiques de ce qui se passe lorsque les mathématiques des transformations d’espace de coordonnées sont traduites en code. Permettez-nous également d’exprimer quelques opinions basées sur nos observations de programmeurs aux prises avec des matrices de rotation. Nous ne nous attendons pas à ce que tout le monde soit d’accord avec nos affirmations, mais nous espérons que chaque lecteur appréciera au moins l’intérêt de considérer ces questions.
Certes, toute bonne bibliothèque mathématique aura une classe de matrice pouvant représenter n’importe quelle transformation arbitraire, c’est-à-dire qu’elle ne fait aucune hypothèse sur la valeur des éléments de la matrice. (Ou peut-être est-ce une matrice pouvant faire de la projection, ou une qui peut faire de la translation mais pas de la projection — ces distinctions ne sont pas importantes ici.) Pour une telle matrice, les opérations sont intrinsèquement exprimées en termes d’un espace de coordonnées d’entrée et d’un espace de coordonnées de sortie. Cela est simplement implicite dans l’idée de multiplication matricielle. Si vous devez passer de la sortie vers l’entrée, vous devez obtenir l’inverse de la matrice.
Il est courant d’utiliser la classe de matrice de transformation générique pour décrire l’orientation d’un objet. Dans ce cas, la rotation est traitée comme n’importe quelle autre transformation. L’interface reste en termes d’espace source et d’espace destination. Malheureusement, dans notre expérience, les deux opérations matricielles suivantes sont de loin les plus couramment utilisées :2
Prendre un vecteur de l’espace objet et l’exprimer en coordonnées droites.
Prendre un vecteur de l’espace droit et l’exprimer en coordonnées de l’espace objet.
Notez que nous devons pouvoir aller dans les deux sens. Nous n’avons aucune expérience ni preuve que l’une des directions soit significativement plus courante que l’autre. Mais plus important encore, la nature même des opérations et la façon dont les programmeurs pensent aux opérations est en termes d’« espace objet » et d’« espace droit » (ou d’une autre terminologie équivalente, telle que « espace parent » et « espace enfant »). Nous ne pensons pas à elles en termes d’espace source et d’espace destination. C’est dans ce contexte que nous souhaitons considérer la question posée au début de cette section : Quelle matrice devons-nous utiliser ?
Premièrement, nous devrions reculer un peu et nous rappeler la distinction mathematiquement insignifiante mais pourtant conceptuellement importante entre orientation et déplacement angulaire. (Voir les notes de terminologie à la fin de la section 8.1.) Si votre but est de créer une matrice qui effectue un déplacement angulaire spécifique (par exemple, « faire pivoter de 30 degrés autour de l’axe »), alors les deux opérations ci-dessus ne sont pas vraiment celles que vous avez en tête, et utiliser une matrice de transformation générique avec sa direction de transformation implicite ne pose pas de problème, donc cette discussion ne s’applique pas. Pour l’instant, nous nous concentrons sur la situation dans laquelle l’orientation d’un objet est stockée comme variable d’état.
Supposons que nous adoptions la politique courante et stockions l’orientation à l’aide de la matrice de transformation générique. Nous sommes obligés de choisir arbitrairement une convention, donc décidons que la multiplication par cette matrice transformera de l’espace objet vers l’espace droit. Si nous avons un vecteur dans l’espace droit et que nous devons l’exprimer en coordonnées de l’espace objet, nous devons multiplier ce vecteur par l’inverse3 de la matrice.
Voyons maintenant comment notre politique affecte le code qui est écrit et lu des centaines de fois par les programmeurs de jeux ordinaires.
Faire pivoter un vecteur de l’espace objet vers l’espace droit se traduit dans le code par une multiplication par la matrice.
Faire pivoter un vecteur de l’espace droit vers l’espace objet se traduit dans le code par une multiplication par l’inverse (ou la transposée) de la matrice.
Notez que le code ne correspond pas terme à terme aux intentions de haut niveau du programmeur. Cela oblige chaque utilisateur à se rappeler les conventions chaque fois qu’il utilise la matrice. Dans notre expérience, ce style de codage est un facteur contribuant à la difficulté que les débutants ont à apprendre à utiliser les matrices ; ils finissent souvent par transposer et négativer des choses au hasard quand les résultats ne semblent pas corrects.
Nous avons trouvé utile d’avoir une classe de matrice spéciale utilisée exclusivement pour stocker l’orientation d’un objet, et non pour des transformations arbitraires. La classe suppose, comme invariant, que la matrice est orthogonale, ce qui signifie qu’elle ne contient que de la rotation. (Nous supposerions probablement également que la matrice ne contient pas de réflexion, même si cela est possible dans une matrice orthogonale.) Avec ces hypothèses en place, nous sommes maintenant libres d’effectuer des rotations à l’aide de la matrice à un niveau d’abstraction plus élevé. Nos fonctions d’interface correspondent exactement aux intentions de haut niveau du programmeur. De plus, nous avons supprimé les détails déroutants d’algèbre linéaire liés aux vecteurs ligne versus vecteurs colonne, quel espace est à gauche ou à droite, quelle est la direction normale et laquelle est l’inverse, et ainsi de suite. Ou plutôt, nous avons confiné ces détails aux éléments internes de la classe — la personne qui implémente la classe doit certainement choisir une convention (et espérons-le la documenter). En fait, dans cette classe de matrice spécialisée, les opérations de « multiplier un vecteur » et « inverser cette matrice » ne sont pas très utiles. Nous préconiserions de garder cette classe de matrice dédiée confinée aux opérations en termes d’espace droit et d’espace objet, plutôt que de multiplier un vecteur.
Donc, revenons à la question posée au début de cette section : Quelle matrice devons-nous utiliser ? Notre réponse est : « Cela ne devrait pas avoir d’importance. » Par là, nous voulons dire qu’il y a une façon de concevoir votre code matriciel de telle sorte qu’il puisse être utilisé sans savoir quel choix a été fait. En ce qui concerne le code C++, c’est purement un changement cosmétique. Par exemple, peut-être remplaçons-nous simplement le nom de fonction multiply() par objectToUpright(), et de même, nous remplaçons multiplyByTranspose() par uprightToObject(). La version du code avec des espaces de coordonnées nommés descriptifs est plus facile à lire et à écrire.
Vous pourriez rencontrer le terme (très classique) de cosinus directeurs dans le contexte de l’utilisation d’une matrice pour décrire l’orientation. Une matrice de cosinus directeurs est la même chose qu’une matrice de rotation ; le terme fait simplement référence à une façon particulière d’interpréter (ou de construire) la matrice, et cette interprétation est intéressante et instructive, donc faisons une pause pour y regarder de plus près. Chaque élément d’une matrice de rotation est égal au produit scalaire d’un axe cardinal dans un espace avec un axe cardinal dans l’autre espace. Par exemple, l’élément central dans une matrice donne le produit scalaire que fait l’axe dans un espace avec l’axe dans l’autre espace.
Plus généralement, supposons que les vecteurs de base d’un espace de coordonnées soient les vecteurs unitaires mutuellement orthogonaux , et , tandis qu’un deuxième espace de coordonnées de même origine a comme base une base différente (mais également orthonormée) , et . (Permettez-nous de rompre avec la convention en supprimant tous les chapeaux des vecteurs unitaires dans cette section, pour éviter une surcharge visuelle distrayante dans les équations.) La matrice de rotation qui fait pivoter les vecteurs ligne du premier espace vers le second peut être construite à partir des cosinus des angles entre chaque paire de vecteurs de base. Bien sûr, le produit scalaire de deux vecteurs unitaires est exactement égal au cosinus de l’angle entre eux, donc le produit matriciel est
Ces axes peuvent être interprétés comme des entités géométriques plutôt que numériques, donc peu importe quelles coordonnées sont utilisées pour décrire les axes (à condition que nous utilisions le même espace de coordonnées pour les décrire tous), la matrice de rotation sera la même.
Par exemple, supposons que nos axes soient décrits à l’aide de coordonnées relatives à la première base. Alors , et ont les formes triviales , et , respectivement. Les vecteurs de base du second espace, , et , ont des coordonnées arbitraires. Lorsque nous substituons les vecteurs triviaux , et dans la matrice de l’équation (8.1) et développons les produits scalaires, nous obtenons
En d’autres termes, les lignes de la matrice de rotation sont les vecteurs de base de l’espace de coordonnées de sortie, exprimés à l’aide des coordonnées de l’espace de coordonnées d’entrée. Bien sûr, ce fait n’est pas seulement vrai pour les matrices de rotation, il est vrai pour toutes les matrices de transformation. C’est l’idée centrale du fonctionnement d’une matrice de transformation, qui a été développée dans la section 4.2.
Regardons maintenant l’autre cas. Au lieu d’utiliser des coordonnées relatives à la première base, nous mesurerons tout en utilisant le deuxième espace de coordonnées (l’espace de sortie). Cette fois, , et ont des formes triviales, et , et sont arbitraires. En les insérant dans la matrice des cosinus directeurs, nous obtenons
Cela dit que les colonnes de la matrice de rotation sont formées à partir des vecteurs de base de l’espace d’entrée, exprimés à l’aide des coordonnées de l’espace de sortie. Cela n’est pas vrai des matrices de transformation en général ; cela s’applique uniquement aux matrices orthogonales telles que les matrices de rotation.
Notons également que notre convention est d’utiliser des vecteurs ligne à gauche. Si vous utilisez des vecteurs colonne à droite, les choses seront transposées.
La forme matricielle est une forme très explicite de représentation de l’orientation. Cette nature explicite offre certains avantages.
La rotation des vecteurs est immédiatement disponible. La propriété la plus importante de la forme matricielle est que vous pouvez utiliser une matrice pour faire pivoter des vecteurs entre l’espace objet et l’espace droit. Aucune autre représentation de l’orientation ne le permet4 — pour faire pivoter des vecteurs, nous devons convertir l’orientation en forme matricielle.
Format utilisé par les API graphiques. En partie pour les raisons de l’élément précédent, les API graphiques utilisent des matrices pour exprimer l’orientation. (API signifie Interface de Programmation d’Application. Fondamentalement, c’est le code que nous utilisons pour communiquer avec le matériel graphique.) Lorsque nous communiquons avec l’API, nous allons devoir exprimer nos transformations sous forme de matrices. La façon dont nous stockons les transformations en interne dans notre programme dépend de nous, mais si nous choisissons une autre représentation, nous allons devoir les convertir en matrices à un certain point dans le pipeline graphique.
Concaténation de plusieurs déplacements angulaires. Un troisième avantage des matrices est qu’il est possible de « fusionner » les relations imbriquées d’espace de coordonnées. Par exemple, si nous connaissons l’orientation de l’objet A par rapport à l’objet B, et que nous connaissons l’orientation de l’objet B par rapport à l’objet C, alors en utilisant des matrices, nous pouvons déterminer l’orientation de l’objet A par rapport à l’objet C. Nous avons déjà rencontré ces concepts lorsque nous avons discuté des espaces de coordonnées imbriqués dans le chapitre 3, puis nous avons abordé la façon dont les matrices peuvent être concaténées dans la section 5.6.
Inversion de matrice. Lorsqu’un déplacement angulaire est représenté sous forme matricielle, il est possible de calculer le déplacement angulaire « opposé » en utilisant l’inversion matricielle. De plus, comme les matrices de rotation sont orthogonales, ce calcul est une simple transposition de la matrice.
La nature explicite d’une matrice présente certains avantages, comme nous l’avons vu, mais elle utilise neuf nombres pour stocker une orientation, alors qu’il est possible de paramétrer l’orientation avec seulement trois nombres. Les nombres « supplémentaires » dans une matrice peuvent causer certains problèmes.
Les matrices occupent plus de mémoire. Si nous devons stocker de nombreuses orientations (par exemple, des images-clés dans une séquence d’animation), cet espace supplémentaire pour neuf nombres au lieu de trois peut vraiment s’accumuler. Prenons un exemple modeste. Disons que nous animons un modèle humain décomposé en 15 pièces pour différentes parties du corps. L’animation est réalisée uniquement en contrôlant l’orientation de chaque partie par rapport à sa partie parente. Supposons que nous stockions une orientation pour chaque partie, par image, et que nos données d’animation soient stockées à un taux modeste, disons 15 Hz. Cela signifie que nous aurons 225 orientations par seconde. En utilisant des matrices et des nombres à virgule flottante 32 bits, chaque image occupera 8 100 octets. En utilisant des angles d’Euler (que nous rencontrerons à la section suivante 8.3), les mêmes données n’occuperaient que 2 700 octets. Pour seulement 30 secondes de données d’animation, les matrices prendraient 162 Ko de plus que les mêmes données stockées avec des angles d’Euler !
Difficile pour les humains. Les matrices ne sont pas intuitives pour les humains qui y travaillent directement. Il y a tout simplement trop de nombres, et ils sont tous entre et . De plus, les humains pensent naturellement à l’orientation en termes d’angles, mais une matrice est exprimée en termes de vecteurs. Avec de la pratique, nous pouvons apprendre à décoder l’orientation depuis une matrice donnée. (Les techniques de la section 4.2 pour visualiser une matrice aident beaucoup à cet égard.) Mais cela reste beaucoup plus difficile qu’avec les angles d’Euler. Et dans le sens inverse c’est beaucoup plus difficile — il faudrait une éternité pour construire la matrice pour une orientation non triviale à la main. En général, les matrices ne sont tout simplement pas la façon dont les gens pensent naturellement à l’orientation.
Les matrices peuvent être mal formées. Comme nous l’avons dit, une matrice utilise neuf nombres, alors que seulement trois sont nécessaires. En d’autres termes, une matrice contient six degrés de redondance. Il y a six contraintes qui doivent être satisfaites pour qu’une matrice soit « valide » pour représenter une orientation. Les lignes doivent être des vecteurs unitaires, et elles doivent être mutuellement perpendiculaires (voir la section 6.3.2).
Considérons ce dernier point plus en détail. Si nous prenons neuf nombres quelconques au hasard et créons une matrice , il est très peu probable que ces six contraintes soient satisfaites, et donc les neuf nombres ne formeront pas une matrice de rotation valide. En d’autres termes, les matrices peuvent être mal formées, du moins pour les besoins de représentation d’une orientation. Les matrices mal formées peuvent être un problème car elles peuvent entraîner des exceptions numériques, des graphiques étrangement déformés et d’autres comportements inattendus.
Comment pourrait-on se retrouver avec une mauvaise matrice ? Il y a plusieurs façons :
Nous pourrions avoir une matrice contenant de la mise à l’échelle, du cisaillement, de la réflexion ou de la projection. Quelle est l’« orientation » d’un objet qui a été affecté par de telles opérations ? Il n’y a vraiment pas de définition claire pour cela. Toute matrice non orthogonale n’est pas une matrice de rotation bien définie. (Voir la section 6.3 pour une discussion complète sur les matrices orthogonales.) Et les matrices de réflexion (qui sont orthogonales) ne sont pas non plus des matrices de rotation valides.
Nous pourrions simplement recevoir de mauvaises données d’une source externe. Par exemple, si nous utilisons un système d’acquisition de données physiques, comme la capture de mouvement, il pourrait y avoir des erreurs dues au processus de capture. De nombreux logiciels de modélisation sont réputés pour produire des matrices mal formées.
Nous pouvons en réalité créer de mauvaises données en raison des erreurs d’arrondi en virgule flottante. Par exemple, supposons que nous appliquions un grand nombre de changements incrémentiels à une orientation, ce qui pourrait se produire régulièrement dans un jeu ou une simulation permettant à un humain de contrôler interactivement l’orientation d’un objet. Le grand nombre de multiplications matricielles, soumis à une précision en virgule flottante limitée, peut résulter en une matrice mal formée. Ce phénomène est connu sous le nom de dérive matricielle. Nous pouvons lutter contre la dérive matricielle en orthogonalisant la matrice, comme nous l’avons déjà discuté dans la section 6.3.3.
Résumons ce que la section 8.2 a dit sur les matrices.
Les matrices sont une méthode « brute force » d’expression de l’orientation : nous listons explicitement les vecteurs de base d’un espace dans les coordonnées d’un espace différent.
Le terme matrice des cosinus directeurs fait allusion au fait que chaque élément d’une matrice de rotation est égal au produit scalaire d’un vecteur de base d’entrée avec un vecteur de base de sortie. Comme toutes les matrices de transformation, les lignes de la matrice sont les coordonnées dans l’espace de sortie des vecteurs de base de l’espace d’entrée. De plus, les colonnes d’une matrice de rotation sont les coordonnées dans l’espace d’entrée des vecteurs de base de l’espace de sortie, un fait qui n’est vrai qu’en vertu de l’orthogonalité d’une matrice de rotation.
La forme matricielle de représentation de l’orientation est utile principalement parce qu’elle nous permet de faire pivoter des vecteurs entre les espaces de coordonnées.
Les API graphiques modernes expriment l’orientation à l’aide de matrices.
Nous pouvons utiliser la multiplication matricielle pour fusionner des matrices pour des espaces de coordonnées imbriqués en une seule matrice.
L’inversion matricielle fournit un mécanisme pour déterminer le déplacement angulaire « opposé ».
Les matrices peuvent occuper deux à trois fois plus de mémoire que d’autres techniques. Cela peut devenir significatif lors du stockage d’un grand nombre d’orientations, comme des données d’animation.
Les nombres dans une matrice ne sont pas intuitifs pour les humains.
Toutes les matrices ne sont pas valides pour décrire une orientation. Certaines matrices contiennent un miroir ou un cisaillement. Nous pouvons nous retrouver avec une matrice mal formée soit en recevant de mauvaises données d’une source externe, soit par dérive matricielle.
Une autre méthode courante de représentation de l’orientation est connue sous le nom d’angles d’Euler. (Rappelons qu’Euler se prononce « oy-leur », pas « you-ler ».) La technique tire son nom du célèbre mathématicien qui les a développés, Leonhard Euler (1707–1783). La section 8.3.1 décrit comment fonctionnent les angles d’Euler et aborde les conventions les plus courantes. La section 8.3.2 aborde d’autres conventions pour les angles d’Euler, notamment le système important à axes fixes. Nous considérons les avantages et les inconvénients des angles d’Euler dans les sections 8.3.3 et 8.3.4. La section 8.3.5 résume les concepts les plus importants concernant les angles d’Euler.
Cette section utilise de nombreuses idées, termes et conventions de la section 7.3.2 concernant les coordonnées sphériques.
L’idée de base des angles d’Euler est de définir un déplacement angulaire comme une séquence de trois rotations autour de trois axes mutuellement perpendiculaires. Cela semble compliqué, mais c’est en réalité assez intuitif. (En fait, sa facilité d’utilisation par les humains est l’un de ses principaux avantages.)
Ainsi, les angles d’Euler décrivent l’orientation comme trois rotations autour de trois axes mutuellement perpendiculaires. Mais quels axes ? Et dans quel ordre ? Il s’avère que trois axes dans n’importe quel ordre fonctionneront, mais la plupart des gens ont trouvé pratique d’utiliser les axes cardinaux dans un ordre particulier. La convention la plus courante, celle que nous utilisons dans ce livre, est la convention dite « cap-tangage-roulis » pour les angles d’Euler. Dans ce système, une orientation est définie par un angle de cap, un angle de tangage et un angle de roulis.
Avant de définir précisément les termes cap, tangage et roulis, passons brièvement en revue les conventions d’espace de coordonnées que nous utilisons dans ce livre. Nous utilisons un système en main gauche, où est vers la droite, est vers le haut et est vers l’avant. (Consultez la figure 1.15 pour une illustration.) De même, si vous avez oublié comment la rotation positive est définie selon la règle de la main gauche, vous pourriez vouloir revenir à la figure 1.14 pour rafraîchir votre mémoire.
Étant donné des angles de cap, tangage et roulis, nous pouvons déterminer l’orientation décrite par ces angles d’Euler à l’aide d’un processus simple en quatre étapes.
Étape 1.Commencez dans l’orientation « identité » — c’est-à-dire avec les axes de l’espace objet alignés avec les axes droits.

Figure 8.4Étape 1 : Un objet dans son orientation identité
Étape 2.Effectuez la rotation de cap, en tournant autour de l’axe , comme indiqué dans la figure 8.5. Une rotation positive tourne vers la droite (dans le sens horaire vu d’en haut).

Figure 8.5 Étape 2 : Le cap est la première rotation et tourne autour de l’axe vertical
Étape 3.Après application du cap, le tangage mesure la quantité de rotation autour de l’axe . Il s’agit de l’axe de l’espace objet, pas de l’axe droit. En restant cohérent avec la règle de la main gauche, une rotation positive tourne vers le bas. En d’autres termes, le tangage mesure en réalité l’angle de déclinaison. Cela est illustré dans la figure 8.6.

Figure 8.6 Étape 3 : Le tangage est la deuxième rotation et tourne autour de l’axe latéral de l’objet
Étape 4.Après application des angles de cap et de tangage, le roulis mesure la quantité de rotation autour de l’axe . Là encore, il s’agit de l’axe de l’espace objet, pas de l’axe original de l’espace droit. La règle de la main gauche dicte que le roulis positif tourne dans le sens antihoraire vu depuis l’origine en regardant vers . Cela est illustré dans la figure 8.7.

Figure 8.7 Étape 4 : Le roulis est la troisième et dernière rotation et tourne autour de l’axe longitudinal de l’objet
Il peut sembler contradictoire que le roulis positif soit antihoraire, puisque le cap positif est horaire. Mais notez que le cap positif est horaire vu de l’extrémité positive de l’axe vers l’origine, la perspective opposée à celle utilisée lors du jugement horaire/antihoraire pour le roulis. Si nous regardons depuis l’origine vers l’extrémité positive de l’axe , alors le cap positif tourne bien dans le sens antihoraire. Ou si nous regardons depuis l’extrémité positive de l’axe vers l’origine (en regardant en arrière depuis devant l’objet), alors le roulis positif semble faire tourner l’objet dans le sens horaire. Dans les deux cas, la règle de la main gauche prévaut.
Vous avez maintenant atteint l’orientation décrite par les angles d’Euler. Notez la similitude des étapes 1–3 avec la procédure utilisée dans la section 7.3.2 pour localiser la direction décrite par les angles de coordonnées sphériques. En d’autres termes, nous pouvons considérer le cap et le tangage comme définissant la direction de base que l’objet regarde, et le roulis définissant la quantité de torsion.
Le système cap-tangage-roulis décrit dans la section précédente n’est pas la seule façon de définir une rotation à l’aide de trois angles autour d’axes mutuellement perpendiculaires. Il existe de nombreuses variantes sur ce thème. Certaines de ces différences s’avèrent être purement de nomenclature ; d’autres sont plus significatives. Même si vous aimez nos conventions, nous vous encourageons à ne pas sauter cette section, car des concepts très importants y sont abordés ; ces sujets sont une source de beaucoup de confusion, que nous espérons dissiper.
Tout d’abord, il y a la question triviale de la nomenclature. La variation la plus courante que vous rencontrerez a été popularisée par le domaine de l’aérospatiale, la méthode lacet-tangage-roulis (yaw-pitch-roll).5 Le terme « roulis » est complètement synonyme de « roulis » (bank), et pour tous les besoins ils sont identiques. De même, dans le contexte limité du lacet-tangage-roulis, le terme « lacet » est pratiquement identique au terme cap. (Cependant, dans un sens plus large, le mot « lacet » a en réalité une signification subtilement différente, et c’est cette différence subtile qui motive notre préférence pour le terme cap. Nous abordons cette distinction assez pointilleuse dans un instant, mais pour l’instant lacet et cap sont identiques.) Ainsi, essentiellement le lacet-tangage-roulis est le même système que le cap-tangage-roulis.
D’autres termes moins courants sont souvent utilisés. Le cap est aussi appelé azimut. L’angle vertical que nous appelons tangage est aussi appelé attitude ou élévation. Le dernier angle de rotation, que nous appelons « roulis », est parfois appelé inclinaison ou torsion.
Et, bien sûr, il y a ces mathématiciens pervers qui (motivés par le besoin d’économiser de l’espace lors d’écritures au tableau ?) insistent à agresser vos yeux avec un flot de lettres grecques. Vous pourriez voir l’un quelconque des suivants :
Tout est grec pour nous
| . |
Ce sont bien sûr des différences cosmétiques. Peut-être plus intéressant est le fait que vous entendrez souvent ces mêmes trois mots listés dans l’ordre inverse : roulis-tangage-lacet. (Une recherche rapide sur Google pour « roll pitch yaw » ou « yaw pitch roll » donne de nombreux résultats pour les deux formes, sans qu’aucune ne semble prédominante.) Compte tenu de l’importance de l’ordre des rotations, les gens sont-ils vraiment assez pervers pour choisir de les lister dans l’ordre inverse ? Nous ne nous attardons pas simplement sur la terminologie ici ; les distinctions de pensée suggérées par les différences de terminologie seront en réalité utiles lorsque nous considérerons comment convertir les angles d’Euler en une matrice de rotation. Il s’avère qu’il existe une explication tout à fait raisonnable pour cette convention « inversée » : c’est l’ordre dans lequel nous effectuons réellement les rotations dans un ordinateur !
Le système à axes fixes est très étroitement lié au système d’angles d’Euler. Dans un système d’angles d’Euler, la rotation s’effectue autour des axes du corps, qui changent après chaque rotation. Ainsi, par exemple, l’axe physique de l’angle de roulis est toujours l’axe longitudinal du corps en espace objet, mais en général il est orienté de façon arbitraire dans l’espace droit. Dans un système à axes fixes, en revanche, les axes de rotation sont toujours les axes droits fixes. Mais il s’avère que le système à axes fixes et le système d’angles d’Euler sont en réalité équivalents, à condition que nous effectuions les rotations dans l’ordre inverse.
Vous devriez visualiser l’exemple suivant pour vous convaincre que c’est vrai. Disons que nous avons un cap de et un tangage de . (Nous ignorons le roulis pour l’instant.) Selon la convention des angles d’Euler, nous effectuons d’abord la rotation autour de l’axe de cap et tournons de autour de l’axe vertical (l’axe ). Puis nous tournons autour de l’axe latéral de l’espace objet (l’axe ) d’un angle . Avec un schéma à axes fixes, nous arrivons à cette même orientation finale en effectuant les rotations dans l’ordre inverse. D’abord, nous effectuons le tangage, en tournant autour de l’axe droit de . Ensuite, nous effectuons la rotation de cap, en tournant autour de l’axe droit de . Bien que nous puissions visualiser les angles d’Euler, à l’intérieur d’un ordinateur lorsque nous faisons pivoter des vecteurs de l’espace droit vers l’espace objet, nous utilisons en réalité un système à axes fixes. Nous en discutons plus en détail dans la section 8.7.1, où nous montrons comment convertir des angles d’Euler en une matrice de rotation. Les conventions à axes fixes sont également appelées extrinsèques, les conventions d’angles d’Euler typiques étant appelées intrinsèques.
Les angles d’Euler tournent autour des axes du corps, de sorte que l’axe de rotation d’une étape donnée dépend des angles utilisés dans les rotations précédentes. Dans le système à axes fixes, les axes de rotation sont toujours les mêmes — les axes droits. Les deux systèmes sont équivalents, à condition que les rotations soient effectuées dans l’ordre inverse.
Nous voudrions maintenant mener une brève mais humble campagne en faveur d’une utilisation plus précise du terme « lacet ». Beaucoup de terminologie aéronautique est héritée de la terminologie nautique.6 Dans un contexte nautique, le sens original du mot « lacet » était essentiellement la même chose que le cap, à la fois en termes d’angle absolu et de changement de cet angle. Dans le contexte des avions et d’autres corps en rotation libre, cependant, nous ne pensons pas que le lacet et le cap soient la même chose. Un mouvement de lacet produit une rotation autour de l’axe de l’objet, alors qu’un changement de cap produit une rotation autour de l’axe droit. Par exemple, lorsqu’un pilote d’avion utilise les pédales pour contrôler le gouvernail de direction, il effectue une rotation de lacet, car la rotation causée par le gouvernail est toujours autour de l’axe de l’espace objet de l’avion. Imaginez un avion plongeant tout droit vers le bas. Si le pilote effectue un lacet de , l’avion se retrouvera « sur l’oreille », ne regardant plus vers le bas, mais vers l’horizon, avec un roulis de . Cela est illustré dans la figure 8.8.

Figure 8.8Cap versus lacet
En revanche, lorsque des joueurs navigant dans un jeu de tir à la première personne bougent la souris de gauche à droite, ils effectuent une rotation de cap. La rotation est toujours autour de l’axe vertical (l’axe droit). Si les joueurs regardent vers le bas et bougent la souris horizontalement pour effectuer une rotation de cap, ils continuent à regarder vers le bas et tournent sur place. L’important n’est certainement pas que le cap soit meilleur que le lacet parce que c’est ce que nous faisons dans les jeux de tir à la première personne. L’important est qu’un mouvement de lacet ne peut pas être accompli en ajustant un seul angle d’Euler, alors qu’un mouvement de cap peut l’être. C’est pourquoi nous pensons que « cap » est un meilleur terme : c’est l’action qui résulte lorsque vous effectuez un changement incrémental au premier angle d’Euler.
Hélas, le même argument peut être avancé contre le terme « tangage ». Si le roulis est non nul, un changement incrémental du deuxième angle d’Euler ne produit pas une rotation autour de l’axe latéral de l’objet. Mais il n’existe pas vraiment de mot simple et bon pour décrire l’angle que l’axe longitudinal de l’objet fait avec l’horizontale, ce qui est ce que le deuxième angle d’Euler spécifie vraiment. (« Inclinaison » ne convient pas car elle est spécifique aux conventions en main droite.)
Nous espérons que vous avez lu nos opinions avec l’humilité que nous avions l’intention d’y mettre, et que vous avez également reçu le message plus important : l’investigation de différences de convention (apparemment cosmétiques) peut parfois nous mener à une compréhension plus profonde des points subtils. Et parfois c’est simplement du pinaillage. Des générations d’ingénieurs aéronautiques ont mis des hommes sur la lune et des robots sur Mars, et construit des avions transportant en toute sécurité les auteurs vers et depuis des villes lointaines, en utilisant tout ce temps les termes lacet et roulis. Vous ne croiriez pas que certains de ces gars ne savent même pas qui nous sommes !? Face au choix de votre propre terminologie, nous disons d’utiliser le mot « cap » quand vous pouvez, mais si vous entendez le mot « lacet », pour l’amour de tout, n’en faites pas autant de cas que nous le faisons dans ces pages, surtout si la personne à qui vous parlez est plus intelligente que vous.
Bien que dans ce livre nous ne suivions pas les conventions de coordonnées aérospatiales en main droite (et que nous ayons un léger désaccord sur la terminologie), en ce qui concerne la stratégie de base des angles d’Euler, dans un sens physique, nous pensons qu’une conformité totale avec la sagesse des pères fondateurs de l’aérospatiale est la seule voie à suivre, du moins si votre univers a une notion de « sol ». Rappelons qu’en théorie, trois axes quelconques peuvent être utilisés comme axes de rotation, dans n’importe quel ordre. Mais vraiment, les conventions qu’ils ont choisies sont les seules qui ont un sens pratique, si vous voulez que les angles individuels soient utiles et significatifs. Peu importe comment vous étiquetez vos axes, le premier angle doit tourner autour de la verticale, le second autour de l’axe latéral du corps, et le troisième autour de l’axe longitudinal du corps.
Comme si tout cela ne suffisait pas, ajoutons-en encore quelques-unes. Dans le système que nous avons décrit, chaque rotation s’effectue autour d’un axe du corps différent. Cependant, le propre système original d’Euler était un système « symétrique » dans lequel les première et dernière rotations s’effectuent autour du même axe. Ces méthodes sont plus pratiques dans certaines situations, comme la description du mouvement d’une toupie, où les trois angles correspondent à la précession, la nutation et le spin. Vous pourriez rencontrer certains puristes qui s’opposent au nom « angles d’Euler » attaché à un système asymétrique, mais cet usage est répandu dans de nombreux domaines, donc soyez assuré que vous les surpassez en nombre. Pour distinguer les deux systèmes, les angles d’Euler symétriques sont parfois appelés angles d’Euler « propres », les conventions plus courantes étant appelées angles de Tait-Bryan, documentés pour la première fois par les pères fondateurs de l’aérospatiale que nous avons mentionnés [1]. O’Reilly [10] aborde les angles d’Euler propres et encore plus de méthodes pour décrire la rotation, comme le vecteur de Rodrigues, les paramètres de Cayley-Klein, et des remarques historiques intéressantes. Le résumé de James Diebel [3] compare différentes conventions d’angles d’Euler et les autres méthodes principales pour décrire la rotation, tout comme le fait ce chapitre, mais suppose un niveau plus élevé de sophistication mathématique.
Si vous devez travailler avec des angles d’Euler qui utilisent une convention différente de celle que vous préférez, nous offrons deux conseils :
Premièrement, assurez-vous de bien comprendre exactement comment fonctionne l’autre système d’angles d’Euler. Les petits détails comme la définition de la rotation positive et l’ordre des rotations font une grande différence.
Deuxièmement, la façon la plus simple de convertir les angles d’Euler dans votre format est de les convertir en forme matricielle puis de reconvertir la matrice dans votre style d’angles d’Euler. Nous apprendrons comment effectuer ces conversions dans la section 8.7. Manipuler directement les angles est beaucoup plus difficile qu’il n’y paraît. Voir [12] pour plus d’informations.
Les angles d’Euler paramétrisent l’orientation en utilisant seulement trois nombres, et ces nombres sont des angles. Ces deux caractéristiques des angles d’Euler présentent certains avantages par rapport à d’autres formes de représentation de l’orientation.
Les angles d’Euler sont faciles pour les humains — considérablement plus faciles que les matrices ou les quaternions. Peut-être parce que les nombres dans un triplet d’angles d’Euler sont des angles, ce qui est la façon naturelle dont les gens pensent à l’orientation. Si les conventions les plus appropriées à la situation sont choisies, alors les angles les plus pratiques peuvent être exprimés directement. Par exemple, l’angle de déclinaison est exprimé directement par le système cap-tangage-roulis. Cette facilité d’utilisation est un avantage sérieux. Lorsqu’une orientation doit être affichée numériquement ou saisie au clavier, les angles d’Euler sont vraiment le seul choix.
Les angles d’Euler utilisent la plus petite représentation possible. Les angles d’Euler utilisent trois nombres pour décrire une orientation. Aucun système ne peut paramétrer l’orientation 3D avec moins de trois nombres. Si la mémoire est limitée, les angles d’Euler sont le moyen le plus économique de représenter une orientation.
Une autre raison de choisir les angles d’Euler lorsque vous avez besoin d’économiser de l’espace est que les nombres stockés sont plus facilement compressés. Il est relativement facile de compresser les angles d’Euler dans un nombre de bits plus petit à l’aide d’un système à précision fixe trivial. Comme les angles d’Euler sont des angles, la perte de données due à la quantification est répartie uniformément. Les matrices et les quaternions nécessitent l’utilisation de très petits nombres, car les valeurs stockées sont des sinus et des cosinus des angles. La différence numérique absolue entre deux valeurs n’est pas proportionnelle à la différence perçue, cependant, comme c’est le cas avec les angles d’Euler. En général, les matrices et les quaternions ne se compressent pas facilement dans un système à virgule fixe.
Conclusion : si vous devez stocker beaucoup de données de rotation 3D dans aussi peu de mémoire que possible, comme c’est très courant lors de la gestion des données d’animation, les angles d’Euler (ou le format carte exponentielle — à aborder dans la section 8.4) sont les meilleurs choix.
N’importe quel ensemble de trois nombres est valide. Si nous prenons trois nombres au hasard, ils forment un ensemble valide d’angles d’Euler que nous pouvons interpréter comme une expression d’une orientation. En d’autres termes, il n’existe pas de chose qu’un ensemble invalide d’angles d’Euler. Bien sûr, les nombres ne sont peut-être pas corrects, mais au moins ils sont valides. Ce n’est pas le cas avec les matrices et les quaternions.
Cette section aborde certains inconvénients de la méthode des angles d’Euler pour représenter l’orientation ; principalement :
La représentation d’une orientation donnée n’est pas unique.
L’interpolation entre deux orientations est problématique.
Abordons ces points en détail. Premièrement, nous avons le problème que pour une orientation donnée, il existe de nombreux triplets d’angles d’Euler différents pouvant être utilisés pour décrire cette orientation. C’est ce qu’on appelle l’aliasage et cela peut être une inconvénience. Ces problèmes irritants sont très similaires à ceux rencontrés lors de la gestion des coordonnées sphériques dans la section 7.3.4. Des questions basiques comme « Deux triplets d’angles d’Euler représentent-ils le même déplacement angulaire ? » sont difficiles à répondre en raison de l’aliasage.
Nous avons déjà vu un type trivial d’aliasage avec les coordonnées polaires : ajouter un multiple de ne change pas l’orientation exprimée, même si les nombres sont différents.
Une deuxième forme d’aliasage plus gênante se produit parce que les trois angles ne sont pas complètement indépendants les uns des autres. Par exemple, un tangage vers le bas de 135° équivaut à un cap de 180°, un tangage vers le bas de 45°, puis un roulis de 180°.
Pour traiter l’aliasage des coordonnées sphériques, nous avons trouvé utile d’établir un ensemble canonique ; tout point donné a une représentation unique dans l’ensemble canonique qui est la façon « officielle » de décrire ce point en coordonnées polaires. Nous utilisons une technique similaire pour les angles d’Euler. Afin de garantir une représentation unique en angles d’Euler pour toute orientation donnée, nous restreignons les plages des angles. Une technique courante consiste à limiter le cap et le roulis à et à limiter le tangage à . Pour toute orientation, il n’existe qu’un seul triplet d’angles d’Euler dans l’ensemble canonique représentant cette orientation. (En réalité, il y a une singularité supplémentaire irritante qui doit être traitée, que nous décrivons dans un instant.) L’utilisation d’angles d’Euler canoniques simplifie beaucoup de tests de base comme « est-ce que je fais approximativement face à l’est ? »
Le type d’aliasage le plus célèbre (et irritant) dont souffrent les angles d’Euler est illustré par cet exemple : si nous nous orientons à droite de de cap et que nous nous penchons vers le bas de de tangage, c’est identique à un tangage vers le bas de 90° puis un roulis de 45°. En fait, une fois que nous choisissons comme angle de tangage, nous sommes restreints à tourner autour de l’axe vertical. Ce phénomène, dans lequel un angle de pour la deuxième rotation peut amener les première et troisième rotations à tourner autour du même axe, est connu sous le nom de blocage de cardan. Pour supprimer cet aliasage de l’ensemble canonique des triplets d’angles d’Euler, nous assignons toute rotation autour de l’axe vertical au cap dans le cas de blocage de cardan. En d’autres termes, dans l’ensemble canonique, si le tangage est , alors le roulis est zéro.
Cette dernière règle pour le blocage de cardan complète les règles pour l’ensemble canonique des angles d’Euler :
Conditions satisfaites par les angles d’Euler dans l’ensemble canonique
Lors de l’écriture de code C++ acceptant des arguments d’angles d’Euler, il est généralement préférable de s’assurer qu’il fonctionne avec des angles d’Euler dans n’importe quelle plage. Heureusement, c’est généralement facile ; les choses fonctionnent souvent sans prendre de précautions supplémentaires, surtout si les angles sont passés à des fonctions trigonométriques. Cependant, lors de l’écriture de code qui calcule ou retourne des angles d’Euler, il est bonne pratique de retourner le triplet d’angles d’Euler canonique. Les méthodes de conversion présentées dans la section 8.7 illustrent ces principes.

Figure 8.9 L’interpolation naïve peut causer une rotation excessive
Une idée fausse courante est que, en raison du blocage de cardan, certaines orientations ne peuvent pas être décrites avec des angles d’Euler. En réalité, pour les besoins de description d’une orientation, l’aliasage ne pose aucun problème. Pour être clair, n’importe quelle orientation en 3D peut être décrite avec des angles d’Euler, et cette représentation est unique dans l’ensemble canonique. De plus, comme nous l’avons mentionné dans la section précédente, il n’existe pas d’ensemble d’angles d’Euler « invalide ». Même si les angles sont hors de la plage habituelle, nous pouvons toujours nous mettre d’accord sur l’orientation décrite par les angles d’Euler.
Donc pour les besoins de simplement décrire l’orientation, l’aliasage n’est pas un problème majeur, surtout lorsque des angles d’Euler canoniques sont utilisés. Alors qu’est-ce qui est si mauvais dans l’aliasage et le blocage de cardan ? Disons que nous souhaitons interpoler entre deux orientations et . En d’autres termes, pour un paramètre donné, , nous souhaitons calculer une orientation intermédiaire qui interpole régulièrement de à à mesure que varie de à . C’est une opération extrêmement utile pour l’animation de personnages et le contrôle de caméra, par exemple.

Figure 8.10 L’interpolation naïve peut faire la rotation par le long chemin.
L’approche naïve à ce problème consiste à appliquer la formule d’interpolation linéaire standard (« lerp ») à chacun des trois angles indépendamment :
Interpolation linéaire simple entre deux angles
Cela est plein de problèmes.
Premièrement, si des angles d’Euler canoniques ne sont pas utilisés, nous pouvons avoir de grandes valeurs d’angles. Par exemple, imaginez que le cap de , noté , soit 720°. Supposons que . Or, , ce qui équivaut à 0°, donc essentiellement et ne sont qu’à 45° l’un de l’autre. Cependant, l’interpolation naïve fera presque deux tours dans la mauvaise direction, comme indiqué dans la figure 8.9.
Bien sûr, la solution à ce problème est d’utiliser des angles d’Euler canoniques. Nous pourrions supposer que nous interpolons toujours entre deux ensembles d’angles d’Euler canoniques. Ou nous pourrions tenter d’imposer cela en convertissant en valeurs canoniques dans notre routine d’interpolation. (Envelopper simplement les angles dans la plage est facile, mais traiter les valeurs de tangage hors de la plage est plus difficile.)
Cependant, même l’utilisation d’angles canoniques ne résout pas complètement le problème. Un deuxième type de problème d’interpolation peut se produire à cause de la nature cyclique des angles de rotation. Supposons que et . Notez que ce sont des valeurs canoniques pour le cap, toutes deux dans la plage . Les deux valeurs de cap ne sont qu’à l’une de l’autre, mais là encore, l’interpolation naïve ne se comportera pas correctement, effectuant la rotation par le long chemin avec une rotation horaire de au lieu de prendre le chemin plus court antihoraire de , comme indiqué dans la figure 8.10.
La solution à ce deuxième type de problème est d’envelopper les différences entre les angles utilisés dans l’équation d’interpolation dans la plage afin de trouver l’arc le plus court. Pour ce faire, nous introduisons la notation
Enveloppement d’un angle entre
où désigne la fonction plancher.
La fonction est un petit outil précis que tout programmeur de jeux devrait avoir dans sa boîte à outils. Elle gère élégamment les situations courantes dans lesquelles nous devons tenir compte de la nature cyclique des angles. Elle fonctionne en ajoutant ou soustrayant le multiple approprié de . Le listing 8.1 montre comment elle serait implémentée en C.
float wrapPi(float theta) {
// Vérifier si déjà dans la plage. Ce n'est pas strictement
// nécessaire, mais ce sera une situation très courante. Nous
// ne voulons pas subir une perte de vitesse et peut-être de
// précision en virgule flottante si ce n'est pas nécessaire.
if (fabs(theta) <= PI) {
// Une révolution est 2 PI.
const float TWOPPI = 2.0f*PI;
// Hors plage. Déterminer combien de "révolutions"
// nous devons ajouter.
float revolutions = floor((theta + PI) * (1.0f/TWOPPI));
// Soustraire
theta -= revolutions*TWOPPI;
}
return theta;
}
Revenons aux angles d’Euler. Comme prévu, l’utilisation de facilite la prise du chemin le plus court lors de l’interpolation entre deux angles :
Prendre le chemin le plus court lors de l’interpolation entre deux angles
Mais même avec ces deux pansements, l’interpolation des angles d’Euler souffre toujours du blocage de cardan, qui dans de nombreuses situations provoque un parcours saccadé et non naturel. L’objet pivote soudainement et semble bloqué quelque part. Le problème de base est que la vitesse angulaire n’est pas constante pendant l’interpolation. Si vous n’avez jamais vu à quoi ressemble le blocage de cardan, vous vous demandez peut-être pourquoi tout ce tapage. Malheureusement, il est très difficile d’apprécier pleinement le problème à partir d’illustrations dans un livre — vous devez l’expérimenter en temps réel. Heureusement, cependant, il est facile de trouver une animation illustrant le problème : faites simplement une recherche sur youtube.com pour « gimbal lock ».
Les deux premiers problèmes avec l’interpolation des angles d’Euler étaient irritants, mais certainement pas insurmontables. Les angles d’Euler canoniques et fournissent des solutions de contournement relativement simples. Le blocage de cardan, malheureusement, est plus qu’un inconvénient mineur ; c’est un problème fondamental. Pourrait-on peut-être reformuler nos rotations et concevoir un système qui ne souffre pas de ces problèmes ? Malheureusement, ce n’est pas possible. Il y a simplement un problème inhérent à l’utilisation de trois nombres pour décrire l’orientation 3D. Nous pourrions changer nos problèmes, mais pas les éliminer. Tout système qui paramétrise l’orientation en 3D en utilisant trois nombres est garanti d’avoir des singularités dans l’espace de paramétrage et donc d’être sujet à des problèmes comme le blocage de cardan. La forme carte exponentielle (voir la section 8.4), un schéma différent pour paramétrer la rotation 3D avec trois nombres, parvient à concentrer les singularités en un seul point : les antipodes. Ce comportement est plus bénin pour certaines situations pratiques, mais il ne supprime pas complètement les singularités. Pour ce faire, nous devons utiliser des quaternions, abordés dans la section 8.5.
Résumons nos conclusions de la section 8.3 sur les angles d’Euler.
Les angles d’Euler stockent l’orientation en utilisant trois angles. Ces angles sont des rotations ordonnées autour des trois axes de l’espace objet.
Le système le plus courant d’angles d’Euler est le système cap-tangage-roulis. Le cap et le tangage indiquent dans quelle direction l’objet regarde — le cap donne une « lecture de boussole » et le tangage mesure l’angle de déclinaison. Le roulis mesure la quantité de « torsion ».
Dans un système à axes fixes, les rotations s’effectuent autour des axes droits plutôt que des axes du corps en mouvement. Ce système est équivalent aux angles d’Euler, à condition que nous effectuions les rotations dans l’ordre inverse.
Beaucoup de gens intelligents utilisent beaucoup de termes différents pour les angles d’Euler, et ils peuvent avoir de bonnes raisons d’utiliser des conventions différentes.7 Il est préférable de ne pas se fier à la terminologie lors de l’utilisation d’angles d’Euler. Assurez-vous toujours d’obtenir une définition de travail précise, ou vous risquez d’être très confus.
Dans la plupart des situations, les angles d’Euler sont plus intuitifs pour les humains par rapport aux autres méthodes de représentation de l’orientation.
Lorsque la mémoire est limitée, les angles d’Euler utilisent la quantité minimale de données possible pour stocker une orientation en 3D, et les angles d’Euler sont plus facilement compressés que les quaternions.
Il n’existe pas d’ensemble invalide d’angles d’Euler. Trois nombres quelconques ont une interprétation significative.
Les angles d’Euler souffrent de problèmes d’aliasage en raison de la nature cyclique des angles de rotation et parce que les rotations ne sont pas complètement indépendantes les unes des autres.
L’utilisation d’angles d’Euler canoniques peut simplifier de nombreuses requêtes de base sur les angles d’Euler. Un triplet d’angles d’Euler est dans l’ensemble canonique si le cap et le roulis sont dans la plage et le tangage est dans la plage . De plus, si le tangage est , alors le roulis est zéro.
Le blocage de cardan se produit lorsque le tangage est . Dans ce cas, un degré de liberté est perdu car le cap et le roulis tournent tous les deux autour de l’axe vertical.
Contrairement à une idée fausse répandue, n’importe quelle orientation en 3D peut être représentée avec des angles d’Euler, et nous pouvons convenir d’une représentation unique pour cette orientation dans l’ensemble canonique.
La fonction est un outil très pratique qui simplifie les situations dans lesquelles nous devons gérer la nature cyclique des angles. Ces situations se présentent fréquemment en pratique, notamment dans le contexte des angles d’Euler, mais aussi à d’autres moments.
Les formes simples d’aliasage sont irritantes, mais il y a des solutions de contournement. Le blocage de cardan est un problème plus fondamental sans solution facile. Le blocage de cardan est un problème parce que l’espace des paramètres d’orientation présente une discontinuité. Cela signifie que de petits changements d’orientation peuvent entraîner de grands changements dans les angles individuels. L’interpolation entre des orientations à l’aide d’angles d’Euler peut s’emballer ou prendre un chemin erratique.
Le nom d’Euler est attaché à toutes sortes de choses liées à la rotation (nous venons de discuter des angles d’Euler dans la section 8.3). Son nom est également attaché au théorème de rotation d’Euler, qui dit essentiellement que tout déplacement angulaire 3D peut être accompli via une seule rotation autour d’un axe soigneusement choisi. Pour être plus précis, étant donné deux orientations quelconques et , il existe un axe tel que nous pouvons passer de à en effectuant une rotation autour de . Avec les angles d’Euler, nous avons besoin de trois rotations pour décrire toute orientation, car nous sommes restreints à tourner autour des axes cardinaux. Cependant, lorsque nous sommes libres de choisir l’axe de rotation, il est possible d’en trouver un tel qu’une seule rotation est nécessaire. De plus, comme nous le montrerons dans cette section, à quelques détails mineurs près, cet axe de rotation est uniquement déterminé.
Le théorème de rotation d’Euler conduit à deux méthodes étroitement liées pour décrire l’orientation. Commençons par quelques notations. Supposons que nous ayons choisi un angle de rotation et un axe de rotation passant par l’origine et parallèle au vecteur unitaire . (Dans ce livre, la rotation positive est définie selon la règle de la main gauche ; voir la section 1.3.3.)
En prenant les deux valeurs et telles quelles, nous avons décrit un déplacement angulaire sous la forme axe-angle. Alternativement, comme a une longueur unitaire, nous pouvons le multiplier par sans perte d’information, donnant le vecteur unique . Ce schéma pour décrire la rotation porte le nom plutôt intimidant et obscur de carte exponentielle.8 L’angle de rotation peut être déduit de la longueur de ; en d’autres termes, , et l’axe est obtenu en normalisant . La carte exponentielle est non seulement plus compacte que l’axe-angle (trois nombres au lieu de quatre), mais elle évite élégamment certaines singularités et possède de meilleures propriétés d’interpolation et de différentiation.
Nous n’allons pas aborder les formes axe-angle et carte exponentielle avec autant de détails que les autres méthodes de représentation de l’orientation, car en pratique leur utilisation est un peu spécialisée. Le format axe-angle est principalement un outil conceptuel. Il est important à comprendre, mais la méthode obtient relativement peu d’utilisation directe par rapport aux autres formats. Sa capacité notable est que nous pouvons directement obtenir un multiple arbitraire du déplacement. Par exemple, étant donné une rotation en format axe-angle, nous pouvons obtenir une rotation représentant le tiers de la rotation ou 2,65 fois la rotation, simplement en multipliant par le montant approprié. Bien sûr, nous pouvons effectuer cette même opération avec la carte exponentielle tout aussi facilement. Les quaternions peuvent faire cela par exponentiation, mais une inspection des mathématiques révèle qu’ils utilisent vraiment le format axe-angle sous le capot. (Même si les quaternions prétendent utiliser la carte exponentielle sous le capot !) Les quaternions peuvent également effectuer une opération similaire en utilisant slerp, mais d’une façon plus indirecte et sans la capacité pour les résultats intermédiaires de stocker des rotations au-delà de 180 degrés. Nous examinerons les quaternions dans la section 8.5.
La carte exponentielle est plus utilisée que l’axe-angle. Tout d’abord, ses propriétés d’interpolation sont meilleures que celles des angles d’Euler. Bien qu’elle ait des singularités (abordées ci-après), elles ne sont pas aussi gênantes que pour les angles d’Euler. Généralement, quand on pense à l’interpolation des rotations, on pense immédiatement aux quaternions ; cependant, pour certaines applications, comme le stockage de données d’animation, la carte exponentielle sous-estimée peut être une alternative viable [5]. Mais l’utilisation la plus importante et la plus fréquente de la carte exponentielle est de stocker non pas le déplacement angulaire, mais la vitesse angulaire. C’est parce que la carte exponentielle se différentie bien (ce qui est quelque peu lié à ses meilleures propriétés d’interpolation) et peut représenter facilement des rotations multiples.
Comme les angles d’Euler, les formes axe-angle et carte exponentielle présentent des aliasages et des singularités, bien que d’une manière légèrement plus restreinte et bénigne. Il y a une singularité évidente à l’orientation identité, ou à la quantité « aucun déplacement angulaire ». Dans ce cas, , et notre choix d’axe est sans importance — n’importe quel axe peut être utilisé. Notez cependant que la carte exponentielle cache élégamment cette singularité, puisque la multiplication par fait disparaître , peu importe quel axe de rotation est choisi. Une autre forme triviale d’aliasage dans l’espace axe-angle peut être produite en niant à la fois et . Cependant, la carte exponentielle esquive également ce problème, puisque négativer à la fois et laisse inchangé !
Les autres alias ne peuvent pas être aussi facilement éliminés. Comme avec les angles d’Euler, l’ajout d’un multiple de à produit un déplacement angulaire résultant dans la même orientation finale, et cette forme d’aliasage affecte à la fois l’axe-angle et la carte exponentielle. Cependant, ce n’est pas toujours un inconvénient — pour décrire la vitesse angulaire, cette capacité à représenter une telle rotation « supplémentaire » est une propriété importante et utile. Par exemple, il est tout à fait important de pouvoir distinguer une rotation autour de l’axe à une vitesse de par seconde d’une rotation autour du même axe à une vitesse de par seconde, même si ces déplacements résultent dans la même orientation finale lorsqu’ils sont appliqués pendant un nombre entier de secondes. Il n’est pas possible de capturer cette distinction en format quaternion.
Il s’avère que, étant donné tout déplacement angulaire pouvant être décrit par une matrice de rotation, la représentation en carte exponentielle est uniquement déterminée. Bien que plus d’une carte exponentielle puisse produire la même matrice de rotation, il est possible de prendre un sous-ensemble des cartes exponentielles (celles pour lesquelles ) et d’établir une correspondance biunivoque avec les matrices de rotation. C’est l’essence du théorème de rotation d’Euler.
Considérons maintenant la concaténation de plusieurs rotations. Disons que et sont deux rotations en format carte exponentielle. Le résultat de l’exécution des rotations en séquence, par exemple puis , n’est pas le même que l’exécution d’une rotation unique . Nous savons que cela ne peut pas être vrai, parce que l’addition vectorielle ordinaire est commutative, mais les rotations dans l’espace à trois dimensions ne le sont pas. Supposons que et . Avec nos conventions, c’est une rotation de tangage vers le bas de et une rotation de cap de vers l’est. En effectuant suivi de , nous finirions par regarder vers le bas avec notre tête pointant vers l’est, mais en faisant les choses dans l’ordre inverse, nous finissons « sur l’oreille » face à l’est. Mais que se passerait-il si les angles étaient beaucoup plus petits, disons au lieu de ? Maintenant, les rotations finales sont plus similaires. À mesure que nous réduisons la magnitude des angles de rotation, l’importance de l’ordre diminue, et à l’extrême, pour des rotations « infinitésimales », l’ordre est complètement sans importance. En d’autres termes, pour des rotations infinitésimales, les cartes exponentielles peuvent être additionnées vectoriellement. Les infinitésimaux sont des sujets importants du calcul, et ils sont au cœur de la définition du taux de changement. Nous examinons ces sujets dans le chapitre 11, mais pour l’instant, l’idée de base est que les cartes exponentielles ne s’additionnent pas vectoriellement lorsqu’elles sont utilisées pour définir une quantité de rotation (un déplacement angulaire ou une orientation), mais elles s’additionnent correctement vectoriellement lorsqu’elles décrivent un taux de rotation. C’est pourquoi les cartes exponentielles sont parfaitement adaptées pour décrire la vitesse angulaire.
Avant de quitter ce sujet, un regrettable avertissement concernant la terminologie. Des noms alternatifs pour ces deux concepts simples abondent. Nous avons essayé de choisir les noms les plus standard possible, mais il était difficile de trouver un fort consensus. Certains auteurs utilisent le terme « axe-angle » pour décrire les deux méthodes (étroitement liées) sans vraiment les distinguer. Encore plus déroutant est l’utilisation du terme « axe d’Euler » pour se référer à l’une ou l’autre forme (mais pas aux angles d’Euler !). « Vecteur de rotation » est un autre terme que vous pourriez voir attaché à ce que nous appelons carte exponentielle. Enfin, le terme « carte exponentielle », dans le contexte plus large de l’algèbre de Lie d’où provient le terme, fait en réalité référence à une opération (une « carte ») plutôt qu’à une quantité. Nous nous excusons de la confusion, mais ce n’est pas notre faute.
Le terme quaternion est un peu un mot à la mode en mathématiques 3D. Les quaternions portent une certaine mystique — ce qui est une façon euphémique de dire que beaucoup de gens trouvent les quaternions compliqués et confus. Nous pensons que la façon dont les quaternions sont présentés dans la plupart des textes contribue à leur confusion, et nous espérons que notre approche légèrement différente aidera à dissiper la « mystique » des quaternions.
Il y a une raison mathématique pour laquelle l’utilisation de seulement trois nombres pour représenter une orientation 3D est garantie de causer les problèmes que nous avons discutés avec les angles d’Euler, comme le blocage de cardan. Cela a quelque chose à voir avec des termes mathématiques assez avancés9 tels que « variétés ». Un quaternion évite ces problèmes en utilisant quatre nombres pour exprimer une orientation (d’où le nom quaternion).
Cette section décrit comment utiliser un quaternion pour définir un déplacement angulaire. Nous allons nous écarter quelque peu de la présentation traditionnelle, qui met l’accent sur l’interprétation intéressante (mais, à notre avis, non essentielle) des quaternions comme nombres complexes. Au lieu de cela, nous allons développer les quaternions principalement d’une perspective géométrique. Voici ce qui nous attend : Premièrement, la section 8.5.1 introduit quelques notations de base. La section 8.5.2 est probablement la section la plus importante — elle explique comment un quaternion peut être interprété géométriquement. Les sections 8.5.3 à 8.5.11 passent en revue les propriétés et opérations de base des quaternions, en examinant chacune d’une perspective géométrique. La section 8.5.12 aborde l’opération importante slerp, utilisée pour interpoler entre deux quaternions et constituant l’un des principaux avantages des quaternions. La section 8.5.13 aborde les avantages et les inconvénients des quaternions. La section 8.5.14 est une digression facultative sur la façon dont les quaternions peuvent être interprétés comme des nombres complexes 4D. La section 8.5.15 résume les propriétés des quaternions.
Ne soyez pas effrayé par ce qui semble être beaucoup de mathématiques difficiles dans cette section. Les choses les plus importantes à retenir sur les quaternions sont les concepts de haut niveau résumés dans la section 8.5.15. Les détails concrets des quaternions sont donnés ici pour montrer que tout ce qui concerne les quaternions peut être dérivé, et vous n’avez pas à nous faire confiance sur parole. Une compréhension détaillée des quaternions n’est pas vraiment nécessaire pour les utiliser,9 mais vous devez comprendre ce que les quaternions peuvent faire.
Un quaternion contient une composante scalaire et une composante vectorielle 3D. Nous appelons généralement la composante scalaire . Nous pouvons désigner la composante vectorielle comme une entité unique ou comme des composantes individuelles , et . Voici des exemples des deux notations :
Deux types de notation de quaternion
Dans certains cas, il sera pratique d’utiliser la notation plus courte avec , et dans d’autres cas, la version « développée » est plus claire. Ce chapitre présente la plupart des équations dans les deux formes.
Nous pouvons également écrire les quaternions développés verticalement :
Contrairement aux vecteurs ordinaires, il n’y a pas de distinction significative entre quaternions « ligne » et « colonne ». Nous sommes libres de faire le choix strictement pour des raisons esthétiques.
Nous désignons les variables de quaternion avec les mêmes conventions de typographie utilisées pour les vecteurs : lettres minuscules en gras (par exemple, ). Lorsque des vecteurs et des quaternions apparaissent ensemble, le contexte (et les lettres choisies pour les variables !) rend généralement clair lesquels sont lesquels.
La forme quaternion est étroitement liée aux formes axe-angle et carte exponentielle de la section 8.4. Rappelons brièvement la notation de cette section, qui sera également utilisée ici. Le vecteur unitaire définit un axe de rotation, et le scalaire est la quantité de rotation autour de cet axe. Ainsi, la paire définit un déplacement angulaire à l’aide du système axe-angle. Vous avez besoin d’une main gauche ou droite11 pour déterminer quelle direction est la rotation positive.
Un quaternion contient également un axe et un angle, mais et ne sont pas simplement stockés directement dans les quatre nombres du quaternion, comme c’est le cas dans l’axe-angle (ce serait trop facile !). À la place, ils sont encodés d’une façon qui peut sembler étrange au premier abord, mais qui s’avère très pratique. L’équation (8.2) montre comment les valeurs d’un quaternion sont liées à et , en utilisant les deux formes de notation de quaternion :
Signification géométrique des quatre valeurs d’un quaternion
Gardez à l’esprit que est lié à , mais qu’ils ne sont pas identiques. De même, et sont liés, mais pas identiques.
Les sections suivantes discutent d’un certain nombre d’opérations sur les quaternions d’un point de vue mathématique et géométrique.
Les quaternions peuvent être négativés. Cela se fait de façon évidente en négativant chaque composante :
Négation d’un quaternion
Le fait surprenant concernant la négation d’un quaternion est qu’elle ne fait vraiment rien, du moins dans le contexte du déplacement angulaire.
Les quaternions et décrivent le même déplacement angulaire. Tout déplacement angulaire en 3D a exactement deux représentations distinctes en format quaternion, et elles sont négatives l’une de l’autre.
Il n’est pas trop difficile de voir pourquoi c’est vrai. Si nous ajoutons à , cela ne change pas le déplacement angulaire représenté par , mais cela négative les quatre composantes de .
Géométriquement, il existe deux quaternions « identité » représentant « aucun déplacement angulaire ». Ce sont :
Quaternions identité
(Notez le zéro en gras, qui indique le vecteur zéro.) Lorsque est un multiple pair de 360°, alors , et nous avons la première forme. Si est un multiple impair de 360°, alors , et nous avons la deuxième forme. Dans les deux cas, = 0, donc la valeur de est sans importance. Cela a un sens intuitif ; si l’angle de rotation est un nombre entier de révolutions complètes autour de n’importe quel axe, alors aucun changement réel n’est apporté à l’orientation.
Algébriquement, il n’y a vraiment qu’un seul quaternion identité : . Lorsque nous multiplions un quaternion quelconque par le quaternion identité, le résultat est . (Nous présentons la multiplication des quaternions dans la section 8.5.7.) Lorsque nous multiplions un quaternion par l’autre quaternion « identité géométrique » , nous obtenons . Géométriquement, cela donne le même quaternion, puisque et représentent le même déplacement angulaire. Mathématiquement, cependant, et ne sont pas égaux, donc n’est pas un « vrai » quaternion identité.
Nous pouvons calculer la norme d’un quaternion, tout comme nous pouvons le faire pour les vecteurs et les nombres complexes. La notation et la formule présentées dans l’équation (8.4) sont similaires à celles utilisées pour les vecteurs :
Norme d’un quaternion
Voyons ce que cela signifie géométriquement pour un quaternion de rotation :
Les quaternions de rotation ont une norme unitaire
C’est une observation importante.
Pour nos besoins d’utilisation des quaternions pour représenter l’orientation, tous les quaternions sont des quaternions unitaires, ayant une norme égale à l’unité.
Pour des informations concernant les quaternions non normalisés, voir le rapport technique de Dam et al. [2].
Le conjugué d’un quaternion, noté , est obtenu en négativant la partie vectorielle du quaternion :
Conjugué d’un quaternion
Le terme « conjugué » est hérité de l’interprétation d’un quaternion comme nombre complexe. Nous examinons cette interprétation plus en détail dans la section 8.5.14.
L’inverse d’un quaternion, noté , est défini comme le conjugué d’un quaternion divisé par sa norme :
Inverse d’un quaternion
L’inverse du quaternion présente une correspondance intéressante avec l’inverse multiplicatif pour les nombres réels (scalaires). Pour les nombres réels, l’inverse multiplicatif est . En d’autres termes, . Il en va de même pour les quaternions. Lorsque nous multiplions un quaternion par son inverse , nous obtenons le quaternion identité . (Nous abordons la multiplication des quaternions dans la section 8.5.7.)
L’équation (8.6) est la définition officielle de l’inverse d’un quaternion. Cependant, si vous n’êtes intéressé que par les quaternions représentant des rotations pures, comme c’est le cas dans ce livre, tous les quaternions sont des quaternions unitaires et le conjugué et l’inverse sont équivalents.
Le conjugué (inverse) est intéressant parce que et représentent des déplacements angulaires opposés. Il est facile de comprendre pourquoi. En négativant , nous négativons l’axe de rotation . Cela ne change pas l’axe dans le sens physique, puisque et sont parallèles. Cependant, cela inverse la direction que nous considérons comme rotation positive. Ainsi, tourne autour d’un axe d’un montant , et tourne dans la direction opposée du même montant.
Pour nos besoins, une définition alternative du conjugué de quaternion aurait pu être de négativer en laissant (et donc ) inchangé. Cela aurait négativé la quantité de rotation , plutôt que d’inverser ce qui est considéré comme rotation positive en retournant l’axe de rotation. Cela aurait été équivalent à la définition donnée dans l’équation (8.5) (pour nos besoins géométriques, du moins) et aurait fourni une interprétation géométrique légèrement plus intuitive. Cependant, le terme conjugué a une signification particulière dans le contexte des nombres complexes, donc restons avec la définition originale.
Les quaternions peuvent être multipliés. Le résultat est similaire au produit vectoriel pour les vecteurs, en ce qu’il produit un autre quaternion (pas un scalaire), et il n’est pas commutatif. Cependant, la notation est différente : nous notons la multiplication des quaternions simplement en plaçant les deux opérandes côte à côte. La formule pour la multiplication des quaternions peut être facilement dérivée à partir de la définition des quaternions comme nombres complexes (voir l’exercice 6), mais nous la présentons ici sans développement, en utilisant les deux notations de quaternion :
Produit de quaternions
Le produit de quaternions est également connu sous le nom de produit de Hamilton ; vous comprendrez pourquoi après avoir lu l’histoire des quaternions dans la section 8.5.14.
Mentionnons rapidement trois propriétés de la multiplication des quaternions, qui peuvent toutes être facilement démontrées en utilisant la définition donnée ci-dessus. Premièrement, la multiplication des quaternions est associative, mais pas commutative :
La multiplication des quaternions est associative, mais pas commutative
Deuxièmement, la norme d’un produit de quaternions est égale au produit des normes (voir l’exercice 9) :
Norme du produit de quaternions
C’est très significatif car cela nous garantit que lorsque nous multiplions deux quaternions unitaires, le résultat est un quaternion unitaire.
Enfin, l’inverse d’un produit de quaternions est égal au produit des inverses pris dans l’ordre inverse :
Inverse du produit de quaternions
Maintenant que nous connaissons quelques propriétés de base de la multiplication des quaternions, parlons de pourquoi l’opération est réellement utile. « Étendons » un point 3D standard dans l’espace des quaternions en définissant le quaternion . En général, n’est pas un quaternion de rotation valide, car il peut avoir une norme quelconque. Soit un quaternion de rotation dans la forme que nous avons discutée, , où est un vecteur unitaire axe de rotation, et est l’angle de rotation. Il est surprenant de réaliser que nous pouvons faire pivoter le point 3D autour de en effectuant la multiplication de quaternions plutôt curieuse
Utilisation de la multiplication de quaternions pour faire pivoter un vecteur 3D
Nous pourrions prouver cela en développant la multiplication, en substituant et , et en comparant le résultat à la matrice que nous avons dérivée pour faire pivoter autour d’un axe arbitraire (équation (5.1.3)), et c’est effectivement l’approche adoptée dans la plupart des textes sur les quaternions. Bien que cela soit certainement un moyen efficace de vérifier que l’astuce fonctionne, cela nous laisse à nous demander comment quelqu’un aurait pu tomber dessus en premier lieu. Dans la section 8.7.3, nous dérivons la conversion du quaternion en forme matricielle d’une façon directe, uniquement à partir de la géométrie des rotations et sans faire référence à . Quant à la façon dont l’association a été découverte, nous ne pouvons pas le dire avec certitude, mais nous offrirons une ligne de pensée pouvant conduire une personne à découvrir la connexion entre ce produit étrange et les rotations dans la section 8.5.14. Cette discussion explique également comment quelqu’un aurait pu découvrir qu’il serait fructueux d’utiliser la moitié de l’angle de rotation pour les composantes.
Il s’avère que la correspondance entre la multiplication des quaternions et les rotations de vecteurs 3D est davantage d’un intérêt théorique que pratique. Certaines personnes (« quaternionphiles » ?) aiment attribuer aux quaternions la propriété utile selon laquelle les rotations de vecteurs sont immédiatement accessibles en utilisant l’équation (8.7). Aux amoureux des quaternions, nous admettons que cette notation compacte est un avantage d’une certaine façon, mais son avantage pratique dans les calculs est discutable. Si vous effectuez réellement ces calculs, vous constaterez que le nombre d’opérations est à peu près le même que la conversion du quaternion en matrice de rotation équivalente (en utilisant l’équation (8.20), développée dans la section 8.7.3) puis la multiplication du vecteur par cette matrice. Pour cette raison, nous ne considérons pas que les quaternions possèdent une capacité directe à faire pivoter des vecteurs, du moins pour les besoins pratiques dans un ordinateur.
Bien que la correspondance entre et la rotation ne soit pas d’une importance pratique directe, elle est d’une importance théorique suprême. Elle nous conduit à une utilisation légèrement différente de la multiplication des quaternions, et cette utilisation est très pratique en programmation. Examinons ce qui se passe lorsque plusieurs rotations sont appliquées à un vecteur. Nous ferons pivoter le vecteur par le quaternion , puis nous ferons pivoter ce résultat par un autre quaternion :
Concaténation de plusieurs rotations avec l’algèbre des quaternions
Remarquez que faire pivoter par puis par est équivalent à effectuer une seule rotation par le produit de quaternions . C’est une observation clé.
La multiplication des quaternions peut être utilisée pour concaténer plusieurs rotations, tout comme la multiplication matricielle.
Nous disons « tout comme la multiplication matricielle », mais en fait il y a une différence légèrement irritante. Avec la multiplication matricielle, notre préférence d’utiliser des vecteurs ligne place les vecteurs à gauche, ce qui donne la belle propriété que les rotations concaténées se lisent de gauche à droite dans l’ordre de transformation. Avec les quaternions, nous n’avons pas cette flexibilité : la concaténation de plusieurs rotations se lira toujours « de l’intérieur vers l’extérieur » de droite à gauche.12
En utilisant la multiplication et l’inverse des quaternions, nous pouvons calculer la différence entre deux quaternions, « différence » signifiant le déplacement angulaire d’une orientation à une autre. En d’autres termes, étant donné les orientations et , nous pouvons calculer le déplacement angulaire qui tourne de vers . Cela peut être exprimé de façon compacte comme
(Rappelons que la multiplication des quaternions effectue les rotations de droite à gauche.)
Résolvons pour . Si les variables dans l’équation représentaient des scalaires, nous pourrions simplement diviser par . Cependant, représentaient des scalaires, nous pourrions simplement diviser par . Cependant, nous ne pouvons pas diviser les quaternions ; nous pouvons seulement les multiplier. Peut-être que la multiplication par l’inverse produira l’effet désiré ? En multipliant les deux membres par à droite (nous devons faire attention car la multiplication des quaternions n’est pas commutative), nous obtenons
La « différence » de quaternions
Nous avons maintenant un moyen de générer un quaternion représentant le déplacement angulaire d’une orientation à une autre. Nous l’utilisons à la Section 8.5.12, lorsque nous explorons le slerp.
Mathématiquement, la différence angulaire entre deux quaternions est en réalité plus similaire à une division qu’à une vraie différence (soustraction).
L’opération de produit scalaire est définie pour les quaternions. La notation et la définition de cette opération sont très similaires au produit scalaire de vecteurs :
Produit scalaire de quaternions
Comme le produit scalaire de vecteurs, le résultat est un scalaire. Pour des quaternions unitaires et , .
Le produit scalaire n’est peut-être pas l’un des opérateurs quaternioniques les plus fréquemment utilisés, du moins en programmation de jeux vidéo, mais il a une interprétation géométrique intéressante. À la Section 8.5.8, nous avons considéré le quaternion différence , qui décrit le déplacement angulaire de l’orientation vers l’orientation . (Nous supposons des quaternions unitaires et remplaçons l’inverse du quaternion par le conjugué.) Si nous développons le produit et examinons le contenu de , nous trouvons que la composante est égale au produit scalaire !
Qu’est-ce que cela signifie géométriquement ? Rappelons le théorème de rotation d’Euler : nous pouvons passer de l’orientation à l’orientation par une seule rotation autour d’un axe soigneusement choisi. Cet axe et cet angle, uniquement déterminés (à un renversement de signe près), sont précisément ceux encodés dans . En nous rappelant la relation entre la composante et l’angle de rotation , nous voyons que , où est la quantité de rotation nécessaire pour aller de l’orientation à l’orientation .
En résumé, le produit scalaire de quaternions a une interprétation similaire à celle du produit scalaire de vecteurs. Plus la valeur absolue du produit scalaire de quaternions est grande, plus les déplacements angulaires représentés par et sont « similaires ». Tandis que le produit scalaire de vecteurs donne le cosinus de l’angle entre les vecteurs, le produit scalaire de quaternions donne le cosinus de la moitié de l’angle nécessaire pour faire tourner un quaternion vers l’autre. Pour mesurer la similarité, nous nous intéressons généralement seulement à la valeur absolue de , car , même si et représentent le même déplacement angulaire.
Bien que l’utilisation directe du produit scalaire soit peu fréquente dans la plupart des codes de jeux vidéo, le produit scalaire est la première étape du calcul de la fonction slerp, dont nous parlons à la Section 8.5.12.
Cette section traite de trois opérations sur les quaternions qui, bien qu’elles soient rarement utilisées directement, constituent la base de plusieurs opérations quaternioniques importantes. Ces opérations sont le logarithme de quaternion, l’exponentielle, et la multiplication par un scalaire.
Commençons par reformuler notre définition d’un quaternion en introduisant une variable égale au demi-angle, :
Définition d’un quaternion en termes du demi-angle
Le logarithme de est défini comme suit
Le logarithme d’un quaternion
Nous utilisons la notation pour signifier « égal par définition ». En général, n’est pas un quaternion unitaire. Notez la similitude entre le calcul du logarithme d’un quaternion et le format de la carte exponentielle (voir Section 8.4).
La fonction exponentielle est définie de manière exactement inverse. Nous définissons d’abord le quaternion de la forme , avec un vecteur unitaire :
Alors la fonction exponentielle est définie comme suit
La fonction exponentielle d’un quaternion
Notez que, par définition, retourne toujours un quaternion unitaire.
Le logarithme et l’exponentielle de quaternions sont liés à leurs analogues scalaires. Pour tout scalaire ,
De même, la fonction exp de quaternion est définie comme étant l’inverse de la fonction log de quaternion :
Enfin, les quaternions peuvent être multipliés par un scalaire, le résultat étant calculé de manière évidente en multipliant chaque composante par le scalaire. Pour un scalaire et un quaternion ,
Multiplication d’un quaternion par un scalaire
Cela ne résultera généralement pas en un quaternion unitaire, c’est pourquoi la multiplication par un scalaire n’est pas une opération très utile dans le contexte de la représentation d’un déplacement angulaire. (Mais nous en trouverons une utilité à la Section 8.5.11.)
Les quaternions peuvent être exponentiés, ce qui signifie que l’on peut élever un quaternion à une puissance scalaire. L’exponentiation de quaternions, notée , ne doit pas être confondue avec la fonction exponentielle . La fonction exponentielle n’accepte qu’un seul argument : un quaternion. L’exponentiation de quaternions a deux arguments : le quaternion et l’exposant scalaire .
La signification de l’exponentiation de quaternions est similaire à celle des nombres réels. Rappelons que pour tout scalaire , différent de zéro, et . Lorsque l’exposant varie de à , la valeur de varie de à . Une affirmation similaire vaut pour l’exponentiation de quaternions : lorsque varie de à , l’exponentiation de quaternions varie de à .
L’exponentiation de quaternions est utile car elle nous permet d’extraire une « fraction » d’un déplacement angulaire. Par exemple, pour calculer un quaternion représentant un tiers du déplacement angulaire représenté par le quaternion , nous calculerions .
Les exposants hors de la plage se comportent généralement comme prévu — avec un bémol majeur. Par exemple, représente deux fois le déplacement angulaire de . Si représente une rotation de 30° dans le sens des aiguilles d’une montre autour de l’axe , alors représente une rotation de 60° dans le sens des aiguilles d’une montre autour de l’axe , et représente une rotation de 10° dans le sens contraire des aiguilles d’une montre autour de l’axe . Notons en particulier que la notation d’inverse peut également être interprétée dans ce contexte et le résultat est le même : le quaternion qui effectue la rotation opposée.
Le bémol que nous avons mentionné est le suivant : un quaternion représente les déplacements angulaires en utilisant l’arc le plus court. Les rotations multiples ne peuvent pas être représentées. Pour continuer notre exemple ci-dessus, n’est pas une rotation de 240° dans le sens des aiguilles d’une montre autour de l’axe comme prévu ; c’est une rotation de 120°\ dans le sens contraire des aiguilles d’une montre. Bien sûr, tourner de 240° dans un sens produit le même résultat final que tourner de 120° dans le sens opposé, et c’est là le point : les quaternions ne capturent vraiment que le résultat final. En général, beaucoup des identités algébriques concernant l’exponentiation de scalaires, telles que , ne s’appliquent pas aux quaternions.
Dans certaines situations, nous nous soucions effectivement de la quantité totale de rotation, pas seulement du résultat final. (L’exemple le plus important est celui de la vitesse angulaire.) Dans ces situations, les quaternions ne sont pas le bon outil ; utilisez plutôt la carte exponentielle (ou sa variante, le format axe-angle).
Maintenant que nous comprenons l’utilité de l’exponentiation de quaternions, voyons comment elle est définie mathématiquement. L’exponentiation de quaternions est définie en termes des opérations « utilitaires » que nous avons apprises à la section précédente. La définition est donnée par
Élever un quaternion à une puissance
Notez qu’une affirmation similaire est vraie concernant l’exponentiation d’un scalaire :
Il n’est pas trop difficile de comprendre pourquoi interpole de l’identité à lorsque varie de à . Notons que l’opération convertit essentiellement le quaternion en format carte exponentielle (à un facteur 2 près). Ensuite, lorsque nous effectuons la multiplication scalaire par l’exposant , l’effet est de multiplier l’angle par . Enfin, l’opération « défait » ce que l’opération a fait, en recalculant les nouveaux et à partir du vecteur exponentiel. C’est du moins ainsi que cela fonctionne académiquement dans une équation. Bien que l’Équation (8.8) soit la définition mathématique officielle et fonctionne élégamment en théorie, la traduction directe en code est plus compliquée que nécessaire. Le listing 8.2 montre comment nous pourrions calculer la valeur de en C. Essentiellement, au lieu de travailler avec une seule quantité de type carte exponentielle comme la formule nous le dit, nous extrayons l’axe et le demi-angle séparément.
// Quaternion (entrée et sortie)
float w,x,y,z;
// Exposant d'entrée
float exponent;
// Vérifier le cas d'un quaternion identité.
// Cela protège contre la division par zéro
if (fabs(w) < .9999f) {
// Extraire le demi-angle alpha (alpha = theta/2)
float alpha = acos(w);
// Calculer la nouvelle valeur d'alpha
float newAlpha = alpha * exponent;
// Calculer la nouvelle valeur de w
w = cos(newAlpha);
// Calculer les nouvelles valeurs xyz
float mult = sin(newAlpha) / sin(alpha);
x *= mult;
y *= mult;
z *= mult;
}
Il y a quelques points à noter concernant ce code. Premièrement, la vérification du quaternion identité est nécessaire car une valeur de entraînerait une division par zéro dans le calcul de mult. Élever un quaternion identité à n’importe quelle puissance résulte en le quaternion identité, donc si nous détectons un quaternion identité en entrée, nous ignorons simplement l’exposant et retournons le quaternion original.
Deuxièmement, lorsque nous calculons alpha, nous utilisons la fonction , qui retourne toujours un angle positif. Cela ne crée pas de perte de généralité. Tout quaternion peut être interprété comme ayant un angle de rotation positif, puisqu’une rotation négative autour d’un axe est identique à une rotation positive autour de l’axe pointant dans la direction opposée.
La raison d’être des quaternions dans les jeux et le graphisme aujourd’hui est une opération connue sous le nom de slerp, qui signifie interpolation Sphérique Linéaire (Spherical Linear interpolation). L’opération slerp est utile car elle nous permet d’interpoler en douceur entre deux orientations. Le slerp évite tous les problèmes qui affectaient l’interpolation des angles d’Euler (voir Section 8.3.4).
Le slerp est un opérateur ternaire, ce qui signifie qu’il accepte trois opérandes. Les deux premiers opérandes du slerp sont les deux quaternions entre lesquels nous souhaitons interpoler. Nous attribuerons ces orientations de départ et d’arrivée aux variables et , respectivement. Le paramètre d’interpolation sera attribué à la variable , et lorsque varie de à , la fonction slerp retourne une orientation qui interpole de à .
Voyons si nous pouvons dériver la formule slerp en utilisant les outils que nous avons jusqu’à présent. Si nous interpolions entre deux valeurs scalaires et , nous pourrions utiliser la formule standard d’interpolation linéaire (lerp) :
Interpolation linéaire simple
La formule standard d’interpolation linéaire fonctionne en partant de et en ajoutant la fraction de la différence entre et . Cela nécessite trois étapes de base :
Calculer la différence entre les deux valeurs.
Prendre une fraction de cette différence.
Prendre la valeur originale et l’ajuster de cette fraction de la différence.
Nous pouvons utiliser la même idée de base pour interpoler entre des orientations. (Rappelons encore que la multiplication de quaternions se lit de droite à gauche.)
Calculer la différence entre les deux valeurs. Nous avons montré comment faire cela à la Section 8.5.8. Le déplacement angulaire de à est donné par
Prendre une fraction de cette différence. Pour cela, nous utilisons l’exponentiation de quaternions, dont nous avons parlé à la Section 8.5.11. La fraction de la différence est donnée par
Prendre la valeur originale et l’ajuster de cette fraction de la différence. Nous « ajustons » la valeur initiale en composant les déplacements angulaires via la multiplication de quaternions :
Ainsi, l’équation du slerp est donnée par
Slerp de quaternions en théorie
Cette forme algébrique est la façon dont le slerp est calculé en théorie. En pratique, nous utilisons une formulation qui est mathématiquement équivalente, mais plus efficace sur le plan computationnel. Pour dériver cette formule alternative, nous commençons par interpréter les quaternions comme existant dans un espace euclidien 4D. Puisque tous les quaternions qui nous intéressent sont des quaternions unitaires, ils « vivent » sur la surface d’une hypersphère 4D. L’idée de base est d’interpoler autour de l’arc qui relie les deux quaternions, le long de la surface de l’hypersphère 4D. (D’où le nom d’interpolation sphérique linéaire.)
Nous pouvons visualiser cela dans le plan (voir Figure 8.11). Imaginons deux vecteurs 2D et , tous deux de longueur unitaire. Nous souhaitons calculer la valeur de , qui est le résultat de l’interpolation en douceur autour de l’arc d’une fraction de la distance de à . Si nous laissons 13 être l’angle sous-tendu par l’arc de à , alors est le résultat de la rotation de autour de cet arc d’un angle de .

Figure 8.11Interpolation d’une rotation
Nous pouvons exprimer comme une combinaison linéaire de et . En d’autres termes, il existe des constantes non négatives et telles que . Nous pouvons utiliser la géométrie élémentaire pour déterminer les valeurs de et . La Figure 8.12 montre comment cela peut être fait.

Figure 8.12Interpolation d’un vecteur le long d’un arc
En appliquant un peu de trigonométrie au triangle rectangle avec comme hypoténuse (et en rappelant que est un vecteur unitaire), nous voyons que
Une technique similaire pour résoudre donne le résultat suivant :
Ainsi, peut s’exprimer comme
La même idée de base peut être étendue à l’espace des quaternions, et nous pouvons reformuler le slerp comme
Slerp de quaternions en pratique
Nous avons juste besoin d’un moyen de calculer , l’« angle » entre les deux quaternions. Il se trouve qu’une analogie issue des mathématiques vectorielles 2D peut être portée dans l’espace des quaternions ; nous pouvons penser au produit scalaire de quaternions comme retournant .
Il y a deux légères complications. Premièrement, les deux quaternions et représentent la même orientation, mais peuvent produire des résultats différents lorsqu’ils sont utilisés comme arguments de slerp. Ce problème ne survient pas en 2D ou 3D, mais la surface d’une hypersphère 4D a une topologie différente de l’espace euclidien. La solution consiste à choisir les signes de et de sorte que le produit scalaire soit non négatif. Cela a pour effet de toujours sélectionner l’arc rotationnel le plus court de à . La seconde complication est que si et sont très proches, alors est très petit, et donc est également très petit, ce qui posera des problèmes lors de la division. Pour éviter cela, si est très petit, nous utiliserons une simple interpolation linéaire. L’extrait de code au Listing 8.3 applique tous ces conseils pour calculer le slerp de quaternions.
// Les deux quaternions d'entrée
float w0,x0,y0,z0;
float w1,x1,y1,z1;
// Le paramètre d'interpolation
float t;
// Le quaternion de sortie sera calculé ici
float w,x,y,z;
// Calculer le « cosinus de l'angle » entre les
// quaternions, en utilisant le produit scalaire
float cosOmega = w0*w1 + x0*x1 + y0*y1 + z0*z1;
// Si le produit scalaire est négatif, nier l'un des quaternions
// d'entrée, pour prendre le plus court « arc » en 4D
if (cosOmega < 0.0f) {
w1 = -w1;
x1 = -x1;
y1 = -y1;
z1 = -z1;
cosOmega = -cosOmega;
}
// Vérifier s'ils sont très proches, pour se protéger
// contre la division par zéro
float k0, k1;
if (cosOmega > 0.9999f) {
// Très proches - utiliser simplement l'interpolation linéaire
k0 = 1.0f-t;
k1 = t;
} else {
// Calculer le sinus de l'angle en utilisant l'identité
// trigonométrique sin^2(omega) + cos^2(omega) = 1
float sinOmega = sqrt(1.0f - cosOmega*cosOmega);
// Calculer l'angle à partir de son sinus et cosinus
float omega = atan2(sinOmega, cosOmega);
// Calculer l'inverse du dénominateur, pour ne diviser
// qu'une seule fois
float oneOverSinOmega = 1.0f / sinOmega;
// Calculer les paramètres d'interpolation
k0 = sin((1.0f - t) * omega) * oneOverSinOmega;
k1 = sin(t * omega) * oneOverSinOmega;
}
// Interpoler
w = w0*k0 + w1*k1;
x = x0*k0 + x1*k1;
y = y0*k0 + y1*k1;
z = z0*k0 + z1*k1;
Les quaternions offrent un certain nombre d’avantages par rapport aux autres méthodes de représentation des déplacements angulaires :
Interpolation en douceur. L’interpolation fournie par le slerp permet une interpolation en douceur entre les orientations. Aucune autre méthode de représentation ne permet une interpolation en douceur.
Concaténation et inversion rapides des déplacements angulaires. Nous pouvons concaténer une séquence de déplacements angulaires en un seul déplacement angulaire en utilisant le produit croisé de quaternions. La même opération avec des matrices implique plus d’opérations scalaires, bien que la plus rapide en pratique sur une architecture donnée ne soit pas si évidente : les opérations vectorielles à instruction unique et données multiples (SIMD) peuvent rendre la multiplication matricielle très rapide. Le conjugué de quaternion fournit un moyen de calculer le déplacement angulaire opposé de manière très efficace. Cela peut être fait en transposant une matrice de rotation, mais ce n’est pas facile avec les angles d’Euler.
Conversion rapide vers et depuis la forme matricielle. Comme nous le voyons à la Section 8.7, les quaternions peuvent être convertis vers et depuis la forme matricielle un peu plus rapidement que les angles d’Euler.
Seulement quatre nombres. Comme un quaternion contient quatre valeurs scalaires, il est considérablement plus économique qu’une matrice, qui utilise neuf nombres. (Cependant, il reste 33 % plus grand que les angles d’Euler.)
Ces avantages ont cependant un coût. Les quaternions souffrent de quelques-uns des problèmes qui affectent les matrices, mais dans une moindre mesure :
Légèrement plus grand que les angles d’Euler. Ce nombre supplémentaire peut sembler peu important, mais un supplément de 33 % peut faire une différence lorsque de grandes quantités de déplacements angulaires sont nécessaires, par exemple lors du stockage de données d’animation. Et les valeurs à l’intérieur d’un quaternion ne sont pas « régulièrement espacées » le long de l’intervalle ; les valeurs des composantes n’interpolent pas en douceur, même si l’orientation le fait. Cela rend les quaternions plus difficiles à compresser en nombre à virgule fixe que les angles d’Euler ou une carte exponentielle.
Peuvent devenir invalides. Cela peut arriver soit par des données d’entrée incorrectes, soit par une accumulation d’erreurs d’arrondi en virgule flottante. (Nous pouvons résoudre ce problème en normalisant le quaternion pour s’assurer qu’il a une magnitude unitaire.)
Difficiles à manipuler pour les humains. Parmi les trois méthodes de représentation, les quaternions sont les plus difficiles à utiliser directement par les humains.
Nous terminons notre discussion sur les quaternions là où la plupart des ouvrages commencent : une discussion de leur interprétation en tant que nombres complexes. Si vous vous intéressez aux quaternions uniquement pour les rotations, vous pouvez ignorer cette section en toute sécurité. Si vous voulez une compréhension plus approfondie ou si vous êtes intéressé par l’héritage mathématique des quaternions et les circonstances qui ont entouré leur invention, cette section sera intéressante. Nous suivrons une approche due à John McDonald de l’Université DePaul [9]. Entre autres, cette méthode est capable d’expliquer deux particularités des quaternions : l’apparition de plutôt que et la forme mathématique inhabituelle :
Nous commençons par examiner comment nous pouvons intégrer l’ensemble des nombres réels dans l’ensemble des matrices . Pour tout scalaire donné , nous l’associons à exactement une matrice , à savoir la matrice qui a sur les deux éléments diagonaux :
Chaque scalaire réel est associé à une matrice
Nous avons choisi un sous-ensemble des matrices et établi une correspondance bijective entre ce plus petit ensemble de matrices et l’ensemble de tous les nombres réels. Nous aurions pu établir cette relation bijective d’autres façons, mais cette façon particulière est importante car elle préserve toutes les lois algébriques ordinaires de l’addition, la soustraction et la multiplication : la propriété associative, la propriété distributive, la non-factorisabilité du zéro, etc. (Nous pouvons même inclure la division si nous la traitons comme une multiplication par l’inverse.) Par exemple,
Addition, soustraction et multiplication fonctionnent de la même manière
Voyons maintenant si nous pouvons créer une correspondance similaire pour l’ensemble des nombres complexes. Vous avez probablement déjà été initié aux nombres complexes ; si c’est le cas, vous devriez vous rappeler que la paire complexe définit le nombre . Le nombre est un nombre spécial tel que . On l’appelle souvent le nombre imaginaire car aucun scalaire ordinaire (un nombre « réel ») ne peut avoir cette propriété. Le mot « imaginaire » donne l’impression que le nombre n’existe pas vraiment ; nous allons éviter ce terme et nous en tenir à un plus descriptif : « complexe ».
Les nombres complexes peuvent être additionnés, soustraits et multipliés. Il suffit de suivre les règles ordinaires de l’arithmétique, et de remplacer par chaque fois qu’il apparaît. Cela donne les identités suivantes :
Addition, soustraction et multiplication de nombres complexes
Maintenant, comment pouvons-nous étendre notre système d’intégration des nombres dans l’espace des matrices pour inclure les nombres complexes ? Auparavant, nous n’avions qu’un seul degré de liberté, , et maintenant nous en avons deux, et . La correspondance que nous utilisons est
Association de chaque nombre complexe à une matrice
Nous pouvons facilement vérifier que le nombre complexe à gauche se comporte exactement de la même manière que la matrice à droite. En un certain sens, ce ne sont que deux notations pour écrire la même quantité :
Addition, soustraction et multiplication en notation standard et sous notre forme
Nous vérifions également que l’équation est toujours valide :
ne semble pas si « imaginaire » sous forme
Appliquons la perspective géométrique du Chapitre 5. En interprétant les colonnes14 et comme les vecteurs de base d’un espace de coordonnées, nous voyons que cette matrice effectue une rotation de .
Nous pouvons interpréter la multiplication par comme une rotation de .14
Il n’y a rien d’« imaginaire » là-dedans. Au lieu de penser à comme à la racine carrée de , pensez plutôt au nombre complexe comme à une entité mathématique avec deux degrés de liberté qui se comporte de manière particulière lorsqu’elle est multipliée. La partie que nous appelons habituellement la partie « réelle », , est le degré de liberté principal, et mesure un degré de liberté secondaire. Les deux degrés de liberté sont en un certain sens « orthogonaux » l’un à l’autre.
En poursuivant plus loin, nous voyons que nous pouvons représenter des rotations par n’importe quel angle arbitraire en utilisant ce schéma. La matrice de rotation de base dérivée à la Section 5.1.1 se trouve être dans cet ensemble spécial de matrices que nous associons aux nombres complexes. Elle est associée au nombre complexe :
Nombres complexes unitaires en tant que rotations
Remarquez comment la conjugaison complexe (négation de la partie complexe) correspond à la transposition matricielle. C’est particulièrement élégant. Rappelons que le conjugué d’un quaternion exprime le déplacement angulaire inverse. Un fait correspondant est vrai pour la transposition des matrices de rotation : comme elles sont orthogonales, leur transposée est égale à leur inverse.
Comment les vecteurs 2D ordinaires s’intègrent-ils dans ce schéma ? Nous interprétons le vecteur comme le nombre complexe , et nous pouvons alors interpréter la multiplication de deux nombres complexes
comme effectuant une rotation. Cela est équivalent à la multiplication matricielle
Bien que ce ne soit pas beaucoup plus que des anecdotes mathématiques pour l’instant, notre objectif est d’établir des parallèles que nous pourrons ensuite transposer aux quaternions, alors répétons le résultat clé.
En 2D, nous pouvons interpréter le vecteur comme un nombre complexe et le faire tourner en utilisant la multiplication complexe .
Une conversion similaire des vecteurs ordinaires vers les nombres complexes est nécessaire pour multiplier les quaternions et les vecteurs 3D.
Avant de quitter la 2D, résumons ce que nous avons appris jusqu’à présent. Les nombres complexes sont des objets mathématiques avec deux degrés de liberté qui obéissent à certaines règles lorsque nous les multiplions. Ces objets sont généralement écrits sous la forme , mais peuvent être écrits de manière équivalente sous la forme d’une matrice . Lorsque nous écrivons les nombres complexes sous forme de matrices, cela appelle l’interprétation géométrique de la multiplication par comme une rotation de . La règle a l’interprétation que combiner deux rotations de donne une rotation de , ce qui nous réconforte. Plus généralement, tout nombre complexe de longueur unitaire peut s’écrire et être interprété comme une rotation par l’angle . Si nous convertissons un vecteur 2D en forme complexe et le multiplions par , cela a pour effet d’effectuer la rotation.
Il est très tentant d’étendre cette technique de la 2D à la 3D. Tentant, mais hélas impossible de manière directe. Le mathématicien irlandais William Hamilton (1805–1865) a apparemment succombé à cette même tentation, et avait cherché pendant des années un moyen d’étendre les nombres complexes de la 2D à la 3D. Ce nouveau type de nombre complexe, pensait-il, aurait une partie réelle et deux parties imaginaires. Cependant, Hamilton ne put créer un type utile de nombre complexe avec deux parties imaginaires. Puis, selon la légende, en 1843, sur le chemin d’un discours à la Royal Irish Academy, il réalisa soudainement que trois parties imaginaires étaient nécessaires plutôt que deux. Il grava les équations définissant les propriétés de ce nouveau type de nombre complexe sur le Pont de Broom. Ses marques originales ont disparu dans la légende, mais une plaque commémorative les perpétue. C’est ainsi que les quaternions furent inventés.
Puisque nous n’étions pas sur le Pont de Broom en 1843, nous ne pouvons pas dire avec certitude ce qui a fait réaliser à Hamilton qu’un système 3D de nombres complexes ne fonctionnait pas, mais nous pouvons montrer pourquoi un tel ensemble ne pourrait pas être facilement associé aux matrices et aux rotations. Un nombre complexe 3D aurait deux parties complexes, et , avec les propriétés . (Nous aurions également besoin de définir les valeurs des produits et . Ce que ces règles devraient être, nous n’en sommes pas sûrs ; peut-être Hamilton a-t-il réalisé que c’était une impasse. De toute façon, cela n’a pas d’importance pour la présente discussion.) Or, une extension directe des idées de la 2D signifierait que nous pourrions d’une manière ou d’une autre associer les nombres 1, et à l’ensemble des matrices , de sorte que toutes les lois algébriques habituelles soient respectées. Le nombre 1 doit évidemment être associé à la matrice identité 3D . Le nombre devrait être associé à son opposé, , qui a des sur la diagonale. Mais nous rencontrons maintenant un problème pour trouver des matrices pour et dont le carré est . Nous pouvons rapidement voir que cela n’est pas possible car le déterminant de est . Pour être une racine de cette matrice, ou doit avoir un déterminant qui est la racine carrée de , car le déterminant d’un produit matriciel est le produit des déterminants. La seule façon que cela fonctionne est que et contiennent des entrées complexes. En bref, il ne semble pas exister de système cohérent de nombres complexes 3D ; il n’en existe certainement pas un qui s’associe élégamment aux rotations analogiquement aux nombres complexes standard et aux rotations 2D. Pour cela, nous avons besoin des quaternions.
Les quaternions étendent le système des nombres complexes en ayant trois nombres imaginaires, , et , qui sont liés par les fameuses équations de Hamilton :
Les règles pour les nombres complexes 4D que Hamilton a gravées sur le Pont de Broom
Le quaternion que nous avons noté correspond au nombre complexe . La définition du produit de quaternions donnée à la Section 8.5.7 découle de ces règles. (Voir aussi Exercice 6.) Le produit scalaire, cependant, ignore fondamentalement tout ce côté complexe et traite les opérandes comme de simples vecteurs 4D.
Revenons maintenant aux matrices. Pouvons-nous intégrer l’ensemble des quaternions dans l’ensemble des matrices de sorte que les règles de Hamilton de l’Équation (8.10) soient toujours respectées ? Oui, nous le pouvons, bien que, comme vous pouvez vous y attendre, nous les associions aux matrices . Les nombres réels sont associés à une matrice avec le nombre sur chaque entrée de la diagonale comme auparavant,
et les quantités complexes sont associées aux matrices
Association des trois quantités complexes à des matrices
Nous vous encourageons à vérifier que ces associations préservent bien toutes les règles de Hamilton avant de continuer.
En combinant les associations ci-dessus, nous pouvons associer un quaternion arbitraire à une matrice comme suit
Encodage des quaternions sous forme de matrices
Encore une fois, nous remarquons comment la conjugaison complexe (nier , , et ) correspond à la transposition matricielle.
Tout ce que nous avons dit jusqu’à présent s’applique aux quaternions de n’importe quelle longueur. Revenons maintenant aux rotations. Nous pouvons voir que les matrices , , de l’Équation (8.11) permutent et nient des axes, de sorte qu’elles présentent une certaine ressemblance avec les rotations de ou les réflexions. Voyons si nous pouvons transposer les idées simples de la 2D avec ces matrices. Notez comment la partie supérieure gauche de la matrice est identique à la toute première matrice pour ; en d’autres termes, une partie de est une rotation de autour de . Par analogie avec le cas 2D, on pourrait raisonnablement s’attendre à ce que le quaternion représente une rotation autour de l’axe par un angle arbitraire . Multiplions-le par le vecteur et voyons ce qui se passe. Comme dans le cas 2D, nous devons « promouvoir » le vecteur dans le domaine complexe ; ce qui est différent ici est que les quaternions ont un nombre supplémentaire. Nous associons au nombre complexe , donc le vecteur est simplement . En développant la multiplication, nous avons
ce qui correspond à , exactement ce que nous attendrions en faisant tourner l’axe autour de l’axe . Jusqu’ici, tout va bien. Essayons un vecteur légèrement plus général , qui est représenté dans le domaine complexe par :
Ce résultat ne correspond pas du tout à un vecteur, puisqu’il a une valeur non nulle pour . La rotation dans le plan a fonctionné comme prévu, mais malheureusement, la composante n’est pas sortie correctement. Il y a une rotation indésirable dans l’hyperplan . Cela est parfaitement clair en regardant comment est représenté sous forme de matrice :
La matrice de rotation en haut à gauche est celle que nous voulons ; la matrice de rotation en bas à droite n’est pas souhaitée.
Nous nous demandons maintenant si nous avons peut-être fait quelque chose de mal. Il existe peut-être d’autres racines de que nous pourrions utiliser pour , et — d’autres façons d’intégrer l’ensemble des quaternions dans l’ensemble des matrices . Il existe effectivement d’autres alternatives, et c’est un indice que quelque chose est un peu différent du cas 2D. Malheureusement, toutes ces alternatives présentent des variations de ce qui est essentiellement le même comportement que nous observons ici. Peut-être, à la place, notre problème est-il que nous avons effectué la multiplication dans le mauvais ordre. (Après tout, la multiplication de , et n’est pas commutative.) Essayons de placer le vecteur à gauche et le quaternion de rotation à droite :
En comparant cela avec l’Équation (8.13), lorsque les opérandes étaient dans l’ordre inverse, nous voyons que la seule différence est le signe de la coordonnée . À première vue, cela semble en fait pire. La rotation dans le plan que nous voulions a été inversée ; nous avons maintenant une rotation par . Entre-temps, la rotation supplémentaire que nous ne voulions pas est exactement la même qu’auparavant. Mais vous pouvez peut-être déjà voir la solution. Si nous utilisons la rotation opposée, qui correspond à utiliser le conjugué du quaternion, nous résolvons les deux problèmes :
Ainsi, la multiplication à gauche par produisait la rotation que nous voulions, plus une rotation supplémentaire indésirable, et la multiplication à droite par le conjugué a réalisé la même rotation désirée, avec la rotation indésirable opposée. Si nous combinons ces deux étapes, la rotation indésirable s’annule, et il ne reste que la rotation que nous voulons. Enfin, pas tout à fait, il reste deux fois la rotation que nous voulons, mais cela se corrige facilement en utilisant au lieu de . Bien sûr, nous savions que apparaîtrait quelque part, mais maintenant nous en voyons la raison. Résumons nos découvertes des paragraphes précédents.
Pour étendre les idées sur les nombres complexes et les rotations de la 2D aux quaternions, nous convertissons d’abord le vecteur en forme quaternionique sous . Une approche directe pour faire tourner le vecteur d’un angle autour de l’axe consisterait à créer le quaternion et à effectuer la multiplication . Cependant, cela ne fonctionne pas ; bien que le résultat contienne la rotation que nous voulons, il contient également une rotation indésirable vers . La multiplication produit également la rotation que nous voulons plus une rotation indésirable, mais dans ce cas la rotation indésirable est exactement opposée à celle produite par . La solution consiste à utiliser le demi-angle et à définir , et la rotation est réalisée en effectuant les deux multiplications : . La première rotation fait tourner à mi-chemin vers l’objectif, plus une rotation indésirable impliquant . La deuxième rotation complète la rotation désirée tout en annulant la rotation indésirable.
Avant de quitter cette section, revenons sur un dernier point plus subtil. Nous avons mentionné qu’il existe d’autres façons d’intégrer l’ensemble des quaternions dans l’ensemble des matrices . (Les Équations (8.11) et (8.12) ne sont pas les seules façons de le faire.) McDonald [9] explore cette idée plus en détail ; ici nous voulons simplement noter que c’est une autre cause sous-jacente du besoin de . En utilisant une seule multiplication, les variations dans l’intégration produiraient des variations dans le résultat de la rotation. Lorsque les deux multiplications sont présentes, le changement d’un style à un autre produit un changement à gauche qui est exactement annulé par le changement correspondant à droite.
La Section 8.5 a couvert beaucoup de mathématiques, et la plupart ne sont pas importants à retenir. Les faits qui sont importants à retenir sur les quaternions sont résumés ici.
Conceptuellement, un quaternion exprime un déplacement angulaire en utilisant un axe de rotation et une quantité de rotation autour de cet axe.
Un quaternion contient une composante scalaire et une composante vectorielle . Elles sont liées à l’angle de rotation et à l’axe de rotation par
Tout déplacement angulaire en 3D a exactement deux représentations différentes dans l’espace des quaternions, et elles sont les négatives l’une de l’autre.
Le quaternion identité, qui représente « aucun déplacement angulaire », est .
Tous les quaternions qui représentent un déplacement angulaire sont des « quaternions unitaires » de magnitude égale à 1.
Le conjugué d’un quaternion exprime le déplacement angulaire opposé et est calculé en niant la partie vectorielle . L’inverse d’un quaternion est le conjugué divisé par la magnitude. Si vous utilisez les quaternions uniquement pour décrire les déplacements angulaires (comme nous le faisons dans ce livre), alors le conjugué et l’inverse sont équivalents.
La multiplication de quaternions peut être utilisée pour concaténer plusieurs rotations en un seul déplacement angulaire. En théorie, la multiplication de quaternions peut également être utilisée pour effectuer des rotations de vecteurs 3D, mais cela a peu de valeur pratique.
L’exponentiation de quaternions peut être utilisée pour calculer un multiple d’un déplacement angulaire. Cela capture toujours le bon résultat final ; cependant, comme les quaternions prennent toujours l’arc le plus court, les révolutions multiples ne peuvent pas être représentées.
Les quaternions peuvent être interprétés comme des nombres complexes 4D, ce qui crée des parallèles intéressants et élégants entre les mathématiques et la géométrie.
Beaucoup plus a été écrit sur les quaternions que nous n’avons eu l’espace d’en discuter ici. Le rapport technique de Dam et al. [2] est un bon résumé mathématique. Le livre de Kuiper [8] est écrit depuis une perspective aérospatiale et fait également un bon travail de connexion entre les quaternions et les angles d’Euler. Le modestement intitulé Visualizing Quaternions de Hanson [6] analyse les quaternions en utilisant des outils de plusieurs disciplines différentes (Géométrie Riemannienne, nombres complexes, algèbre de Lie, repères mobiles) et est parsemé d’intéressantes anecdotes mathématiques et d’ingénierie ; il discute également de la façon de visualiser les quaternions. Une présentation plus courte sur la visualisation des quaternions est donnée par Hart et al. [7].
Passons en revue les découvertes les plus importantes des sections précédentes. Le Tableau 8.1 résume les différences entre les trois méthodes de représentation.
Rotation de points entre espaces de coordonnées (objet et droit)
Matrice : Possible ; peut souvent être fortement optimisé par les instructions SIMD.
Angles d’Euler : Impossible (il faut convertir en matrice de rotation).
Carte exponentielle : Impossible (il faut convertir en matrice de rotation).
Quaternion : Sur le tableau noir, oui. En pratique, dans un ordinateur, pas vraiment. Autant convertir en matrice de rotation.
Concaténation de plusieurs rotations
Matrice : Possible ; peut souvent être fortement optimisé par les instructions SIMD. Attention à la dérive matricielle.
Angles d’Euler : Impossible.
Carte exponentielle : Impossible.
Quaternion : Possible. Moins d’opérations scalaires que la multiplication matricielle, mais peut-être pas aussi facile de tirer parti des instructions SIMD. Attention à la dérive des erreurs.
Inversion des rotations
Matrice : Facile et rapide, en utilisant la transposition matricielle.
Angles d’Euler : Pas facile.
Carte exponentielle : Facile et rapide, en utilisant la négation de vecteur.
Quaternion : Facile et rapide, en utilisant le conjugué de quaternion.
Interpolation
Matrice : Extrêmement problématique.
Angles d’Euler : Possible, mais le blocage de Cardan provoque des comportements erratiques.
Carte exponentielle : Possible, avec quelques singularités, mais pas aussi problématique que les angles d’Euler.
Quaternion : Le slerp fournit une interpolation en douceur.
Interprétation directe par les humains
Matrice : Difficile.
Angles d’Euler : La plus facile.
Carte exponentielle : Très difficile.
Quaternion : Très difficile.
Efficacité de stockage en mémoire ou dans un fichier
Matrice : Neuf nombres.
Angles d’Euler : Trois nombres facilement quantifiables.
Carte exponentielle : Trois nombres facilement quantifiables.
Quaternion : Quatre nombres qui se quantifient mal ; peut être réduit à trois en supposant que la quatrième composante est toujours non négative et que le quaternion a une longueur unitaire.
Représentation unique pour une rotation donnée
Matrice : Oui.
Angles d’Euler : Non, en raison de l’aliasage.
Carte exponentielle : Non, en raison de l’aliasage, mais pas aussi compliqué que les angles d’Euler.
Quaternion : Exactement deux représentations distinctes pour tout déplacement angulaire, et elles sont les négatives l’une de l’autre.
Possibilité de devenir invalide
Matrice : Six degrés de redondance inhérents à la matrice orthogonale. La dérive matricielle peut survenir.
Angles d’Euler : Tout triplet de nombres peut être interprété sans ambiguïté.
Carte exponentielle : Tout triplet de nombres peut être interprété sans ambiguïté.
Quaternion : La dérive des erreurs peut survenir.
Tableau 8.1Comparaison des matrices, angles d’Euler, cartes exponentielles et quaternions
Certaines situations sont mieux adaptées à un format d’orientation ou à un autre. Les conseils suivants devraient vous aider à sélectionner le meilleur format :
Les angles d’Euler sont les plus faciles à utiliser pour les humains. L’utilisation des angles d’Euler simplifie grandement l’interaction humaine lors de la spécification de l’orientation des objets dans le monde. Cela inclut la saisie directe au clavier d’une orientation, la spécification d’orientations directement dans le code (c.-à-d., le positionnement de la caméra pour le rendu), et l’examen dans le débogueur. Cet avantage ne doit pas être sous-estimé. Ne sacrifiez certainement pas la facilité d’utilisation au nom de l’« optimisation » tant que vous n’êtes pas certain que cela fera une différence.
La forme matricielle doit éventuellement être utilisée si des transformations de l’espace de coordonnées de vecteurs sont nécessaires. Cependant, cela ne signifie pas que vous ne pouvez pas stocker l’orientation dans un autre format et générer ensuite une matrice de rotation lorsque vous en avez besoin. Une stratégie courante consiste à stocker la « copie principale » d’une orientation en format angle d’Euler ou quaternion, tout en maintenant également une matrice pour les rotations, en recalculant cette matrice chaque fois que les angles d’Euler ou le quaternion changent.
Pour le stockage de grands nombres d’orientations (p. ex., données d’animation), les angles d’Euler, les cartes exponentielles et les quaternions offrent divers compromis. En général, les composantes des angles d’Euler et des cartes exponentielles se quantifient mieux que les quaternions. Il est possible de stocker un quaternion de rotation en seulement trois nombres. Avant de supprimer la quatrième composante, nous vérifions son signe ; si elle est négative, nous nions le quaternion. Ensuite, la composante supprimée peut être récupérée en supposant que le quaternion a une longueur unitaire.
Une interpolation de bonne qualité fiable ne peut être réalisée qu’en utilisant des quaternions. Même si vous utilisez une forme différente, vous pouvez toujours convertir en quaternions, effectuer l’interpolation, puis reconvertir à la forme originale. L’interpolation directe en utilisant des cartes exponentielles pourrait être une alternative viable dans certains cas, car les points de singularité se situent à des orientations très extrêmes et peuvent en pratique souvent être facilement évités.
Pour la vitesse angulaire ou toute autre situation où les « tours supplémentaires » doivent être représentés, utilisez la carte exponentielle ou le format axe-angle.
Nous avons établi que différentes méthodes de représentation de l’orientation sont appropriées dans différentes situations, et avons également fourni quelques lignes directrices pour choisir la méthode la plus appropriée. Cette section traite de la façon de convertir un déplacement angulaire d’un format à un autre. Elle est divisée en six sous-sections :
Section 8.7.1 montre comment convertir des angles d’Euler en matrice.
Section 8.7.2 montre comment convertir une matrice en angles d’Euler.
Section 8.7.3 montre comment convertir un quaternion en matrice.
Section 8.7.4 montre comment convertir une matrice en quaternion.
Section 8.7.5 montre comment convertir des angles d’Euler en quaternion.
Section 8.7.6 montre comment convertir un quaternion en angles d’Euler.
Pour plus d’informations sur la conversion entre les formes de représentation, voir l’article de James Diebel [3].
Les angles d’Euler définissent une séquence de trois rotations. Chacune de ces trois rotations est une rotation simple autour d’un axe cardinal, donc chacune est facile à convertir individuellement en forme matricielle. Nous pouvons calculer la matrice qui définit le déplacement angulaire total en concaténant les matrices pour chaque rotation individuelle. Cet exercice est effectué dans de nombreux livres et sites web. Si vous avez déjà essayé d’utiliser l’une de ces références, vous vous êtes peut-être demandé : « Exactement que se passe-t-il si je multiplie un vecteur par cette matrice ? » La raison de votre confusion est qu’ils ont oublié de mentionner si la matrice effectue la rotation de l’espace objet vers l’espace droit ou de l’espace droit vers l’espace objet. En d’autres termes, il y a en réalité deux matrices différentes, pas seulement une. (Bien sûr, ce sont les transposées l’une de l’autre, donc, en un sens, il n’y a vraiment qu’une seule matrice.) Cette section montre comment calculer les deux.
Certains lecteurs16 pourraient penser que nous insistons trop sur le sujet. Vous avez peut-être compris comment utiliser cette matrice de rotation de ce livre ou site web, et maintenant c’est totalement évident pour vous. Mais nous avons vu cela constituer un obstacle pour trop de programmeurs, donc nous avons choisi d’insister sur ce point. Un exemple courant illustrera la confusion que nous avons observée.
Considérons une situation en temps réel typique avec des objets en mouvement. Supposons que l’orientation de chaque objet est maintenue au format angle d’Euler comme variable d’état. L’un de ces objets est la caméra, et naturellement nous utilisons le même système d’angles d’Euler pour décrire l’orientation de la caméra que pour tout autre objet. Maintenant, à un certain moment, nous aurons besoin de communiquer ces référentiels à l’API graphique. C’est là que la confusion se produit : la matrice que nous utilisons pour décrire l’orientation des objets n’est pas la même matrice que nous utilisons pour décrire l’orientation de la caméra ! L’API graphique nécessite deux types de matrices. (Nous les discuterons plus en détail à la Section 10.3.1.) La transformation de modèle est une matrice qui transforme les vecteurs de l’espace objet vers l’espace monde. La transformation de vue transforme les vecteurs de l’espace monde vers l’espace objet de la caméra. La partie rotation de la matrice de transformation de modèle est une matrice objet-vers-droit, mais la partie rotation de la matrice de transformation de vue est une matrice droit-vers-objet. Ainsi, parler de la matrice de rotation d’Euler omet quelques détails pratiques importants.
Maintenant, dérivons les matrices. Nous commençons par dériver la matrice objet-vers-droit qui effectue la rotation des points de l’espace objet vers l’espace droit. Nous utiliserons les matrices de rotation simple développées à la Section 5.1.2, et celles-ci ont été développées en utilisant la perspective de la transformation active (voir Section 3.3.1 si vous ne vous souvenez pas de la différence entre les transformations actives et passives). Ainsi, pour visualiser la tâche à accomplir, imaginez un point arbitraire sur notre objet. L’objet commence dans l’orientation « identité », et les coordonnées du corps pour notre point, que nous connaissons, sont également les coordonnées droites en ce moment car les deux espaces sont alignés. Nous effectuons la séquence de rotations d’Euler sur l’objet, et le point se déplace dans l’espace jusqu’à ce que, après la troisième rotation, l’objet soit arrivé dans l’orientation décrite par les angles d’Euler. Pendant tout ce temps, notre espace de coordonnées droit utilisé pour mesurer les coordonnées reste fixe. Donc le résultat final de ces calculs est les coordonnées droites pour le point dans son orientation arbitraire.
Il y a un dernier point à noter. Les matrices de rotation élémentaires que nous souhaitons utiliser comme blocs de construction effectuent chacune une rotation autour d’un axe cardinal. Avec les angles d’Euler, les axes de rotation sont les axes du corps, qui (après la première rotation) seront orientés de manière arbitraire. Donc au lieu de faire les rotations d’Euler autour des axes du corps, nous effectuons des rotations à axes fixes, où les rotations se font autour des axes droits. Cela signifie que nous effectuons en réalité les rotations dans l’ordre inverse : d’abord le roulis, puis le tangage, et enfin le cap. Voir la Section 8.3.2 si vous ne vous souvenez pas de ce que sont les rotations à axes fixes.
En résumé, la génération de la matrice de rotation objet-vers-droit est une concaténation simple de trois matrices de rotation simples,
où , et sont les matrices de rotation pour le roulis, le tangage et le cap, qui effectuent des rotations autour des axes -, - et -, respectivement. Nous avons appris à calculer ces matrices de rotation élémentaires à la Section 5.1.2.
Matrices de rotation élémentaires pour le roulis, le tangage et le cap
En assemblant le tout (et en omettant les calculs fastidieux des multiplications matricielles), nous obtenons
Matrice de rotation objet-vers-droit à partir des angles d’Euler
où nous avons introduit la notation abrégée
Pour effectuer la rotation des vecteurs de l’espace droit vers l’espace objet, nous utiliserons l’inverse de cette matrice objet-vers-droit. Nous savons que comme une matrice de rotation est orthogonale, l’inverse est simplement la transposée. Cependant, vérifions cela.
Pour visualiser la transformation droit-vers-objet, imaginons annuler les rotations à axes fixes. Nous annulons d’abord le cap, puis le tangage, et enfin le roulis. Comme auparavant, l’objet (et ses points) se déplacent dans l’espace, et nous utilisons les coordonnées droites pour tout mesurer. La seule différence est que cette fois nous partons des coordonnées droites. À la fin de ces rotations, les axes du corps de l’objet sont alignés avec les axes droits, et les coordonnées résultantes sont les coordonnées de l’espace objet :
Matrice de rotation droit-vers-objet à partir des angles d’Euler
En comparant les Équations (8.14) et (8.15), nous voyons que la matrice objet-vers-droit est bien la transposée de la matrice droit-vers-objet, comme prévu.
Notez également que nous pouvons considérer les matrices de rotation , et soit comme les inverses de leurs homologues, soit comme des matrices de rotation ordinaires utilisant les angles de rotation opposés.
La conversion d’un déplacement angulaire de la forme matricielle en représentation par angles d’Euler implique plusieurs considérations :
Nous devons savoir quelle rotation effectue la matrice : soit objet-vers-droit, soit droit-vers-objet. Cette section développe une technique utilisant la matrice objet-vers-droit. Le processus de conversion d’une matrice droit-vers-objet en angles d’Euler est très similaire, car les deux matrices sont les transposées l’une de l’autre.
Pour tout déplacement angulaire donné, il existe une infinité de représentations en angles d’Euler, en raison de l’aliasage des angles d’Euler (voir Section 8.3.4). La technique que nous présentons ici retourne toujours les angles d’Euler canoniques, avec le cap et le roulis dans la plage et le tangage dans la plage .
Certaines matrices peuvent être mal formées, et nous devons donc tolérer les erreurs de précision en virgule flottante. Certaines matrices contiennent des transformations autres que la rotation, comme la mise à l’échelle, la mise en miroir ou le cisaillement. La technique décrite ici ne fonctionne que sur des matrices de rotation correctes, peut-être avec l’imprécision habituelle en virgule flottante mais sans rien de grossièrement non orthogonal. Si cette technique est utilisée sur une matrice non orthogonale, les résultats sont imprévisibles.
En gardant ces considérations à l’esprit, nous cherchons à résoudre les angles d’Euler à partir de la matrice de rotation (Équation (8.14)) directement. Pour votre commodité, la matrice est développée ci-dessous :
Nous pouvons résoudre immédiatement à partir de :
La fonction de la bibliothèque standard C asin() retourne une valeur dans la plage radians, ce qui correspond à , exactement la plage de valeurs pour le tangage autorisées dans l’ensemble canonique.
Maintenant que nous connaissons , nous connaissons aussi . Supposons d’abord que . Puisque , cela signifie que . Nous pouvons déterminer et en divisant et par :
Une fois que nous connaissons le sinus et le cosinus d’un angle, nous pouvons calculer la valeur de l’angle avec la fonction de la bibliothèque standard C atan2(). Cette fonction retourne un angle dans la plage radians ( ), qui est de nouveau notre plage de sortie souhaitée. Connaître seulement le sinus ou le cosinus d’un angle n’est pas suffisant pour identifier de manière unique un angle pouvant prendre n’importe quelle valeur dans cette plage, c’est pourquoi nous ne pouvons pas simplement utiliser asin() ou acos().
En substituant les résultats de l’Équation (8.16), nous obtenons
Cependant, nous pouvons en fait simplifier cela car atan2(y,x) fonctionne en calculant l’arctangente du quotient , en utilisant les signes des deux arguments pour placer l’angle dans le bon quadrant. Comme , les divisions n’affectent pas les signes de ou , et ne changent pas non plus le quotient . En omettant les divisions inutiles par , le cap peut être calculé plus simplement par
Le roulis est calculé de manière similaire à partir de et :
Nous avons maintenant les trois angles. Cependant, si , alors nous ne pouvons pas utiliser l’astuce ci-dessus car cela entraînerait une division par zéro. Mais notez que lorsque , alors , ce qui signifie que nous regardons directement vers le haut ou vers le bas. C’est la situation de blocage de Cardan, où le cap et le roulis effectuent en fait une rotation autour du même axe physique (l’axe vertical). En d’autres termes, les singularités mathématiques et géométriques se produisent en même temps. Dans ce cas, nous attribuerons arbitrairement toute la rotation autour de l’axe vertical au cap, et fixerons le roulis à zéro. Cela signifie que nous connaissons les valeurs de tangage et de roulis, et il ne nous reste plus qu’à résoudre pour le cap. Si nous faisons les hypothèses simplificatrices
et que nous substituons ces hypothèses dans l’Équation (8.14), nous obtenons
Nous pouvons maintenant calculer à partir de et , qui contiennent respectivement le sinus et le cosinus du cap.
Le Listing 8.4 est du code C qui extrait les angles d’Euler d’une matrice de rotation objet-vers-droit, en utilisant la technique développée ci-dessus.
// Supposer que la matrice est stockée dans ces variables :
float m11,m12,m13;
float m21,m22,m23;
float m31,m32,m33;
// Nous calculerons les valeurs des angles d'Euler en radians
// et les stockerons ici :
float h,p,b;
// Extraire le tangage de m32, en faisant attention aux erreurs de domaine avec
// asin(). Nous pourrions avoir des valeurs légèrement hors plage en raison de
// l'arithmétique en virgule flottante.
float sp = -m32;
if (sp <= -1.0f) {
p = -1.570796f; // -pi/2
} else if (sp >= 1.0f) {
p = 1.570796f; // pi/2
} else {
p = asin(sp);
}
// Vérifier le cas de blocage de Cardan, avec une légère tolérance
// pour l'imprécision numérique
if (fabs(sp) > 0.9999f) {
// Nous regardons directement vers le haut ou vers le bas.
// Forcer le roulis à zéro et simplement définir le cap
b = 0.0f;
h = atan2(-m13, m11);
} else {
// Calculer le cap à partir de m13 et m33
h = atan2(m31, m33);
// Calculer le roulis à partir de m21 et m22
b = atan2(m12, m22);
}
Nous avons quelques options pour convertir un quaternion en matrice de rotation. La façon la plus courante est de développer la multiplication de quaternions . Cela produit la matrice correcte, mais nous n’avons aucune vraie certitude quant à la raison pour laquelle la matrice est correcte. (Nous acquérons cependant une certaine expérience dans la manipulation des quaternions ; voir Exercice 10.) Nous choisissons une autre option et nous en tenons purement à l’interprétation géométrique des composantes du quaternion. Puisqu’un quaternion est essentiellement une version encodée d’une rotation axe-angle, nous essayons de construire la matrice à partir de Section 5.1.3, qui effectue une rotation autour d’un axe arbitraire :
Malheureusement, cette matrice est exprimée en termes de et , mais les composantes d’un quaternion sont
Voyons si nous pouvons manipuler la matrice pour obtenir une forme où nous pouvons substituer , , et . Nous devons faire cela pour les neuf éléments de la matrice. Heureusement, la matrice a beaucoup de structure, et il n’y a vraiment que deux cas principaux à traiter : les éléments diagonaux, et les éléments non diagonaux.
Cette dérivation est délicate, et il n’est pas nécessaire de comprendre comment la matrice est dérivée pour utiliser la matrice. Si vous n’êtes pas intéressé par les mathématiques, passez à l’Équation (8.20).
Commençons par les éléments diagonaux de la matrice. Nous travaillons ici ; et peuvent être résolus de manière similaire :
Nous effectuons d’abord quelques manipulations qui peuvent sembler être un détour. Le but de ces étapes deviendra apparent dans un instant :
Maintenant, nous devons éliminer le terme ; et nous voudrions le remplacer par quelque chose qui contient ou , puisque les composantes d’un quaternion contiennent ces termes. Comme nous l’avons fait auparavant, posons . Nous écrivons l’une des formules de l’angle double pour le cosinus de la Section 1.4.5 en termes de , puis nous substituons :
En substituant dans l’Équation (8.17), nous obtenons
Maintenant, nous utilisons le fait que puisque est un vecteur unitaire, , et donc :
Les éléments et sont dérivés de manière similaire. Les résultats sont présentés à la fin de cette section lorsque nous donnons la matrice complète à l’Équation (8.20).
Examinons maintenant les éléments non diagonaux de la matrice ; ils sont plus faciles que les éléments diagonaux. Nous utilisons comme exemple :
Nous utilisons l’inverse de la formule de l’angle double pour le sinus (voir la Section 1.4.5) :
Maintenant, nous substituons les Équations (8.17) et (8.19) dans l’Équation (8.18) et simplifions :
Les autres éléments non diagonaux sont dérivés de manière similaire.
Enfin, nous présentons la matrice de rotation complète construite à partir d’un quaternion :
Conversion d’un quaternion en matrice de rotation
D’autres variantes peuvent être trouvées dans d’autres sources.17 Par exemple, fonctionne également, car . En hommage à Shoemake, qui a porté les quaternions à l’attention de la communauté d’infographie, nous avons adapté notre dérivation pour produire la version de sa source précoce et faisant autorité [11].
Pour extraire un quaternion de la matrice de rotation correspondante, nous faisons de l’ingénierie inverse sur l’Équation (8.20). En examinant la somme des éléments diagonaux (connue sous le nom de trace de la matrice), nous obtenons
et donc nous pouvons calculer par
Les trois autres éléments peuvent être calculés de manière similaire, en niant deux des trois éléments de la trace :
Malheureusement, nous ne pouvons pas utiliser cette astuce pour les quatre composantes, car la racine carrée donnera toujours des résultats positifs. (Plus précisément, nous n’avons aucune base pour choisir la racine positive ou négative.) Cependant, puisque et représentent la même orientation, nous pouvons arbitrairement choisir d’utiliser la racine non négative pour l’une des quatre composantes et retourner toujours un quaternion correct. Nous ne pouvons tout simplement pas utiliser la technique ci-dessus pour les quatre valeurs du quaternion.
Une autre approche consiste à examiner la somme et la différence des éléments matriciels diagonalement opposés :
Armés de ces formules, nous développons une stratégie en deux étapes. Nous résolvons d’abord l’une des composantes à partir de la trace, en utilisant l’une des Équations (8.21)–(8.26). Ensuite, nous substituons cette valeur connue dans les Équations (8.27)–(8.32) pour résoudre les trois autres. Essentiellement, cette stratégie se résume à sélectionner une ligne du Tableau 8.2 et ensuite résoudre les équations dans cette ligne de gauche à droite.
Tableau 8.2Extraction d’un quaternion à partir d’une matrice de rotation
La seule question est : « Quelle ligne devrions-nous utiliser ? » En d’autres termes, quelle composante devrions-nous résoudre en premier ? La stratégie la plus simple serait de simplement en choisir une arbitrairement et toujours utiliser la même procédure, mais ce n’est pas bon. Disons que nous choisissons de toujours utiliser la première ligne, ce qui signifie que nous résolvons à partir de la trace, puis , et avec les équations du côté droit de la flèche. Mais si , les divisions à suivre seront indéfinies. Même si , un petit produira une instabilité numérique. Shoemake [11] suggère la stratégie de déterminer d’abord laquelle parmi , , et a la plus grande valeur absolue (ce que nous pouvons faire sans effectuer de racines carrées), de calculer cette composante en utilisant la diagonale de la matrice, et ensuite de l’utiliser pour calculer les trois autres selon le Tableau 8.2.
Le Listing 8.5 implémente cette stratégie de manière directe.
// Matrice d'entrée :
float m11,m12,m13;
float m21,m22,m23;
float m31,m32,m33;
// Quaternion de sortie
float w,x,y,z;
// Déterminer laquelle parmi w, x, y, z a la plus grande valeur absolue
float fourWSquaredMinus1 = m11 + m22 + m33;
float fourXSquaredMinus1 = m11 - m22 - m33;
float fourYSquaredMinus1 = m22 - m11 - m33;
float fourZSquaredMinus1 = m33 - m11 - m22;
int biggestIndex = 0;
float fourBiggestSquaredMinus1 = fourWSquaredMinus1;
if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) {
fourBiggestSquaredMinus1 = fourXSquaredMinus1;
biggestIndex = 1;
}
if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) {
fourBiggestSquaredMinus1 = fourYSquaredMinus1;
biggestIndex = 2;
}
if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) {
fourBiggestSquaredMinus1 = fourZSquaredMinus1;
biggestIndex = 3;
}
// Effectuer la racine carrée et la division
float biggestVal = sqrt(fourBiggestSquaredMinus1 + 1.0f) * 0.5f;
float mult = 0.25f / biggestVal;
// Appliquer le tableau pour calculer les valeurs du quaternion
switch (biggestIndex) {
case 0:
w = biggestVal;
x = (m23 - m32) * mult;
y = (m31 - m13) * mult;
z = (m12 - m21) * mult;
break;
case 1:
x = biggestVal;
w = (m23 - m32) * mult;
y = (m12 + m21) * mult;
z = (m31 + m13) * mult;
break;
case 2:
y = biggestVal;
w = (m31 - m13) * mult;
x = (m12 + m21) * mult;
z = (m23 + m32) * mult;
break;
case 3:
z = biggestVal;
w = (m12 - m21) * mult;
x = (m31 + m13) * mult;
y = (m23 + m32) * mult;
break;
}
Pour convertir un déplacement angulaire de la forme angle d’Euler en quaternion, nous utilisons une technique similaire à celle utilisée à la Section 8.7.1 pour générer une matrice de rotation à partir des angles d’Euler. Nous convertissons d’abord les trois rotations en format quaternion individuellement, ce qui est une opération triviale. Ensuite, nous concaténons ces trois quaternions dans le bon ordre. Tout comme avec les matrices, il y a deux cas à considérer : l’un lorsque nous souhaitons générer un quaternion objet-vers-droit, et un second lorsque nous voulons le quaternion droit-vers-objet. Comme les deux sont les conjugués l’un de l’autre, nous effectuons la dérivation uniquement pour le quaternion objet-vers-droit.
Comme nous l’avons fait à la Section 8.7.1, nous attribuons les angles d’Euler aux variables , et . Soient , et des quaternions qui effectuent les rotations autour des axes , et , respectivement :
Maintenant, nous concaténons ces quaternions dans le bon ordre. Nous avons deux sources de « renversement », qui s’annulent mutuellement. Nous utilisons des rotations à axes fixes, donc l’ordre des rotations est en réalité le roulis, puis le tangage, et enfin le cap. Cependant, la multiplication de quaternions effectue les rotations de droite à gauche (voir Section 8.7.1 si vous ne comprenez pas la première source de renversement, et Section 8.5.7 pour la seconde) :
Calcul du quaternion objet-vers-droit à partir d’un ensemble d’angles d’Euler
Le quaternion droit-vers-objet est simplement le conjugué :
Le quaternion droit-vers-objet à partir d’un ensemble d’angles d’Euler
Pour extraire les angles d’Euler d’un quaternion, nous pourrions résoudre les angles d’Euler à partir de l’Équation (8.33) directement. Cependant, voyons si nous pouvons tirer parti de notre travail dans les sections précédentes et obtenir la réponse sans autant d’efforts. Nous avons déjà développé une technique pour extraire les angles d’Euler d’une matrice à la Section 8.7.2. Et nous avons montré comment convertir un quaternion en matrice. Donc prenons simplement notre technique de conversion d’une matrice en angles d’Euler et substituons nos résultats de l’Équation (8.20).
Notre méthode de la Section 8.7.2 pour extraire les angles d’Euler d’une matrice objet-vers-droit est résumée ci-dessous.
Pour votre commodité, nous répétons les éléments matriciels nécessaires de l’Équation (8.20) :
En substituant les Équations (8.37)–(8.39) dans les Équations (8.34)–(8.36) et en simplifiant, nous obtenons
Nous pouvons traduire cela directement en code, comme le montre le Listing 8.6, qui convertit un quaternion objet-vers-droit en angles d’Euler.
// Quaternion d'entrée
float w,x,y,z;
// Angles d'Euler de sortie (radians)
float h,p,b;
// Extraire sin(tangage)
float sp = -2.0f * (y*z - w*x);
// Vérifier le blocage de Cardan, avec une légère tolérance
// pour l'imprécision numérique
if (fabs(sp) > 0.9999f) {
// Regarder directement vers le haut ou vers le bas
p = 1.570796f * sp; // pi/2
// Calculer le cap, forcer le roulis à zéro
h = atan2(-x*z + w*y, 0.5f - y*y - z*z);
b = 0.0f;
} else {
// Calculer les angles
p = asin(sp);
h = atan2(x*z + w*y, 0.5f - x*x - y*y);
b = atan2(x*y + w*z, 0.5f - x*x - z*z);
}
Pour convertir un quaternion droit-vers-objet en format angle d’Euler, nous utilisons un code presque identique, mais avec les valeurs , et negées, car nous supposons que le quaternion droit-vers-objet est le conjugué du quaternion objet-vers-droit.
// Extraire sin(tangage)
float sp = -2.0f * (y*z + w*x);
// Vérifier le blocage de Cardan, avec une légère tolérance
// pour l'imprécision numérique
if (fabs(sp) > 0.9999f) {
// Regarder directement vers le haut ou vers le bas
p = 1.570796f * sp; // pi/2
// Calculer le cap, forcer le roulis à zéro
h = atan2(-x*z - w*y, 0.5f - y*y - z*z);
b = 0.0f;
} else {
// Calculer les angles
p = asin(sp);
h = atan2(x*z - w*y, 0.5f - x*x - y*y);
b = atan2(x*y - w*z, 0.5f - x*x - z*z);
}

Figure 8.13 Exemples d’orientations pour les exercices 1, 2, 4 et 5.
Associez chacune des matrices de rotation ci-dessous avec l’orientation correspondante de la Figure 8.13. Ces matrices transforment les vecteurs-ligne à gauche de l’espace objet vers l’espace droit.
(a)
(b)
(c)
(d)
(e)
(f)
Associez chacun des triplets d’angles d’Euler suivants avec l’orientation correspondante de la Figure 8.13, et déterminez si l’orientation est dans l’ensemble canonique des angles d’Euler. Sinon, expliquez pourquoi.
(a)h = , ,
(b)h = , ,
(c)h = , ,
(d)h = , ,
(e)h = , ,
(f)h = , ,
(g)h = , ,
(h)h = , ,
(i)h = , ,
Construire un quaternion pour effectuer une rotation de 30° autour de l’axe .
Quelle est la magnitude de ce quaternion ?
Quel est son conjugué ?
Supposer que le quaternion est utilisé pour effectuer la rotation des points de l’espace objet vers l’espace droit d’un certain objet. Quelle est l’orientation, en angles d’Euler, de cet objet ?
Associez chacun des quaternions suivants avec l’orientation correspondante de la Figure 8.13. Ces quaternions transforment les vecteurs de l’espace objet vers l’espace droit. (Nous vous avions dit que les quaternions sont plus difficiles à utiliser pour les humains ! Essayez de les convertir en forme matricielle ou en angles d’Euler et tirez parti de votre travail précédent.)
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)
(i)
Associez chacune des orientations axe-angle suivantes avec l’orientation correspondante de la Figure 8.13. (Indice : cela peut être assez difficile à visualiser. Essayez de convertir l’axe et l’angle en quaternion et utilisez ensuite les résultats de vos calculs précédents. Voyez ensuite si vous pouvez le visualiser.)
(a)
(b)
(c)
(d)
(e)
(f)
(g)
(h)
(i)
Dériver la formule de multiplication des quaternions, en interprétant les quaternions comme des nombres complexes 4D et en appliquant les règles de l’Équation (8.10).
Calculer un quaternion qui effectue deux fois la rotation du quaternion .
Considérer les quaternions :
(a)Calculer le produit scalaire .
(b)Calculer le produit quaternionique .
(c)Calculer la différence de à .
Prouver l’affirmation faite à la Section 8.5.7 : la magnitude du produit de deux quaternions est le produit des magnitudes.
Développer la multiplication , et vérifier que la matrice de l’Équation (8.20) est correcte.
Faire une étude de quelques moteurs de jeu et de code open source et déterminer les conventions concernant les vecteurs-ligne/colonne, les matrices de rotation et les angles d’Euler.
Je porte un collier, parce que je veux savoir quand je suis à l’envers.
— Mitch Hedberg (1968–2005)
Références
[1] G. H. Bryan. Stability In Aviation: An Introduction to Dynamical Stability as Applied to the Motions of Aeroplanes. London: Macmillan and Co., 1911.
[2] Erik B. Dam, Martin Koch, and Martin Lillholm. “Quaternions, Interpolation and Animation.” Technical Report DIKU-TR-98/5, Department of Computer Science, University of Copenhagen, 1998. http://www.diku.dk/students/myth/quat.html.
[3] James Diebel. “Representing Attitude: Euler Angles, Unit Quaternions, and Rotation Vectors.” http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.110.5134, 2006.
[4] Fletcher Dunn and Ian Parberry. 3D Math Primer for Graphics and Game Development, First edition. Plano, TX: Wordware Publishing, 2002.
[5] F. Sebastin Grassia. “Practical Parameterization of Rotations Using the Exponential Map.” J. Graph. Tools 3 (1998), 29–48. http://jgt.akpeters.com/papers/Grassia98/.
[6] Andrew J. Hanson. Visualizing Quaternions (The Morgan Kaufmann Series in Interactive 3D Technology). San Francisco: Morgan Kaufmann, 2006.
[7] John C. Hart, George K. Francis, and Louis H. Kauffman. “Visualizing Quaternion Rotation.” ACM Trans. Graph. 13:3 (1994), 256–276.
[8] Jack B. Kuipers. Quaternions and Rotation Sequences: A Primer with Applications to Orbits, Aerospace, and Virtual Reality. Princeton, NJ: Princeton University Press, 1999.
[9] John McDonald. “Teaching Quaternions Is Not Complex.” Computer Graphics Forum 29:8 (2010), 2447–2455.
[10] Oliver M. O’Reilly. Intermediate Dynamics for Engineers: A Unified Treatment of Newton–Euler and Lagrangian Mechanics. Cambridge, UK: Cambridge University Press, 2008.
[11] Ken Shoemake. “Quaternions and Matrices.” In Graphics Gems II, edited by James Arvo. San Diego: Academic Press Professional, 1991.
[12] Ken Shoemake. “Euler Angle Conversion.” In Graphics Gems IV, edited by Paul S. Heckbert. San Diego: Academic Press Professional, 1994.
En réalité, nous pouvons aussi mettre les vecteurs dans les colonnes d’une matrice. Cela est certainement vrai si nous utilisons des vecteurs-colonne — mais il s’avère que cela fonctionne même si nous préférons utiliser des vecteurs-ligne. C’est parce que les matrices de rotation sont orthonormales, ce qui signifie que nous pouvons les inverser en prenant leur transposée. Nous en discutons à la Section 8.2.1.
Nous mesurons la fréquence d’utilisation en fonction du nombre de fois que l’opération est codée, et non de la fréquence à laquelle elle est exécutée à l’exécution. Par exemple, la transformation des sommets à travers le pipeline graphique est certainement une opération matricielle extrêmement couramment utilisée, mais il y a relativement peu de lignes de code qui effectuent cette opération. Cela s’est avéré vrai dans une grande variété de genres de jeux, tels que les courses, les combats, les jeux de société 3D et les jeux de tir, bien que, bien sûr, nous ne puissions pas parler pour l’environnement de travail de chacun.
En réalité, probablement la multiplication par la transposée, puisque les matrices de rotation sont orthogonales — mais ce n’est pas le point ici.
C’est un avantage souvent mis en avant des quaternions qu’ils peuvent être utilisés pour effectuer des rotations par multiplication de quaternions (voir Section 8.5.7). Cependant, si nous examinons les mathématiques, nous voyons que ce « raccourci » équivaut à une multiplication par la matrice de rotation correspondante.
C’est probablement un peu présomptueux de notre part de qualifier lacap-tangage-roulis de variation. Après tout, il existe un article Wikipedia sur le lacet-tangage-roulis, mais aucun sur le cap-tangage-roulis, alors qui peut dire que notre préférence n’est pas la variation ? Nous admettons cette présomption et sommes prêts à défendre notre préférence sous peu.
Le mot « aéronautique » en est un exemple.
Il y a aussi beaucoup de personnes peu avisées qui ne ont pas de bonnes raisons pour les choix qu’elles font — mais au final, le résultat est le même.
La raison en est que cela provient de la branche des mathématiques tout aussi intimidante et obscure connue sous le nom d’algèbre de Lie. (Lie se prononce « li », car c’est le nom d’une personne.) La carte exponentielle a une définition plus large dans ce contexte, et l’espace des rotations 3D (parfois noté ) est juste un type de groupe de Lie. D’autres commentaires regrettables sur la terminologie à venir.
Dans ce cas, le mot « avancé » signifie « en dehors de l’expertise des auteurs. »
C’est-à-dire, si vos bibliothèques de classes sont bien conçues.
Avec nos excuses auprès de nos lecteurs en Inde, nous préférons la gauche.
En fait, vous avez une certaine flexibilité si vous êtes prêt à aller à contre-courant. Certains auteurs audacieux \cite_need_fixup{first-edition} sont allés jusqu’à fournir une définition alternative du produit quaternionique avec les opérandes inversés. Cela peut mener à un code plus facile à comprendre, et cette option pourrait valoir la peine d’être considérée dans votre propre code. Cependant, nous nous en tiendrons au standard dans ce livre.
C’est la lettre grecque oméga, prononcée « oh-MAY-gah. »
Notre convention habituelle est d’utiliser des vecteurs-ligne, mais nous allons utiliser des vecteurs-colonne ici car l’ordre de droite à gauche des rotations correspond plus étroitement aux quaternions.
La question de savoir si la rotation est dans le sens des aiguilles d’une montre ou dans le sens contraire est une question de convention et n’est pas inhérente aux nombres complexes. En fait, vous avez probablement déjà remarqué que nous aurions pu nier l’autre dans la matrice de l’Équation (8.9) et avoir encore un moyen valide d’associer l’ensemble des nombres complexes aux matrices . Notre choix arbitraire deviendra utile dans un instant.
Probablement ceux qui connaissent déjà tout cela. Hé, que faites-vous dans la pataugeoire — n’avez-vous pas des sauts arrière depuis le plongeoir à faire en ce moment ?
Y compris la première édition de ce livre \cite_need_fixup{first-edition}.
<< Systèmes de coordonnées polaires
Retour en haut