retour index

chapitre 2

Fractales mathématiques

La courbe de Koch par récursivité

L'île des fjords

La courbe de Lévy

La courbe du dragon

La courbe de Sierpinski

Les courbes de Péano

La courbe de Hilbert

La dimension fractale

Transformations linéaires affines

Le rameau

La fougère de Barnley

Du triangle à l'arbre de Noël

Exercices

 

Dans ce chapitre, on va voir une autre façon de tracer les fractales à partir de l'opérateur de Hutchinson de celles-ci, économe en temps de calcul ;c'est le procédé de récursivité. On en profitera pour tracer des courbes de Péano, qui sont des courbes qui remplissent une portion de plan, c'est-à-dire qui passent par tous les points de cette portion. On verra ensuite une première généralisation des fractales qui consiste à prendre des transformations linéaires affines généralisant les similitudes pour tracer les fractales qui ne sont alors plus strictement autosimilaires. Cela permet de tracer de belles figures qui se rapprochent des objets naturels.

 

début chapitre

La courbe de Koch par récursivité

Une façon très élégante et rapide pour tracer un grand nombre de fractales est de procéder par récursivité.On va illustrer cette méthode sur la courbe de Koch.

L'opérateur de Hutchinson consiste à réduire d'un facteur 3 la courbe de Koch, à en faire 4 copies et à les disposer bout à bout, la première dans la direction initiale, la seconde tournée de $\pi /3,$ la troisième tournée de $-2\pi /3$ par rapport à la seconde, et la dernière de $\pi /3$ par rapport à la troisième.

Une première procédure, appelée segment , trace, à partir du dernier point (x,y) d'une suite, le point suivant, d'abcisse $x+\cos (a)$ et d'ordonnée $y+\sin (a),$ a étant l'angle polaire avec Ox. Elle permettra de tracer les $4^{n}$ segments qui composent la courbe de Koch à l'itération n.

La procédure principale, appelée Koch dépend du nombre n d'itérations ;si n = 0, elle se réduit à segment. Si n >0, Koch(n) se compose de 4 procédures Koch(n-1) séparées par les changements d'angle indiqués et le procédé se répètera jusqu'à tomber sur n=0 où les segments seront tracés ;en cela consiste le procédé de récursivité, économe en mémoire puisque le liste des points est tracée en une seule fois. On ne s'occupe pas de diviser les longueurs des segments à chaque étape puisque l'ordinateur adapte automatiquement l'échelle du dessin à l'écran.

> restart:with(plots):with(plottools):

> segment:=proc(a) local k: global courbe: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

>a:=0:Koch:=proc(n) global a: if n=0 then segment(a) else

Koch(n-1):a:=a+Pi/3: Koch(n-1):a:=a-2*Pi/3: Koch(n-1):

a:=a+Pi/3: Koch(n-1): fi end:

> courbe:=0,0:Koch(4):

>p:= pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none):

Profitons-en pour tracer l'île de Koch formée de trois courbes de Koch s'appuyant sur un triangle équilatéral :

>p1:=reflect(p,[[0,0],[1,0]]):p2:=rotate(p,Pi/3):

p3:=rotate(p,-Pi/3,[3^4,0]):

>display(p1,p2,p3);


chap2__7.pngfigure 2.1 : île de Koch par récursivité

Si l'on tourne la courbe de Koch vers l'intérieur en changeant $\pi /3$ en $-\pi /3,$ on obtient l'île suivante :


chap2__10.pngfigure 2.2 : île de Koch tournée vers l'intérieur

On peut obtenir des dessins très différents en changeant les valeurs numériques. Prenons un exemple, obtenu simplement en changeant l'angle $\pi /3$ en $84\pi /180$ (84MATH) :

> restart:with(plots):with(plottools):

> segment:=proc(a) local k: global courbe:k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> a:=0:Koch:=proc(n) global a:

if n=0 then segment(a) else Koch(n-1):

a:=a+evalf(84*Pi/180): Koch(n-1):a:=a-2*evalf(84*Pi/180):

Koch(n-1):a:=a+evalf(84*Pi/180): Koch(n-1): fi end:

