Synthèse d images (4) Modèles procéduraux Plan de l exposé 1- Formes naturelles 2- Récursivité 3- Hasard 4- Bibliographie ppmforge (John Walker)
Le besoin : appréhender la complexité des formes naturelles eau / terre / feu / vie Première approche : récurence et/ou hasard simulé Exemples de tous les jours : - Le chou-fleur - Cristal de sel que l'on casse (Hauÿ) - Cristaux de neige et de givre 1. Formes naturelles Kaemtz - Traité de météorologie, trad. Martins 1843
Exemple des côtes de Bretagne Loi de L. F. Richardson [LAUWERIER] p. 30 IGN - Catalogue des cartes série bleue et Top 25
2. Récursivité Exemple fondateur : le flocon de von Koch (1919) On peut décrire ce type de courbe par une grammaire générative : w : F-F-F-F P : F=>F-F+F+FF-F-F+F F :avance + :à gauche - :àdroite [DONY] p. 152
Autres exemples [DONY] p. 159
L'ensemble de Mandelbrot On étudie la fonction itérative complexe : z(n+1) = z(n)^2 + c avec z(0) = c Selon la valeur de c, la suite tend soit vers l'infini, soit vers une constante Exemples : c = 1+i c = -1 + 0.25 i itération 1 module de z = 0.5 itération 2 module de z = 0.559 itération 3 module de z = 0.731 itération 80 module de z = 0.493 L'ensemble de Mandelbrot est constitué par tous les c tels que z^2+c reste fini quelque soit le nombre d'itération itération 1 module de z = 3.162 itération 2 module de z = 9.899 itération 3 module de z = 97.01 itération 4 module de z = 9409
Exemple de calcul (en Java) Source complet sur http://cedric.cnam.fr/personne/cubaud/ colonne+=inccolonne; g.drawimage(ofbuff,0,0,null); colonne=0; while (colonne<=larg) { p0=x1+colonne*incx; ligne=0; while (ligne <= (haut/2)) { q0=y1+ligne*incy; x=0;y=0;compt=1;module=0; while ((compt<=limite)&&(module<4.0)) { aux=x; x=x*x-y*y+p0; y=2*y*aux+q0; module=x*x+y*y; compt++; if (module<4.0) { ofg.drawline(colonne,ligne,colonne,ligne); ofg.drawline(colonne,haut-ligne,colonne,haut-ligne); // pour patienter pdt le calcul g.drawline(colonne,ligne,colonne,ligne); ligne+=incligne;
Exploration avec MandelBrowser (Jess Jones, 1995 - pour Macintosh)
3. Hasard Calculer du pseudo hasard Méthodes congruentielles (Lehmer, 1951) Trois paramètres : U0 : le Uk = (auk-1) modulo m germe ("seed") m : le diviseur (terme de congruence) a : le multiplicateur Exemple : U k = 3U k 1 mod31 période = 31 car 31=2^5-1 U0 = 15 (premier avec 31) U1 = 3*15 mod 31 = 45 mod 31 = 14 U2 = 3*14 mod 31 = 11 U3 = 3*11 mod 31 = 2 U4 = 3*2 mod 31 = 6 U30 = 15 U31 = 14 = U1 la période est atteinte Autre germe : U0 = 10 (premier avec 31) U1 = 3*10 mod 31 = 30 U2 = 3*30 mod 31 = 28 etc Un bon générateur (Park & Miller, 1988) : On choisi a = 7^5 = 16807 et m = 2^31-1 Si entiers sur 32 bits : overflow function random(var u:integer):real const a=16807; m=2147483647; q=127773; (* m div a *) r=2836; (* m mod a *) var nu:integer; begin nu:= a*(u mod q) - r*(u div q); if nu>0 then u:=nu else u:=nu+m; random:=u/m; end;
Croissance végétale http://cedric.cnam.fr/personne/cubaud/ Léonard de Vinci - Bib. de l'institut - in [COMAR] p. 13 void Fractale(Graphics g,int ax,int ay,int bx,int by,double angle,int i) { g.drawline(ax,ay,bx,by); if (i!=iter) { double ag=angle-math.random()*ang; double ad=angle+math.random()*ang; double dist=math.sqrt((bx-ax)*(bx-ax)+(byay)*(by-ay)); int cx=(int) (pos*bx+(1-pos)*ax); int cy=(int) (pos*by+(1-pos)*ay); int dx=(int) (cx+rap*dist*math.sin(ag)); int dy=(int) (cy-rap*dist*math.cos(ag)); int ex=(int) (cx+rap*dist*math.sin(ad)); int ey=(int) (cy-rap*dist*math.cos(ad)); Fractale(g,cx,cy,dx,dy,ag,i+1); Fractale(g,cx,cy,ex,ey,ad,i+1); On peut étendre le principe des grammaires génératives (cf biblio) Exemple avec 3 niveaux d'itérations
Modèles de reliefs Exemple de marche aléatoire : le gain au jeu de pile ou face : main() { int s,i; s1=354675; /* racines du generateur aleatoire */ s2=78364; s=0; for(i=1;i<=100;i++) { if (Uniform()<0.5){s++; else {s--; printf("%d \n",s); Visualisation avec GNUplot : 2 0 'resmont' -2-4 -6-8 Feller - An introduction to probability theory - vol 1. - Wiley, 1950. p. 87-10 -12-14 0 10 20 30 40 50 60 70 80 90 100
Mouvement brownien La figure ci-jointe reproduit trois dessins obtenus en traçant les segments qui joignent les positions consécutives d'un même grain de mastic, à 30 secondes d'intervalle. C'est le demi-carré moyen de tels segments qui vérifie la loi d'einstein. L'un de ces dessins contient 50 positions consécutives d'un même grain. Ils ne donnent qu'une idée très affaiblie du prodigieux enchevêtrement de la trajectoire réelle. Si, en effet, on faisait des pointés de secondes en secondes, chacun de ces segments rectilignes se trouverait remplacé par un contour polygonal de 30 côtés relativement aussi compliqué que le dessin reproduit ici, et ainsi de suite. 1 carreau = 5mm pour 1.7µm main(){ int t;double y; /* racines du generateur aleatoire */ s1=354675;s2=78364; t=0.0;y=0.0; printf("%.2f %.2f\n",t,y); for(t=0;t<tmax;t++) { y += Normal(0.0,D); printf("%d %f \n",t,y); Visualisation avec GNUplot : 40 35 30 25 20 15 10 5 0-5 'resbrown1d' J. Perrin Ann. Chimie et Physique, 8ème série, 18, 1909. reprod. in Œuvres scientifiques de J. Perrin, CNRS, 1950 p. 217-8 voir aussi : Les atomes -10 0 200 400 600 800 1000 L'écart-type D ne modifie que l'amplitude du mouvement (en ordonnée ici), mais pas la rugosité du signal. Celle-ci dépend finalement de N
Subdivion récursive du mouvement brownien On choisit (xd,yd) la position de départ (t=0) On choisit (xf,yf) la position finale à date t=t Celle-ci suit une loi normale de moyenne (xd,yd) et de variance 2DT La position intermédiaire à date T/2 connaissant le départ et l'arrivée suit elle-aussi une loi normale de variance 2D(T/2)=DT On montre que sa position moyenne est la moyenne des positions initiales et finales (S. Karlin Initiation aux processus aléatoires Dunod 1969 p. 301) IMPORTANT : Ceci parce que la loi normale est stable pour l'opération d'addition ( infiniment divisible ). Ce n'est pas la seule. Point de départ des travaux de P. Lévy, puis de B. Mandelbrot *Une démo : http://www.stat.umn.edu/~charlie/stoch/
Algorithme largeur d'abord!! #define D 1.0 #define N 12 main() { s1=354675;s2=78364; /* racines du generateur aleatoire */ Avec N=5 : 33 points 1 0.5 0-0.5 'resrec5' fin=nouveau(100.0,0.0,null); deb=nouveau(0.0,0.0,fin); s=sqrt(d); for(i=1;i<=n;i++){ p=deb; while (p!=fin){ xm=normal((p->x+p->suiv->x)/2.0,s); ym=normal((p->y+p->suiv->y)/2.0,s); q=nouveau(xm,ym,p->suiv); p->suiv=q; p=q->suiv; s /= sqrt(2.0); p=deb; while (p!=null) { printf("%f %f\n",p->x,p->y); p=p->suiv; -1-1.5-2 -2.5 0 10 20 30 40 50 60 70 80 90 100 Avec N=12 : 4097 points 1.5 'resrec12' 1 0.5 0-0.5-1 -1.5-2 -2.5 0 10 20 30 40 50 60 70 80 90 100
Mouvement brownien fractionnaire *Mandelbrot. Une classe de processus stochastiques homothétiques à soi ; application à la loi climatologique de H.E. Hurst. CRAS t. 260, pp. 3274-7 (mars 65) rep. in B. Mandelbrot. Fractales, hasard et finance. Flammarion, 1997 pp. 26-9) On introduit le paramètre 0<H<1 (facteur de Hurst) dans la variance du processus brownien : var(x(t)) = D.t^(2H) Le processus reste self-similaire, mais apparaît un phénomène de dépendance à long terme. En pratique, H=3/4 se rencontre souvent dans la nature (séries climatologiques, reliefs ) L'algorithme de subdivision peut facilement être modifié : s /= sqrt(2.0); devient : s /= pow(2.0,h); mais le processus produit n'est qu'une approximation du MBf
Exemples : avec H =3/4= 0.75 1 0.5 'resfbm12-9' 1 0.5 0-0.5-1 -1.5 'resfbm12' 0-0.5-1 -1.5-2 0 10 20 30 40 50 60 70 80 90 100-2 0 10 20 30 40 50 60 70 80 90 100 avec H=0.90 comparer avec le mvt. brownien ordinaire (H=0.5)
Modèles de terrains (bis) On a utilisé un polygône de 13 côtés H = 0.7 N = 12 D = 5e4 pour le repère choisi : 0<x<11000 et 0<y<11000 8000 7800 'resfrance0' 'resfrance5' 10000 9000 8000 7000 6000 5000 4000 3000 2000 1000 'resfrance0' 'resfrance5' 7600 7400 7200 7000 6800 6600 6400 6200 6000 1000 1200 1400 1600 1800 2000 2200 2400 2600 2800 3 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000
Une variante *Fournier, Fussel, Carpenter. Computer rendering of stochastic models Comm. ACM 25(6) June 1982 p. 377 F.S. Hill Computer graphics Prentice-Hall 1990 pp. 162-4 Xm = (Xd+Xf)/2 Ym = (Yd+Yf)/2 R, réalisation d'une va N(0,S*f) avec f=2^(1/2-h) départ intermédiaire M final void Divise(ax,ay,bx,by,stdev) double ax,ay,bx,by,stdev; { double l,xm,ym,r; l=sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by)); if (l<minseg) printf("%f %f\n",bx,by); else { r=normal(0.0,stdev*f); xm=(ax+bx)/2.0-r*(by-ay); ym=(ay+by)/2.0+r*(bx-ax); Divise(ax,ay,xm,ym,stdev*f); Divise(xm,ym,bx,by,stdev*f); Xi = Xm-(Yf-Yd)*R Yi = Ym+(Xf-Xd)*R avec :
Encore une autre (et j'arrête) void Divise(xg,yg,xd,yd,n) double xg,yg,xd,yd;int n; { double xm,ym,min,max; 0.131 0.13 0.129 0.128 'resmont27' xm=(xg+xd)/2.0; if (yg<yd){min=yg;max=yd; else {min=yd;max=yg; ym=min+(max-min)*uniform(); if (n==0) {printf("%f %f\n",xm,ym); else { Divise(xg,yg,xm,ym,n-1); Divise(xm,ym,xd,yd,n-1); 0.127 0.126 0.125 0.124 0.123 0 10 20 30 40 50 60 70 80 90 100 main() { s1=354675;/* racines du generateur aleatoire */ s2=78364; Divise(0.0,Uniform(),100.0,Uniform(),7);
En 3 dimension L'algorithme de subdivision peut se généraliser à des surfaces du type z=f(x,y) ("surfaces d'élévation"). *Fournier et al. op. cit. p. 381 *le topo de Paul Martz http://gameprogrammer.com/fractal/fractal.html *Celui de Paul Bourke (avec le logiciel FracHill) http://www.mhri.edu.au/~pdb/fractals/landscapes
4. Bibliographie complémentaire Benoit Mandelbrot "Les objets fractals" collection "Champs", Flammarion, 1995, 4ème ed. Hans Lauwerier "Fractals : images of chaos" Penguin books, 1991 HO Peitgen & PH Ritcher "The beauty of fractals" Springer, 1986 HO Peitgen & D. Saupe "The science of fractal images" Springer Prusinkiewicz & Lindenmayer "The algorithmic beauty of plants" collection "The virtual laboratory", Springer, 1996 Meinhardt "The algorithmic beauty of sea shells" collection "The virtual laboratory", Springer, 1995