discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

dynamic FOR statement

R
runsun
Sun, Nov 13, 2016 1:37 AM

Yea I did miss it. Apology for quick action.


$  Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf )

View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19066.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Yea I did miss it. Apology for quick action. ----- $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 );   $ tips: hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2, 3 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ) -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19066.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Sun, Nov 13, 2016 12:10 PM

You have to download a recent dev snapshot (and alter the prefs there) to be
able to use each and if/else in lc.

There is also a nice solution that works for elder versions of OpenSCAD not
supporting the new features:

function circle(R,N) =
Each([ for (w = [0:round(360/N):359])
(w<90)?    [[Rcos(w),Rsin(w)]]:
(w<180)?  [[Rcos(w),Rsin(w)]]:
(w==180)?
[[Rcos(w),Rsin(w)],[Rcos(w)+1,Rsin(w)],[Rcos(w)+1,Rsin(w)+1],[Rcos(w),Rsin(w)+1]]:
(w<270)?  [[Rcos(w),Rsin(w)]]:
[[Rcos(w),Rsin(w)]]
]);

function Each(L) = [for(i=L, j=i) j];

Note: Each has not exactly the same semantics as each as it always
returns a list and expects a list of lists. While it works at a different
nesting level, it does what you want.

It can even be implemented to do away with the extra brackets, which turns
it into a "special case list flatterer":

function circle(R,N) =
EachSC([ for (w = [0:round(360/N):359])
(w<90)?    [Rcos(w),Rsin(w)]:
(w<180)?  [Rcos(w),Rsin(w)]:
(w==180)?
[[Rcos(w),Rsin(w)],[Rcos(w)+1,Rsin(w)],[Rcos(w)+1,Rsin(w)+1],[Rcos(w),Rsin(w)+1]]:
(w<270)?  [Rcos(w),Rsin(w)]:
[Rcos(w),Rsin(w)]
]);

function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j];

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19068.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

You have to download a recent dev snapshot (and alter the prefs there) to be able to use *each* and *if/else* in lc. There is also a nice solution that works for elder versions of OpenSCAD not supporting the new features: > function circle(R,N) = > Each([ for (w = [0:round(360/N):359]) > (w<90)? [[R*cos(w),R*sin(w)]]: > (w<180)? [[R*cos(w),R*sin(w)]]: > (w==180)? > [[R*cos(w),R*sin(w)],[R*cos(w)+1,R*sin(w)],[R*cos(w)+1,R*sin(w)+1],[R*cos(w),R*sin(w)+1]]: > (w<270)? [[R*cos(w),R*sin(w)]]: > [[R*cos(w),R*sin(w)]] > ]); > > function Each(L) = [for(i=L, j=i) j]; Note: *Each* has not exactly the same semantics as *each* as it always returns a list and expects a list of lists. While it works at a different nesting level, it does what you want. It can even be implemented to do away with the extra brackets, which turns it into a "special case list flatterer": > function circle(R,N) = > EachSC([ for (w = [0:round(360/N):359]) > (w<90)? [R*cos(w),R*sin(w)]: > (w<180)? [R*cos(w),R*sin(w)]: > (w==180)? > [[R*cos(w),R*sin(w)],[R*cos(w)+1,R*sin(w)],[R*cos(w)+1,R*sin(w)+1],[R*cos(w),R*sin(w)+1]]: > (w<270)? [R*cos(w),R*sin(w)]: > [R*cos(w),R*sin(w)] > ]); > > function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j]; -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19068.html Sent from the OpenSCAD mailing list archive at Nabble.com.
RP
Ronaldo Persiano
Sun, Nov 13, 2016 2:37 PM

Are you sure this is what you want?

