Une tortue pour dessiner des branches
Bonjour,
Je suis en train d'essayer de programmer le dessin de fractales par les L-systems, avec le principe de la tortue sur Caml-light. Le principe est simple : la tortue est définie par ses positions x et y et sa direction phi. Une chaîne de caractères est lue au fur et à mesure, et à chaque caractère correspond à une instruction. Cette chaîne est obtenue à partir d'une chaîne de départ, qui est changée à chaque itération à partir de règles que le programmeur précise. Mais là n'est pas mon problème.
J'ai plusieurs types de caractères dans ces chaînes :
* F : la tortue avance d'un pas constant l selon sa direction phi, en traçant une ligne sur son parcours.
* f : la torute se déplace de la même manière, mais sans tracer de ligne.
* + : un angle constant phi est ajouté a la direction de la torute
* - : Cet angle est cette fois soustrait.
* [ : le programme garde en mémoire l'état de la tortue.
* ] : la tortue revient au dernier état correspondant au dernier [ précédent.
Ces deux dernières commandes permettent de créer des branches dans les graphes... et me posent problème. Voici mon code qui dessine le graphe à partir d'une chaîne de caractères:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| let dessine phrase l theta p =
clear_graph();
let L = string_length phrase and stock = ref [] in
for i = 0 to L-1 do
match phrase.[i] with
|`F`-> F p l;
|`f`-> f p l;
|`+`-> plus p theta;
|`-`-> moins p theta;
|`[`-> stock := p::(!stock);
|`]`-> let pc = (hd !stock) in
p.x <- pc.x; p.y <- pc.y ; p.phi <- pc.phi;
stock := (tl !stock);
| _ -> ();
done;; |
la fonction prend en entrée la chaîne de carctères à étudier, phrase, le pas selon lequel avancer, l, l'angle selon lequel l'orientation change, theta, et l'état initial de la tortue, p={x:float;y:float;phi:float}.
J'ai créé auparavant les fonctions correspondant à `F`,`f`,`+`,`-`, respectivement F, f, plus et moins. Elles fonctionnent : j'ai pu faire le flocon de Von Koch.
stock est la liste conservant les états de la tortues à chaque passage de `[`, puisqu'il peut y avoir plusieurs branches imbriquées. A chaque passage devant ce caractère, l'état est stocké en début de liste. Lorsque `]` est lu, le tortue doit revenir au dernier état stocké, donc celui en début de liste. La tortue y retourne, et cet état, désormais inutile, est ôté de stock.
Et là je ne sais pas trop quoi penser du résultat... Tout à l'heure j'ai réussi à avoir des branches, mais impossible de rendre compte sur le graphe de branches imbriquées. Et il y a quelques instants, sans que j'ai fait de modifications, je n'ai même plus de branches, seulement une ligne.
Je n'arrive pas à trouver mon erreur de syntaxe et/ou de logique. Quelqu'un saurait-il m'aider?
Bien cordialement,
Toufraita
PS:au cas où ça vous intéresse, les fonctions F, f, plus, moins, et la définition du type tortue.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
type turtule = {mutable x : float; mutable y : float; mutable phi : float};;
let F p l =
let x2 = (p.x) +. l *. cos (rad_of_deg p.phi)
and y2 = (p.y) +. l *. sin (rad_of_deg p.phi) in
moveto (round p.x) (round p.y); lineto (round x2) (round y2);
p.x <- x2; p.y <- y2;;
let f p l =
p.x <- p.x +. l *. cos (rad_of_deg p.phi);
p.y <- p.y +. l *. sin (rad_of_deg p.phi);;
let plus p theta =
p.phi <- p.phi +. theta;;
let moins p theta =
p.phi <- p.phi -. theta;; |
round arrondit le flottant en entier, rad_of_deg convertit l'angle en degré en radians, puisque les fonctions cos et sin prennent en entrée des radians.