Ce cours est visible gratuitement en ligne.

Got it!
Créez des programmes en 3D avec OpenGL

Créez des programmes en 3D avec OpenGL

Last updated on Tuesday, January 8, 2013

Les matrices

Cette annexe mathématique est un passage obligé pour tous ceux qui veulent comprendre ce qui se passe réellement derrière les calculs qu'OpenGL fait pour nous.
Bien que l'objet mathématique matrice ne soit enseigné à l'école que dans le supérieur il n'a rien de mystique et une utilisation basique avec peu de connaissances en est tout à fait possible.
Je ne détaillerai ici que ce que nous avons besoin de savoir pour le cours d'OpenGL et vous verrez que ça n'a vraiment rien de sorcier.
Les novices y découvriront donc un nouvel objet mathématique très pratique, ceux qui les connaissent déjà dans d'autres contextes (trouver le Kernel, le vecteur propre, oui oui je suis passé par là aussi ;) ) quant à eux vont enfin voir une application pratique et très simple des matrices.

L'outil matrice

Représentation

Une matrice (matrix en anglais) se représente comme un tableau de nombres composé de lignes et de colonnes.

Image utilisateur

Un exemple de matrice

On désigne généralement un élément par son numéro de ligne suivi de son numéro de colonne. Par exemple pour la matrice ci-dessus, l'élément en (1,2) est 15.

Les matrices peuvent être de toutes tailles mais dans le cas d'OpenGL les matrices que nous utiliserons, implicitement ou non, seront des matrices 4x4 (4 lignes, 4 colonnes). Cette taille n'est pas anodine et est liée à l'utilisation géométrique qui en est faite en 3D (nous le verrons juste après).

Tout comme avec les nombres ou les vecteurs, nous pouvons effectuer certaines opérations sur les matrices. La seule qui nous intéresse ici est la multiplication.

Multiplication de matrices

Multiplier deux matrices est une gymnastique facile et rigolote. Mais les erreurs quand on le fait à la main sont assez fréquentes (tous ces chiffres qui se croisent, pauvres de nous ! ^^ ).

Le principe est simple, pour calculer l'élément (i,j) de la matrice C, produit de deux matrices A et B, on multiplie la ligne i de A par la colonne j de B comme formalisé par :

Image utilisateur

Cette formule un peu barbare se résume très simplement par le schéma suivant :

Image utilisateur

Principe de la multiplication matrice x matrice

Et pour bien comprendre ce que l'on fait de chaque élément, voici un calcul étape par étape pour 2 matrices simples :

Image utilisateur

Détail d'une multiplication matrice x matrice

Comme vous le voyez pour multiplier une ligne par une colonne, on fait la somme de chaque sous-produit entre éléments de la ligne de la matrice de gauche et de la colonne de la matrice de droite. La meilleure façon pour bien assimiler la technique est la pratique avec un papier et un crayon (ça va pour les matrices simples seulement, quand ça devient grand on s'embrouille vite :lol: ).

Pour une raison évidente, comme nous multiplions des lignes par des colonnes, on ne peut multiplier deux matrices A et Bque si le nombre de colonnes de A est égal au nombre de lignes de B. Mais rassurez-vous, vous n'avez pas à vous en préoccuper car dans notre cas nous utilisons des matrices carrées (autant de lignes que de colonnes) et donc cette condition est toujours vérifiée.

Multiplication matrice x vecteur

Un vecteur n'est qu'un cas particulier de matrice avec une seule colonne. Il est donc tout à fait possible de multiplier une matrice par un vecteur (si la condition sur les tailles énoncée plus haut est remplie).

Exemple :

Image utilisateur

Multiplication matrice x vecteur (le résultat est un vecteur)

Matrice identité

La matrice identité est une matrice particulière, souvent notée I, dont tous les éléments de la diagonale sont à 1 (exemple en 4x4) :

Image utilisateur

C'est ce que l'on appelle un élément neutre, en effet un vecteur multiplié par la matrice identité en ressort inchangé :

Image utilisateur

Inverse

La dernière propriété qui nous intéresse sur les matrices est la notion d'inverse. Si par exemple nous avons une matrice M qui vient coder d'une certaine façon une translation de (1,1,1), alors son inverse M' sera une translation de (-1,-1,-1). Donc si l'on applique la matrice et son inverse à la suite à un vecteur, il reviendra donc comme il était au début. Mathématiquement on écrit ça comme ceci :

Image utilisateur

Le produit d'une matrice avec son inverse donne l'identité. L'exemple qui était pris (translation) était très simple. Dans le cas général calculer l'inverse d'une matrice est assez barbare mais je vous en donnerai l'implémentation quand nous en aurons besoin.

Transformations

Maintenant que nous comprenons l'outil mathématique matrice, je vais vous en montrer une utilisation bien pratique : les transformations géométriques.

Nous l'avons vu plus haut, multiplier une matrice par un vecteur donne un autre vecteur. Ce vecteur résultat n'est autre que la transformée du vecteur initial par la transformation « contenue » dans la matrice.

On se sert donc d'une simple multiplication matrice de transformation x vecteur de coordonnées pour obtenir les coordonnées transformées d'un point :

Image utilisateur

Comme il est possible en utilisant une matrice de transformer un vecteur par un autre, nous allons utiliser cette propriété pour stocker dans la matrice des éléments pour exécuter chaque transformation élémentaire dont nous avons besoin en 3D : la rotation, la translation, et le changement d'échelle :

Image utilisateur

Vous trouverez l'explication numérique de chaque transformation un peu après.

À quoi servent donc les éléments du bas qui n'ont d'utilité pour aucune transformation apparemment ?

Le fait que la matrice fasse 4 colonnes de large est fixé pour nos besoins (rotation, scale, translation). Mais pour pouvoir faciliter les choses et plus tard savoir, à partir d'une matrice, trouver son inverse, il faut que celle-ci soit carrée (autant de lignes que de colonnes). C'est pourquoi la matrice de transformation possède aussi 4 lignes au lieu de 3. Il s'avère qu'une partie de la 4e ligne est utilisée par OpenGL pour la projection mais nous n'avons pas besoin d'en savoir plus sur le sujet.

Coordonnées homogènes

Ok pour la taille de la matrice mais nos vecteurs sont en 3D hein, c'est quoi ce 4e élément ? C'est le temps ?

Non non, ici nous ne travaillons pas en 4D :) mais bien en 3D. Vous le savez maintenant pour pouvoir multiplier une matrice et un vecteur il faut une condition particulière sur les dimensions : la taille du vecteur doit être égale au nombre de colonnes de la matrice, ici 4. Nous introduisons donc temporairement une 4e coordonnée (appelée w) pour exprimer et former ce que l'on appelle une coordonnée homogène.