> courbe:=0,0:Koch(4):

> p:=pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none):

> p1:=reflect(p,[[0,0],[1,0]]):p2:=rotate(p1,Pi/2):

p3:=translate(p1,0,(2+2*sin(6*Pi/180))^4):

p4:=translate(rotate(p,Pi/2),(2+2*sin(6*Pi/180))^4,0):

> display(p,p2,p3,p4);


chap2__14.pngfigure 2.3 : pavement fractal


 

début chapitre

L'île des fjords

On désire tracer la fractale dont le motif, en partant du segment [0,1] est le suivant :


chap2__16.pngfigure 2.4 : 1$^{\grave{e}re} $ itération de l'île des fjords

Les points intermédiaires ont pour coordonnées (0,3, 0,3) et (0,7, -0,3). La longueur du premier et du 3$^{i\grave{e}me}$ segment est donc MATH la longueur du second MATH L'angle dont on tourne au départ est de $\pi /4$ ;il faut tourner ensuite de MATH puis de l'angle opposé ;ne pas oublier à la fin de tourner de $-\pi /4$ pour revenir à l'orientation initiale.

Cette fois, la procédure doit dépendre non seulement du nombre d'itérations n, mais également de la longueur du segment l.

> restart:with(plots):with(plottools):

>segment:=proc(l,a) local k: global courbe:k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+l*cos(a),courbe[k]+l*sin(a) end:

> l:=1:a:=0:pro:=proc(n,l) global a: if n=0 then segment(l,a)

else a:=a+Pi/4: pro(n-1,sqrt(0.3^2+0.3^2)*l):

a:=a-(Pi/4+arctan(0.3/0.2)): pro(n-1,sqrt(0.3^2+0.2^2)*2*l):

a:=a+Pi/4+arctan(0.3/0.2): pro(n-1,sqrt(0.3^2+0.3^2)*l):

a:=a-Pi/4 fi end:

> courbe:=0,0:n:=5:pro(n,1):

>pointplot([courbe],scaling=constrained,

style=line,color=red,axes=none);

L'île s'obtient en faisant 4 copies s'appuyant sur les côtés d'un carré ;

> p:=pointplot([courbe],scaling=constrained,

style=line,color=red,axes=none):

> :p1:=rotate(p,Pi/2):p2:=translate(p,0,1):

p3:=translate(rotate(p,Pi/2),1,0):

> display(p,p1,p2,p3);


chap2__23.pngfigure 2.5 : l'île des fjords


 

début chapitre

La courbe de Lévy

Procédons de la même façon pour la courbe de Lévy,

qui se compose de 2 copies réduites, la première tournée de $\pi /4$ et la seconde de $-\pi /4$ :

> restart:with(plots):

> segment:=proc(a) local k: global courbe:k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

>a:=0:Levy:=proc(n) global a: if n=0 then segment(a) else

a:=a+Pi/4:Levy(n-1):a:=a-Pi/2:Levy(n-1):a:=a+Pi/4 fi end:

> courbe:=0,0:Levy(10):

> pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none);


chap2__26.pngfigure 2.6 : courbe de Lévy par récursivité


 

début chapitre

La courbe du dragon

C'est la courbe obtenue en pliant en deux une feuille de papier, puis encore en deux dans le même sens et en répétant encore l'opération. Après 3 itérations, on obtient,en regardant par la tranche, le pliage suivant, qui est le point de départ de la fractale :


chap2__27.pngfigure 2.7 : feuille pliée 3 fois

et après 4 itérations, on obtient le motif, où chacun des segments du dessin précédent est remplacé par 2 segments :


chap2__28.pngfigure 2.8 : feuille pliée 4 fois

Si le segment est horizontal et a donc un angle a = 0, il se transforme en 2 segments d'angles 0 et $-\pi /2$ ;si le segment est vertical descendant et a $a=-\pi /2,$ il se transforme en un segment d'angle $\pi $ suivi de $-\pi /2$ ;s'il est horizontal vers la gauche et a pour angle $\pi $, il se transforme en $\pi $ suivi de $\pi /2$ ;enfin, s'il est vertical ascendant d'angle $\pi /2,$ il se transforme en segments d'angles $\pi /2$ et $\pi .$

