Previous Up Next

Chapitre 7  La recursivité sur des exemples

7.1  Des spirales

7.1.1  Une spirale

Voici le début du dessin d’une spirale(90) :

On tape dans un éditeur de programmes :

spirale(l):={
si (l>10) alors 
avance(l);
tourne_gauche 90;
avance(l);
tourne_gauche 90;
spirale(l-10);
fsi;
}

On tape dans une ligne de commande :
efface;spirale(100)
On obtient :

7.1.2  Une spirale plus générale

On tape dans un éditeur de programmes :

//chaque segment de la spirale est obtenu par similitude de rapport k 
//k=rapport et t=angle de rotation (externe)
//n=nombre de segments a construire
spirales(l,k,t,n):={
pour j de 1 jusque n faire
avance(l);
tourne_gauche(t);
l:=k*l;
fpour;
};

ou encore avec la recursivité

//n=nombre de segments a construire=nombre d'appels recursifs
spiraler(l,k,t,n):={
si n>0 alors
 avance(l);
 tourne_gauche(t);
 spiraler(l*k,k,t,n-1);
fsi;
}:;

On tape par exemple dans une ligne de commande :
spirales(90,0.8,60,20)
ou
efface;spiraler(90,0.8,60,20)
On obtient :

7.2  Des arbres

7.2.1  Un arbre a deux branches

Un arbre est composé d’un tronc de hauteur h et de deux branches symétriques faisant 45 degrés avec le tronc et que l’on définit comme étant chacune un arbre de tronc h/2.
Pour le réaliser, on tape dans un éditeur de programmes :