Pour passer d'un vecteur 3D (x,y,z) à son équivalent en coordonnées homogènes il suffit de rajouter un 1 soit (x,y,z,1). Par contre pour passer d'un vecteur en coordonnées homogènes (x,y,z,w) à sa version 3D normale il faut diviser les 3 premières coordonnées par la dernière soit : (x/w,y/w,z/w).
Dans notre cas (les transformations), la 4e coordonnée n'est jamais modifiée et reste donc toujours à 1. Nous n'avons donc pas à nous en soucier.

Voyons donc maintenant ce qui est mis réellement dans la matrice pour coder les transformations.

Identité

Image utilisateur

Nous l'avons vu plus tôt cette matrice ne fait rien. Ça peut paraître inutile mais c'est ce que nous utiliserons pour réinitialiser la matrice à un état connu dont nous sommes sûrs qu'il n'affecte par les coordonnées des vertices.

Translation

Une translation de (x,y,z) s'écrit matriciellement :

Image utilisateur

Et en effet si on effectue la multiplication d'un vecteur quelconque (a,b,c) par cette matrice de translation, on obtient un vecteur résultat qui n'est ni plus ni moins que l'image du premier vecteur par cette translation.

Changement d'échelle (Scale)

Un changement d'échelle s'écrit matriciellement :

Image utilisateur

En effectuant la multiplication de la matrice de changement d'échelle par un vecteur quelconque on voit bien que ses composantes sont multipliées par chacune des composantes du changement d'échelle.

Rotation

Attention accrochez-vous, une rotation d'angle thêta, autour d'un axe quelconque (x,y,z) s'écrit matriciellement :

Image utilisateur

Ça fait peur hein ! :diable: Ici c'est le cas le plus général qui soit. Simplifions vite cela en prenant le cas particulier de la rotation d'angle thêta (et oui toujours) autour de l'axe Z (0,0,1). Tout ce qui concerne x et y s'en va et on se retrouve avec une matrice qui fait nettement moins peur :

Image utilisateur

Pour vérifier que cela marche bien comme on l'entend, prenons encore un cas plus particulier : celui de la rotation de 90° autour de l'axe Z et appliquons-la au vecteur (1,1) :

Image utilisateur

Par le calcul on obtient donc le vecteur (-1,1) en rouge qui est en effet la rotation de 90° du vecteur (1,1) en noir.

Image utilisateur

Combinaison de transformations

Pour l'instant nous avons vu comment écrire chaque transformation de base matriciellement. Mais qu'en est-il quand nous souhaitons en faire plusieurs à la suite ?

Eh bien il suffit de les multiplier ! On fait ce qu'on appelle des multiplications à droite. Si nous voulons d'abord faire une translation puis une rotation, la matrice représentant la transformation totale sera : Translation x Rotation.

Exemple :
Translation de (1,0,0) suivie d'une rotation de 90° autour de l'axe Z :

Image utilisateur

Ordre des transformations

L'ordre dans lequel sont faites les transformations est important. En effet faire une translation suivie d'une rotation n'a pas le même effet que faire une rotation suivie d'une translation.

Reprenons l'exemple de la translation de (1,0,0) mais cette fois-ci précédée d'une rotation de 90° autour de l'axe Z :

Image utilisateur

La matrice finale n'est pas la même que précédemment. Et en effet si on compare graphiquement, l'effet est totalement différent :

Image utilisateur

Importance de l'ordre des transformations

Ce chapitre assez mathématique peut nécessiter plusieurs lectures et je vous conseille de le relire conjointement avec le chapitre sur les transformations pour avoir des exemples appliqués à OpenGL.

Si vous voulez en savoir un peu plus sur l'outil matrice je vous conseille d'aller faire un tour sur Wikipédia.

Et enfin si vous vous demandez d'où je tire toutes ces informations barbares sur les représentations matricielles des transformations, je vous conseille, si ce n'est déjà fait, de jeter un coup d'oeil dans l'excellentedocumentation d'OpenGL, notamment les pages de :

Toutes ces informations combinées nous permettent de mieux comprendre comment fonctionne OpenGL et surtout d'être capables d'implémenter nous-mêmes les transformations (nous serons amenés à les utiliser).

Example of certificate of achievement
Example of certificate of achievement