diff --git a/src/experimental/_impl/_lsystem3_impl.scad b/src/experimental/_impl/_lsystem3_impl.scad new file mode 100644 index 00000000..a7a29ccd --- /dev/null +++ b/src/experimental/_impl/_lsystem3_impl.scad @@ -0,0 +1,76 @@ +use ; +use ; +use ; + +// It doesn't use recursion to avoid recursion error. +function _join(str_lt) = + let(leng = len(str_lt)) + [for(i = 0, s = str_lt[0]; i < leng; i = i + 1, s = str(s, str_lt[i])) s][leng - 1]; + +function c_or_v(c, v, rules, rules_pr, leng, i = 0) = + i == leng ? c : ( + let(idx = search([v[i]], rules, num_returns_per_match=0, index_col_num = 1)[0][0]) + rand(0, 1) <= rules_pr[idx] ? v[i] : c_or_v(c, v, rules, rules_pr, leng, i + 1) + ); + +function _derive1_p(base, rules, rules_pr) = + _join([ + for(c = base) + let(v = [for(r = rules) if(r[0] == c) r[1]]) + v == [] ? c : + c_or_v(c, v, rules, rules_pr, len(v)) + ]); + +function _derive_p(base, rules, rules_pr, n, i = 0) = + i == n ? base : _derive_p(_derive1_p(base, rules, rules_pr), rules, rules_pr, n, i + 1); + +function _derive1(base, rules) = _join([ + for(c = base) + let(v = assoc_lookup(rules, c)) + is_undef(v) ? c : v +]); + +function _derive(base, rules, n, i = 0) = + i == n ? base : _derive(_derive1(base, rules), rules, n, i + 1); + +function _lsystem3_derive(axiom, rules, n, rules_pr) = + is_undef(rules_pr) ? _derive(axiom, rules, n) : + _derive_p(axiom, rules, rules_pr, n); + +function _next_stack(t, code, stack) = + code == "[" ? concat([t], stack) : + let(leng = len(stack)) + code == "]" ? + (leng > 1 ? [for(i = [1:leng - 1]) stack[i]] : []) : + stack; + +function _next_t1(t1, t2, code, stack) = + code == "[" ? t1 : + code == "]" ? stack[0] : t2; + +function _next_t2(t, code, angle, leng) = + is_undef(code) || code == "[" || code == "]" ? t : + code == "F" || code == "f" ? turtle3d("xu_move", t, leng) : + code == "+" ? turtle3d("zu_turn", t, angle) : + code == "-" ? turtle3d("zu_turn", t, -angle) : t; + +// It doesn't use recursion to avoid recursion error. +function _lines(t, codes, angle, leng) = + let(codes_leng = len(codes)) + [ + for( + i = 0, + stack = [], + t1 = t, + t2 = _next_t2(t1, codes[i], angle, leng); + + i < codes_leng; + + t1 = _next_t1(t1, t2, codes[i], stack), + stack = _next_stack(t1, codes[i], stack), + i = i + 1, + t2 = _next_t2(t1, codes[i], angle, leng) + ) + if(search(codes[i], "F+-") != []) + [turtle3d("pt", t1), turtle3d("pt", t2)] + ]; \ No newline at end of file diff --git a/src/experimental/lsystem3.scad b/src/experimental/lsystem3.scad new file mode 100644 index 00000000..f0f61a13 --- /dev/null +++ b/src/experimental/lsystem3.scad @@ -0,0 +1,18 @@ +use ; +use ; + +function lsystem3(axiom, rules, n, angle, leng = 1, heading = 0, start = [0, 0, 0], forward_chars = "F", rules_pr) = + let( + derived = _lsystem3_derive(axiom, rules, n, rules_pr), + codes = forward_chars == "F" ? derived : _join([ + for(c = derived) + let(idx = search(c, forward_chars)) + idx == [] ? c : "F" + ]) + ) + _lines( + turtle3d("create", start, [[1, 0, 0], [0, 1, 0], [0, 0, 1]]), + codes, + angle, + leng + ); \ No newline at end of file