The (corrected and as a result simpler) recursive version of this function
is used in this version of the l-system code
https://github.com/KitWallace/openscad/blob/master/tiling/lsystem-recursive.scad
The Hilbert curve fails at k=5
--
Sent from: http://forum.openscad.org/
kitwallace kit.wallace@gmail.com wrote:
The (corrected and as a result simpler) recursive version of this function
is used in this version of the l-system code
The last version you referred defines a string_to_points() function which
still is unable to have the tail recursion eliminated.
Applying your correction to my alternative recursion version, it becomes:
function string_to_points(s,step=1,angle=90,pos=[0,0,0],dir=0,i=0,ps=[]) =
i == len(s)
? ps
: string_to_points(s,
step,
angle,
s[i]=="F" ||s[i]=="A" || s[i]=="B" // newpos
? pos + step*[cos(dir), sin(dir)]
: pos,
s[i]=="+" // newdir
? dir + angle
: s[i]=="-"
? dir - angle
: dir,
i+1,
concat([pos],ps) );
And now it will be eligible to tail recursion elimination.
With that correction, the iterative version also gets simpler and don't
need any explicit concat() (neither 'each'):
function string_to_points(s,step=1,angle=90,pos=[0,0,0],dir=0) =
[for( i = 0;
i <= len(s);
c = s[i],
pos = c=="F" ||c=="A" || c=="B"
? pos + step*[cos(dir), sin(dir)]
: pos,
dir = c=="+"
? dir + angle
: c=="-"
? dir - angle
: dir,
i = i+1 )
pos ];
The Hilbert curve fails at k=5
This failure is due to something else: the 'for' in module path() has more
then 9999 elements. This is an arbitrary (and low) limit in OpenSCAD range
'for's.
As an workaround, you may consider the following code with two nested 'for'
meant to 'cheat' the limit rule:
module path(points,width,closed=false) {
r=width/2;
for (j=[0:len(points)/1000]) { // this { brace pair is mandatory
for(i=[0:min(999,len(points)-2-1000j)]) {
hull() {
translate(points[1000j+i]) circle(r);
translate(points[1000*j+i+1]) circle(r);
}
}
}
if (closed) {
hull() {
translate(points[len(points)-1]) circle(r);
translate(points[0]) circle(r);
}
}
};
It should work up to 999999 elements in 'points'.
Now, Hilbert curve works with k=6 which has 13651 points and with the 54611
points generated when k=7.
Re the recusion example - I posted it at Torsten's request that so that it
could be used as a test case for the enhancement which I believe should
handle that case.
The correction I made was to concatenate only new points and I couldnt get
that to work with your inlined version - maybe didnt try hard enough!
Re the for range limit, i posted separately about that and the workaround I
came up with:
for (i=to_n(len(points)-2))
where
function to_n(n) = [for (i=0;i<=n;i=i+1) i];
--
Sent from: http://forum.openscad.org/
On 15.10.19 16:56, kitwallace wrote:
Re the recusion example - I posted it at Torsten's
request that so that it could be used as a test case
for the enhancement which I believe should handle
that case.
Thanks for that, I can confirm it works as expected. The
nightly does not abort with stack overflow so the tail
recursion elimination works nicely.
With the range workaround it successfully generates the
design with k=8.
ciao,
Torsten.
Hi kitwallace, I also have an L-system implementation which I've posted
about previously on the list:
http://forum.openscad.org/L-systems-demo-Fractal-designs-interpreter-performance-stress-testing-tp23295p25927.html
The latest revision is here:
https://gist.github.com/thehans/a1494db8046a58832e2ebb10a5908a66
I spent a lot of time optimizing this code (and even made changes to
OpenSCAD to support recursion more efficiently specifically because of
it). It's pretty good with high iterations.
https://gist.github.com/thehans/a1494db8046a58832e2ebb10a5908a66
On Tue, Oct 15, 2019 at 10:23 AM Torsten Paul Torsten.Paul@gmx.de wrote:
On 15.10.19 16:56, kitwallace wrote:
Re the recusion example - I posted it at Torsten's
request that so that it could be used as a test case
for the enhancement which I believe should handle
that case.
Thanks for that, I can confirm it works as expected. The
nightly does not abort with stack overflow so the tail
recursion elimination works nicely.
With the range workaround it successfully generates the
design with k=8.
ciao,
Torsten.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Hi thehans
Thanks for the pointer - sorry I missed your work earlier - my L-system
doesn't handle moves nor pop and push so that's very useful. My code
generates a list of points first, then the curve or a polygon as a separete
step because I'm particularly interested in fractals which tesselate - like
the 5-rep-tile ["5-rep-tile", "F-F-F-F-", [["F", "F+F-F"]], 90] and
terdragon boundary ["Terdragon boundary", "A-B--A-B--", [["A","A+B"],
["B","A-B"]], 60]. I like your handling of F synonyms and will steal that.
Kit
--
Sent from: http://forum.openscad.org/