discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

How to avoid the 'flatten' function

DM
doug moen
Wed, May 6, 2015 7:18 PM

Since we introduced list comprehensions, people have been using them to
generate arguments for polyhedron. But they've run into a problem where the
list is nested too deeply. So a convention of using the function 'flatten'
has arisen.

I've been thinking about different ways to eliminate the need for an
auxiliary flatten function, and I've come up with an idiom that works
today, without any language changes.

Here's the "before" code, using flatten (I forget the original author):

r = 10;
h = 20;
w = 2;
s = 2;
step = 4;
vertices = [for (a=[0:step:360]) [
[rcos(a), rsin(a), 0],
[rcos(a), rsin(a), h + ssin(a6)],
[(r-w)cos(a), (r-w)sin(a), h + ssin(a6)],
[(r-w)cos(a), (r-w)sin(a), 0]
]];
nv = 4
360/step;
indices = [for (a=[0:360/step]) [
[(4
a+0)%nv, (4a+1)%nv, (4a+5)%nv, (4a+4)%nv],
[(4
a+1)%nv, (4a+2)%nv, (4a+6)%nv, (4a+5)%nv],
[(4
a+2)%nv, (4a+3)%nv, (4a+7)%nv, (4a+6)%nv],
[(4
a+3)%nv, (4a+0)%nv, (4a+4)%nv, (4*a+7)%nv]]];
function flatten(list) = [ for (i = list, v = i) v ];
polyhedron(flatten(vertices), flatten(indices));

Now here is the "after" code, which eliminates the need for 'flatten'.

r = 10;
h = 20;
w = 2;
s = 2;
step = 4;
vertices = [
for (a=[0:step:360])
for (pt = [
[rcos(a), rsin(a), 0],
[rcos(a), rsin(a), h + ssin(a6)],
[(r-w)cos(a), (r-w)sin(a), h + ssin(a6)],
[(r-w)cos(a), (r-w)sin(a), 0]
]) pt
];
nv = 4
360/step;
indices = [
for (a=[0:360/step])
for (pt = [
[(4
a+0)%nv, (4a+1)%nv, (4a+5)%nv, (4a+4)%nv],
[(4
a+1)%nv, (4a+2)%nv, (4a+6)%nv, (4a+5)%nv],
[(4
a+2)%nv, (4a+3)%nv, (4a+7)%nv, (4a+6)%nv],
[(4
a+3)%nv, (4a+0)%nv, (4a+4)%nv, (4*a+7)%nv]
]) pt
];
polyhedron(vertices, indices);

I guess it is a matter of personal taste, but I hope some people find this
useful.

Since we introduced list comprehensions, people have been using them to generate arguments for polyhedron. But they've run into a problem where the list is nested too deeply. So a convention of using the function 'flatten' has arisen. I've been thinking about different ways to eliminate the need for an auxiliary flatten function, and I've come up with an idiom that works today, without any language changes. Here's the "before" code, using flatten (I forget the original author): r = 10; h = 20; w = 2; s = 2; step = 4; vertices = [for (a=[0:step:360]) [ [r*cos(a), r*sin(a), 0], [r*cos(a), r*sin(a), h + s*sin(a*6)], [(r-w)*cos(a), (r-w)*sin(a), h + s*sin(a*6)], [(r-w)*cos(a), (r-w)*sin(a), 0] ]]; nv = 4*360/step; indices = [for (a=[0:360/step]) [ [(4*a+0)%nv, (4*a+1)%nv, (4*a+5)%nv, (4*a+4)%nv], [(4*a+1)%nv, (4*a+2)%nv, (4*a+6)%nv, (4*a+5)%nv], [(4*a+2)%nv, (4*a+3)%nv, (4*a+7)%nv, (4*a+6)%nv], [(4*a+3)%nv, (4*a+0)%nv, (4*a+4)%nv, (4*a+7)%nv]]]; function flatten(list) = [ for (i = list, v = i) v ]; polyhedron(flatten(vertices), flatten(indices)); Now here is the "after" code, which eliminates the need for 'flatten'. r = 10; h = 20; w = 2; s = 2; step = 4; vertices = [ for (a=[0:step:360]) for (pt = [ [r*cos(a), r*sin(a), 0], [r*cos(a), r*sin(a), h + s*sin(a*6)], [(r-w)*cos(a), (r-w)*sin(a), h + s*sin(a*6)], [(r-w)*cos(a), (r-w)*sin(a), 0] ]) pt ]; nv = 4*360/step; indices = [ for (a=[0:360/step]) for (pt = [ [(4*a+0)%nv, (4*a+1)%nv, (4*a+5)%nv, (4*a+4)%nv], [(4*a+1)%nv, (4*a+2)%nv, (4*a+6)%nv, (4*a+5)%nv], [(4*a+2)%nv, (4*a+3)%nv, (4*a+7)%nv, (4*a+6)%nv], [(4*a+3)%nv, (4*a+0)%nv, (4*a+4)%nv, (4*a+7)%nv] ]) pt ]; polyhedron(vertices, indices); I guess it is a matter of personal taste, but I hope some people find this useful.