La procédure étant différente suivant les valeurs de a, drag sera une procédure à deux variables, le nombre d'itérations et l'angle. Cela donne le programme suivant :

> restart:with(plots):

> segment:=proc(a) local k:global courbe:k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

>drag:=proc(n,a) global courbe:if n=0 then segment(a)

else if a=0 then drag(n-1,a):drag(n-1,a-Pi/2)

elif a=-Pi/2 then drag(n-1,a+3*Pi/2):drag(n-1,a)

elif a=Pi then drag(n-1,a):drag(n-1,a-Pi/2)

elif a=Pi/2 then drag(n-1,a-Pi/2):drag(n-1,a):

fi fi end:

> courbe:=0,0:drag(12,0):

> pointplot([courbe],style=line,color=red,axes=framed,

scaling=constrained);


chap2__39.pngfigure 2.9 : le dragon de Conway


 

début chapitre

La courbe de Sierpinski

Il s'agit d'une courbe qui ne se recoupe pas et qui visite l'ensemble des points du triangle de Sierpinski !


chap2__42.pngfigure 2.10 : 1$^{i\grave{e}re}$ et 2$^{i\grave{e}me}$ itérations de la courbe de Sierpinski

La première itération est en trait gras. C'est le point de départ La 2$^{i\grave{e}me}$ itération, qui est le motif, reproduit bien la première sur chacun des segments, mais elle est sitée à droite pour le 1$^{er}$ et le 3$^{i\grave{e}me}$ segments, et à gauche pour le second. Il faut donc changer les angles de la seconde copie. On va donc faire une procédure dépendant du nombre d'itérations et d'un nombre p qui permettra de changer le signe des angles. Ce qui donne le programme suivant :

> restart:with(plots):

> segment:=proc(a) global courbe:local k: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> a:=0:Sier:=proc(n,p) global a: if n=0 then segment(a)

else a:=a+p*Pi/3:Sier(n-1,-p): a:=a-p*Pi/3:Sier(n-1,p):

a:=a-p*Pi/3:Sier(n-1,-p):a:=a+p*Pi/3 fi end:

> courbe:=0,0:Sier(7,1):

> pointplot([courbe],style=line,scaling=constrained,color=red);


chap2__46.pngfigure 2.11 : courbe de Sierpinski


 

début chapitre

Les courbes de Péano

Ce sont des courbes introduites par Péano en 1890 et par Hilbert en 1891, qui ''remplissent'' le plan, en ce sens que ces courbes passent par tous les points d'une portion de plan. Nous verrons que leur dimension fractale est 2. La nature d'ailleurs procède de la même façon lorsqu'elle irrigue la totalité des cellules du corps à l'aide du réseau sanguin.

La courbe de Péano 1


chap2__47.pngfigure 2.12 : motif de la courbe de Péano 1

Sa construction consiste à remplacer le segment de longueur unité par le motif constitué de 9 petits segments de longueur 1/3, dans l'ordre indiqué sur la figure ci-dessus. On procède alors comme pour la courbe de Koch par récursivité en suivant le dessin :

> restart:with(plots):

> segment:=proc(a) local k: global courbe: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> pea:=proc(n) global a,courbe:

if n=0 then segment(a) else pea(n-1):a:=a+Pi/2:pea(n-1)

:a:=a-Pi/2:pea(n-1):a:=a-Pi/2:pea(n-1):a:=a-Pi/2:pea(n-1):

a:=a+Pi/2:pea(n-1):a:=a+Pi/2:pea(n-1):a:=a+Pi/2:pea(n-1):

a:=a-Pi/2:pea(n-1):fi:end:

> a:=0:courbe:=0,0:pea(3):

> pointplot([courbe],style=line,color=red,scaling=constrained);


chap2__48.pngfigure 2.13 : courbe de Péano 1

On peut améliorer le tracé en arrondissant de façon à éviter les intersections; pour cela, on trace les segments joignant le 1/4 et le 3/4 des segments initiaux :