echo(EachSC([[2,3],1,[4,5],[[6,7],[8,9]]]));
echo(EachSC([1,[2,3],[4,5],[[6,7],[8,9]]]));
echo(EachSC([[[6,7],[8,9]],1,[2,3],[4,5]]));
//ECHO: [[2, 3], [2, 3], 1, [4, 5], [4, 5], [6, 7], [8, 9]]
//ECHO: [1, [2, 3], [2, 3], [4, 5], [4, 5], [6, 7], [8, 9]]
//ECHO: [[6, 7], [8, 9], 1, [2, 3], [2, 3], [4, 5], [4, 5]]

2016-11-13 10:10 GMT-02:00 Parkinbot rudolf@parkinbot.com:

You have to download a recent dev snapshot (and alter the prefs there) to
be
able to use each and if/else in lc.

There is also a nice solution that works for elder versions of OpenSCAD not
supporting the new features:

function circle(R,N) =
Each([ for (w = [0:round(360/N):359])
(w<90)?    [[Rcos(w),Rsin(w)]]:
(w<180)?  [[Rcos(w),Rsin(w)]]:
(w==180)?
[[Rcos(w),Rsin(w)],[Rcos(w)+1,Rsin(w)],[Rcos(w)+1,R

sin(w)+1],[Rcos(w),Rsin(w)+1]]:

 (w<270)?   [[R*cos(w),R*sin(w)]]:
                  [[R*cos(w),R*sin(w)]]

]);

function Each(L) = [for(i=L, j=i) j];

Note: Each has not exactly the same semantics as each as it always
returns a list and expects a list of lists. While it works at a different
nesting level, it does what you want.

It can even be implemented to do away with the extra brackets, which turns
it into a "special case list flatterer":

function circle(R,N) =
EachSC([ for (w = [0:round(360/N):359])
(w<90)?    [Rcos(w),Rsin(w)]:
(w<180)?  [Rcos(w),Rsin(w)]:
(w==180)?
[[Rcos(w),Rsin(w)],[Rcos(w)+1,Rsin(w)],[Rcos(w)+1,R

sin(w)+1],[Rcos(w),Rsin(w)+1]]:

 (w<270)?   [R*cos(w),R*sin(w)]:
                  [R*cos(w),R*sin(w)]

]);

function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j];

--
View this message in context: http://forum.openscad.org/
dynamic-FOR-statement-tp19053p19068.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Are you sure this is what you want? echo(EachSC([[2,3],1,[4,5],[[6,7],[8,9]]])); echo(EachSC([1,[2,3],[4,5],[[6,7],[8,9]]])); echo(EachSC([[[6,7],[8,9]],1,[2,3],[4,5]])); //ECHO: [[2, 3], [2, 3], 1, [4, 5], [4, 5], [6, 7], [8, 9]] //ECHO: [1, [2, 3], [2, 3], [4, 5], [4, 5], [6, 7], [8, 9]] //ECHO: [[6, 7], [8, 9], 1, [2, 3], [2, 3], [4, 5], [4, 5]] 2016-11-13 10:10 GMT-02:00 Parkinbot <rudolf@parkinbot.com>: > You have to download a recent dev snapshot (and alter the prefs there) to > be > able to use *each* and *if/else* in lc. > > There is also a nice solution that works for elder versions of OpenSCAD not > supporting the new features: > > > > function circle(R,N) = > > Each([ for (w = [0:round(360/N):359]) > > (w<90)? [[R*cos(w),R*sin(w)]]: > > (w<180)? [[R*cos(w),R*sin(w)]]: > > (w==180)? > > [[R*cos(w),R*sin(w)],[R*cos(w)+1,R*sin(w)],[R*cos(w)+1,R* > sin(w)+1],[R*cos(w),R*sin(w)+1]]: > > (w<270)? [[R*cos(w),R*sin(w)]]: > > [[R*cos(w),R*sin(w)]] > > ]); > > > > function Each(L) = [for(i=L, j=i) j]; > > Note: *Each* has not exactly the same semantics as *each* as it always > returns a list and expects a list of lists. While it works at a different > nesting level, it does what you want. > > It can even be implemented to do away with the extra brackets, which turns > it into a "special case list flatterer": > > > function circle(R,N) = > > EachSC([ for (w = [0:round(360/N):359]) > > (w<90)? [R*cos(w),R*sin(w)]: > > (w<180)? [R*cos(w),R*sin(w)]: > > (w==180)? > > [[R*cos(w),R*sin(w)],[R*cos(w)+1,R*sin(w)],[R*cos(w)+1,R* > sin(w)+1],[R*cos(w),R*sin(w)+1]]: > > (w<270)? [R*cos(w),R*sin(w)]: > > [R*cos(w),R*sin(w)] > > ]); > > > > function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j]; > > > > > > > > -- > View this message in context: http://forum.openscad.org/ > dynamic-FOR-statement-tp19053p19068.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
P
Parkinbot
Sun, Nov 13, 2016 3:10 PM

