- Ajouter à la classe Matrice programmée au TP précédent une méthode pour multiplier deux matrices, c'est-à-dire pour composer deux applications linéaires.
- Utiliser la classe Matrice pour obtenir une visualisation "fil de fer" d'un cube se transformant en 3D
a. Terminez le TP2 (au moins jusqu'à l'exercice 7 inclus).
b. Terminez le TP3 (au moins jusqu'à l'exercice 3 inclus).
c. Créez une copie du répertoire correspondant au TP3 et renommez cette copie TP4. Sous blueJ, ouvrez le projet intitulé TP4 correspondant à la copie du TP3 que vous venez de créer.
La composition f o g de deux applications linéaires f et g est caractérisée par le produit des matrices associées (pour plus de détails, voir le rappel de cours donné à la fin de l'énoncé de cet exercice). L'objectif de cet exercice est d'implémenter cette opération de multiplication matricielle. Pour cela, on s'appuiera sur la décomposition de matrices en vecteurs colonnes et en vecteurs lignes et sur des produits scalaires.
a. Ajoutez à la classe Matrice une méthode publique getVecteurColonne à un paramètre, de type int, retournant un Vecteur ayant pour coordonnées les coefficients de l'instance courante de la classe Matrice dont le second indice est égal au paramètre de la méthode. En d'autres termes, le vecteur retourné correspond à la colonne indicé par l'entier passé en paramètre.
b. Ajoutez à la classe Matrice une fonction publique produitMatriciel à un paramètre de type Matrice. Cette méthode agit de la manière suivante :
- si le nombre de colonne de l'instance courante de la classe Matrice est égal au nombre de ligne de la Matrice passée en paramètre, alors la méthode retourne une nouvelle Matrice qui est le produit de l'instance courante par le paramètre.
- sinon, la méthode retourne la référence null pour indiquer que l'opération ne peut pas être effectuée.
c. Testez votre méthode avec la matrice 2 x 3
2 | 1 | 1 |
4 | 2 | 3 |
-1 | 2 |
3 | 2 |
-1 | 2 |
Soient n, m et k trois entiers naturels. Soit f une application linéaire de Rn dans Rm et g une application linéaire de Rm dans Rk.
Définition 1 (composée). La composée de f et g, notée g o f, est une application de Rn dans Rk qui associe à tout vecteur u de Rn le vecteur v de Rk obtenu en appliquant f puis g au vecteur u (i.e., v = g(f(u))).
Propriété 1. La composée g of de f et g est une application linéaire.
D'après la propriété 1, la composée g o f est une application linéaire de Rn dans Rk. Il existe donc une matrice de taille k x n qui caractérise cette application. Comme indiquée par la propriété 3 ci-dessous, le produit matriciel permet précisément d'obtenir cette matrice caractéristique à partir des matrices caractéristiques de f et g.
Soient F et G les deux matrices caractéristiques des applications f et g. Notons que F et G sont donc respectivement de taille m x n et k x m.
Définition 2 (produit matriciel). Le produit (matriciel) de G par F, noté G x F, est la matrice de taille k xn telle que, pour tout indice i compris entre 0 et k-1 et tout indice j compris entre 0 et n -1, le coefficient [G x F]i,j est le produit scalaire du i-ème vecteur ligne de G avec le j-ème vecteur colonne de F :
[G x F]i,j = Gi,. . F.,jT
où Gi,.désigne le i-ème vecteur ligne de Get où F.,j désigne le j-ème vecteur colonne de F.
Propriété 3. G x F est la matrice caractéristique de l'application g o f .
En d'autres termes, cela signifie que si l'on veut trouver l'image v d'un vecteur u par la composée g o f de f et g, on peut procéder de deux manières différentes :
1 - on obtient d'abord l'image w = f(u) de u par f en multipliant F par u (ie, w = F. u), puis on obtient l'image v = g(w) de w par g (donc v = g(f(u))) en multipliant G par w (ie, v = G.w) ;
2 - on obtient d'abord la matrice H caractéristique de l'application g o f en multipliant G par F (ie, H = G x F), puis on obtient l'image de u par g o f en multipliant H par u (ie, v = H.u).
Lorsque l'on souhaite trouver l'image d'un unique vecteur par g o f, la méthodes 1 est moins coûteuse que la méthode 2. On pourra notamment vérifier qu'elle nécessite un moins grand nombre d'opérations. En revanche, la méthode 2 est nettement moins coûteuse que la méthode 1 pour trouver les images de plusieurs (plus que m) vecteurs par g o f car le produit de F par G ne doit alors être effectué qu'une seule fois. Cette situation sera illustrée dans l'exercice 3 où l'on souhaite trouver l'image des 8 coins d'un cube (i.e., 8 vecteurs de R3) par une composée d'applications linéaires.
a. Téléchargez le fichier 'TestCube.java' et importez la classe TestCube dans votre projet (sous Bluej, cliquer sur l'option 'add Class from File' à partir du menu 'Edit' et choissez le fichier 'TestCube.java').
b. Inspectez la procédure statique test de la classe TestCube. Qu'est elle censée faire ? Essayez d'exécuter cette procédure ? Décrivez ce que vous voyez apparaître dans le Plan qui s'affiche à l'écran ? Expliquez pourquoi ce que vous voyez correspond bien à un cube.
c. L'objectif de cette question et des deux suivantes est de produire d'autres visualisations (différents angles de vue et facteurs de grossissement) du cube créé par la méthode test. Pour cela, on peut tourner le cube, changer sa taille, ou plus généralement appliquer à ses sommets n'importe quelle application linéaire. Dans la classe TestCube, compléter la procédure appliquer permettant d'effectuer de telles actions. Cette procédure est spécifiée par :
- nom : appliquer ;
- visibilité : public ;
- paramètres : un tableau de Vecteur nommé
pVecteurs et une Matrice nommée pTransformation
(dans la suite, on suppose que les vecteurs du tableau sont tous en dimension
3 et que la matrice est de taille 3 x 3) ;
- action : remplace chaque Vecteur de pVecteurs par le
produit de pTransformation par
ce Vecteur.
En d'autres termes, à l'issue de la procédure appliquer, pVecteurs contient
les images des vecteurs initiaux par l'application linéaire caractérisée par
pTransormation.
d. Dans la procédure test, avant l'invocation de la procédure qui dessine le cube à l'écran, créez une matrice de rotation 3 x 3 et appliquez la au tableau contenant les sommets du cube. Exécutez la méthode test et vérifiez que l'affichage est conforme à la rotation programmée. Essayez avec une rotation autour de chacun des axes.
e. Même question qu'en d. mais avec une homotétie.
f. Ecrire, dans la classe TestCube, une fonction getRotation à trois paramètres réels alpha1, alpha2 et alpha3 qui retourne la matrice correspondant à la composition des rotations d'angles autour alpha1, alpha2 et alpha3 autours respectivement des 3 axes (1 ; 0 ; 0), (0 ; 1 ; 0) et (0 ; 0 ; 1).
g. Même question qu'en d., mais avec une transformation qui est la composition d'une rotation de π / 4 autour de l'axe (1 ; 0 ; 0), d'une rotation π / 4 de autour de l'axe (0 ; 1 ; 0) et d'une rotation de π / 4 autour de l'axe (0 ; 0 ; 1). Testez de nouveau l'affichage.
h. L'objectif de cette dernière question est d'obtenir une visualisation animé du cube. Pour cela, il faut décomposer l'animation en étapes élémentaires et visualiser le cube à chacune de ces étapes élémentaires. Chaque étape élémentaire correspond à un petit déplacement du cube, c'est à dire à appliquer au cube une application linéaire qui déplace très légèrement ses sommets (par exemple, la transformation de la question f. avec une valeur de 0,01 radian au lieu de π / 4). Dans la procédure test, remplacer la ligne d'instruction qui permet de dessiner le cube par une boucle qui permet d'itérer les étapes élémentaires de déplacement et de visualiser le cube à chacune de ces itérations. Testez avec différentes applications linéaires.
Sujet rédigé par Jean Cousty, Benjamin Perret et Leïla Reille pour l'unité A3PAL à ESIEE Paris.