(* desenează o variantă de triunghi Sierpinski în format SVG * vezi https://en.wikipedia.org/wiki/L-system * compilează: ocamlc fisier.ml * rulează ./a.out > fisier.svg (Linux) sau ./a > fisier.svg (Windows) *) open Printf module M = Map.Make(Char) let pi3 = acos 0.5 let len = 3. (* dimensiunea unui segment *) (* scrie comanda SVG l dx dy pentru o linie la unghiul dat, returnează unghiul *) let line phi = printf "l %.1f %.1f " (len *. cos phi) (len *. sin phi); phi (* o literă neterminal e asociată cu o regulă de rescriere *) let gram = M.singleton 'A' ['B';'-';'A';'-';'B'] |> M.add 'B'['A';'+';'B';'+';'A'] (* o literă reprezintă o acțiune în functie de starea curentă (unghi): poate desena ceva, și returnează o nouă stare -- aici, noul unghi *) let actions = M.singleton 'A' line |> M.add 'B' line |> M.add '+' ((+.) pi3) (* întoarce la stânga *) |> M.add '-' ((+.) (-.pi3)) (* întoarce la dreapta *) (* expandează recursiv de n ori un caracter după regulile din dicționar * pentru terminali și în final execută acțiunea din dicționar *) let rec expand n state c = if n = 0 then state |> M.find c actions (* gata: deseneaza *) else try M.find c gram |> List.fold_left (expand (n-1)) state with Not_found -> state |> M.find c actions (* terminal: deseneaza *) (* începe cu 'A' sau 'B', ca să deseneze în jos; ignoră unghiul rezultate *) let fractal n = expand n 0. (if n mod 2 = 0 then 'A' else 'B') |> ignore let () = ( (* antet SVG, fractal, apoi încheie SVG *) print_string "<?xml version=\"1.0\"?>\n\ <svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n\ <path fill=\"none\" stroke=\"blue\" d=\"M 0 0 "; fractal 8; (* desenul *) print_string "\"/>\n</svg>" )
This document was generated using caml2html