Ronaldo, it was an answer to one of the questions the thread was started with

  • and not a general purpose solution for replacing each to deal with
    wildly nested structures.

Parkinbot wrote

It can even be implemented to do away with the extra brackets,

which turns it into a "special case list flatterer"

:

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19070.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo, it was an answer to one of the questions the thread was started with - and not a general purpose solution for replacing *each* to deal with wildly nested structures. Parkinbot wrote > It can even be implemented to do away with the extra brackets, * > which turns it into a "special case list flatterer" * > : -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19070.html Sent from the OpenSCAD mailing list archive at Nabble.com.
RP
Ronaldo Persiano
Sun, Nov 13, 2016 7:12 PM

2016-11-13 13:10 GMT-02:00 Parkinbot rudolf@parkinbot.com:

Ronaldo, it was an answer to one of the questions the thread was started
with

  • and not a general purpose solution for replacing each to deal with
    wildly nested structures.

I have understood that. However, I don't think, however, that repetitions
were intended.

function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j];

function EachSC2(L) = [for(i=L, j = (i[0][0]!= undef? i:[i])) j];

L = [1,[2,2],[3,3,3], [[4,4,4],[5,5,5]],[6]];

echo(EachSC=EachSC(L));
echo(EachSC2=EachSC2(L));
//ECHO: EachSC = [1, [2, 2], [2, 2], [3, 3, 3], [3, 3, 3], [3, 3, 3], [4,
4, 4], [5, 5, 5], [6]]
//ECHO: EachSC2 = [1, [2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6]]

2016-11-13 13:10 GMT-02:00 Parkinbot <rudolf@parkinbot.com>: > Ronaldo, it was an answer to one of the questions the thread was started > with > - and not a general purpose solution for replacing *each* to deal with > wildly nested structures. > I have understood that. However, I don't think, however, that repetitions were intended. function EachSC(L) = [for(i=L, j=i) i[0][0]== undef?i:j]; function EachSC2(L) = [for(i=L, j = (i[0][0]!= undef? i:[i])) j]; L = [1,[2,2],[3,3,3], [[4,4,4],[5,5,5]],[6]]; echo(EachSC=EachSC(L)); echo(EachSC2=EachSC2(L)); //ECHO: EachSC = [1, [2, 2], [2, 2], [3, 3, 3], [3, 3, 3], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6]] //ECHO: EachSC2 = [1, [2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5], [6]]
JJ
Johan Jonker
Sun, Nov 13, 2016 9:50 PM

I installed the snapshot version and activated the options.
Now I have all the suggested improvements working.
Also interesting to see how people like parkinbot manage to do the same with
the standard version.
Thanks for helping me.

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19080.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I installed the snapshot version and activated the options. Now I have all the suggested improvements working. Also interesting to see how people like parkinbot manage to do the same with the standard version. Thanks for helping me. -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19080.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Sun, Nov 13, 2016 10:18 PM

Ronaldo, all your example data structures are not wellformed according to the
discussed semantics. You also wouldn't call polygon() with it, or get an
error, because you are not allowed to feed a structure that is not a vector
of 2D points.