//tourne_gauche;arbre1(60)
arbre1(h):={
si (h<5) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(45);
arbre1(h/2);
tourne_gauche(90);
arbre1(h/2):
tourne_droite(45);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre1(60)
On obtient :

Ou bien, on rajoute un paramètre n (la profondeur) pour faire le test d’arrêt, on tape on tape dans un éditeur de programmes :

//tourne_gauche;arbre2(60,3)
arbre2(h,n):={
si (n==0) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(45);
arbre2(h/2,n-1);
tourne_gauche(90);
arbre2(h/2,n-1):
tourne_droite(45);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre2(60,5)
On obtient :

7.2.2  Un arbre a p branches

Un arbre est composé d’un tronc de hauteur h et de p branches également réparties et que l’on définit comme étant chacune un arbre de tronc h/2.
On tape dans un éditeur de programmes :

//tourne_gauche;arbre3(80,4)
arbre3(h,p):={
si (h<5) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(90*(p-1)/p);
repete(p,arbre3(h/2,p),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre3(80,4)
On obtient :

Ou bien, on rajoute un paramètre n (la profondeur) pour faire le test d’arrêt, on tape dans un éditeur de programmes :

//tourne_gauche;arbre4(60,5,3)
arbre4(h,p,n):={
si (n==0) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(90*(p-1)/p);
repete(p,arbre4(h/2,p,n-1),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre4(80,5,4)
On obtient :

Et maintenant, un arbre aléatoire :
à chaque nœud on choisit, de façon aléatoire le rapport k de réduction, qui fera les p branches comme un arbre réduit avec le coefficient k.
On tape dans un éditeur de programmes :

//tourne_gauche ;saute(-80);arbre5(60,4,3);
arbre5(h,p,n):={
local k;
si (n==0) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(90*(p-1)/p);
k:=hasard(0,1);
repete(p,arbre5(h*k,p,n-1),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre5(60,5,4)
On obtient :

Et enfin, un arbre encore plus aléatoire :
pour chaque branche on choisit, de façon aléatoire le rapport hasard(0,1) de réduction, qui fera cette branche comme un arbre réduit avec ce coefficient.
On tape dans un éditeur de programmes :

//tourne_gauche ;saute(-80);arbre6(60,4,3);
arbre6(h,p,n):={
si (n==0) alors
avance(h);
recule(h);
sinon
avance(h);
tourne_droite(90*(p-1)/p);
repete(p,arbre6(h*hasard(0,1),p,n-1),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
recule(h);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre6(60,5,4)
On obtient :

7.2.3  Un arbre ramifié

Ici on suppose que, du tronc de longueur h, il part p branches de longueur h/2. Ces branches donnent naissance à p−1 branches de longueur h/4 etc... jusqu’à p=2. On tape dans un éditeur de programmes :

//tourne_gauche;saute(-80);arbre7(60,5)
arbre7(h,p):={
avance(h);
si (p>=2) alors
tourne_droite(90*(p-1)/p);
repete(p,arbre7(h/2,p-1),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
fsi;
recule(h);
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre7(80,5)
On obtient :

En utilisant aussi la profondeur dans le test d’arrêt on tape dans un éditeur de programmes :

//tourne_gauche;saute(-80);arbre8(90,5,3)
arbre8(h,p,n):={
avance(h);
si (p>=2 et n>=1) alors
tourne_droite(90*(p-1)/p);
repete(p,arbre8(h/2,p-1,n-1),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
fsi;
recule(h);
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;arbre8(80,6,5)
On obtient :

Exercice Refaire les exemples précédents mais en ne dessinant que la frondaison de l’arbre, c’est à dire l’arbre sans son tronc.
Une réponse Voici la réponse correspondant à arbre7 et à arbre8. Bien sûr, pour avoir la frondaison de arbre7(60,5) il faut taper arbre9(30,5) et pour avoir la frondaison de arbre8(60,5,3) il faut taper arbre10(30,5,3).

//tourne_gauche;saute(-80);arbre9(90,5,3)
arbre9(h,p):={
si (p>=2) alors
tourne_droite(90*(p-1)/p);
repete(p,avance(h),arbre9(h/2,p-1),recule(h),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
fsi;
}
//tourne_gauche;saute(-80);arbre10(90,5,3)
arbre10(h,p,n):={
si (n>=1 et p>=2) alors
tourne_droite(90*(p-1)/p);
repete(p,avance(h),arbre10(h/2,p-1,n-1),recule(h),tourne_gauche(180/p));
tourne_droite(90*(p+1)/p);
fsi;
}

7.2.4  Un sapin

Pour décrire un sapin, il faut choisir un paramètre par exemple sa hauteur h du sapin.
On dit alors qu’un sapin de hauteur h est composé de :

Cette définition sera récursive si on dit que les deux branches basses latérales sont des sapins plus petits (de hauteur égale à la moitié de la hauteur du sapin) et que la tête est aussi un sapin plus petit (de hauteur égale au trois-quart de la hauteur du sapin). Le tronc a donc pour hauteur le quart de la hauteur du sapin. Il nous faut alors définir ce que l’on considére comme sapin "initial" : c’est le sapin formé d’un tronc unique.
Voici la croissance de ces sapins :

On tape dans un éditeur de programme :

//tourne_gauche;sapin1(90)
sapin1(h):={
si (h<5) alors
avance(h);
recule(h);
sinon
tourne_droite(60);
sapin1(h/2);
tourne_gauche(120);
sapin1(h/2):
tourne_droite(60);
avance(h/4);
sapin1(3*h/4);
recule(h/4);
fsi;
}:;

Ou on tape en utilisant pour faire le test d’arrêt la profondeur n :

//tourne_gauche;sapin2(90,4)
sapin2(h,n):={
si (n==0) alors
avance(h);
recule(h);
sinon
tourne_droite(60);
sapin2(h/2,n-1);
tourne_gauche(120);
sapin2(h/2,n-1):
tourne_droite(60);
avance(h/4);
sapin2(3*h/4,n-1);
recule(h/4);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche;sapin2(100,7)
On obtient :

Les différentes étapes ont été obtenus en exécutant :
tourne_gauche; sapin2(90,0) puis
tourne_gauche; sapin2(90,1) puis
tourne_gauche; sapin2(90,2) puis
tourne_gauche; sapin2(90,3).

7.3  Les flocons de Koch

Voici les étapes de construction d’une courbe découverte par Koch :


On voit l’étape 0 : un segment de longueur l.
Pour obtenir l’étape 1, on divise ce segment de longueur l en trois et on réalise la deuxième figure qui est composée de quatre segments de longueur l/3 (le deuxiéme et troisiéme segments sont les côtés d’un triangle équilatéral), puis on recommence en transformant chacun de ces 4 segments en 4 segments....
et cela tant que l ≥ 10. On tape dans un éditeur de programme :

//koch1(90)
koch1(l):={
si (l<10) alors
avance(l);
sinon
koch1(l/3);tourne_gauche(60);
koch1(l/3);tourne_droite(120);
koch1(l/3);tourne_gauche(60);
koch1(l/3);
fsi;
}:;

Ou on tape en utilisant un paramètre n représentant la profondeur (i.e. le nombre d’appels récursifs) :

//koch2(90,3)
koch2(l,n):={
si (n==0) alors
avance(l);
sinon
koch2(l/3,n-1);tourne_gauche(60);
koch2(l/3,n-1);tourne_droite(120);
koch2(l/3,n-1);tourne_gauche(60);
koch2(l/3,n-1);
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;koch2(270,7)
On obtient :

Les dessins des différentes étapes ont été obtenus en tapant :
koch2(90,0) puis,
koch2(90,1) puis,
koch2(90,2)

7.4  Les courbes de Péano

Parmi les nombreuses courbes inventées par Péano, prouvant l’existence de courbes remplissant un carré, on n’en retiendra que trois, celles décrites dans les paragraphes suivants.

7.4.1  La courbe C0 de Péano

Soit un carré de diagonale l :
au jour 0, on trace une diagonale,
au jour 1, on divise ce carré en 9 carrés et on trace les diagonales de ces carrés, de façon à avoir un trait continu en parcourant la première ligne, puis la deuxième, et enfin la troisième, comme ci-dessous :

puis on recommence le même processus.
On tape dans un éditeur de programme :

//peano(90)
peano(l):={
  si (l<10) alors avance(l);
  sinon
  peano(l/3);
  tourne_droite;peano(l/3);
  tourne_gauche;peano(l/3);
  tourne_gauche;peano(l/3);
  tourne_gauche;peano(l/3);
  tourne_droite;peano(l/3);
  tourne_droite;peano(l/3);
  tourne_droite;peano(l/3);
  tourne_gauche;peano(l/3);
  fsi
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;tourne_gauche 45;peano(200)
On obtient :

7.4.2  La courbe de Péano binaire

Soit un carré de coté l :
au jour 0, on trace un segment de longueur l i.e. un coté du carré,
au jour 1, on remplace ce segment, en traçant 4 segments de longueur l/2 qui sont disposés selon les trois cotés d’un rectangle situé à gauche de la position de la tortue, de largeur l/2 et de longueur l,
au jour 2, on remplace chaque segment de longueur k par 4 segments de longueur k/2 en tracant les trois coés d’un rectangle de largeur k/2 et de longueur k et situé soit à droite soit à gauche de la position de la tortue comme cela :

puis on recommence le même processus.
On remarque que l’on remplace un segment en tracant un rectangle situé soit à droite soit à gauche de la position de la tortue : on introduit donc un paramètre s qui vaut 1 si ce rectangle se situe à droite et qui vaut -1 si ce rectangle se situe à gauche.
On tape :

//peanob(90,1)
peanob(l,s):={
  si (l<10) alors avance(l);
  sinon
  tourne_gauche(-90*s);peanob(l/2,-s);
  tourne_droite(-90*s);peanob(l/2,s);
  peanob(l/2,s);tourne_droite(-90*s);
  peanob(l/2,-s);tourne_gauche(-90*s);
  fsi
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :
efface;peanob(200,-1)
On obtient :

7.4.3  La courbe de Péano ternaire

Au jour 1, on trace la première courbe peano1(l,0) dans le carré de coté l,
Au jour 2, on trace la deuxème courbe dans le carré de coté l obtenue en partageant le carré en 9 carrés et en traçant dans le premier carré peano1(l,0), et dans les autres soit peano1(l,1), soit peano1(l,-1), de façon à ce que les courbes se raccordent entre elles.
Voici les dessins, où la position de départ et d’arrivée de la tortue est choisie comme indiquée sur la première figure :

 peano1(60,0) peano1(60,1) peano1(60,-1) On décide alors de prendre comme départ de la tortue le sommet inférieur gauche du carré. On définit car(l) qui dessine un carré de côté l, on tape :

//carre de cote l
car(l):={
repete(4,avance(l),tourne_gauche 90);
}:;
//peano1(30,0) ou peano1(30,1) ou peano1(30,-1)
peano1(l,s):={
si (s==-1) alors 
  tourne_droite(45);saute(-l*sqrt(2)/6);rond(round(l*sqrt(2)/6.),90);
sinon 
  si (s==1) alors
   tourne_gauche(135);saute(-l*sqrt(2)/6);rond(round(-l*sqrt(2)/6.),90);
  sinon
   tourne_gauche(45);
   saute(l*sqrt(2)/6);
  fsi;
fsi;
rond(round(l*sqrt(2)/6.),90);
rond(round(-l*sqrt(2)/6.),270);
rond(round(l*sqrt(2)/6.),270);
rond(round(-l*sqrt(2)/6.),90);
saute(l*sqrt(2)/6);
tourne_droite(45);
}:;
//peanot(90,0)
peanot(l,s):={
  si (l<31) alors 
    peano1(l,s);
  sinon
    peanot(l/3,s);
    tourne_droite;peanot(l/3,1);
    tourne_gauche;peanot(l/3,-1);
    tourne_gauche;peanot(l/3,-1);
    tourne_gauche;peanot(l/3,-1);
    tourne_droite;peanot(l/3,1);
    tourne_droite;peanot(l/3,1);
    tourne_droite;peanot(l/3,1);
    tourne_gauche;peanot(l/3,-1);
  fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :

dessine_tortue;
crayon jaune;
car(90);
crayon noir;
peanot(90,0);

On obtient :

Mais, on voit qu’à cause des erreurs d’arrondis, la courbe n’est pas centrée dans le carré. En particuler, peanot(120,0), peanot(110,0),peanot(100,0) donne le même dessin !!!

On décide alors de prendre comme départ de la tortue le centre du carré.

carc(l):={
pas_de_cote -l/2;
repete(4,avance l/2,tourne_gauche ,avance l/2);
pas_de_cote l/2;
}:;
pean1(l,s):={
tourne_gauche 45;
rond(round(l*sqrt(2)/6.),270);
rond(round(-l*sqrt(2)/6.),90);
si (s==-1) alors 
  rond(round(-l*sqrt(2)/6.),90);
  tourne_droite 180;
  rond(round(l*sqrt(2)/6.),90);
sinon 
  si (s==1) alors
   rond(round(l*sqrt(2)/6.),90); 
   tourne_droite 180;
   rond(round(-l*sqrt(2)/6.),90);
   sinon tourne_droite 180;
  fsi;
fsi;
rond(round(l*sqrt(2)/6.),90);
rond(round(-l*sqrt(2)/6.),270);
tourne_droite 225;
}:;
pean2(l,s):={
tourne_droite 135;
rond(round(l*sqrt(2)/6.),270);
rond(round(-l*sqrt(2)/6.),90);
tourne_droite 180;
rond(round(l*sqrt(2)/6.),90);
rond(round(-l*sqrt(2)/6.),270);
tourne_gauche -45;
}:;
pean(l,s):={
pean2(l,s);
pean1(l,s)
}:;
peant(l,s):={
  si (l<31) alors 
    pean(l,s);
  sinon
  pas_de_cote -l/3;
  saute -l/3;
  peant(l/3,s);
  saute l/3;tourne_droite;peant(l/3,1);
  pas_de_cote l/3;tourne_gauche;peant(l/3,-1);
  pas_de_cote l/3;tourne_gauche;peant(l/3,-1);
  pas_de_cote l/3;tourne_gauche;peant(l/3,-1);
  saute l/3;tourne_droite;peant(l/3,1);
  saute l/3;tourne_droite;peant(l/3,1);
  saute l/3;tourne_droite;peant(l/3,1);
  pas_de_cote l/3;tourne_gauche;peant(l/3,-1);
  pas_de_cote -l/3;saute -l/3;
fsi;
}:;

On valide avec OK ou avec F9.
On tape par exemple dans une ligne de commande :

dessine_tortue;
peant(180,0);
crayon jaune;
carc(180);

On obtient :

Mais ce n’est pas encore parfait, la courbe est bien centrée dans le carré mais les raccords entres les différents morceaux ne se fait pas bien : c’est toujours à cause des erreus d’arrondis !

On peut aussi supprimer les saute, les tourne et les √2, c’est à dire en prenant comme départ et d’arrivée de la tortue les tangentes aux arcs et comme paramètre l la diagonale du carré et en rajoutant le paramètre n pour la profondeur.
On tape :

//fait le dessin de la tortue
des_tor():={
cache_tortue;
tourne_gauche;
avance 5;
tourne_droite(180-180/pi*atan(3.4));
avance(sqrt(25+17^2));
tourne_droite(180-2*180/pi*atan(1/3.4));
avance(sqrt(25+17^2));
tourne_droite(180-180/pi*atan(3.4));
avance 5;tourne_droite;
montre_tortue;
}:;
//carre de cote l
card(d):={
repete(4,avance(d/sqrt(2)),tourne_gauche 90);
}:;
//peano2(30,0) ou peano2(30,-1) ou peano2(30,1)
peano2(l,s):={
  si (s==-1) alors 
   rond(round(l/6),90);
  sinon 
    si (s==1) alors
    rond(round(-l/6),90);
    fsi;
  fsi;
  rond(round(l/6),90);
  rond(round(-l/6),270);
  rond(round(l/6),270);
  rond(round(-l/6),90);
}:;

//tourne_gauche 45;peanot2(90,0,2)
peanot2(l,s,n):={
  si (n==1) alors 
    peano2(l,s);
  sinon
    peanot2(l/3,s,n-1);
    peanot2(l/3,1,n-1);
    peanot2(l/3,-1,n-1);
    peanot2(l/3,-1,n-1);
    peanot2(l/3,-1,n-1);
    peanot2(l/3,1,n-1);
    peanot2(l/3,1,n-1);
    peanot2(l/3,1,n-1);
    peanot2(l/3,-1,n-1);
 fsi;
}:;

On remarquera que peanot2 commence à un sommet du carré et se termine en un point proche du sommet opposé : le point d’arrivée est ici fonction de la valeur du paramètre n et est a une distance de l/3n/2 du sommet opposé au carré.
Puis on tape par exemple :

efface ;
tourne_gauche 45;
crayon jaune;
dessine_tortue;
crayon noir;
peanot2(180,0,2);
des_tor();
saute 180/3^2/2;
tourne_droite 135;
crayon jaune;
card(180);
cache_tortue;

On obtient :

Puis on tape par exemple :

efface ;
tourne_gauche 45;
crayon jaune;
dessine_tortue;
crayon noir;
peanot2(162,0,4);
des_tor();
saute 162/3^4/2;
tourne_droite 135;
crayon jaune;
card(162);
cache_tortue;

On obtient :

Si on définit :

//peanot1(90,0,2)
peanot1(l,s,n):={
tourne_gauche 45;
saute(l/2/3^n);
peanot2(l,s,n);
saute(l/2/3^n);
tourne_droite 45;
}:;

On a :
peanot1(l/sqrt(2),s,n) ressemble à peanot(l,s)....mais ce n’est pas parfait à cause des erreurs d’arrondis.

7.5  La courbe de Hilbert

C’est une courbe remplissant un carré qui a été découverte par Hilbert : cette courbe se fait a partir de quatre procédures récursives qui s’appellent les unes les autres et que j’ai appelé hilbg, hilbd, bertg, bertd.
Voici les étapes de construction : - au jour 0 on trace un segment,
- au jour 1 on trace les dessins où on a dessiné les positions de départ et d’arrivée de la tortue (la forme pleine représente la tortue au départ et la forme vide celle d’arrivée).

hilbg    hilbd    bertg    bertd
hilbg est composée de 4 segments qui sont le dessin obtenu au jour 0 par hilbd hilbg bertg bertd
hilbd est composée de 4 segments qui sont le dessin obtenu au jour 0 par hilbg hilbd bertd bertg
bertg est composée de 4 segments qui sont le dessin obtenu au jour 0 par hilbd hilbg bertg hilbd
bertd est composée de 4 segments qui sont le dessin obtenu au jour 0 par hilbg hilbd bertd hilbg
On écrit :

//hilbg(200)
hilbg(l):={
si (l<=10) alors
avance(l);
sinon
tourne_gauche(90);hilbd(l/2);
tourne_droite(90);hilbg(l/2);
tourne_droite(90);bertg(l/2);
tourne_gauche(90);bertd(l/2);
fsi;
}:;
hilbd(l):={
si (l<=10) alors
avance(l);
sinon
tourne_droite(90);;hilbg(l/2);
tourne_gauche(90);;hilbd(l/2);
tourne_gauche(90);bertd(l/2);
tourne_droite(90);bertg(l/2);
fsi;
}:;
bertg(l):={
si (l<=10) alors
avance(l);
sinon
tourne_droite(180);hilbd(l/2);
tourne_droite(90);hilbg(l/2);
tourne_droite(90);bertg(l/2);
hilbd(l/2);
fsi;
}:;
bertd(l):={
si (l<=10) alors
avance(l);
sinon
tourne_droite(180);hilbg(l/2);
tourne_gauche(90);hilbd(l/2);
tourne_gauche(90);bertd(l/2);
hilbg(l/2);
fsi;
}:;

On tape par exemple :

efface ;
crayon jaune;
dessine_tortue;
crayon noir;
hilbg(200);

On obtient :

7.6  Le dragon

0/ Prener une longue bande de papier AB de longueur l : c’est le dragon au jour 0.
1/ Plier cette bande de papier en deux, en amenant B en coincidence avec A par une rotation d’angle +2 et de centre C, milieu de AB : en dépliant à angle droit, on a le dragon au jour 1.
2/ Replier comme précédemment, puis plier à nouveau en deux, en amenant C en coincidence avec A par une rotation d’angle +2 : en dépliant à angle droit chaque pliure, on a le dragon au jour 2.
3/ Recommencer tant que la longueur à plier n’est pas trop petite (pour la tortue on s’arrête de plier si l<10).
Voici les 5 premières étapes :

On remarque que le segment AC et le segment CB donne naissance à deux dragons symétriques : on appelle dragong le dragon obtenu par des pliages fait avec une rotation d’angle +2 et dragond le dragon obtenu par des pliages fait avec une rotation d’angle −2.
On tape :

//dragong(1800)
dragong(l):={
si (l<10) alors
avance(l);
sinon
dragong(l/2);
tourne_gauche(90);
dragond(l/2);
fsi;
}:;
dragond(l):={
si (l<10) alors
avance(l);
sinon
dragong(l/2);
tourne_droite(90);
dragond(l/2);
fsi;
}:;

Ou encore en utilisant une seule procédure dragon2 mais avec un paramètre supplémentaire s (si s=1 on a un dragon gauche et si s=-1 on a un dragon droit).
On tape :

//dragon2(1800,1)
dragon2(l,s):={
si (l<10) alors
avance(l);
sinon
dragon2(l/2,1);
tourne_gauche(90*s);
dragon2(l/2,-1);
fsi;
}

On tape par exemple :

efface;
rayon jaune;
dessine_tortue;
crayon noir;
dragon2(2880,1)}


Ou encore on écrit dragon3 en utilisant le paramètre n profondeur pour faire le test d’arrêt :

//dragon3(1800,1,3)
dragon3(l,s,n):={
si (n==0) alors
avance(l);
sinon
dragon3(l/2,1,n-1);
tourne_gauche(90*s);
dragon3(l/2,-1,n-1);
fsi;
}:;

Les dessins des 5 premières étapes ont été réalisés en exécutant :

efface ;
crayon jaune;
dessine_tortue;
crayon noir;
dragon3(60,1,0);
des_tor();
saute 20;
crayon jaune;
dessine_tortue;
crayon noir;
dragon3(60,1,1);
des_tor();
pas_de_cote -20;
saute -30;
tourne_droite ;
crayon jaune;
dessine_tortue;
crayon noir;
dragon3(60,1,2);
des_tor();
pas_de_cote -40;
saute -30;
tourne_droite ;
crayon jaune;
dessine_tortue;
crayon noir;
dragon3(60,1,3);des_tor();
pas_de_cote -60;
saute -15;
tourne_droite ;
crayon jaune;
dessine_tortue;
crayon noir;
dragon3(60,1,4);

7.6.1  La courbe de Gosper

Voici gosperg(40,1); et gosperd(40,1); qui forment la courbe de Gosper et l’étape 2 (gosperg(40,2)) :
On remarque que les 7 segments de la première courbe donne naissance soit à la première courbe, soit à la courbe obtenue en faisant le trajet en sens inverse. On va donc définir deux procédures :
gosperg et gosperd qui réalisent les dessins suivants (avec comme position de départ de la tortue, le triangle plein et comme position d’arrivée, le triangle vide) :

On déduit l’écriture de gosperd de celle de gosperg en mettant les instructions de gosperg de la dernière à la première en changeant gauche en droite et réciproqement.

//gosperg(80,3)
gosperg(l,n):={
  si (n==0) alors avance(l);
sinon
  gosperg(l/2,n-1);
  tourne_gauche(60);
  gosperd(l/2,n-1);
  tourne_gauche(120);
  gosperd(l/2,n-1);
  tourne_droite(60);
  gosperg(l/2,n-1);
  tourne_droite(120);
  gosperg(l/2,n-1);
  gosperg(l/2,n-1);
  tourne_droite(60);
  gosperd(l/2,n-1);
  tourne_gauche(60);
fsi;
};
gosperd(l,n):={
  si (n==0) alors avance(l);
sinon
  tourne_droite(60);
  gosperg(l/2,n-1);
  tourne_gauche(60);
  gosperd(l/2,n-1);
  gosperd(l/2,n-1);
  tourne_gauche(120);
  gosperd(l/2,n-1);
  tourne_gauche(60);
  gosperg(l/2,n-1);
  tourne_droite(120);
  gosperg(l/2,n-1);
  tourne_droite(60);
  gosperd(l/2,n-1);
fsi;
};

On tape : gosperg(80,3)
On obtient :
la courbe de gosper à la troisième génération

Autre écriture on choisit les flèches départ et d’arrivée comme ci-dessous mais alors la tortue a changé de direction il faut donc aussi la faire changer de la même direction dans le test d’arrêt. L’écriture de gosperd se fait encore à partir de celle de gosperg, en mettant les instructions de gosperg de la dernière à la première en changeant gauche en droite et réciproqement, et cela même dans le test d’arrêt!!!

//gosperg2(80,3)
gosperg2(l,n):={
 si (n==0) alors 
   avance(l);tourne_droite(60);
 sinon
  gosperg2(l/2,n-1);
  tourne_gauche(60);
  gosperd2(l/2,n-1);
  tourne_gauche(60);
  gosperd2(l/2,n-1);
  tourne_droite(60);
  gosperg2(l/2,n-1);
  tourne_droite(60);
  gosperg2(l/2,n-1);
  tourne_gauche(60);
  gosperg2(l/2,n-1);
  tourne_droite(60);
  gosperd2(l/2,n-1);
 fsi;
}:;
gosperd2(l,n):={
 si (n==0) alors 
  tourne_gauche(60);avance(l);
 sinon
  gosperg2(l/2,n-1);
  tourne_gauche(60);
  gosperd2(l/2,n-1);
  tourne_droite(60);
  gosperd2(l/2,n-1);
  tourne_gauche(60);
  gosperd2(l/2,n-1);
  tourne_gauche(60);
  gosperg2(l/2,n-1);
  tourne_droite(60);
  gosperg2(l/2,n-1);
  tourne_droite(60);
  gosperd2(l/2,n-1);
 fsi;
}:;

On tape :
gosperg2(80,3)
On obtient :
la courbe de gosper à la troisième génération


Previous Up Next