> liste1:=seq(op([courbe[2*i-1]+(courbe[2*i+1]-courbe[2*i-1])/4,

courbe[2*i]+(courbe[2*i+2]-courbe[2*i])/4,

courbe[2*i-1]+(courbe[2*i+1]-courbe[2*i-1])*3/4,

courbe[2*i]+(courbe[2*i+2]-courbe[2*i])*3/4]),

i=1..nops([courbe])/2-1):

> pointplot([liste1],style=line,color=red,scaling=constrained);

Ce qui donne à l'ordre 1 :


chap2__49.pngfigure 2.14 : courbe de Péano arrondie à l'ordre 1

et à l'ordre 3


chap2__50.pngfigure 2.15 : courbe de Péano 1 arrondie

On peut également tracer une variante en joingnant les milieux des segments de la courbe Péano 1 :

> liste:=seq(op([(courbe[2*i-1]+courbe[2*i+1])/2,

(courbe[2*i]+courbe[2*i+2])/2]),i=1..nops([courbe])/2-1):

> pointplot([liste],style=line,color=red,scaling=constrained);


chap2__51.pngfigure 2.16 : variante de la courbe de Péano 1

Courbe de Péano 2

C'est encore une courbe qui remplit entièrement un carré, autorépulsive en ce sens qu'elle n'a pas d'intersection.

Les trois premières étapes sont les suivantes :


chap2__52.pngfigure 2.17 : premières étapes de la courbe de Péano 2

La première figure pour n=0 se compose de trois segments d'angles $\pi /2,$ 0 et $-\pi /2.$ On voit que la seconde figure, qui est le motif, se déduit de la première en prenant 4 copies, séparées par 3 segments, 2 verticaux et un horizontal. La 3$^{i\grave{e}me}$ figure se déduit de la seconde de la même façon. Pour la copie 1 de la seconde figure, il faut, à partir de la figure initiale, la faire tourner de $\pi /2$ et inverser les angles, puis tracer un segment vertical ;les copies 2 et 3 reproduisent la figure initiale avec un segment horizontal entre les deux ;suit un segment vertical descendant et la copie 4, obtenue en changeant les angles de la figure initiale, ce que l'on fait en introduisant p dans la procédure pea comme on l'a fait pour la courbe de Sierpinski, et en prenant pea(n-1,-p) pour la $1^{\grave{e}re}$ et la $4^{i\grave{e}me}$ copie :

> restart:with(plots):

> segment:=proc(a) local k: global courbe: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> pea:=proc(n,p) global courbe,a:

if n=0 then a:=a+p*Pi/2:segment(a):a:=a-p*Pi/2:segment(a):

a:=a-p*Pi/2:segment(a):a:=a+p*Pi/2

else a:=a+p*Pi/2:pea(n-1,-p): segment(a):

a:=a-p*Pi/2:pea(n-1,p): segment(a): pea(n-1,p):

a:=a-p*Pi/2: segment(a): pea(n-1,-p):a:=a+p*Pi/2:fi end:

> a:=0:courbe:=0,0:pea(4,1):

>pointplot([courbe],style=line,color=red,scaling=constrained);


chap2__59.pngfigure 2.18 : courbe de Péano 2

Courbe de Péano 3

Elle est un peu plus compliquée. La figure montre le point de départ, le motif et l'itération suivante :


chap2__60.pngfigure 2.19 : les 3 premières étapes de la courbe de Péano 3

La première étape, correspondant à n = 0, a une forme de S. La seconde étape s'obtient avec 9 copies de la première, certaines identiques, d'autres avec changement des signes, séparées de 8 segments. Cela donne finalement :

> restart:with(plots):

> segment:=proc(a) local k: global courbe: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> pea:=proc(n,p) global courbe,a: if n=0 then segment(a):

a:=a+p*Pi/2:segment(a):a:=a+p*Pi/2:segment(a):

a:=a-p*Pi/2:segment(a):a:=a-p*Pi/2:segment(a)

else pea(n-1,p):segment(a): pea(n-1,-p):segment(a): (n=0)

pea(n-1,p): a:=a+p*Pi/2:segment(a):a:=a+p*Pi/2:pea(n-1,-p):

