1include <BOSL2/std.scad>
 2
 3function _lsystem_recurse(s, rules, lev) =
 4    lev<=0? s : _lsystem_recurse([
 5        for (
 6            i = 0,
 7            slen = len(s),
 8            sout = "";
 9
10            i <= slen;
11
12            ch = s[i],
13            found = search([ch], rules)[0],
14            sout = str(sout, i==slen? "" : found==[]? ch : rules[found][1]),
15            i = i + 1
16        ) if (i==slen) sout
17    ][0], rules, lev-1);
18
19
20function _lsystem_to_turtle(s, step=1, angle=90, startang=0) =
21    concat(
22        startang? ["left", startang] : [],
23        ["angle", angle, "length", step],
24        [
25            for (
26                i = 0,
27                slen = len(s);
28
29                i <= slen;
30
31                ch = s[i],
32                cmd = (ch=="A" || ch=="B" || ch=="F")? ["move"] :
33                    (ch=="+")? ["left"] :
34                    (ch=="-")? ["right"] :
35                    [],
36                i=i+1
37            ) if(i>0 && cmd!=[]) each cmd
38        ]
39    );
40
41
42function lsystem_turtle(basis, rules, levels=5, step=1, angle=90, startang=0) =
43    turtle(_lsystem_to_turtle(_lsystem_recurse(basis, rules, levels), step=step, angle=angle, startang=startang));
44
45
46function dragon_curve        (levels=9,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "FX",        [["X", "X+YF+"], ["Y", "-FX-Y"]]);
47function terdragon_curve     (levels=7,  step=1) = lsystem_turtle(levels=levels, step=step, angle=120, "F",         [["F", "F+F-F"]]);
48function twindragon_curve    (levels=11, step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "FX+FX+",    [["X", "X+YF"], ["Y","FX-Y"]]);
49function moore_curve         (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "LFL+F+LFL", [["L", "-RF+LFL+FR-"], ["R", "+LF-RFR-FL+"]]);
50function hilbert_curve       (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "X",         [["X","-YF+XFX+FY-"], ["Y","+XF-YFY-FX+"]]);
51function gosper_curve        (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=60,  "A",         [["A", "A-B--B+A++AA+B-"], ["B", "+A-BB--B-A++A+B"]]);
52function quadratic_gosper    (levels=2,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "-YF",       [["X", "XFX-YF-YF+FX+FX-YF-YFFX+YF+FXFXYF-FX+YF+FXFX+YF-FXYF-YF-FX+FX+YFYF-"], ["Y", "+FXFX-YF-YF+FX+FXYF+FX-YFYF-FX-YF+FXYFYF-FX-YFFX+FX+YF-YF-FX+FX+YFY"]]);
53function peano_curve         (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "X",         [["X","XFYFX+F+YFXFY-F-XFYFX"], ["Y","YFXFY-F-XFYFX+F+YFXFY"]]);
54function koch_snowflake      (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=60,  "F++F++F",   [["F","F-F++F-F"]]);
55function sierpinski_arrowhead(levels=6,  step=1) = lsystem_turtle(levels=levels, step=step, angle=60,  "A",         [["A", "B-A-B"], ["B","A+B+A"]]);
56function sierpinski_triangle (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=120, "A-B-B",     [["A","A-B+A+B-A"], ["B","BB"]]);
57function square_sierpinski   (levels=5,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "F+XF+F+XF", [["X","XF-F+F-XF+F+XF-F+F-X"]]);
58function cesaro_curve        (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=85,  "F",         [["F","F+F--F+F"]]);
59function paul_bourke1        (levels=3,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "F+F+F+F+",  [["F","F+F-F-FF+F+F-F"]]);
60function paul_bourke_triangle(levels=6,  step=1) = lsystem_turtle(levels=levels, step=step, angle=120, "F+F+F",     [["F","F-F+F"]]);
61function paul_bourke_crystal (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "F+F+F+F",   [["F","FF+F++F+F"]]);
62function space_filling_tree  (levels=4,  step=1) = lsystem_turtle(levels=levels, step=step, angle=90,  "X",         [["X","FX++F-FX++F-FX++F-FX++F-"],["F", "FF"]], startang=45);
63function krishna_anklets     (levels=6,  step=1) = lsystem_turtle(levels=levels, step=step, angle=45,  "-X--X",     [["X","XFX--XFX"]]);
64
65
66points = hilbert_curve(levels=5, step=100/pow(2,5));
67stroke(points, width=1);
68
69
70// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap