next up previous contents index
suivant: Deux courbes de Péano monter: Quelques dessins doublement récursifs précédent: Les sphinx   Table des matières   Index

Le dragon

Ces programmes se trouvent dans examples/recur/dragon.cxx.
On se donne deux points A et B (ou deux nombres complexes a et b qui sont l'affixe de ces points) et on considère le carré ACBD direct ayant pour diagonale AB.
Le segment AB peut donner naissance à un dragon gauche, pour cela, on remplace le segment AB par les deux côtés AD et DB du carré ACBD situé à gauche du vecteur AB ou,
le segment AB peut donner naissance à un dragon droit, pour cela, on remplace le segment AB par les deux côtés AC et CB du carré ACBD situé à droite du vecteur AB. Pour la fabrication du dragon gauche, ces deux segments sont considérés comme allant donner naissance à un dragon gauche (AD) et à un dragon droit (DB) et
pour la fabrication du dragon droit, ces deux segments sont considérés comme allant donner naissance à un dragon gauche (AC) et à un dragon droit (CB).
On a :
b - c = i*(a - c) et b - d = - i*(a - d ) donc :
c = (b - i*a)*(1 + i)/2 et d = (b + i*a)*(1 - i)/2.
On écrit donc en prenant comme test d'arrêt la profondeur n c'est à dire le nombre de générations.
// dessine un dragon dragong(-i,2+i,10)
//x=a,y=b et d=u
 dragong(x,y,n):={
local u;
DispG();
if (n==0){segment(x,y);return 0;}
u:=(y+i*x)*(1-i)/2;
dragong(x,u,n-1);
dragond(u,y,n-1);
};
// dessine un dragon dragond(-i,2+i,10)
//x=a,y=b et c=u
dragond(x,y,n):={
local u;
DispG();
if (n==0){segment(x,y);return 0;}
u:=(y-i*x)*(1+i)/2;
dragong(x,u,n-1);
dragond(u,y,n-1);
};
Remarque
Il est facile d'obtenir la courbe du dragon en prenant une longue bande de papier que l'on plie n fois sur elle même, toujours dans le même sens. Lorsqu'on a pris soin de bien marquer les plis, on obtient un dragon lorsqu'on déplie la bande en disposant les plis à angle droit.
Ce n'est pas tout à fait ce que l'on a programmer car dans le programme à chaque étape on multiplie la longueur du dragon par $ \sqrt{2}$.
Sauriez vous programmer le dragon de la bande de papier ? Voici la solution : on remarquera que le dragon droit est réalisé par la deuxième moitié de la bande de papier et donc la fonction dragonpapierd est la fonction dragonpapierg en changeant gauche en droite, et en commençant par la dernière instruction.
dragonpapierg(x,y,n):={
local u,v,a,b;
DispG();
if (n==0){segment(x,y); return y;}
u:=x+(y-x)/2;
a:=dragonpapierg(x,u,n-1);
v:=a+(y-x)*i/2;
b:=dragonpapierd(a,v,n-1);
return b
};

dragonpapierd(x,y,n):={
local u,v,a,b;
DispG();
if (n==0){segment(x,y); return y;}
v:=x+(y-x)*i/2;
b:=dragonpapierg(x,v,n-1);
u:=a+(y-x)/2;
a:=dragonpapierd(b,u,n-1);
return a
};
On tape :
dragonpapierg(-3.0,13,8)

Voici une autre solution où on repère l'arrivée et la direction du dernier trait. Dans ce cas on connait le départ et la direction de départ du dragon droit....mais c'est nettement plus compliqué.

dragonpaperg(x,y,n):={
local u,v,a,b;
DispG();
if (n==0){segment(x,y); return (x,y);}
u:=x+(y-x)/2;
a:=dragonpaperg(x,u,n-1);
v:=a[1]+abs((y-x)/(a[1]-a[0]))*(a[1]-a[0])*i/2;
b:=dragonpaperd(a[1],v,n-1);
return b
};

dragonpaperd(x,y,n):={
local u,v,a,b;
DispG();
if (n==0){segment(x,y); return (x,y);}
u:=x+(y-x)/2;
a:=dragonpaperg(x,u,n-1);
v:=a[1]-abs((y-x)/(a[1]-a[0]))*(a[1]-a[0])*i/2;
b:=dragonpaperd(a[1],v,n-1);
return b
};
On tape :
dragonpaperg(-3,13,8)
next up previous contents index
suivant: Deux courbes de Péano monter: Quelques dessins doublement récursifs précédent: Les sphinx   Table des matières   Index
Documentation de giac écrite par Renée De Graeve