Quaternion/fr
Portail d'Aide & Base de connaissances: |
Avatar | Bugs | Client | Communication | Communauté | Lexique | Multimédia | Navigation | Objet | Tutorials Vidéo | Terrain | Wiki | Divers |
LSL Portail Francophone | LSL Portail Anglophone | Fonctions | Évènements | Types | Operateurs | Constantes | Contrôle d'exécution | Bibliothèque | Tutoriels |
quaternion
Un mot-clé accepté par le compilateur, qui signifie la même chose que rotation et est interchangeable avec lui.
Définition et propriétés
Les quaternions sont une généralisation des nombres complexes inventée par William Rowan Hamilton au milieu du 19ème siècle. Rappelez-vous qu'un nombre complexe est la somme d'un nombre réel ordinaire a et d'un nombre imaginaire bi, où i est défini par :
i2 = -1
Pour construire un quaternion, nous introduisons des unités imaginaires généralisées j et k avec les hypothèses :
j2 = -1 ; k2 = -1 ; ijk = -1
À partir de ces définitions de base il est facile de dériver les relations multiplicatives entre ces quantités imaginaires généralisées :
ij = k ; jk = i ; ki = j
et
ji = -k ; kj = -i ; ik = -j
Cela veut dire que la multiplication des quaternions n'est pas commutative. Bien que les opérations non commutatives soient de nos jours une caractéristique familière de l'algèbre linéaire, à l'époque de leur invention l'idée était révolutionnaire.
Un quaternion est donc un nombre de la forme
Q = a + bi + cj + dk
où a, b et c sont des nombres réels ordinaires. Ajouter des quaternions est assez facile, on ajoute simplement les facteurs correspondants :
a + bi + cj + dk + e + fi + gj + hk = ( a+e) + (b+f)i + (c+g)j + (d+h)k
Le résultat de la multiplication de deux quaternions peut être déduit des relations multiplicatives précédentes, en se souvenant de conserver l'ordre des termes en i, j et k puisque les unités imaginaires ne commutent pas.
QR = (a + bi + cj + dk)(e + fi + gj + hk) =
ae + afi + agj + ahk + bei - bf + bgij + bhik + cej + cfji - cg + chjk + dek + dfki + dgkj - dh
= ae + afi + agj + ahk + bei - bf + bgk - bhj + cej - cfk - cg + chi + dek + dfj - dgi - dh
= (ae - bf - cg - dh) + (af + be + ch - dg)i + (ag -bh + ce + df)j + (ah + bg - cf + de)k
(... et vous qui pensiez que la multiplication des nombres complexes était compliquée !)
À présent, nous pouvons définir l'équivalent du conjugué d'un nombre complexe (nous utiliserons la notation *, mais d'autres notations sont également répandues) :
Q*= a - bi - cj - dk
Le produit d'un quaternion et de son conjugué est :
QQ* = (a + bi + cj + dk)(a - bi - cj - dk) =
= (a2 + b2 + c2 + d2) + (-ab + ba - cd + dc)i + (-ac + bd + ca - db)j + (-ad - bc + cb + da)k
= (a2 + b2 + c2 + d2)
ce qui ressemble drôlement au carré d'une longueur euclidienne. Si nous considérons le triplet (b, c, d) comme un vecteur V, nous pouvons réécrire cette longueur au carré comme :
QQ* = a2 + ||V||2
Le premier terme, a, est souvent désigné comme le scalaire, ou parfois comme la partie réelle du quaternion, et le triplet (b, c, d) comme la partie vectorielle.
Quaternions et rotations
La raison qui nous fait nous intéresser aux quaternions est que Second Life les utilise pour représenter des rotations. Comment cela ? Considerons la représentation sous forme de quaternion d'un vecteur V = (b, c, d), c'est-à-dire simplement un quaternion avec une partie réelle nulle :
Q(V) = 0 + bi + cj + dk
Si nous multiplions Q par un autre quaternion, en général nous obtenons une partie réelle non nulle ; en d'autres termes, nous avons transformé le vecteur en un quaternion qui n'est pas un vecteur, ce qui ne ressemble pas du tout à l'effet attendu d'une rotation. Néanmoins, si nous multiplions d'un côté par un quaternion z, et de l'autre côté par l'inverse pour la multiplication de z, z-1, nous obtenons un résultat avec une partie réelle nulle :
Re[zQ(V)z-1] = 0
-- en fait, nous avons transformé un vecteur en vecteur. Pour s'assurer qu'il en est bien ainsi, on remarque que dans les formules de multiplication, la partie réelle de deux quaternions ne dépend pas de l'ordre de multiplication, c'est-à-dire :
Re[QR] = Re[RQ].
Nous pouvons donc inverser l'ordre du premier et du troisième quaternions dans la transformation sans changer la partie réelle :
Re[z(Q(V)z-1)] = Re[(Q(V)z-1)z] = Re[Q(V)(z-1z)] = Re[Q(V)(1)] = 0
puisque la multiplication des quaternions est associative et que nous avions supposé que Q a une partie réelle nulle. Cette opération consistant à multiplier à gauche par un quaternion et à droite par son inverse est connue sous le nom de conjugaison par z. Les lecteurs familiers avec le calcul matriciel verront la ressemblance avec la décomposition d'une matrice en une rotation et un pur changement d'échelle (une matrice diagonale).
À quelle condition le conjugué d'un quaternion est-il identique au quaternion de départ ?
zQz-1 = Q implique zQ = Qz
(ce que l'on peut démontrer facilement en multipliant la première expression à droite par z). Quand les quaternions commutent-ils ? Si l'on revient à l'expression du produit de deux quaternions, en se souvenant que les parties réelles commutent de toute façon, nous avons par exemple pour la partie facteur de i :
(af + be + ch - dg)i + ... = (eb+ fa + gd - hc)i + ...
lorsque la multiplication est commutative. Cela ne peut être vrai que si ch - dg = 0, soit c/d = g/h : dans le cas où la pente de la partie vectorielle dans le plan (j, k) est la même pour les deux quaternions. En reprenant le même raisonnement pour les parties facteur de j et de k, il doit également en être de même dans les plans (i, j) et (i, k) : les deux quaternions doivent avoir des vecteurs qui pointent dans la même direction. Q et R doivent avoir des parties vectorielles colinéaires.
Il n'est pas dur non plus de voir que la conjugaison est également linéaire (que le conjugué d'une somme est égal à la somme des conjugués), et il est facile de voir que la longueur de la partie vectorielle de Q est préservée par conjuguaison. Quelle sorte de transformation conservant la longueur ne préserve un vecteur que lorsque son axe coincide avec le vecteur ? Mais -- une rotation, bien sûr. Ainsi, conjuguer Q par z revient à tourner la partie vectorielle de Q autour de l'axe défini par la partie vectorielle de z.
Essayons sur un cas simple. Considérons le vecteur V = (1, 0, 0) et le quaternion correspondant Q = 0 + i. Pour tourner autour de l'axe des z, nous avons besoin d'un quaternion de la forme a + ck. Le conjugué est alors :
Q' = (a+ck) (i) (a + ck)-1
Quel est l'inverse de z ? Il est facile de voir que si nous choisissons a et c de manière à ce que la longueur du quaternion soit 1, alors l'inverse est égal au conjugué :
longueur(z) = 1 = zz* implique z* = z-1
ainsi nous pouvons écrire :
Q' = (a+ck) (i) (a - ck) = (a+ck) (ai + cj) = a2i + acj + caj - c2i = ( a2- c2)i + 2acj
La contrainte :
a2+ c2 = 1
implique que nous pouvons écrire a = cos(θ/2), b = sin(θ/2) pour un certain angle θ (la raison d'être du facteur 1/2 deviendra claire dans un moment).
Les termes en i et j deviennent respectivement :
cos2(θ/2) - sin2(θ/2) = cos(θ)
et
2 cos(θ/2) sin(θ/2) = sin(θ)
Cela représente bien une rotation de i d'un angle θ. Nous pouvons généraliser cela, pour tourner un vecteur V autour d'un axe porté par un vecteur unitaire A= (b, c, d) (||A|| = 1) d'un angle θ, nous construisons le quaternion
z = cos(θ/2) + sin(θ/2)A = cos(θ/2) + sin(θ/2){bi + cj + dk}
et nous conjuguons ensuite le quaternion Q = 0 + V par z :
Q' = zQz*
duquel nous extrayons la partie vectorielle :
Q' = 0 + V' => V'
V' étant le vecteur V après rotation.
Dans Second Life, les quaternions qui représentent des rotations sont donnés sous la forme de quatre nombres en virgule flottante. Les trois premiers forment la partie vectorielle et le dernier est la partie scalaire : Q = <Q.x, Q.y, Q.z, Q.s>. En termes de directions de régions de Second Life, la direction Est-Ouest est l'axe des x, la direction Nord-Sud est l'axe des y et la direction haut-bas est l'axe des z. Souvenez-vous que x correspond à l'axe imaginaire i, y à j et z à k. Nous pouvons voir qu'il s'agit d'un système de coordonnées direct, où s'applique donc la règle de la main droite : si vous enroulez les doigts de votre main droite de x vers y, votre pouce pointera dans la direction z. Par défaut, les angles de rotation sont définis en radians de -π à π ; nous pouvons donc tourner dans le sens contraire aux aiguilles d'une montre (sens positif) d'un demi-tour, ou dans le sens des aiguilles d'une montre (négatif) d'un demi-tour, en se retrouvant dans la même direction à un angle de rotation de 3,141 radians, soit 180 degrés. La rotation dans le sens contraire aux aiguilles d'une montre d'une face dirigée vers l'Ouest, autour de l'axe des z, de 90 degrés (pour se retrouver face au Sud) est :
<0, 0, 0.707, 0.707>
puisque le sinus et le cosinus de π/4 (de la moitié de l'angle de rotation) valent tous les deux 1/20.5.
Pour continuer et pointer vers l'Est est soit
<0, 0, 1, 0> soit <0, 0, -1, 0>
Pour faire basculer (c'est-à-dire le faire tourner dans le sens contraire aux aiguilles d'une montre autour de l'axe des x) de 90 degrés est décrit par :
<0.707, 0, 0, 0.707>
et pour le coucher (dans le sens des aiguilles d'une montre autour de l'axe des y) avec la même amplitude :
<0, -0.707, 0, 0.707>.
Il est important de remarquer que la transformation d'un vecteur isolé ne détermine pas de façon unique la rotation à base de quaternion correspondante. Par exemple, dans la figure ci-dessous, nous voyons plusieurs façons de faire tourner l'axe des x jusqu'à ce qu'il coïncide avec l'axe des y. Des rotations différentes se traduisent par des orientations finales différentes dans les directions orthogonales (y et z).