segment(a): pea(n-1,p):segment(a):pea(n-1,-p):

a:=a-p*Pi/2:segment(a):a:=a-p*Pi/2: pea(n-1,p):

segment(a): pea(n-1,-p):segment(a):pea(n-1,p) fi end: (n>0)

> a:=0:courbe:=0,0:pea(3,1):

> pointplot([courbe],style=line,color=red,scaling=constrained);


chap2__61.pngfigure 2.20 : courbe de Péano 3


 

début chapitre

La courbe de Hilbert

Prenons pour dernier exemple de courbes remplissant un carré la courbe de Hilbert ne présentant pas un aspect labyrinthique comme les courbes de Péano 2 et 3, mais des intersections.

La figure ci-dessous présente le point de départ, le motif et l'itération suivante :


chap2__62.pngfigure 2.21 : les trois premières étapes de la courbe de Hilbert

La seconde étape s'obtient à l'aide de 4 copies de la première, mais il faut changer le signe des angles dans la première et la dernière. Il faut donc une procédure Hil(n,p), dépendant du nombre d'itérations, mais aussi de p qui permet de changer les signes.

> restart:with(plots):with(plottools):

> segment:=proc(a) local k: global courbe:

k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+cos(a),courbe[k]+sin(a) end:

> Hil:=proc(n,p) global a:

if n=0 then segment(a) else a:=a+p*Pi/2:Hil(n-1,-p):

a:=a-p*Pi/2:Hil(n-1,p):Hil(n-1,p):a:=a-p*Pi/2:Hil(n-1,-p):

a:=a+p*Pi/2 fi end:

> a:=0:courbe:=0,0:Hil(6,1):

> pointplot([courbe],scaling=constrained,style=line,color=red);


chap2__63.pngfigure 2.22 : courbe de Hilbert

A noter que, si l'on remplace -p par p dans les deux procédures où figure -p (ce qui revient à supprimer p et à mettre toutes les copies du même côté), on obtient la courbe de Lévy !

 

début chapitre

La dimension fractale

On peut quantifier une fractale plus ou moins tourmentée et faisant plus ou moins de méandres par sa dimension fractale. C'est un nombre qui, en général, n'est pas un nombre entier. S'il est inférieur à 1, on a affaire à une poussière de points ne comportant aucun segment. S'il est compris entre 1 et 2, on a une succession de fragments remplissant de plus en plus le plan lorsqu'on se rapproche de 2 ;entre 2 et 3, c'est un ensemble de surfaces emplissant plus ou moins une portion de l'espace.

Il existe plusieurs définitions de la dimension fractale ;les plus utilisées sont la dimension d'autosimilarité et la méthode des boîtes (box-counting dimension).

Pour la dimension d'autosimilarité, il faut considérer le nombre de morceaux qui composent la fractale en fonction de l'échelle choisie. Prenons l'exemple de l'ensemble de Cantor, obtenu en retirant le tiers central des segments ;à chaque itération, l'échelle de longueur est divisée par 3 alors que le nombre de segments est multiplié par 2. La dimension d'autosimilarité est le rapport des logarithmes du nombre de segments et de l'inverse de l'échelle de longueur. Ici,
MATH

Sa valeur est comprise entre 0 et 1, conformément au fait qu'il s'agit d'une poussière de points.

Pour la courbe de Koch, le nombre de segments est multiplié par 4 quand l'échelle est divisée par 3, soit
MATH

C'est plus qu'une courbe et moins qu'une surface.

Pour le triangle de Sierpinski, le nombre de triangles est multiplié par 3 quand l'échelle est divisée par 2, soit
MATH

Le triangle de Sierpinski ''remplit'' donc plus le plan que la courbe de Koch, comme on le constate visuellement.

Pour la courbe de Péano 1, on a 9 segments quand l'échelle est divisée par 3, soit
MATH

La courbe de Péano remplit entièrement le carré et passe par chacun de ses points.