Back to the initial question of Johan: In the release version of OpenSCAD it
is no so easy to return more than one list element per cycle in a for-loop
(unless you use a pattern employing a second loop variable plus some
filters). So, if you want to return more than one element within a specific
cycle, you might get the idea to pack those elements into a sub-list and
later use a function for unpacking. This is the pattern my code example
shows.

Say, the overall aim is to get a 2D point list for polygon(). Each()
expects all elements being packed into sublists forcing you to write all
those extra bracket pairs for all cases in the orginal for loop.
If you don't wanna do this for single 2D points, you can  write a
/specialized function/ like EachSC() that will test for nested list
elements and flatten only them.

Rudolf

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19082.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo, all your example data structures are not wellformed according to the discussed semantics. You also wouldn't call *polygon()* with it, or get an error, because you are not allowed to feed a structure that is not a vector of 2D points. Back to the initial question of Johan: In the release version of OpenSCAD it is no so easy to return more than one list element per cycle in a *for*-loop (unless you use a pattern employing a second loop variable plus some filters). So, if you want to return more than one element within a specific cycle, you might get the idea to pack those elements into a sub-list and later use a function for unpacking. This is the pattern my code example shows. Say, the overall aim is to get a 2D point list for *polygon()*. *Each()* expects all elements being packed into sublists forcing you to write all those extra bracket pairs for all cases in the orginal *for* loop. If you don't wanna do this for single 2D points, you can write a /specialized function/ like *EachSC()* that will test for nested list elements and flatten only them. Rudolf -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19082.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Mon, Nov 14, 2016 3:00 AM

Sorry, Rudolf. My examples were unfortunate and overshadow my main point. As
far I understand your proposal for Johan's question, the output of the
EachSC function for the the input list

[ [1,1], [2,2], [ [3,3], [4,4] ], [5,5] ]

should be

[ [1,1], [2,2], [3,3], [4,4] , [5,5] ]

However, its output is

[ [1, 1], [1, 1], [2, 2], [2, 2], [3, 3], [4, 4], [5, 5], [5, 5] ]

The function EachSC2 follows your concept and does what you intended.

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19091.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Sorry, Rudolf. My examples were unfortunate and overshadow my main point. As far I understand your proposal for Johan's question, the output of the EachSC function for the the input list [ [1,1], [2,2], [ [3,3], [4,4] ], [5,5] ] should be [ [1,1], [2,2], [3,3], [4,4] , [5,5] ] However, its output is [ [1, 1], [1, 1], [2, 2], [2, 2], [3, 3], [4, 4], [5, 5], [5, 5] ] The function EachSC2 follows your concept and does what you intended. -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19091.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Mon, Nov 14, 2016 10:23 AM

Ronaldo, finally I got your point. Thanks for debugging the code. Didn't
spend much time on it for testing.

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19092.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo, finally I got your point. Thanks for debugging the code. Didn't spend much time on it for testing. -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19092.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Mon, Nov 14, 2016 10:50 AM

I just looked it up in my code base. I'm indeed using the following version,
which is more explicit, but clumsier.

function Each_(L) = Each([for(i=L) i[0][0]?i:[i]]);
function Each(L) = [for(i=L, j=i) j];
echo(Each_([ [1,1], [2,2], [ [3,3], [4,4] ], [5,5] ]));

--
View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19093.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I just looked it up in my code base. I'm indeed using the following version, which is more explicit, but clumsier. > function Each_(L) = Each([for(i=L) i[0][0]?i:[i]]); > function Each(L) = [for(i=L, j=i) j]; > echo(Each_([ [1,1], [2,2], [ [3,3], [4,4] ], [5,5] ])); -- View this message in context: http://forum.openscad.org/dynamic-FOR-statement-tp19053p19093.html Sent from the OpenSCAD mailing list archive at Nabble.com.