Hello, is there a way to solve this problem without classic variables? The setup is (simplified for this example): In a vector I have a number of vectors that define the dimesions of boxes (length, height). The width for all boxes is fixed, and all these boxes should be placed one immedialety after another, however, when the total length exceeds a given maxWidth, the starting xposition should be reset to zero and y should be increased by width. It is a similar problem to e.g. typesetting words aligned to left In a "normal" scripting language I'd do something like
But because of the weird behaviour of the nonvariable variables in OpenSCAD I'm stuck. Any hint for me? Many thanks. Sent from the OpenSCAD mailing list archive at Nabble.com. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Personally, i’d probably uses a recursive function like this:
width = 10; maxWidth = 50; boxes = [ [10,10], [25,5], [5,15], [20, 5], [10,10], [25,5], [5,15], [20, 5], [10,10], [25,5], [5,15], [20, 5]]; function justify(width = 0, index = 0, boxesInLine = []) = (index >= len(boxes))  (width + boxes[index].x > maxWidth) ? [boxesInLine, width] : justify( concat(boxesInLine, index), width + boxes[index].x, index + 1) ; echo(justify());
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by janek
I had a similar issue recently... What you're trying is to fit a 1 dimensional problem into a 2 dimensional map. The currentX and CurrentY may look like a good idea, but... You only need ONE of them. CurrentX Just add up the CurrentX, then divide by Maxwidth, an multiply the integer result by the width to et 'CurrentY. The proper CurrentX position is the modulo of CurrentX and Maxwidth. translate([CurrentX%maxwidth, floor(CurrentX/Maxwidth, 0]) Something like that, at least... Why do things complicated? ;) Trygve On 23 June 2020 at 23:57:33 +02:00, janek <[hidden email]> wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by boxcarmib
Thanks, I must confess, I came to a similar solution. However, since my programming experience tells me that recursion is a powerful tool with huge costs (typically memory and performance killer), suffering also from call stack size limitation (even though it is not my case yet, would I be able to process something, that would produce a matrix of ca. 100 x 200 elements using recursion?), I was wondering if there is a better method. JanDne 24.06.2020 v 0:22 Hugo Jackson
napsal(a):
Personally, i’d probably uses a recursive function like this: _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Gadgetman!
Thank you, Dne 24.06.2020 v 0:50
[hidden email] napsal(a):
That's exactly my problem
This is what I do for fixedsize boxes (I started with those). I
can simply loop through the vector and calculate current position
using method similar to described. However, here, I cannot
calculate "statically" currentX and I cannot find the way to
repeatedly add to the currentX inside the loop  at least without
recursion. Also, using this method, would boxes be aligned properly? If I
understand it, then not. It is not given that the sum of lengths
on first line would be divisible by MaxWidth and then all further
rows would be shifted, wouldn't they? But yes, that could have been solved by temporal calculation of "remaining space" and another addition to currentX  in case I had a method of summing/incrementing a variable inside a loop.
My words. I love the idea of OpenScad. I bang my forehead to the
closest wall almost every time I try to do something in a normal
(for a person with some experience with common programming
languages), readable or elegant way and call out a loud WHY! :) Jan
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Hi! Also, using this method, would boxes be aligned properly? If I
understand it, then not. It is not given that the sum of lengths
on first line would be divisible by MaxWidth and then all further
rows would be shifted, wouldn't they?
You're right. That was a mistake on my part. I believe it can be solved by adding an IF clause and an addition, but yeah, I'm on vacation right now, it's midday and I haven't even had breakfast yet. My brain probably won't work properly for at least a couple of weeks more.... Trygve, or possibly a multiplication
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
This seems to work. Doing the calculation before starting
to generate geometry makes it easier to debug and also there's not really a problem regarding the recursion as pretty much any list that's too long at this point will likely be impossible to render later anyway due to number of vertices generated. The commented out generator will make 10001 objects which takes about a second to preview on my notebook. maxWidth = 9; o = [ [3, "gray"], [1, "lightblue"], [4, "orange"], [2, "indigo"], [2, "violet"], [3, "yellow"], [5, "green"] ]; /* maxWidth = 300; r = rands(1, 10, pow(maxWidth / 3, 2) + 3); o = [ for (i = [0 : len(r)  3]) [ r[i], [ r[i + 1], r[i + 2], r[i + 3] ] / 10] ]; */ function wadd(w, list, idx, cnt = 0) = cnt < 0 ? w : w + wadd(idx < len(list) ? list[idx][0] : 0, list, idx + 1, cnt  1); function map(list, w) = [ for ( idx = 0, w = 0, y = 0; idx < len(list); w0 = wadd(w, list, idx), w1 = wadd(w, list, idx, 1), w = w1 > maxWidth ? 0 : w0, y = y + (w1 > maxWidth ? 1 : 0), idx = idx + 1 ) [each list[idx], w, y] ]; echo(Number_of_objects = len(o)); %linear_extrude(1) offset(delta = 1) square(maxWidth); for (a = map(o)) { color(a[1]) translate([a[2], a[3], 0]) cube([a.x, 1, rands(2,5,1)[0]]); } _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Torsten

In reply to this post by janek
Recursion is an invaluable resource you should try to master to easily use OpenSCAD . You don't need recursion to sum up a list of numbers or get its accumulated sum but you can't avoid some functions and list comprehension:
To solve your problem we may use recursion to find the break points of the box rows from the box widths l and maximum width wmax:
That is not an easy way for a beginner but it is a tail recursion elimination solution that doesn't overload stacks. Luckly, an equivalent nonrecursive solution may be written using Clike for:
That might be easier to understand by a beginner used to list comprehension and imperative programming. As soon as you have the break points bp of the length list l, the row lengths may be computed by:
A simple final check of everything:
Using the break points how to find the Y displacement of the rows? ( list comprehension => https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/List_Comprehensions ) _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In sum() why do you test for i < len(l) when the loop terminates at len(l)  1 ? And why would you want a zero in the vector of ones? On Thu, 25 Jun 2020 at 12:45, Ronaldo Persiano <[hidden email]> wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In sum() why do you test for i < len(l) when the loop terminates at len(l)  1 ? And why would you want a zero in the vector of ones? You are right, the if is unnecessary. I just have done a lazy change in a more general version of it: // total sum of the first n elements a list of numbers (or of the rows of a matrix) _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
There has been a lot of discussion about summing up something in OpenSCAD.
Wouldn't it be worth to add feature request for a sum(list) primitive to OpenSCAD? Especially newbies, who aren't running their own libs or writing functions, would appreciate this. Not having a sum(), is like not having a len() function and having to implement it on your own: echo(len([1,2,3, 7])); function len(X=[],i=0) = X[i]== undef?0:1+len(X,i+1); I mean we have functions like cross(), norm(), abs(), min(), max(), floor(), ceil(), sign(), sqrt()  to name the most prominent ones  which could all be implemented by the users as well, so why is sum() missing? Personally I also wouldn't be unhappy with a basic set of file functions, like fopen(), fecho(), to eventually leave the medieval darkness OpenSCAD is selfrestricting itself ;)  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
I am in favour of sum, and some sort of file io. It would be nice to be able to add users pace support for new file formats. The fopen/fread/fwrite/fclose/ftell/fseek set is complete, at least On Thu, 25 Jun 2020, 09:08 Parkinbot, <[hidden email]> wrote: There has been a lot of discussion about summing up something in OpenSCAD. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Free forum by Nabble  Edit this page 