La méthode des boîtes, très utilisée en particulier pour les fractales statistiques où l'on ne peut pas calculer de dimension d'autosimilarité, consiste à tracer un quadrillage et à compter le nombre de carrés du quadrillage touchés par la fractale en fonction de l'échelle de celui-ci. Ce nombre, comme toutes les propriétés quantitatives des fractales, est une loi de puissance, c'est-à-dire qu'il se met sous la forme MATHs est la dimension de l'échelle. Pour obtenir la valeur de $d=\alpha ,$ on fait un tracé $\log -\log $, en portant le logarithme du nombre en ordonnée et le logaritme de l'inverse de l'échelle en abcisse. Ce tracé est une droite dont la pente est le dimension cherchée puisque MATH

 

début chapitre

Transformations linéaires affines

Toutes les fractales ne sont pas autosimilaires. Les exemples du chapitre précédent étaient des fractales strictement autosimilaires, où l'opérateur de Hutchinson, qui reconstitue la fractale en effectuant un collage à partir de copies réduites, ne se compose que de similitudes (changement d'échelle ou homothétie, rotation, translation et reflexion). Une première généralisation autorise les transformations linéaires affines comprenant les similitudes mais aussi les cisaillements qui ne conservent pas les angles comme les similitudes. Cela permet de construire des fractales plus variées comportant des structures courbées que ne peuvent engendrer de simples similitudes.

Les transformations linéaires affines comprennent les similitudes, mais également d'autres transformations.

Une transformation linéaire s'écrit de façon générale
MATH

définie par la matrice
MATH

La transformation linéaire affine y ajoute une translation
MATH

Elle est définie par 6 nombres
MATH

La matrice de l'application linéaire peut s'écrire
MATH

Il suffit de poser MATH et MATH le signe étant donné par la valeur de $\sin (\varphi ).$

Si r = s et $\varphi =\psi ,$ on retrouve une similitude réduction-rotation, qui conserve les angles. Si $r\neq s,$ on n'a pas le même facteur d'échelle sur les deux axes, et, si MATH on a un cisaillement qui ne conserve pas les angles.

Voyons quelques exemples de fractales qui utilisent, dans l'opérateur de Hutchinson, des transformations linéaires affines.

 

début chapitre

Le rameau

L'opérateur de Hutchinson de cette fractale se compose de trois applications linéaires affines. Appliqué à un carré initial de côté unité, cela donne, à la 1$^{\grave{e}re},$ 2$^{i\grave{e}me}$ et 5$^{i\grave{e}me}$ itération :


chap2__86.pngfigure 2.23 : rameau à partir d'un carré

La première transformation, notée 1 sur la figure, correspond à la matrice
MATH

On a ici $r=s=0,58$ et MATH Il s'agit d'une homothétie-rotation de facteur d'échelle 0,58 et d'angle 47MATH suivie d'une réflexion autour de l'axe Oy et d'une translation de composantes 0,25 suivant x et 0,52 suivant y.

La seconde transformation est
MATH

On a $r=0,44,$ $s=0,33,$ $\varphi $ est voisin de 0 et $\psi $ est légèrement inférieur à $\pi $ ;le carré est donc déformé en parallélogramme, le côté parrallèle à $x$ étant un peu plus grand que le côté suivant $y$ qui est tourné d'un angle inférieur à 180MATH Ce n'est pas une similitude.

La troisième est
MATH

On a $r=0,48,$ $s=0,025,$ MATH et MATH C'est la transformation qui forme la tige, de longueur voisine de 0,5, de largeur presque nulle et retournée d'un angle supérieur à 180MATH qui n'est évidemment pas une similitude. En itérant ces transformations , on arrive au rameau.

En partant d'un point, on va multiplier par 3 le nombre de points à chaque itération et ceux-ci vont rapidement engendrer la fractale :

> restart:with(plots):

> f:=proc(x,y) 0.39*x+.43*y+0.25,0.43*x-0.39*y+0.52,

0.44*x-0.09*y+0.42,-0.01*x-0.32*y+0.50,

-0.47*x+0.02*y+0.4,-0.11*x+0.015*y+0.4 end:

> liste:=0,0:for i from 1 to 7 do:

liste:=seq(f(liste[2*i-1],liste[2*i]),i=1..nops([liste])/2):od:

> pointplot([liste],symbol=circle,color=red);


