Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > Bibliothèques > OpenGL > Créez des programmes en 3D avec OpenGL > Annexes > Les Matrices > Lecture du tutoriel

Les Matrices

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Auteur : Kayl
Visualisations : 8 484


Plus d'informations Plus d'informations
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.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

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 2 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 2 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 B que 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.

Contrairement aux nombres, la multiplication entre matrices n'est pas commutative ( AxB != BxA ). L'ordre des multiplications est donc important (comme nous le verrons lors de la combinaison de transformations).


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 qu'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 interesse 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 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.

A 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 4ème 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 4ème é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 4ème coordonnée (appelée w) pour exprimer former ce qu'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 4ème 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 plutôt cette matrice ne fait rien. Ça peut paraître inutile mais c'est ce que nous utiliserons pour réinitialiser la matrice a un état connu dont on est sûr 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 ça 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 là 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 ?

Et 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 de 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écedemment. 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'excellente documentation d'OpenGL, notamment les pages de :



Toutes ces informations combinées nous permettent de mieux comprendre comment fonctionne OpenGL et surtout d'être capable d'implémenter nous même les transformations (nous serons amener à les utiliser).
Chapitre précédent Sommaire Chapitre suivant
Retour en haut Retour en haut


Créé : le 24/10/2007 à 18:42:30
Modifié : le 08/11/2008 à 15:22:24
Avancement : 0%
Licence : Copie non autorisée

Commentaires

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 603 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1361s (0.123s)