From c78eade2f2590a8fd7502e2dfb904f5aae53298d Mon Sep 17 00:00:00 2001 From: Revar Desmera <revarbat@gmail.com> Date: Sun, 22 Mar 2020 01:14:26 -0700 Subject: [PATCH] Added initial Fractal Tree demo tutorial. Still need to gen images. --- examples/fractal_tree.scad | 55 +++------- examples/randomized_fractal_tree.scad | 48 +++++++++ tutorials/Fractal_Tree.md | 139 ++++++++++++++++++++++++++ version.scad | 2 +- 4 files changed, 200 insertions(+), 44 deletions(-) create mode 100644 examples/randomized_fractal_tree.scad create mode 100644 tutorials/Fractal_Tree.md diff --git a/examples/fractal_tree.scad b/examples/fractal_tree.scad index 0cb34c2..5ef423e 100644 --- a/examples/fractal_tree.scad +++ b/examples/fractal_tree.scad @@ -1,48 +1,17 @@ include <BOSL2/std.scad> -include <BOSL2/paths.scad> -include <BOSL2/beziers.scad> - -module leaf(s) { - path = [ - [0,0], [1.5,-1], - [2,1], [0,3], [-2,1], - [-1.5,-1], [0,0] - ]; - xrot(90) - linear_sweep_bezier( - scale_points(path, [s,s]/2), - height=0.02 - ); -} - -module branches(minsize, s1, s2){ - if(s2>minsize) { +module tree(l=1500, sc=0.7, depth=10) + recolor("lightgray") + cylinder(l=l, d1=l/5, d2=l/5*sc) attach(TOP) - zrot(gaussian_rands(90,20)[0]) - zrot_copies(n=floor(log_rands(2,5,4)[0])) - zrot(gaussian_rands(0,5)[0]) - yrot(gaussian_rands(30,10)[0]) { - sc = gaussian_rands(0.7,0.05)[0]; - cylinder(d1=s2, d2=s2*sc, l=s1) - branches(minsize, s1*sc, s2*sc); - } - } else { - recolor("springgreen") - attach(TOP) zrot(90) - leaf(gaussian_rands(100,5)[0]); - } -} - -module tree(h, d, minsize) { - sc = gaussian_rands(0.7,0.05)[0]; - recolor("lightgray") { - cylinder(d1=d, d2=d*sc, l=h) { - branches(minsize, h, d*sc); - } - } -} - -tree(d=300, h=1500, minsize=10); + if (depth>0) + zrot(90) + zrot_copies(n=2) + yrot(30) tree(depth=depth-1, l=l*sc, sc=sc); + else + recolor("springgreen") + yscale(0.67) + teardrop(d=l*3, l=1, anchor=BOT, spin=90); +tree(); // vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/examples/randomized_fractal_tree.scad b/examples/randomized_fractal_tree.scad new file mode 100644 index 0000000..0cb34c2 --- /dev/null +++ b/examples/randomized_fractal_tree.scad @@ -0,0 +1,48 @@ +include <BOSL2/std.scad> +include <BOSL2/paths.scad> +include <BOSL2/beziers.scad> + +module leaf(s) { + path = [ + [0,0], [1.5,-1], + [2,1], [0,3], [-2,1], + [-1.5,-1], [0,0] + ]; + xrot(90) + linear_sweep_bezier( + scale_points(path, [s,s]/2), + height=0.02 + ); +} + +module branches(minsize, s1, s2){ + if(s2>minsize) { + attach(TOP) + zrot(gaussian_rands(90,20)[0]) + zrot_copies(n=floor(log_rands(2,5,4)[0])) + zrot(gaussian_rands(0,5)[0]) + yrot(gaussian_rands(30,10)[0]) { + sc = gaussian_rands(0.7,0.05)[0]; + cylinder(d1=s2, d2=s2*sc, l=s1) + branches(minsize, s1*sc, s2*sc); + } + } else { + recolor("springgreen") + attach(TOP) zrot(90) + leaf(gaussian_rands(100,5)[0]); + } +} + +module tree(h, d, minsize) { + sc = gaussian_rands(0.7,0.05)[0]; + recolor("lightgray") { + cylinder(d1=d, d2=d*sc, l=h) { + branches(minsize, h, d*sc); + } + } +} + +tree(d=300, h=1500, minsize=10); + + +// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/tutorials/Fractal_Tree.md b/tutorials/Fractal_Tree.md new file mode 100644 index 0000000..095f6d6 --- /dev/null +++ b/tutorials/Fractal_Tree.md @@ -0,0 +1,139 @@ +# Fractal Tree Tutorial + +### Start with a Tree Trunk + +Firstoff, include the BOSL2 library, then add a tapered cylinder for the tree trunk. + +```openscad-example +include <BOSL2/std.scad> +cylinder(l=1500, d1=300, d2=210); +``` + +### Parameterize It + +It's easier to adjust a model if you split out the defining parameters. + +```openscad-example +include <BOSL2/std.scad> +l = 1500; +sc = 0.7; +cylinder(l=l, d1=l/5, d2=l/5*sc); +``` + +### Attaching Branches + +You can attach branches to the top of the trunk by using `attach()` as a child of the trunk cylinder. + +```openscad-example +include <BOSL2/std.scad> +l = 1500; +sc = 0.7; +cylinder(l=l, d1=l/5, d2=l/5*sc) { + attach(TOP) yrot( 30) cylinder(l=l*sc, d1=l/5*sc, d2=l/5*sc*sc); + attach(TOP) yrot(-30) cylinder(l=l*sc, d1=l/5*sc, d2=l/5*sc*sc); +} +``` + +### Replicate Branches + +Instead of attaching each branch individually, you can attach multiple branch copies at once. + +```openscad-example +include <BOSL2/std.scad> +l = 1500; +sc = 0.7; +cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + zrot_copies(n=2) // Make multiple rotated copies + yrot(30) cylinder(l=l*sc, d1=l/5*sc, d2=l/5*sc*sc); +``` + +### Make it a Module + +Lets make this into a module, for convenience. + +```openscad-example +include <BOSL2/std.scad> +module tree(l=1500, sc=0.7) + cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + zrot_copies(n=2) + yrot(30) cylinder(l=l*sc, d1=l/5*sc, d2=l/5*sc*sc); +tree(); +``` + +### Use Recursion + +Since branches look much like the main trunk, we can make it recursive. Don't forget the termination clause, or else it'll try to recurse forever! + +```openscad-example +include <BOSL2/std.scad> +module tree(l=1500, sc=0.7, depth=10) + cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + if (depth>0) // Important! + zrot_copies(n=2) + yrot(30) tree(depth=depth-1, l=l*sc, sc=sc); +tree(); +``` + +### Make it Not Flat + +A flat planar tree isn't what we want, so lets bush it out a bit by rotating each level 90 degrees. + +```openscad-example +include <BOSL2/std.scad> +module tree(l=1500, sc=0.7, depth=10) + cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + if (depth>0) + zrot(90) // Bush it out + zrot_copies(n=2) + yrot(30) tree(depth=depth-1, l=l*sc, sc=sc); +tree(); +``` + +### Adding Leaves + +Let's add leaves. They look much like squashed versions of the standard teardrop() module, so lets use that. + +```openscad-example +include <BOSL2/std.scad> +module tree(l=1500, sc=0.7, depth=10) + cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + if (depth>0) + zrot(90) + zrot_copies(n=2) + yrot(30) tree(depth=depth-1, l=l*sc, sc=sc); + else + yscale(0.67) + teardrop(d=l*3, l=1, anchor=BOT, spin=90); +tree(); +``` + +### Adding Color + +We can finish this off with some color. The `color()` module will force all it's children and +their descendants to the new color, even if they were colored before. The `recolor()` module, +however, will only color children and decendants that don't already have a color set by a more +nested `recolor()`. + +```openscad-example +include <BOSL2/std.scad> +module tree(l=1500, sc=0.7, depth=10) + recolor("lightgray") + cylinder(l=l, d1=l/5, d2=l/5*sc) + attach(TOP) + if (depth>0) + zrot(90) + zrot_copies(n=2) + yrot(30) + tree(depth=depth-1, l=l*sc, sc=sc); + else + recolor("springgreen") + yscale(0.67) + teardrop(d=l*3, l=1, anchor=BOT, spin=90); +tree(); +``` + diff --git a/version.scad b/version.scad index 73cabf9..8cdf21c 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,212]; +BOSL_VERSION = [2,0,213]; // Section: BOSL Library Version Functions