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:
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}.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;;
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.
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;;
Partager