chap2__106.pngfigure 2.24 : le rameau tracé par points


 

début chapitre

La fougère de Barnsley

La fougère de Barnsley est, avec l'attracteur de Lorenz et l'ensemble de Mendelbrot une des figures symboles de la théorie des systèmes dynaniques et des fractales. Son opérateur de Hutchinson se compose de 4 transformations linéaires affines ;appliquées à un carré de côté 1, cela donne :


chap2__108.pngfigure 2.25 : 1$^{\grave{e}re}$ itération de la fougère à partir d'un carré

La transformation 1 est une homothétie-rotation de facteur de réduction 0,85 et d'angle de rotation -2,5MATH suivie d'une translation suivant Oy ;les autres ne sont pas des similitudes car le facteur de réduction n'est pas le même sur les deux axes ;la dernière forme la tige.

La tige n'ayant pas besoin d'être détaillée, on va affecter des poids différents aux transformations en introduisant un nombre entier au hasard entre 0 et 100 (c'est le rôle de a:=rand(0..100)() :). La transformation 4 se fait avec une probabilité de 2%, la 3 de 15%, la 2 de 13% et la 1 de 70% (c'est elle qui donne la structure générale de la fougère).

> restart:with(plots):

> x:=0.5:y:=0:liste:=op([]):

for i from 1 to 2000 do a:=rand(0..100)():

if a<=2 then c:=0.5:y:=0.16*y:x:=c: (tige)

elif a<=17 then c:=-0.15*x+0.283*y+0.575:

y:=0.26*x+0.237*y-0.084:x:=c: (transformation 3)

elif a<=30 then c:=0.197*x-0.226*y+0.40:

y:=0.226*x+0.197*y+0.049:x:=c: (transformation 2)

else c:=0.849*x+0.037*y+0.075: (transformation 1)

y:=-0.037*x+0.849*y+0.183:x:=c:fi:liste:=liste,x,y:od:

> pointplot([liste],color=black,scaling=constrained);


chap2__110.pngfigure 2.26 : la fougère de Barnsley


 

début chapitre

Du triangle à l'arbre de Noël

En changeant progressivement les coefficients des transformations, on peut passer progressivement d'une fractale à une autre. Prenons l'exemple du passage du triangle de Sierpinski à ''l'arbre de Noël de Sierpinski''.

Lorsque i passe de 0 à 5, le triangle de Sierpinski se déforme pour arriver au sapin de Noël.

>restart:with(plots):with(plottools):

> f:=proc(x,y,i) (0.5-0.1*i)*x-0.1*i*y+0.1*i,

0.1*i*x+(0.5-0.1*i)*y,(0.5-0.1*i)*x+0.1*i*y+0.5,

-0.1*i*x+(0.5-0.1*i)*y+0.1*i,0.5*x+0.05*i,0.5*y+0.5 end:

> liste:=0,0:for j to 6 do:

liste:=seq(f(liste[2*j-1],liste[2*j],0),j=1..nops([liste])/2) od:

