mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-08-13 18:24:28 +02:00
first attempt to create lsystem3
This commit is contained in:
76
src/experimental/_impl/_lsystem3_impl.scad
Normal file
76
src/experimental/_impl/_lsystem3_impl.scad
Normal file
@@ -0,0 +1,76 @@
|
||||
use <experimental/assoc_lookup.scad>;
|
||||
use <turtle/turtle3d.scad>;
|
||||
use <util/rand.scad>;
|
||||
|
||||
// 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)]
|
||||
];
|
18
src/experimental/lsystem3.scad
Normal file
18
src/experimental/lsystem3.scad
Normal file
@@ -0,0 +1,18 @@
|
||||
use <experimental/_impl/_lsystem3_impl.scad>;
|
||||
use <turtle/turtle3d.scad>;
|
||||
|
||||
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
|
||||
);
|
Reference in New Issue
Block a user