Problématique
-
Emploi de "matrices" de variables dans le cadre de nombreux problèmes
-
Matrice: Tableau à deux indices
Déclaration de tableaux à deux indices en langage algorithmique et en langage Java
Matrices pour les Mathématiques
-
Matrice: Tableau de variables à deux indices
-
Composantes du même type
-
Premier indice: Numéro de ligne
-
Second indice: Numéro de colonne
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
nombre lignes = 3, nombre colonnes = 5
-
Vecteur: Tableau de variables à deux indices dont l'une des 2 tailles est égale à 1
nombre lignes = 3, nombre colonnes = 1
|
nombre lignes = 1, nombre colonnes = 5
|
-
Matrices et vecteurs: "Objets" mathématiques de même catégorie: Tableau à 2 dimensions
-
Si tailles compatibles, objets associables au moyen d'opérations matricielles:
-
Addition
-
Soustraction
-
Multiplication (composition)
-
En programmation informatique, vecteur usuellement géré de manière simplifiée en utilisant un tableau à une dimension
-> Pas de second indice toujours égal à 0 à "traîner"
-
Matrice carrée: Matrice avec des nombres de lignes et de colonnes identiques
-
En mathématiques utilisation fréquente des notions de matrice et de vecteur:
-
Ensemble de valeurs: Un tableau unidimensionnel de taille arbitraire
-
Position dans un espace: Un tableau unidimentionnel de taille égale à la dimension de l'espace
-
Transformation géométrique: Un tableau bidimentionnel carré de taille égale à la dimension de l'espace
-
Equation linéaire: Un tableau unidimentionnel de taille égale au nombre de variables de l'équation linéaire + 1
-
Système d'équations linéaires: Tableau bidimentionnel de taille ne*nv + tableau unidimentionnel de taille ne
où ne = nombre d'équations et nv = nombre d'inconnues
-
...
-
Utilisation fréquente de matrices carrées
Exemples
-
Mathématiques matricielles: Produit matrice par vecteur
Exemple:
.
= 
constante N : entier <- ...
{ Methode de calcul du produit d'un tableau }
{ carre de taille N.N par un tableau }
{ a 1 indice de taille N }
{ Resultat: Un tableau a 1 indice de taille N }
Tableau [N] de reel fonction produitMatriceVecteur(m,v)
Données
m : Tableau [N][N] de reel
v : Tableau [N] de reel
Locales
i : entier
j : entier
w : Tableau [N] de reel
pour i de 0 à N-1 faire
w[i] <- 0.0
pour j de 0 à N-1 faire
w[i] <- w[i] + m[i][j]*v[j]
fait
fait
retourner w
fin fonction
|
/* Methode de calcul du produit d'un tableau */
/* carre de taille n.n par un tableau */
/* a 1 indice de taille n */
/* Resultat: Un tableau a 1 indice de taille n */
static double [] produitMatriceVecteur(double [][] m,
double [] v) {
int i;
int j;
int n;
n = v.length;
double [] w = new double[n];
for ( i = 0 ; i < n ; i = i+1 ) {
w[i] = 0.0;
for ( j = 0 ; j < n ; j = j+1 ) {
w[i] = w[i] + m[i][j]*v[j]; } }
return w;
}
|
ProduitMatriceVecteur.lda
ProduitMatriceVecteur.java
Exemple d'exécution |
-
Mathématiques matricielles: Produit matrice par matrice
Exemple:
.
= 
constante N : entier <- ...
constante M : entier <- ...
constante P : entier <- ...
{ Methode de calcul du produit d'un tableau }
{ de dimension 2 de taille N.M }
{ par un tableau de dimension 2 de taille M.P }
{ Resultat: Un tableau de dimension 2 }
{ de taille N.P }
Tableau [N][P] de reel fonction produitMatriceMatrice(m1,m2)
Données
m1 : Tableau [N][M] de reel
m2 : Tableau [M][P] de reel
Locales
i : entier
j : entier
k : entier
r : Tableau [N][P] de reel
pour i de 0 à N-1 faire
pour j de 0 à P-1 faire
r[i][j] <- 0.0
pour k de 0 à M-1 faire
r[i][j] <- r[i][j] + m1[i][k]*m2[k][j]
fait
fait
fait
retourner r
fin fonction
|
/* Methode de calcul du produit d'un tableau */
/* de dimension 2 de taille n.m */
/* par un tableau de dimension 2 de taille m.p */
/* Resultat: Un tableau de dimension 2 */
/* de taille n.p */
static double [][] produitMatriceMatrice(double [][] m1,
double [][] m2) {
int i;
int j;
int k;
int n;
int m;
int p;
n = m1.length;
m = m2.length;
p = m2[0].length;
double [][] r = new double[n][p];
for ( i = 0 ; i < n ; i = i+1 ) {
for ( j = 0 ; j < p ; j = j+1 ) {
r[i][j] = 0.0;
for ( k = 0 ; k < m ; k = k+1 ) {
r[i][j] = r[i][j] + m1[i][k]*m2[k][j]; } } }
return r;
}
|
ProduitMatriceMatrice.lda
ProduitMatriceMatrice.java
Exemple d'exécution |
-
Algèbre linéaire: Résolution d'un système de n équations linéaires à n inconnues
-
On considère le système de n équations linéaires à n inconnues:

où les inconnues sont les vi et les constantes sont les aij et les bi.
-
Présentation possible sous la forme matricielle A.V = B:

où A est une matrice carrée de taille n*n, V et B sont des vecteurs de taille n.
-
Résolution de ce système:
-
Détermination, s'il existe, du seul vecteur des vi qui vérifie l'ensemble de ces équations et donc du vecteur V qui vérifie le
produit matriciel.
-
Exemples d'application pratique
-
En deux dimensions: Trouver la position de l'intersection de deux droites
-
En trois dimensions: Trouver la position de l'intersection entre une droite et un plan
-
En dimension n avec n très grand (> 1000000):
En informatique graphique, calculer l'éclairage d'une scène par radiosité
Exemple:
Les matrices A et B sont
et .
-
Etape n°1
-
Traitement de la ligne 2 par soustraction de 4.0 fois la ligne 1:
et .
-
Traitement de la ligne 3 par soustraction de 3.0 fois la ligne 1:
et .
-
Traitement de la ligne 4 par soustraction de -2.0 fois la ligne 1:
et .
-
Traitement de la ligne 5 par soustraction de 6.0 fois la ligne 1:
et .
-
Etape n°2
-
Permutation des lignes 2 et 3 car la composante d'indice (2,2) est égale à 0.0:
et .
-
Traitement des lignes 4 et 5:
et .
-
Etape n°3
-
Traitement des lignes 4 et 5:
et .
-
Etape n°4
-
Traitement de la ligne 5:
et .
-
Une seconde (et dernière) étape: Calcul de V
-
vn d'ores et déjà calculable car sur la ligne n de la matrice A, il ne reste que des 0.0 sauf pour la dernière valeur d'indice
(n,n)
-> vn = bn/ann
-
Calcul de vn-1 possible car, vn étant connu, toutes les valeurs nécessaires à son calcul sont maintenant connues.
-
Calcul de vn-2 possible car, vn et vn-1 étant connus, toutes les valeurs nécessaires à son calcul sont maintenant
connues.
-
Poursuite du calcul des v du calcul des vi jusqu'à v1.
Sur l'exemple précédent:
-
v5 = -1.8/-6.0 = 0.3
-
v4 = (24.0 - 20.0*0.3)/-10.0 = -1.8
-
v3 = (-2.0 + 5.0*0.3 + 5.0*1.8)/1.0 = 8.5
-
v2 = (-4.0 + 0.0*0.3 + 3.0*1.8 + 1.0*8.5)/1.0 = 9.9
-
v1 = (1.0 - 1.0*0.3 - 1.0*1.8 - 1.0*8.5 + 0.0*9.9)/1.0 = -9.6
constante N : entier <- ...
{ Resolution d'une systeme de N equations }
{ lineaires a N inconnues }
{ par la methode de du pivot Gauss }
{ Permutation de Gauss }
action permutation(l,m,v)
Données
l : entier
Données / Résultats
m : Tableau [N][N] de réel
v : Tableau [N] de réel
Locales
ll : entier
i : entier
aux : reel
ll <- l
tant que m[ll][l] = 0.0 faire
ll <- ll+1
fait
pour i de l à N-1 faire
aux <- m[l][i]
m[l][i] <- m[ll][i]
m[ll][i] <- aux
fait
aux <- v[l]
v[l] <- v[ll]
v[ll] <- aux
fin action
{ Transformation de Gauss }
action transformation(m,v)
Données / Résultats
m : Tableau [N][N] de réel
v : Tableau [N] de réel
Locales
i : entier
j : entier
k : entier
facteur : reel
pour i de 1 à N-1 faire
si m[i-1][i-1] = 0.0 alors
permutation(i-1,m,v)
fsi
pour j de i à N-1 faire
facteur <- m[j][i-1]/m[i-1][i-1]
pour k de i-1 à N-1 faire
m[j][k] <- m[j][k] - m[i-1][k]*facteur
fait
v[j] <- v[j] - v[i-1]*facteur
fait
fait
fin action
{ Extraction de Gauss }
Tableau [N] de réel fonction extraction(a,b)
Données
a : Tableau [N][N] de réel
b : Tableau [N] de réel
Locales
i : entier
j : entier
v : Tableau [N] de reel
v[N-1] <- b[N-1]/a[N-1][N-1]
pour i de N-2 à 0 pas -1 faire
v[i] <- b[i]
pour j de N-1 à j+1 pas -1 faire
v[i] <- v[i] - v[j]*a[i][j]
fait
v[i] <- v[i]/a[i][i]
fait
retourner v
fin fonction
{ Resolution de Gauss }
Tableau [N] de réel fonction resolution(a,b)
Données
a : Tableau [N][N] de réel
b : Tableau [N] de réel
Locales
v : Tableau [N] de reel
transformation(a,b)
v <- extraction(a,b)
retourner v
fin fonction
|
/* Methode de clonage d'un tableau */
/* a 1 indice de double */
static double [] clone(double [] t) {
int i;
int n = t.length;
double [] nt = new double[n];
for ( i = 0 ; i < n ; i = i+1 ) {
nt[i] = t[i]; }
return nt;
}
/* Methode de clonage d'un tableau */
/* a 2 indices de double */
static double [][] clone(double [][] t) {
int i;
int j;
int n = t.length;
int m = t[0].length;
double [][] nt = new double[n][m];
for ( i = 0 ; i < n ; i = i+1 ) {
for ( j = 0 ; j < m ; j = j+1 ) {
nt[i][j] = t[i][j]; } }
return nt;
}
/* Permutation de Gauss */
static void permutation(int l,double [][] m,double [] v) {
int ll;
int i;
int n = v.length;
double aux;
ll = l;
while ( m[ll][l] == 0.0 ) {
ll = ll+1; }
for ( i = l ; i < n ; i = i+1 ) {
aux = m[l][i];
m[l][i] = m[ll][i];
m[ll][i] = aux; }
aux = v[l];
v[l] = v[ll];
v[ll] = aux;
}
/* Transformation de Gauss */
static void transformation(double [][] m,
double [] v) {
int n = v.length;
int i;
int j;
int k;
double facteur;
for ( i = 1 ; i < n ; i++ ) {
if ( m[i-1][i-1] == 0.0 )
permutation(i-1,m,v);
for ( j = i ; j < n ; j++ ) {
facteur = m[j][i-1]/m[i-1][i-1];
for ( k = i-1 ; k < n ; k++ ) {
m[j][k] = m[j][k] - m[i-1][k]*facteur; }
v[j] = v[j] - v[i-1]*facteur; } }
}
/* Extraction de Gauss */
static double [] extraction(double [][] a,
double [] b) {
int i;
int j;
int n = b.length;
double [] v = new double[n];
v[n-1] = b[n-1]/a[n-1][n-1];
for ( i = n-2 ; i >= 0 ; i = i-1 ) {
v[i] = b[i];
for ( j = n-1 ; j > i ; j = j-1 ) {
v[i] = v[i] - v[j]*a[i][j]; }
v[i] = v[i]/a[i][i]; }
return v;
}
/* Resolution de Gauss */
static double [] resolution(double [][] a,
double [] b) {
double [] v;
transformation(a,b);
v = extraction(a,b);
return v;
}
/* Resolution de Gauss */
/* sur une copie des 2 tableaux en parametres */
static double [] resolutionGauss(double [][] a,
double [] b) {
double [][] ca = clone(a);
double [] cb = clone(b);
double [] v;
v = resolution(ca,cb);
return v;
}
|
PivotGauss.lda
PivotGauss.java
Exemple d'exécution |
Matrices pour la Physique
-
Large appel à l'informatique comme outil de simulation
-
Pourquoi simuler?
-
Moins cher que les tests réels (crashs automobiles, analyses d'écoulements turbulents, ...)
-
Réalisation de prévisions (météo, évolution climatique, collision de galaxies, ...)
-
Analyse de phénomènes qu'il n'est pas possible de tester dans la réalité (essais nucléaires, formation des étoiles, super-novae, ...)
-
...
-
Phénomènes à simuler fréquement décrits par des équations
(continues ou non) pour lesquelles il n'existe pas de méthode de résolution analytique (i.e.
pas de solution présentable sous la forme d'une formule simple, voire complexe)
-
Méthodes numériques de résolution de certaines classes de problèmes permettant de trouver une solution à partir d'une discrétisation du champ
de travail
-
Champ unidimentionnel: Appel à des tableaux
-
Champ bidimentionnel: Utilisation de matrices
-
Dimension 3: Tableaux à 3 indices
Exemples
-
Propagation de la chaleur au sein d'une barre métallique
-
Problème en dimension 1
-
Décomposition (discrétisation) de la barre en une suite de morceaux pour chacun desquels la température est considérée uniforme
-
Valeurs stockées et gérées dans un tableau à 1 indice
-
Augmentation du pas de discrétisation -> Obtention de résultats plus précis au prix d'un temps de calcul plus long
-
Propagation de la chaleur au sein d'une plaque métallique
-
Problème en 2 dimensions
-
Décomposition de la plaque en une grille de cellules pour chacune desquelles la température est considérée uniforme
-
Valeurs stockées dans un tableau à 2 indices





Simulation de l'évolution de la température d'une plaque métallique sur laquelle
sont créés des points chauds
Exemple d'exécution
-
Simulation de la surface océanique


Simulation de surface océanique
Kit de développement CUDA (NVidia)
-
Evolution climatique
-
Premiers modèles: Modèles en deux dimensions
-
Surface de la Terre décomposée en longitude et en latitude en un maillage "carré"
-
Informations relatives aux cellules de ce maillage stockées dans une matrice de variables
-
Etude de l'évolution du climat en considérant chaque cellule comme une entité atomique de caractéristiques uniformes
-
Modèles plus complexes: Trois dimensions

Décomposition de l'atmosphère en un maillage 2D

Décomposition de l'atmosphère en volumes élémentaires
-
Analyse des turbulences dans un fluide 2D
-
Problème en deux dimensions
-
Résolution des équations de mécanique des fluides (Navier-Stockes) complexe et extrêmement coûteuse en temps de calcul



Simulation de fluides
Kit de développement CUDA (NVidia)
-
Analyse des turbulences sur une aile d'avion
-
Problème en trois dimensions
-
Résolution des équations de mécanique des fluides (Navier-Stockes)
-
Historiquement, problème géré en dimension 2 avec simulation numérique sur des profils 2D de l'objet 3D
-
Accroissement de la puissance des ordinateurs -> Passage en 3D avec une aile complète
-
Bientôt possible de simuler l'écoulement sur un avion entier: ailes, fuselage, gouvernes, pylônes, réacteurs, ...

-
Problème des n-corps
-
Comment évolue un système de n corps sous l'effet des forces de gravité qu'ils appliquent les uns sur les autres?
-
Pour n masses, 3*n équations différentielles du 2ème ordre
-> 6*n inconnues





Résolution du problème des n-corps
Kit de développement CUDA (NVidia)


Simulations de collisions de galaxies
Matrices pour l'Informatique
-
Utilisation de matrices pour gérer les problèmes de l'informatique fondamentale qui se présentent naturellement sous forme 2D
Exemples

Dessin d'un segment de droite

Dessin d'un arc de cercle

Remplissage d'une facette triangulaire
/**
* Logiciel de dessin bitmap.
*
* @author Nicolas JANEY, Universite de Franche-Comte, France, <a href="mailto:nicolas.janey@univ-fcomte.fr">nicolas.janey@univ-fcomte.fr</a>
*/
public class DessinBitmap {
/**
* Type structure de description d'une couleur
*/
public static class Couleur {
/**
* Valeur de rouge.
*/
public int r = 0;
/**
* Valeur de vert.
*/
public int v = 0;
/**
* Valeur de bleu.
*/
public int b = 0;
}
/**
* Type structure de description d'une position 2D a coordonnees reelles
*/
public static class Position2D {
/**
* Abscisse.
*/
public double x = 0.0;
/**
* Ordonnee.
*/
public double y = 0.0;
}
/**
* Type structure de description d'un pixel
*/
public static class Pixel {
/**
* Position.
*/
public Position2D pos = new Position2D();
}
/**
* Type structure de description d'un segment en 2D
*/
public static class Segment2D {
/**
* Sommet initial.
*/
public Position2D si = new Position2D();
/**
* Sommet final.
*/
public Position2D sf = new Position2D();
}
/**
* Type structure de description d'un rectangle en 2D
*/
public static class Rectangle2D {
/**
* Position du centre.
*/
public Position2D c = new Position2D();
/**
* Taille en x.
*/
public double tx = 1.0;
/**
* Taille en y.
*/
public double ty = 1.0;
/**
* Rotation.
*/
public double rot = 0.0;
}
/**
* Type structure de description d'un cercle en 2D
*/
public static class Cercle2D {
/**
* Position du centre.
*/
public Position2D c = new Position2D();
/**
* Rayon.
*/
public double r = 1.0;
}
/**
* Type structure de description d'une ellipse en 2D
*/
public static class Ellipse2D {
/**
* Position du centre.
*/
public Position2D c = new Position2D();
/**
* Demi grand axe en x.
*/
public double a = 1.0;
/**
* Demi grand axe en y.
*/
public double b = 1.0;
/**
* Rotation.
*/
public double rot = 0.0;
}
/**
* Type structure de description d'un polygone regulier en 2D
*/
public static class PolygoneRegulier2D {
/**
* Position du centre.
*/
public Position2D c = new Position2D();
/**
* Nombre de sommets.
*/
public int n = 3;
/**
* Rotation.
*/
public double r = 1.0;
/**
* Rotation.
*/
public double rot = 0.0;
}
/**
* Saisie clavier d'une couleur.
*
* @param message Le message d'accompagnement a la saisie.
* @param c La couleur saisie.
*/
public static void saisie(String message,Couleur c) {
Ecran.afficherln(message);
Ecran.afficher("Rouge : ");
c.r = Clavier.saisirInt();
Ecran.afficher("Vert : ");
c.v = Clavier.saisirInt();
Ecran.afficher("Bleu : ");
c.b = Clavier.saisirInt();
}
/**
* Saisie clavier d'une position en 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param p La position saisie.
*/
public static void saisie(String message,Position2D p) {
Ecran.afficherln(message);
Ecran.afficher("x : ");
p.x = Clavier.saisirInt();
Ecran.afficher("y : ");
p.y = Clavier.saisirInt();
}
/**
* Saisie clavier d'un pixel.
*
* @param message Le message d'accompagnement a la saisie.
* @param p Le pixel saisi.
*/
public static void saisie(String message,Pixel p) {
Ecran.afficherln(message);
saisie("Position",p.pos);
}
/**
* Saisie clavier d'un segment 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param s Le segment 2D saisi.
*/
public static void saisie(String message,Segment2D s) {
Ecran.afficherln(message);
saisie("Sommet initial",s.si);
saisie("Sommet final",s.sf);
}
/**
* Saisie clavier d'un rectangle 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param r Le rectangle 2D saisi.
*/
public static void saisie(String message,Rectangle2D r) {
Ecran.afficherln(message);
saisie("Centre",r.c);
Ecran.afficher("Largeur : ");
r.tx = Clavier.saisirInt();
Ecran.afficher("Hauteur : ");
r.ty = Clavier.saisirInt();
Ecran.afficher("Rotation : ");
r.rot = Clavier.saisirDouble();
}
/**
* Saisie clavier d'un cercle 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param c Le cercle 2D saisi.
*/
public static void saisie(String message,Cercle2D c) {
Ecran.afficherln(message);
saisie("Centre",c.c);
Ecran.afficher("Rayon : ");
c.r = Clavier.saisirDouble();
}
/**
* Saisie clavier d'une ellipse 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param e L'ellipse 2D saisie.
*/
public static void saisie(String message,Ellipse2D e) {
Ecran.afficherln(message);
saisie("Centre",e.c);
Ecran.afficher("Largeur : ");
e.a = Clavier.saisirInt();
Ecran.afficher("Hauteur : ");
e.b = Clavier.saisirInt();
Ecran.afficher("Rotation : ");
e.rot = Clavier.saisirDouble();
}
/**
* Saisie clavier d'un polygone regulier 2D.
*
* @param message Le message d'accompagnement a la saisie.
* @param p Le polygone regulier 2D saisi.
*/
public static void saisie(String message,PolygoneRegulier2D p) {
Ecran.afficherln(message);
saisie("Centre",p.c);
Ecran.afficher("Rayon : ");
p.r = Clavier.saisirDouble();
Ecran.afficher("Nombre sommets : ");
p.n = Clavier.saisirInt();
Ecran.afficher("Rotation : ");
p.rot = Clavier.saisirDouble();
}
/**
* Calcul de la position obtenue par rotation d'une position autour d'une position.
*
* @param c Le centre de rotation.
* @param x L'abscisse de la position a traiter par rapport au centre de rotation.
* @param y L'ordonnee de la position a traiter par rapport au centre de rotation.
* @param a L'angle de rotation (en radians).
* @return La Position2D calculee.
*/
public static Position2D positionAvecRotation(Position2D c,double x,double y,double a) {
Position2D p = new Position2D();
p.x = c.x + x*Math.cos(a)-y*Math.sin(a);
p.y = c.y + x*Math.sin(a)+y*Math.cos(a);
return p;
}
/**
* Calcul de la suite de sommets d'un rectangle 2D.
*
* @param r Le rectangle 2D.
* @return Le tableau de Position2D calcule.
*/
public static Position2D [] sommets(Rectangle2D r) {
Position2D [] t = new Position2D[4];
t[0] = positionAvecRotation(r.c,r.tx/2.0,r.ty/2.0,r.rot);
t[1] = positionAvecRotation(r.c,-r.tx/2.0,r.ty/2.0,r.rot);
t[2] = positionAvecRotation(r.c,-r.tx/2.0,-r.ty/2.0,r.rot);
t[3] = positionAvecRotation(r.c,r.tx/2.0,-r.ty/2.0,r.rot);
return t;
}
/**
* Calcul de la suite de sommets d'un cercle 2D.
*
* @param c Le cercle 2D.
* @param n Le nombre de sommets a calculer.
* @return Le tableau de Position2D calcule.
*/
public static Position2D [] sommets(Cercle2D c,int n) {
Position2D [] t = new Position2D[n];
for ( int i = 0 ; i < n ; i++ ) {
double a = i*2.0*Math.PI/n;
t[i] = new Position2D();
t[i].x = c.c.x+c.r*Math.cos(a);
t[i].y = c.c.y+c.r*Math.sin(a); }
return t;
}
/**
* Calcul de la suite de sommets d'une ellipse 2D.
*
* @param e L'ellipse 2D.
* @param n Le nombre de sommets a calculer.
* @return Le tableau de Position2D calcule.
*/
public static Position2D [] sommets(Ellipse2D e,int n) {
Position2D [] t = new Position2D[n];
for ( int i = 0 ; i < n ; i++ ) {
double a = i*2.0*Math.PI/n;
t[i] = positionAvecRotation(e.c,e.a*Math.cos(a),e.b*Math.sin(a),e.rot); }
return t;
}
/**
* Calcul de la suite de sommets d'un polygone regulier 2D.
*
* @param p Le polygone regulier 2D.
* @return Le tableau de Position2D calcule.
*/
public static Position2D [] sommets(PolygoneRegulier2D p) {
Position2D [] t = new Position2D[p.n];
for ( int i = 0 ; i < p.n ; i++ ) {
double a = i*2.0*Math.PI/p.n;
t[i] = positionAvecRotation(p.c,p.r*Math.cos(a),p.r*Math.sin(a),p.rot); }
return t;
}
/**
* Affichage en boucle fermee de segements de droite d'un tableau de position 2D.
*
* @param t Le tableau de positions 2D a afficher graphiquement.
*/
public static void affichageTableauSommets(Position2D [] t) {
for ( int i = 0 ; i < t.length ; i++ ) {
EcranGraphique.drawLine((int) t[i].x,(int) t[i].y,
(int) t[(i+1)%t.length].x,(int) t[(i+1)%t.length].y); }
}
/**
* Affichage graphique d'un pixel.
*
* @param p Le pixel a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(Pixel p,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
EcranGraphique.drawPixel((int) p.pos.x,(int) p.pos.y);
}
/**
* Affichage graphique d'un segment 2D.
*
* @param s Le segment 2D a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(Segment2D s,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
EcranGraphique.drawLine((int) s.si.x,(int) s.si.y,(int) s.sf.x,(int) s.sf.y);
}
/**
* Affichage graphique d'un rectangle 2D.
*
* @param r Le rectangle 2D a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(Rectangle2D r,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
affichageTableauSommets(sommets(r));
}
/**
* Affichage graphique d'un cercle 2D.
*
* @param cl Le cercle 2D a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(Cercle2D cl,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
affichageTableauSommets(sommets(cl,180));
}
/**
* Affichage graphique d'une ellipse 2D.
*
* @param e L'ellipse 2D a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(Ellipse2D e,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
affichageTableauSommets(sommets(e,180));
}
/**
* Affichage graphique d'un polygone regulier 2D.
*
* @param p Le polygone regulier 2D a afficher.
* @param c La couleur d'affichage.
*/
public static void affichageGraphique(PolygoneRegulier2D p,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
affichageTableauSommets(sommets(p));
}
/**
* Affichage graphique d'une croix.
*
* @param x L'abscisse du centre de la croix.
* @param y L'ordonnee du centre de la croix.
*/
public static void croix(int x,int y,Cercle2D cl,Couleur c) {
EcranGraphique.setColor(c.r,c.v,c.b);
EcranGraphique.drawLine(x-10,y,x+10,y);
EcranGraphique.drawLine(x,y-10,x,y+10);
affichageGraphique(cl,c);
}
/**
* Saisie d'un cercle 2D interactivement a la souris.
*
* @param cl Le cercle a saisir interactivement.
*/
public static void saisieInteractiveSouris(Cercle2D cl) {
while ( EcranGraphique.getMouseState() == 0 );
EcranGraphique.setXorMode(true);
int xOld = EcranGraphique.getMouseX();
int yOld = EcranGraphique.getMouseY();
Couleur blanc = new Couleur();
blanc.r = 255;
blanc.v = 255;
blanc.b = 255;
cl.c.x = xOld;
cl.c.y = yOld;
cl.r = 0.0;
croix(xOld,yOld,cl,blanc);
while ( EcranGraphique.getMouseState() == 1 ) {
int x = EcranGraphique.getMouseX();
int y = EcranGraphique.getMouseY();
if ( ( x != xOld ) || ( y != yOld ) ) {
croix(xOld,yOld,cl,blanc);
xOld = x;
yOld = y;
cl.r = Math.sqrt(Math.pow(x-cl.c.x,2.0)+Math.pow(y-cl.c.y,2.0));
croix(x,y,cl,blanc);
EcranGraphique.flush(); } }
croix(xOld,yOld,cl,blanc);
EcranGraphique.flush();
EcranGraphique.setXorMode(false);
}
/**
* Gestion du menu principal de choix de l'action a realiser.
*
* @return L'entier saisi.
*/
public static int resultatMenuPrincipal() {
int v;
Ecran.sautDeLigne();
Ecran.afficherln(" 1: Choix de la couleur de trace");
Ecran.afficherln(" 2: Afficher un pixel");
Ecran.afficherln(" 3: Afficher un segment de droite");
Ecran.afficherln(" 4: Afficher un rectangle");
Ecran.afficherln(" 5: Afficher un cercle");
Ecran.afficherln(" 6: Afficher une ellipse");
Ecran.afficherln(" 7: Afficher un polygone regulier");
Ecran.afficherln(" 8: Afficher n objets tires au hasard");
Ecran.afficherln(" 9: Choisir la couleur d'effacement de la fenetre");
Ecran.afficherln("10: Effacer la fenetre");
Ecran.afficherln("11: Tracer dynamiquement un cercle");
Ecran.afficherln(" 0: Quitter");
Ecran.afficher("Que voulez vous faire ? ");
v = Clavier.saisirInt();
Ecran.sautDeLigne();
return v;
}
/**
* Programme principal.
*
* @param args Le tableau des parametres de lancement.
*/
public static void main(String [] args) {
int n;
int tx;
int ty;
int choix;
Pixel px = new Pixel();
Segment2D sg = new Segment2D();
Rectangle2D rt = new Rectangle2D();
Cercle2D cl = new Cercle2D();
Ellipse2D el = new Ellipse2D();
PolygoneRegulier2D pr = new PolygoneRegulier2D();
/* Couleurs de trace et d'effacement */
Couleur ct = new Couleur();
ct.r = 0;
ct.v = 0;
ct.b = 0;
Couleur ce = new Couleur();
ce.r = 255;
ce.v = 255;
ce.b = 255;
/* Initialisation de la fenetre d'affichage */
Ecran.afficherln("Taille de la fenetre");
Ecran.afficher("Tx : ");
tx = Clavier.saisirInt();
Ecran.afficher("Ty : ");
ty = Clavier.saisirInt();
EcranGraphique.init(50,50,tx,ty,tx-40,ty-80,"Dessin bitmap");
EcranGraphique.setClearColor(255,255,255);
EcranGraphique.clear();
EcranGraphique.flush();
choix = resultatMenuPrincipal();
while ( choix != 0 ) {
switch (choix) {
case 1 :
saisie("Couleur de trace?",ct);
break;
case 2 :
saisie("Votre pixel?",px);
affichageGraphique(px,ct);
EcranGraphique.flush();
break;
case 3 :
saisie("Votre segment?",sg);
affichageGraphique(sg,ct);
EcranGraphique.flush();
break;
case 4 :
saisie("Votre rectangle?",rt);
affichageGraphique(rt,ct);
EcranGraphique.flush();
break;
case 5 :
saisie("Votre cercle?",cl);
affichageGraphique(cl,ct);
EcranGraphique.flush();
break;
case 6 :
saisie("Votre ellipse?",el);
affichageGraphique(el,ct);
EcranGraphique.flush();
break;
case 7 :
saisie("Votre polygone regulier?",pr);
affichageGraphique(pr,ct);
EcranGraphique.flush();
break;
case 8 :
Ecran.afficher("Nombre d'objets : ");
n = Clavier.saisirInt();
for ( int i = 0 ; i < n ; i++ ) {
int type =(int) (Math.random()*6.0);
switch(type) {
case 0 :
px.pos.x = Math.random()*tx;
px.pos.y = Math.random()*ty;
affichageGraphique(px,ct);
break;
case 1 :
sg.si.x = Math.random()*tx;
sg.si.y = Math.random()*ty;
sg.sf.x = Math.random()*tx;
sg.sf.y = Math.random()*ty;
affichageGraphique(sg,ct);
break;
case 2 :
rt.c.x = Math.random()*tx;
rt.c.y = Math.random()*ty;
rt.tx = 3.0+Math.random()*500.0;
rt.ty = 3.0+Math.random()*500.0;
rt.rot = Math.random()*2.0*Math.PI;
affichageGraphique(rt,ct);
break;
case 3 :
cl.c.x = Math.random()*tx;
cl.c.y = Math.random()*ty;
cl.r = 3.0+Math.random()*200.0;
affichageGraphique(cl,ct);
break;
case 4 :
el.c.x = Math.random()*tx;
el.c.y = Math.random()*ty;
el.a = 3.0+Math.random()*200.0;
el.b = 3.0+Math.random()*200.0;
el.rot = Math.random()*2.0*Math.PI;
affichageGraphique(el,ct);
break;
case 5 :
pr.c.x = Math.random()*tx;
pr.c.y = Math.random()*ty;
pr.n = 3+(int) (Math.random()*10.0);
pr.r = 3.0+Math.random()*200.0;
pr.rot = Math.random()*2.0*Math.PI;
affichageGraphique(pr,ct);
break; } }
EcranGraphique.flush();
break;
case 9 :
saisie("Couleur d'effacement?",ce);
break;
case 10 :
EcranGraphique.setClearColor(ce.r,ce.v,ce.b);
EcranGraphique.clear();
EcranGraphique.flush();
break;
case 11 :
saisieInteractiveSouris(cl);
affichageGraphique(cl,ct);
EcranGraphique.flush();
break; }
choix = resultatMenuPrincipal(); }
Ecran.afficherln("Return pour quitter");
Clavier.saisirString();
EcranGraphique.exit();
}
}
|
Exemple d'affichage graphique bitmap |
-
Deux techniques de stockage d'images dans des fichiers:
-
Vectoriel: Images stockées sous la forme d'objets graphiques de type segment de droite, rectangle, rectangle rempli, cercle, disque, ...
-
Bitmap: Images stockées sous la forme d'une grille rectangulaire de pixels décrits individuellement par une couleur
-
Déclinaison de ces techniques de diverses manières avec pour conséquence l'apparition de divers formats de fichiers:
-
Exemples de formats vectoriels: Postscript (.ps) et SVG (.svg, Scalable Vector Graphic)
-
Exemples de formats bitmap: JPEG, BMP, GIF, PNG
-
Compression ou non
-
Si compression, perte de qualité ou non
-
Format 8 bits, 24 bits ou 32 bits
-
...
-
Traitement particulier applicable aux images bitmaps: Réalisation d'opérations de traitement d'image visant à en changer les caractéristiques:
-
Afficher en fausses couleurs
-
Augmenter/diminuer la luminosité
-
Augmenter/diminuer le contraste
-
Flouter
-
Extraire les contours
-
Négativer
-
...
-
Traitement mathématique de chaque pixel de la matrice de pixels représentant l'image
-
Calcul de la nouvelle valeur d'un pixel à partir de son ancienne valeur
-> Filtrage spectral
-
Calcul de la nouvelle valeur d'un pixel à partir de son ancienne valeur ainsi que des valeurs d'autres pixels (généralement les pixels voisins)
-> Filtrage matriciel

Image originale

Image floutée
Remplacement de chaque pixel par la moyenne de ce pixel et des pixels voisins

Image après extraction de contours
Gradiant calculé sur les pixels voisins
/**
* Conversion d'une couleur RVB en un entier.
*
* @param r La composante de rouge de la couleur a convertir.
* @param v La composante de vert de la couleur a convertir.
* @param b La composante de bleu de la couleur a convertir.
*
* @return L'entier codant la Couleur
* selon la formule b*256*256+v*256+r.
*/
public static int couleur(int r,int v,int b) {
int couleur;
couleur = b*256*256+v*256+r;
return couleur;
}
/**
* Diminution de la luminosite d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
static void diminuerLuminosite(int [][] img,double prct) {
double fact = 1.0-prct/100.0;
int r;
int v;
int b;
for ( int x = 0 ; x < img.length ; x++ ) {
for ( int y = 0 ; y < img[0].length ; y++ ) {
r = img[x][y]%256;
v = (img[x][y]/256)%256;
b = img[x][y]/65536;
r =(int) (r*fact);
v =(int) (v*fact);
b =(int) (b*fact);
img[x][y] = couleur(r,v,b); } }
}
/**
* Augmentation de la luminosite d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
static void augmenterLuminosite(int [][] img,double prct) {
double fact = 1.0-prct/100.0;
int r;
int v;
int b;
for ( int x = 0 ; x < img.length ; x++ ) {
for ( int y = 0 ; y < img[0].length ; y++ ) {
r = img[x][y]%256;
v = (img[x][y]/256)%256;
b = img[x][y]/65536;
r = 255 - (int) ((255-r)*fact);
v = 255 - (int) ((255-v)*fact);
b = 255 - (int) ((255-b)*fact);
img[x][y] = couleur(r,v,b); } }
}
/**
* Diminution du contraste d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
static void diminuerContraste(int [][] img,double prct) {
double fact = 1.0-prct/100.0;
int r;
int v;
int b;
for ( int x = 0 ; x < img.length ; x++ ) {
for ( int y = 0 ; y < img[0].length ; y++ ) {
r = img[x][y]%256;
v = (img[x][y]/256)%256;
b = img[x][y]/65536;
r = 127 -(int) ((127-r)*fact);
v = 127 -(int) ((127-v)*fact);
b = 127 -(int) ((127-b)*fact);
img[x][y] = couleur(r,v,b); } }
}
/**
* Augmentation du contraste d'une image.
*
* @param img Le tableau image a traiter.
* @param prct Le pourcentage de modification.
*/
static void augmenterContraste(int [][] img,double prct) {
double fact = 1.0-prct/100.0;
int r;
int v;
int b;
for ( int x = 0 ; x < img.length ; x++ ) {
for ( int y = 0 ; y < img[0].length ; y++ ) {
r = img[x][y]%256;
v = (img[x][y]/256)%256;
b = img[x][y]/65536;
if ( r <= 127 )
r =(int) (r*fact);
else
r = 255 - (int) ((255-r)*fact);
if ( v <= 127 )
v =(int) (v*fact);
else
v = 255 - (int) ((255-v)*fact);
if ( b <= 127 )
b =(int) (b*fact);
else
b = 255 - (int) ((255-b)*fact);
img[x][y] = couleur(r,v,b); } }
}
/* Methode de clonage d'un tableau */
/* a 2 indices de int */
static int [][] clone(int [][] t) {
int i;
int j;
int n = t.length;
int m = t[0].length;
int [][] nt = new int[n][m];
for ( i = 0 ; i < n ; i = i+1 ) {
for ( j = 0 ; j < m ; j = j+1 ) {
nt[i][j] = t[i][j]; } }
return nt;
}
/**
* Floutage d'une image.
*
* @param img Le tableau image a traiter.
*/
static void flouter(int [][] img) {
int [][] image = clone(img);
int r;
int v;
int b;
int totr;
int totv;
int totb;
int nb;
for ( int x = 0 ; x < image.length ; x++ ) {
for ( int y = 0 ; y < image[0].length ; y++ ) {
totr = 0;
totv = 0;
totb = 0;
nb = 0;
for ( int xx = x-2 ; xx <= x+2 ; xx++ ) {
for ( int yy = y-2 ; yy <= y+2 ; yy++ ) {
if ( ( xx >= 0 ) && ( xx < image.length ) &&
( yy >= 0 ) && ( yy < image[0].length ) ) {
totr = totr+image[xx][yy]%256;
totv = totv+(image[xx][yy]/256)%256;
totb = totb+image[xx][yy]/65536;
nb = nb+1; } } }
r = totr/nb;
v = totv/nb;
b = totb/nb;
img[x][y] = couleur(r,v,b); } }
}
/**
* Extraction de contours dans une image.
*
* @param img Le tableau image a traiter.
*/
static void extraireContours(int [][] img) {
int [][] image = clone(img);
int r;
int v;
int b;
for ( int x = 0 ; x < image.length ; x++ ) {
img[x][0] = 0;
img[x][img[0].length-1] = 0; }
for ( int y = 1 ; y < image[0].length-1 ; y++ ) {
img[0][y] = 0;
img[img.length-1][y] = 0; }
for ( int x = 1 ; x < image.length-1 ; x++ ) {
for ( int y = 1 ; y < image[0].length-1 ; y++ ) {
r = 4*(image[x][y]%256);
v = 4*((image[x][y]/256)%256);
b = 4*(image[x][y]/65536);
r = r-image[x-1][y]%256;
v = v-(image[x-1][y]/256)%256;
b = b-image[x-1][y]/65536;
r = r-image[x+1][y]%256;
v = v-(image[x+1][y]/256)%256;
b = b-image[x+1][y]/65536;
r = r-image[x][y-1]%256;
v = v-(image[x][y-1]/256)%256;
b = b-image[x][y-1]/65536;
r = r-image[x][y+1]%256;
v = v-(image[x][y+1]/256)%256;
b = b-image[x][y+1]/65536;
r = Math.abs(r);
if ( r > 255 )
r = 255;
v = Math.abs(v);
if ( v > 255 )
v = 255;
b = Math.abs(b);
if ( b > 255 )
b = 255;
img[x][y] = couleur(r,v,b); } }
}
|
Exemple de traitement d'image |
-
Jeu de la vie
-
Une grille de booléens initialisés à vrai ou à faux
-
Chaque cellule évolue en fonction du contenu de ses 8 voisines
-
Si 2 voisins à vrai, la cellule ne change pas
-
Si 3 voisins à vrai, la cellule passe à vrai
-
Dans tous les autres cas, la cellule passe à faux
-
Automate cellulaire
-
Evolution d'un eco-système




Placement aléatoire -> Stabilisation au bout d'un certain nombre d'étapes
Exemple d'exécution



Evolution cyclique en place: Galaxie
Exemple d'exécution

Evolution cyclique avec déplacement régulier: Vaisseau
Exemple d'exécution

Tétris

Candy Crush
|