[OpenSCAD] recursion limit on concat()

Ronaldo Persiano rcmpersiano at gmail.com
Tue Oct 15 10:31:56 EDT 2019

 kitwallace <kit.wallace at 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,
                         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,
                        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
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) {
  for (j=[0:len(points)/1000]) { // this { brace pair is mandatory
   for(i=[0:min(999,len(points)-2-1000*j)]) {
    hull() {
        translate(points[1000*j+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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20191015/e2562400/attachment.html>

More information about the Discuss mailing list