Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox
Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par lilive (Olivier Tarasse), le 04 mars 2010

Navigation:
Introduction
Présentation des matrices et de la multiplication
Les matrices c'est super, mais à quoi ça sert?
Utilisation des matrices en Actionscript
Anticiper le résultat de la transformation géométrique par une matrice
Matrices et translations
Transformations successives par matrices
[ Exemples d'applications avec les matrices ]
Matrix, x, y, scaleX, scaleY, et rotation
Conclusion

Exemples d'applications avec les matrices

Nous avons bien mérité (à mon avis) quelques applications pratiques utilisant nos nouvelles connaissances :). Pour reprendre les exemples fournis dans l'introduction de ce tutoriel, voici deux mises en application simples de ce que nous venons de voir. J'y ajoute un troisième exemple plus technique pour mettre en évidence une dernière possibilité des matrices. Puis nous terminerons par une comparaison entre les méthodes de transformation x, y, scaleX, scaleY, rotation et les transformation par matrices.


Rotation autour d'un autre point que le point d'alignement

Supposons que nous ayons un DisplayObject dont le point d'alignement est en haut à gauche de l'objet. Ce point d'alignement n'est autre que le point (0,0) dans le système de coordonnées de cet objet. Ce sera le cas si vous chargez un fichier image ou un fichier .swf dans votre application avec la classe Loader. Ce sera également le cas si vous créez par le code une image de votre bibliothèque. Si vous utilisez des symboles définis dans l'IDE de Flash, vous aurez par contre eu la possibilité de redéfinir le point d'alignement de ce symbôle, mais vous ne pourrez plus y toucher une fois l'application démarrée, donc cette astuce peut également vous servir.

Voici une image que nous voudrions faire pivoter de 45 degrés autour du point A (50,100):

Si nous nous contentions d'appliquer une matrice de rotation de 45 degrés ainsi:

var m:Matrix = new Matrix();
m.rotate( Math.PI / 4 );
image.transform.matrix = m;

Nous aurions le résultat suivant:

L'image pivoterait non pas autour du point A, mais du point (0,0).

Nous allons donc procéder en plusieurs étapes:


1 - Amener le point de pivot A sur le point (0,0):

var m:Matrix = new Matrix();
m.translate( -50 , -100 );
image.transform.matrix = m;


2 - Faire pivoter l'image autour du point (0,0):

var m:Matrix = new Matrix();
m.translate( -50 , -100 );
m.rotate( Math.PI / 4 );
image.transform.matrix = m;


3 - Ramener le point de pivot A à son emplacement d'origine

var m:Matrix = new Matrix();
m.translate( -50 , -100 );
m.rotate( Math.PI / 4 );
m.translate( 50 , 100 );
image.transform.matrix = m;

Et voilà! Si nous comparons maintenant l'image à son emplacement d'origine et à son nouvel emplacement…

…nous voyons que l'image a bien pivotée autour du point A :)


Revoici l'application qui utilise ce procédé en utilisant pour point A les cordonnées de la souris. Déplacez la souris sur l'image de départ (l'image grisée) pour définir le point autour duquel elle doit pivoter. Le résultat est immédiatement appliqué sur l'image en rotation.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.


Zoom avant / arrière sur un point d'une image

Dans le même ordre d'idée, voici comment agrandir / rétrécir une image autour d'un point précis.

Supposons que nous ayons l'image suivante, dont le point d'alignement est en haut à gauche, et que nous voulions zoomer sur le point A (130,120):

Si pour faire un zoom avant sur cette image nous faisions…

// Partir de la matrice de transformation actuelle de l'image
var m:Matrix = image.transform.matrix;
// Augmenter légèrement l'échelle de la matrice
m.scale(1.3, 1.3);
// Appliquer cette nouvelle matrice
image.transform.matrix = m;

…et pour faire un zoom arrière nous faisions la même chose avec…

// Diminuer légèrement l'échelle de la matrice
m.scale(0.8, 0.8);

…voici ce que nous obtiendrions (cliquez sur les loupes pour zoomer avant / arrière):

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Comme la mise à l'échelle se fait “autour” du point d'alignement (0,0), nous perdons de vue le point A dès que le zoom est trop important.

Pour résoudre le problème nous allons nous y prendre exactement comme dans le cas de la rotation. Pour le zoom avant cela donne:

// Partir de la matrice de transformation actuelle de l'image
var m:Matrix = image.transform.matrix;
// Amener le point A au point (0,0)
m.translate( -130, -120 );
// Augmenter légèrement l'échelle de la matrice
m.scale(1.3, 1.3);
// Ramener le point A à sa position d'origine
m.translate( 130, 120 );
// Appliquer cette nouvelle matrice
image.transform.matrix = m;

Et c'est aussi simple que cela :)

Voici une mise en oeuvre où les coordonnées de la souris servent de point A. Cliquez d'abord sur la loupe que vous voulez utiliser, puis cliquez sur l'image pour zoomer:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

(Icônes des loupes crées par FatCow Web Hosting, licence Creative Commons (Attribution 3.0 United States))

Comme dans le cas de la rotation, les matrices nous permettent de résoudre facilement le cas, ce qui nous aurait sinon demandé des calculs plus ardus (voyez ici une façon de faire sans les matrices).


Connaître l'ensemble des transformations appliquées sur un objet

Maintenant une dernière application, un peu plus poussée.

Avec les matrices, il est également possible de connaître l'ensemble des transformations que subit n'importe quel objet. Ceci peut être très utile.

Voici un exemple d'objets animés imbriqués les uns dans les autres, tous en déplacement. Chaque objet est un enfant de l'objet qui le contient visuellement.

  • Au clic sur un objet, je dessine un rectangle des dimensions de l'objet cliqué, non transformé. J'ajoute ce rectangle au-dessus de tous les autres objets, directement à la racine de la scène.
  • Puis, à chaque image, je récupère la composition de toutes les transformations appliquées sur l'objet cliqué, depuis son ancêtre le plus lointain jusqu'à lui-même. Ceci se fait grâce à la propriété transform.concatenatedMatrix.
  • J'applique alors cette matrice au rectangle créé.

Le code permettant de reproduite le placement de l'objet sur le rectangle est:

// target est le DisplayObject cliqué
var m:Matrix = target.transform.concatenatedMatrix;
// frame est le DisplayObject où est dessiné le rectangle
frame.transform.matrix = m;

Le résultat est un rectangle qui suit l'objet cliqué, en restant au-dessus de tout les autres, quel que soit le niveau d'imbrication dans la liste d'affichage de l'objet cliqué. Là encore, le résultat serait plus long à obtenir sans le secours des matrices:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Téléchargez les sources pour en savoir plus, le code est commenté.



Page suivante >>