Closed dpellegr closed 4 years ago
Maybe, I am not sure. I just need to draw this irregular pipe, nothing like those fancy fractals.
I needed to avoid having to explicitly define every point as in the turtle examples. If L-system covers this, maybe an example would be useful.
L-system functions will be published and documented in the next release. Your requirement seems like using a turtle to imitate freehand drawing. As you said, it might be useful in some situations. I'll consider implementing it some other day.
Exactly! The code above works properly, although having access to the interior of the library it can probably be implemented in a more efficient way. No need to rush. Thank you for the great library!
On Fri, May 8, 2020, 01:37 Justin Lin notifications@github.com wrote:
L-system functions will be published and documented in the next release. Your requirement seems like using a turtle to imitate freehand drawing. As you said, it might be useful in some situations. I'll consider implementing it some other day.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JustinSDK/dotSCAD/issues/10#issuecomment-625549936, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB3UFLTGBALIXNAOSAMCHTDRQNA5DANCNFSM4M3FJHKQ .
Ah, FYI, this is the code that I used to make the arc:
function arc(r, a, dir="z", $fn=$fn) =
let(
t=a/$fn, l=2*r*sin(t/2),
lst = [for (i=[1:1:$fn]) [[str(dir,"turn"), (i==1)?t/2:t], ["xforward", l]] ]
)
concat(lst, [lst[0][0]]);
It produces an ordered list of $fn
xforward
commands and $fn+1
turn
commands to create an arc of radius r
and total bending angle a
around the dir
axis. Note how the first and last turn rotate by half of the angle step.
2D footprints2
function:
use <turtle/footprints2.scad>;
use <hull_polyline2d.scad>;
function arc_cmds(radius, angle, steps) =
let(
fa = angle / steps,
ta = fa / 2,
leng = sin(ta) * radius * 2
)
concat(
[["turn", ta]],
[
for(i = [0:steps - 2])
each [["forward", leng], ["turn", fa]]
],
[["forward", leng], ["turn", ta]]
);
poly = footprints2(
concat(
[
["forward", 10],
["turn", 90],
["forward", 10]
],
arc_cmds(5, 180, 12),
[
["turn", -90],
["forward", 10],
["turn", 90],
["forward", 10],
["turn", 90],
["forward", 10]
]
)
);
hull_polyline2d(poly, width = 1);
3D footprints3
function:
use <hull_polyline3d.scad>;
use <turtle/footprints3.scad>;
function xy_arc_cmds(radius, angle, steps) =
let(
fa = angle / steps,
ta = fa / 2,
leng = sin(ta) * radius * 2
)
concat(
[["turn", ta]],
[
for(i = [0:steps - 2])
each [["forward", leng], ["turn", fa]]
],
[["forward", leng], ["turn", ta]]
);
// cmds: "forward" ("xu_move"), "turn" ("zu_turn"), "roll" (negative "xu_turn"), "pitch" (negative "yu_turn")
poly = footprints3(
concat(
[
["forward", 10],
["turn", 90],
["forward", 10]
],
xy_arc_cmds(5, 180, 12),
[
["pitch", 90],
["forward", 10],
["roll", 90]
],
xy_arc_cmds(5, 180, 12),
[
["forward", 10]
]
)
);
hull_polyline3d(poly, thickness = 1);
Another improvement: you can avoid the extra brackets around commands when mixing them with arcs. For that I use the repack function. It fully flattens a nested list, then it groups back the elements in sub-lists of the desired length (2 in this case). For instance:
let( L = [1,2,[3],[4,[5,6]]] )
fullflat( L ) => [1,2,3,4,5,6]
repack( L, 2) => [[1,2],[3,4],[5,6]]
repack( L, 3) => [[1,2,3],[4,5,6]]
so you can do:
poly = footprints3(
repack([
["forward", 10],
["turn", 90],
["forward", 10],
xy_arc_cmds(5, 180, 12),
["pitch", 90],
["forward", 10],
["roll", 90],
xy_arc_cmds(5, 180, 12),
["forward", 10]
])
);
You can also move the repack call inside the footprint3 function so that the user does not need to call it himself.
Here is an implementation of repack:
function flatten(l) = [ for (a = l) if (is_string(a)) a else for (b = a) b ];
function fullflat(l) = l == flatten(l) ? l : fullflat(flatten(l));
function repack(l, n=2) = let(lf=fullflat(l)) [ for (i=[0:n:len(lf)-1]) [for (j=[0:1:n-1]) lf[i+j] ]];
repack
is another story. I think it's better to be a utility function independent of footprints functions.
Yes of course. It just comes in very handy in here :)
On Sat, May 9, 2020, 12:36 Justin Lin notifications@github.com wrote:
repack is another story. I think it's better to be a utility function independent of footprints functions.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JustinSDK/dotSCAD/issues/10#issuecomment-626145701, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB3UFLV5VNFHNUMC2UHVYE3RQUWZTANCNFSM4M3FJHKQ .
Hi, please consider the code below. It allows for constructing a polyline directly from a sequence of turtle commands. When constructing the list of 3D points, I automatically drop the turn commands which would produce duplicates.
It would also be interesting to add some commands to produce arcs in a straightforward way, but that is for another time.