diff --git a/README.md b/README.md index f5fa317c..5f2fc8d2 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ See [examples](examples). - [turtle/footprints2](https://openhome.cc/eGossip/OpenSCAD/lib2x-footprints2.html) - [turtle/footprints3](https://openhome.cc/eGossip/OpenSCAD/lib2x-footprints3.html) - [turtle/lsystem2](https://openhome.cc/eGossip/OpenSCAD/lib2x-lsystem2.html) +- [turtle/lsystem3](https://openhome.cc/eGossip/OpenSCAD/lib2x-lsystem3.html) ---- diff --git a/docs/images/lib2x-lsystem3-1.JPG b/docs/images/lib2x-lsystem3-1.JPG new file mode 100644 index 00000000..9f66963e Binary files /dev/null and b/docs/images/lib2x-lsystem3-1.JPG differ diff --git a/docs/images/lib2x-lsystem3-2.JPG b/docs/images/lib2x-lsystem3-2.JPG new file mode 100644 index 00000000..630878bc Binary files /dev/null and b/docs/images/lib2x-lsystem3-2.JPG differ diff --git a/docs/images/lib2x-lsystem3-3.JPG b/docs/images/lib2x-lsystem3-3.JPG new file mode 100644 index 00000000..f8c3257a Binary files /dev/null and b/docs/images/lib2x-lsystem3-3.JPG differ diff --git a/docs/lib2x-lsystem2.md b/docs/lib2x-lsystem2.md index 90a8d469..459875b2 100644 --- a/docs/lib2x-lsystem2.md +++ b/docs/lib2x-lsystem2.md @@ -26,7 +26,7 @@ ## Examples -[lsystem-collections.scad](https://github.com/JustinSDK/dotSCAD/blob/master/examples/turtle/lsystem2_collection.scad) collects several L-system grammars. Here's one of them. +[lsystem2-collections.scad](https://github.com/JustinSDK/dotSCAD/blob/master/examples/turtle/lsystem2_collection.scad) collects several L-system grammars. Here's one of them. use ; use ; diff --git a/docs/lib2x-lsystem3.md b/docs/lib2x-lsystem3.md new file mode 100644 index 00000000..62f907f1 --- /dev/null +++ b/docs/lib2x-lsystem3.md @@ -0,0 +1,84 @@ +# lsystem3 + +`lsystem3` is a 3D implementation of [L-system](https://en.wikipedia.org/wiki/L-system). It's based on the algorithm of turtle grahpics. Instructions for generation of rules are as follows: + + F Move forward and draw line + f Move forward without drawing a line + + Turn left + - Turn right + | Reverse direction (ie: turn by 180 degrees) + & Pitch down + ^ Pitch up + \ Roll left + / Roll right + [ Push current turtle state onto stack + ] Pop current turtle state from the stack + +**Since:** 2.4 + +## Parameters + +- `axiom` : The initial state of the system. +- `rules` : A list of production rules. The first element of each rule is the predecessor, and the second is the successor. +- `n` : Iteration times. +- `angle` : Used when turing. +- `leng` : Used when forwarding. Default to `1`. +- `heading` : The initial angle of the turtle. Default to `0`. +- `start` : The starting point of the turtle. Default to `[0, 0]`. +- `forward_chars` : Chars used for forwarding after the last iteration. Default to `'F'`. +- `rule_prs` : The probabilities for taking rules. If each rule is chosen with a certain probability, it's a stochastic L-system. Each probability value for a rule ranges from 0 to 1. + +## Examples + +[lsystem3-collections.scad](https://github.com/JustinSDK/dotSCAD/blob/master/examples/turtle/lsystem3_collection.scad) collects several L-system grammars. Here's one of them. + + use ; + use ; + + for(line = hilbert_curve()) { + hull_polyline3d( + [line[0], line[1]], + thickness = 0.5, + $fn = 4 + ); + } + + function hilbert_curve(n = 3, angle = 90, leng = 1, heading = 0, start = [0, 0, 0]) = + let( + axiom = "A", + rules = [ + ["A", "B-F+CFC+F-D&F^D-F+&&CFC+F+B//"], + ["B", "A&F^CFB^F^D^^-F-D^|F^B|FC^F^A//"], + ["C", "|D^|F^B-F+C^F^A&&FA&F^C+F+B^F^D//"], + ["D", "|CFB-F+B|FA&F^A&&FB-F+B|FC//"] + ] + ) + lsystem3(axiom, rules, n, angle, leng, heading, start); + +![lsystem3](images/lib2x-lsystem3-1.JPG) + + // a stochastic L-system + + use ; + use ; + + for(line = vine()) { + hull_polyline3d( + [line[0], line[1]], + thickness = 0.5, + $fn = 4 + ); + } + + function vine(n = 3, angle = 18, leng = 1, heading = 0, start = [0, 0, 0]) = + let( + axiom = "--F", + rules = [ + ["F", "/F[++F]-\\F[--F]+//F"] + ] + ) + lsystem3(axiom, rules, n, angle, leng, heading, start, rule_prs = [0.8]); + +![lsystem3](images/lib2x-lsystem3-2.JPG) + +![lsystem3](images/lib2x-lsystem3-3.JPG) \ No newline at end of file diff --git a/src/turtle/_impl/_lsystem3_impl.scad b/src/turtle/_impl/_lsystem3_impl.scad index 0d188ff6..ac04d205 100644 --- a/src/turtle/_impl/_lsystem3_impl.scad +++ b/src/turtle/_impl/_lsystem3_impl.scad @@ -3,9 +3,9 @@ use <../turtle3d.scad>; function _lsystem3_join(str_lt) = _join(str_lt); -function _lsystem3_derive(axiom, rules, n, rules_pr) = - is_undef(rules_pr) ? _derive(axiom, rules, n) : - _derive_p(axiom, rules, rules_pr, n); +function _lsystem3_derive(axiom, rules, n, rule_prs) = + is_undef(rule_prs) ? _derive(axiom, rules, n) : + _derive_p(axiom, rules, rule_prs, n); function _next_stack(t, code, stack) = code == "[" ? concat([t], stack) : diff --git a/src/turtle/lsystem3.scad b/src/turtle/lsystem3.scad index e62f4fb5..58872599 100644 --- a/src/turtle/lsystem3.scad +++ b/src/turtle/lsystem3.scad @@ -1,25 +1,19 @@ +/** +* lsystem3.scad +* +* @copyright Justin Lin, 2020 +* @license https://opensource.org/licenses/lgpl-3.0.html +* +* @see https://openhome.cc/eGossip/OpenSCAD/lib2x-lsystem3.html +* +**/ + use <_impl/_lsystem3_impl.scad>; use ; -/* - - F Move forward and draw line - f Move forward without drawing a line - + Turn left - - Turn right - | Reverse direction (ie: turn by 180 degrees) - & Pitch down - ^ Pitch up - \ Roll left - / Roll right - [ Push current turtle state onto stack - ] Pop current turtle state from the stack - -*/ - -function lsystem3(axiom, rules, n, angle, leng = 1, heading = 0, start = [0, 0, 0], forward_chars = "F", rules_pr) = +function lsystem3(axiom, rules, n, angle, leng = 1, heading = 0, start = [0, 0, 0], forward_chars = "F", rule_prs) = let( - derived = _lsystem3_derive(axiom, rules, n, rules_pr), + derived = _lsystem3_derive(axiom, rules, n, rule_prs), codes = forward_chars == "F" ? derived : _lsystem3_join([ for(c = derived) let(idx = search(c, forward_chars))