(faire i=0 pour p0, puis i=1 pour p1 et ceci jusqu'à 5)

> p0:=pointplot([liste],color=red,scaling=constrained):

> p1:=pointplot([liste],color=red,scaling=constrained):

> p2:=pointplot([liste],color=red,scaling=constrained):

> p3:=pointplot([liste],color=red,scaling=constrained):

> p4:=pointplot([liste],color=red,scaling=constrained):

> p5:=pointplot([liste],color=red,scaling=constrained):

> display(p0,translate(p1,1,0),translate(p2,2,0),

translate(p3,0,-1.5),translate(p4,1,-1.5),translate(p5,2,-1.5));


chap2__111.pngfigure 2.27 : du triangle à l'arbre de Noël de Sierpinski


 

début chapitre

Exercices

Exercice 1

La courbe 3/2

Sur le modèle de la courbe de Koch par récursivité, tracer la courbe autosimilaire appellée courbe 3/2.

Partant d'un segment de longueur 1, on passe à la figure ci-dessous composée de 8 segments.


chap2__113.pngfigure 2.28 : première itération de la courbe $3/2$

Programmer la courbe 3/2 puis tracer l'île carrée 3/2 en s'appuyant sur un carré

Calculer la dimension d'autosimilarité et montrer qu'elle est égale à 3/2.

Exercice 2

Le point de croix fractal

On se propose de tracer la fractale de motif


chap2__114.pngfigure 2.29 : motif du point de croix

comprenant 4 segments dont 2 sont confondus, les segments 2 et 3 ayant une longueur égale aux 2/3 de la longueur des segments 1 et 2.

Cette fractale se trace sur le modèle de l'île des fjords. Tracer le carré fractal.

Exercice 3

Cristal de glace

On considère la fractale de motif


chap2__115.pngfigure 2.30 : motif du cristal de glace

Elle est constituée de 6 segments, les angles étant de $\pi /3$ et les longueurs des segments 3, 4, 5 et 6 étant moitié des longueurs des segments 1 et 6. On prend pour modèle l'île de fjords, mais on mettra les 3 copies sur un triangle équilatéral.

Réponses aux exercices

exercice 1

Reprendre la programmation de la courbe de Koch par récursivité. Il suffit de modifier la procédure :

> a:=0:pro:=proc(n) global a:

if n=0 then segment(a) else

pro(n-1):a:=a+Pi/2:pro(n-1):a:=a-Pi/2:pro(n-1):

a:=a-Pi/2:pro(n-1):pro(n-1):a:=a+Pi/2:pro(n-1):

a:=a+Pi/2:pro(n-1):a:=a-Pi/2:pro(n-1):

fi end:

Pour le carré, ajouter :

> p:=pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none):

> :p1:=rotate(p,Pi/2):p2:=translate(p,0,4^n):

p3:=translate(rotate(p,Pi/2),4^n,0):

> display(p,p1,p2,p3);


chap2__117.pngfigure 2.31 : l'île 3/2

Le nombre de morceaux est multiplié par 8 quand l'échelle est divisée par 4 ;la dimension d'autosimilarité est MATH

 

Exercice 2

> restart:with(plots):with(plottools):

> segment:=proc(l,a) local k: global courbe: k:=nops([courbe]):

courbe:=courbe,courbe[k-1]+l*cos(a),courbe[k]+l*sin(a) end:

> l:=1:a:=0:croix:=proc(n,l) global a:

if n=0 then segment(l,a) else croix(n-1,l):

a:=a+evalf(Pi/2): croix(n-1,2*l/3):a:=a-2*evalf(Pi/2):

croix(n-1,2*l/3):a:=a+evalf(Pi/2): croix(n-1,l): fi end:

> courbe:=0,0:n:=6:croix(n,1):

> p:=pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none):

> p1:=reflect(p,[[0,0],[1,0]]):p2:=rotate(p1,Pi/2):

p3:=translate(p1,0,2^n):p4:=translate(rotate(p,Pi/2),2^n,0):

> display(p,p2,p3,p4);


chap2__119.pngfigure 2.32 : point de croix fractal

Exercice 3

> restart:with(plots):with(plottools):

> segment:=proc(l,a) local k: global courbe:

k:=nops([courbe]): courbe:=courbe,courbe[k-1]+l*cos(a),

courbe[k]+l*sin(a) end:

> l:=1:a:=0:cris:=proc(n,l) global a:

if n=0 then segment(l,a) else

cris(n-1,l):a:=a+evalf(2*Pi/3): cris(n-1,l/2):a:=a+evalf(Pi):

cris(n-1,l/2):a:=a+evalf(2*Pi/3): cris(n-1,l/2):

a:=a+evalf(Pi):cris(n-1,l/2): a:=a+evalf(2*Pi/3):cris(n-1,l) fi end:

> courbe:=0,0:n=4:cris(n,1):

> p:=pointplot([courbe],scaling=constrained,style=line,

color=red,axes=none):

> p1:=reflect(p,[[0,0],[1,0]]):p2:=rotate(p1,Pi/3):

p3:=translate(rotate(p1,-Pi/3),2^(n-1),2^n)*sin(Pi/3)):

> display(p,p2,p3);


chap2__120.pngfigure 2.33 : cristal de glace triangulaire

début chapitre

retour index