DS
Dan Shriver
Thu, Feb 8, 2018 8:14 PM
I'm going to attach some code (only look at it if you need it to get an
idea of what I am trying to do, I am sure there are bugs plus I didn't copy
any of the helper functions...).
I am having trouble figuring out how to deal with recursion on something I
am drawing. My problems are:
-
a Module can't return anything, correct? At the same time I don't see
how to (in a Function) do a lot of code setup, call helper functions, etc.
I guess I could setup a variable in a Function with "let" but how do I do a
block of code with conditionals etc. I would either like to return a list
of points from a Module, or figure out how to do "real work" (helper calls,
conditionals, etc) from a Function
-
If I have something that generates a list of points, assuming I
recursively call that how do I elegantly keep the list one dimensional (not
nested lists). Do I just a call to some flatten function at the end?
Ideally I'd like not to generate nested lists to begin with, but I'm having
a little trouble seeing how to do that?
Basically, what I am doing below is what I call a "bat curve" because I
imagine it will look slightly like the stylized bats in traditional Chinese
art (somewhat, not exactly, I can go into differences later, I don't need
it to look exactly like that and am just using that as a convenient
description). The shape is going to be a fractal of arcs of increasingly
smaller circles (generations determines how many levels deep the fractal
goes). Basically one large arc subdivides on both sides into a spiral of
increasingly smaller radii arcs. You could think of a letter D where the
straight line is removed and at both ends of the D there is a spiral.
module bCurve2(radius, number, generations, quadrant, pointsPerGeneration,
direction, angle) {
if (direction > 0) {
newQuadrant = (quadrant + 1) % 4;
startAngle = angle;
endAngle = computeAngle(number, newQuadrant);
}
else {
newQuadrant = (quadrant + 3) % 4;
startAngle = computeAngle(number, newQuadrant);
endAngle = angle;
}
}
//quadrant is the graph quadrant for the next circle except it is C indexed
so it is 0 - 3 rather than 1 - 4
module bCurve(radius, number, generations, quadrant, pointsPerGeneration) {
if (generations > -1) {
angle1 = computeAngle(number, quadrant);
angle2 = computeAngle(number, nextQuadrant(quadrant));
span = angle1 - angle2;
stepSize = span/pointsPerGeneration;
newRadius = radius * sin(atan(2/(number-1)));
quadrantA = (quadrant + 3)%4;
quadrantB = (quadrant + 2) %4;
points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
bCurve2(newRadius, number, (generations -1), quadrantB,
pointsPerGeneration, 1, angle2) ];
difference() {
offset(0.01) polygon(points);
polygon(points);
}
}
}
I'm going to attach some code (only look at it if you need it to get an
idea of what I am trying to do, I am sure there are bugs plus I didn't copy
any of the helper functions...).
I am having trouble figuring out how to deal with recursion on something I
am drawing. My problems are:
1) a Module can't return anything, correct? At the same time I don't see
how to (in a Function) do a lot of code setup, call helper functions, etc.
I guess I could setup a variable in a Function with "let" but how do I do a
block of code with conditionals etc. I would either like to return a list
of points from a Module, or figure out how to do "real work" (helper calls,
conditionals, etc) from a Function
2) If I have something that generates a list of points, assuming I
recursively call that how do I elegantly keep the list one dimensional (not
nested lists). Do I just a call to some flatten function at the end?
Ideally I'd like not to generate nested lists to begin with, but I'm having
a little trouble seeing how to do that?
Basically, what I am doing below is what I call a "bat curve" because I
imagine it will look slightly like the stylized bats in traditional Chinese
art (somewhat, not exactly, I can go into differences later, I don't need
it to look exactly like that and am just using that as a convenient
description). The shape is going to be a fractal of arcs of increasingly
smaller circles (generations determines how many levels deep the fractal
goes). Basically one large arc subdivides on both sides into a spiral of
increasingly smaller radii arcs. You could think of a letter D where the
straight line is removed and at both ends of the D there is a spiral.
------------------------
module bCurve2(radius, number, generations, quadrant, pointsPerGeneration,
direction, angle) {
if (direction > 0) {
newQuadrant = (quadrant + 1) % 4;
startAngle = angle;
endAngle = computeAngle(number, newQuadrant);
}
else {
newQuadrant = (quadrant + 3) % 4;
startAngle = computeAngle(number, newQuadrant);
endAngle = angle;
}
}
//quadrant is the graph quadrant for the next circle except it is C indexed
so it is 0 - 3 rather than 1 - 4
module bCurve(radius, number, generations, quadrant, pointsPerGeneration) {
if (generations > -1) {
angle1 = computeAngle(number, quadrant);
angle2 = computeAngle(number, nextQuadrant(quadrant));
span = angle1 - angle2;
stepSize = span/pointsPerGeneration;
newRadius = radius * sin(atan(2/(number-1)));
quadrantA = (quadrant + 3)%4;
quadrantB = (quadrant + 2) %4;
points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
bCurve2(newRadius, number, (generations -1), quadrantB,
pointsPerGeneration, 1, angle2) ];
difference() {
offset(0.01) polygon(points);
polygon(points);
}
}
}
FV
Frank van der Hulst
Thu, Feb 8, 2018 10:17 PM
- A module "returns" an object... whatever object is generated by a
module is its return "value". So you could return a polygon created from a
list of points, for example, by having a polygon ([list]) statement at the
end of the module.
You can use the ternary operator to do if-then-else evaluations in a let()
call in a function. And a function can call other functions.
- The concat () function flattens multiple lists into a single list.
On Friday, February 9, 2018, Dan Shriver tabbydan@gmail.com wrote:
I'm going to attach some code (only look at it if you need it to get an
idea of what I am trying to do, I am sure there are bugs plus I didn't copy
any of the helper functions...).
I am having trouble figuring out how to deal with recursion on something I
am drawing. My problems are:
-
a Module can't return anything, correct? At the same time I don't see
how to (in a Function) do a lot of code setup, call helper functions, etc.
I guess I could setup a variable in a Function with "let" but how do I do a
block of code with conditionals etc. I would either like to return a list
of points from a Module, or figure out how to do "real work" (helper calls,
conditionals, etc) from a Function
-
If I have something that generates a list of points, assuming I
recursively call that how do I elegantly keep the list one dimensional (not
nested lists). Do I just a call to some flatten function at the end?
Ideally I'd like not to generate nested lists to begin with, but I'm having
a little trouble seeing how to do that?
Basically, what I am doing below is what I call a "bat curve" because I
imagine it will look slightly like the stylized bats in traditional Chinese
art (somewhat, not exactly, I can go into differences later, I don't need
it to look exactly like that and am just using that as a convenient
description). The shape is going to be a fractal of arcs of increasingly
smaller circles (generations determines how many levels deep the fractal
goes). Basically one large arc subdivides on both sides into a spiral of
increasingly smaller radii arcs. You could think of a letter D where the
straight line is removed and at both ends of the D there is a spiral.
module bCurve2(radius, number, generations, quadrant, pointsPerGeneration,
direction, angle) {
if (direction > 0) {
newQuadrant = (quadrant + 1) % 4;
startAngle = angle;
endAngle = computeAngle(number, newQuadrant);
}
else {
newQuadrant = (quadrant + 3) % 4;
startAngle = computeAngle(number, newQuadrant);
endAngle = angle;
}
}
//quadrant is the graph quadrant for the next circle except it is C
indexed so it is 0 - 3 rather than 1 - 4
module bCurve(radius, number, generations, quadrant, pointsPerGeneration) {
if (generations > -1) {
angle1 = computeAngle(number, quadrant);
angle2 = computeAngle(number, nextQuadrant(quadrant));
span = angle1 - angle2;
stepSize = span/pointsPerGeneration;
newRadius = radius * sin(atan(2/(number-1)));
quadrantA = (quadrant + 3)%4;
quadrantB = (quadrant + 2) %4;
points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
bCurve2(newRadius, number, (generations -1), quadrantB,
pointsPerGeneration, 1, angle2) ];
difference() {
offset(0.01) polygon(points);
polygon(points);
}
}
}
1) A module "returns" an object... whatever object is generated by a
module is its return "value". So you could return a polygon created from a
list of points, for example, by having a polygon ([list]) statement at the
end of the module.
You can use the ternary operator to do if-then-else evaluations in a let()
call in a function. And a function can call other functions.
2) The concat () function flattens multiple lists into a single list.
On Friday, February 9, 2018, Dan Shriver <tabbydan@gmail.com> wrote:
> I'm going to attach some code (only look at it if you need it to get an
> idea of what I am trying to do, I am sure there are bugs plus I didn't copy
> any of the helper functions...).
>
> I am having trouble figuring out how to deal with recursion on something I
> am drawing. My problems are:
>
> 1) a Module can't return anything, correct? At the same time I don't see
> how to (in a Function) do a lot of code setup, call helper functions, etc.
> I guess I could setup a variable in a Function with "let" but how do I do a
> block of code with conditionals etc. I would either like to return a list
> of points from a Module, or figure out how to do "real work" (helper calls,
> conditionals, etc) from a Function
>
> 2) If I have something that generates a list of points, assuming I
> recursively call that how do I elegantly keep the list one dimensional (not
> nested lists). Do I just a call to some flatten function at the end?
> Ideally I'd like not to generate nested lists to begin with, but I'm having
> a little trouble seeing how to do that?
>
> Basically, what I am doing below is what I call a "bat curve" because I
> imagine it will look slightly like the stylized bats in traditional Chinese
> art (somewhat, not exactly, I can go into differences later, I don't need
> it to look exactly like that and am just using that as a convenient
> description). The shape is going to be a fractal of arcs of increasingly
> smaller circles (generations determines how many levels deep the fractal
> goes). Basically one large arc subdivides on both sides into a spiral of
> increasingly smaller radii arcs. You could think of a letter D where the
> straight line is removed and at both ends of the D there is a spiral.
>
>
>
> ------------------------
> module bCurve2(radius, number, generations, quadrant, pointsPerGeneration,
> direction, angle) {
> if (direction > 0) {
> newQuadrant = (quadrant + 1) % 4;
> startAngle = angle;
> endAngle = computeAngle(number, newQuadrant);
> }
> else {
> newQuadrant = (quadrant + 3) % 4;
> startAngle = computeAngle(number, newQuadrant);
> endAngle = angle;
> }
> }
>
> //quadrant is the graph quadrant for the next circle except it is C
> indexed so it is 0 - 3 rather than 1 - 4
> module bCurve(radius, number, generations, quadrant, pointsPerGeneration) {
>
> if (generations > -1) {
> angle1 = computeAngle(number, quadrant);
> angle2 = computeAngle(number, nextQuadrant(quadrant));
>
> span = angle1 - angle2;
> stepSize = span/pointsPerGeneration;
> newRadius = radius * sin(atan(2/(number-1)));
>
> quadrantA = (quadrant + 3)%4;
> quadrantB = (quadrant + 2) %4;
>
> points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
> number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
> xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
> bCurve2(newRadius, number, (generations -1), quadrantB,
> pointsPerGeneration, 1, angle2) ];
>
> difference() {
> offset(0.01) polygon(points);
> polygon(points);
> }
> }
> }
>
DS
Dan Shriver
Fri, Feb 9, 2018 12:23 AM
on 2) the wiki book says that concat() does not change the levels, just
tacks one on to another. Because of recursion I will have a heterogeneous
list which has points and also members that are lists of points...
like this (ignore the values they are nonsense)
[ [ (4,7), (8,2), (7,8) ] (1,2), (5,10), (3,8) [ (11,21), (15,10), (3,18)
] ]
and I want to flatten it into a one dimensional list (not a list of
lists... which will have nested lists up to how many times I am recursing)
like this
[ (4,7), (8,2), (7,8) (1,2), (5,10), (3,8) (11,21), (15,10), (3,18) ]
On Thu, Feb 8, 2018 at 5:17 PM, Frank van der Hulst <drifter.frank@gmail.com
- A module "returns" an object... whatever object is generated by a
module is its return "value". So you could return a polygon created from a
list of points, for example, by having a polygon ([list]) statement at the
end of the module.
You can use the ternary operator to do if-then-else evaluations in a let()
call in a function. And a function can call other functions.
- The concat () function flattens multiple lists into a single list.
On Friday, February 9, 2018, Dan Shriver tabbydan@gmail.com wrote:
I'm going to attach some code (only look at it if you need it to get an
idea of what I am trying to do, I am sure there are bugs plus I didn't copy
any of the helper functions...).
I am having trouble figuring out how to deal with recursion on something
I am drawing. My problems are:
-
a Module can't return anything, correct? At the same time I don't see
how to (in a Function) do a lot of code setup, call helper functions, etc.
I guess I could setup a variable in a Function with "let" but how do I do a
block of code with conditionals etc. I would either like to return a list
of points from a Module, or figure out how to do "real work" (helper calls,
conditionals, etc) from a Function
-
If I have something that generates a list of points, assuming I
recursively call that how do I elegantly keep the list one dimensional (not
nested lists). Do I just a call to some flatten function at the end?
Ideally I'd like not to generate nested lists to begin with, but I'm having
a little trouble seeing how to do that?
Basically, what I am doing below is what I call a "bat curve" because I
imagine it will look slightly like the stylized bats in traditional Chinese
art (somewhat, not exactly, I can go into differences later, I don't need
it to look exactly like that and am just using that as a convenient
description). The shape is going to be a fractal of arcs of increasingly
smaller circles (generations determines how many levels deep the fractal
goes). Basically one large arc subdivides on both sides into a spiral of
increasingly smaller radii arcs. You could think of a letter D where the
straight line is removed and at both ends of the D there is a spiral.
module bCurve2(radius, number, generations, quadrant,
pointsPerGeneration, direction, angle) {
if (direction > 0) {
newQuadrant = (quadrant + 1) % 4;
startAngle = angle;
endAngle = computeAngle(number, newQuadrant);
}
else {
newQuadrant = (quadrant + 3) % 4;
startAngle = computeAngle(number, newQuadrant);
endAngle = angle;
}
}
//quadrant is the graph quadrant for the next circle except it is C
indexed so it is 0 - 3 rather than 1 - 4
module bCurve(radius, number, generations, quadrant, pointsPerGeneration)
{
if (generations > -1) {
angle1 = computeAngle(number, quadrant);
angle2 = computeAngle(number, nextQuadrant(quadrant));
span = angle1 - angle2;
stepSize = span/pointsPerGeneration;
newRadius = radius * sin(atan(2/(number-1)));
quadrantA = (quadrant + 3)%4;
quadrantB = (quadrant + 2) %4;
points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
bCurve2(newRadius, number, (generations -1), quadrantB,
pointsPerGeneration, 1, angle2) ];
difference() {
offset(0.01) polygon(points);
polygon(points);
}
}
}
on 2) the wiki book says that concat() does not change the levels, just
tacks one on to another. Because of recursion I will have a heterogeneous
list which has points and also members that are lists of points...
like this (ignore the values they are nonsense)
[ [ (4,7), (8,2), (7,8) ] (1,2), (5,10), (3,8) [ (11,21), (15,10), (3,18)
] ]
and I want to flatten it into a one dimensional list (not a list of
lists... which will have nested lists up to how many times I am recursing)
like this
[ (4,7), (8,2), (7,8) (1,2), (5,10), (3,8) (11,21), (15,10), (3,18) ]
On Thu, Feb 8, 2018 at 5:17 PM, Frank van der Hulst <drifter.frank@gmail.com
> wrote:
> 1) A module "returns" an object... whatever object is generated by a
> module is its return "value". So you could return a polygon created from a
> list of points, for example, by having a polygon ([list]) statement at the
> end of the module.
>
> You can use the ternary operator to do if-then-else evaluations in a let()
> call in a function. And a function can call other functions.
>
> 2) The concat () function flattens multiple lists into a single list.
>
> On Friday, February 9, 2018, Dan Shriver <tabbydan@gmail.com> wrote:
>
>> I'm going to attach some code (only look at it if you need it to get an
>> idea of what I am trying to do, I am sure there are bugs plus I didn't copy
>> any of the helper functions...).
>>
>> I am having trouble figuring out how to deal with recursion on something
>> I am drawing. My problems are:
>>
>> 1) a Module can't return anything, correct? At the same time I don't see
>> how to (in a Function) do a lot of code setup, call helper functions, etc.
>> I guess I could setup a variable in a Function with "let" but how do I do a
>> block of code with conditionals etc. I would either like to return a list
>> of points from a Module, or figure out how to do "real work" (helper calls,
>> conditionals, etc) from a Function
>>
>> 2) If I have something that generates a list of points, assuming I
>> recursively call that how do I elegantly keep the list one dimensional (not
>> nested lists). Do I just a call to some flatten function at the end?
>> Ideally I'd like not to generate nested lists to begin with, but I'm having
>> a little trouble seeing how to do that?
>>
>> Basically, what I am doing below is what I call a "bat curve" because I
>> imagine it will look slightly like the stylized bats in traditional Chinese
>> art (somewhat, not exactly, I can go into differences later, I don't need
>> it to look exactly like that and am just using that as a convenient
>> description). The shape is going to be a fractal of arcs of increasingly
>> smaller circles (generations determines how many levels deep the fractal
>> goes). Basically one large arc subdivides on both sides into a spiral of
>> increasingly smaller radii arcs. You could think of a letter D where the
>> straight line is removed and at both ends of the D there is a spiral.
>>
>>
>>
>> ------------------------
>> module bCurve2(radius, number, generations, quadrant,
>> pointsPerGeneration, direction, angle) {
>> if (direction > 0) {
>> newQuadrant = (quadrant + 1) % 4;
>> startAngle = angle;
>> endAngle = computeAngle(number, newQuadrant);
>> }
>> else {
>> newQuadrant = (quadrant + 3) % 4;
>> startAngle = computeAngle(number, newQuadrant);
>> endAngle = angle;
>> }
>> }
>>
>> //quadrant is the graph quadrant for the next circle except it is C
>> indexed so it is 0 - 3 rather than 1 - 4
>> module bCurve(radius, number, generations, quadrant, pointsPerGeneration)
>> {
>>
>> if (generations > -1) {
>> angle1 = computeAngle(number, quadrant);
>> angle2 = computeAngle(number, nextQuadrant(quadrant));
>>
>> span = angle1 - angle2;
>> stepSize = span/pointsPerGeneration;
>> newRadius = radius * sin(atan(2/(number-1)));
>>
>> quadrantA = (quadrant + 3)%4;
>> quadrantB = (quadrant + 2) %4;
>>
>> points = [ for (i = [0:pointsPerGeneration]) [ bCurve2(newRadius,
>> number, (generations -1), quadrantA, pointsPerGeneration, -1, angle1),
>> xArc(radius, angle1, stepSize, i), yArc(radius, angle1, stepSize, i)],
>> bCurve2(newRadius, number, (generations -1), quadrantB,
>> pointsPerGeneration, 1, angle2) ];
>>
>> difference() {
>> offset(0.01) polygon(points);
>> polygon(points);
>> }
>> }
>> }
>>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
TP
Torsten Paul
Fri, Feb 9, 2018 12:29 AM
The simplest way to do single level flatten is shown in
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/List_Comprehensions#Flattening_a_nested_vector
ciao,
Torsten.
RP
Ronaldo Persiano
Fri, Feb 9, 2018 1:40 AM
If you want to collect all 2D points in a list, whatever depth it has in
it, this may help you:
function get_2D_points(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
get_2D_points(L,n+1, concat(res,[L[n]]))
: get_2D_points(L,n+1, get_2D_points(L[n],0,res));
l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
However, this function crashes if the list is not a nested list of 2D
points like [[1,2], 3] or [1,2,3].or ["a"], etc.
2018-02-08 22:23 GMT-02:00 Dan Shriver tabbydan@gmail.com:
on 2) the wiki book says that concat() does not change the levels, just
tacks one on to another. Because of recursion I will have a heterogeneous
list which has points and also members that are lists of points...
like this (ignore the values they are nonsense)
[ [ (4,7), (8,2), (7,8) ] (1,2), (5,10), (3,8) [ (11,21), (15,10), (3,18)
] ]
and I want to flatten it into a one dimensional list (not a list of
lists... which will have nested lists up to how many times I am recursing)
like this
[ (4,7), (8,2), (7,8) (1,2), (5,10), (3,8) (11,21), (15,10), (3,18) ]
If you want to collect all 2D points in a list, whatever depth it has in
it, this may help you:
function get_2D_points(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
get_2D_points(L,n+1, concat(res,[L[n]]))
: get_2D_points(L,n+1, get_2D_points(L[n],0,res));
l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
However, this function crashes if the list is not a nested list of 2D
points like [[1,2], 3] or [1,2,3].or ["a"], etc.
2018-02-08 22:23 GMT-02:00 Dan Shriver <tabbydan@gmail.com>:
> on 2) the wiki book says that concat() does not change the levels, just
> tacks one on to another. Because of recursion I will have a heterogeneous
> list which has points and also members that are lists of points...
>
> like this (ignore the values they are nonsense)
>
> [ [ (4,7), (8,2), (7,8) ] (1,2), (5,10), (3,8) [ (11,21), (15,10), (3,18)
> ] ]
>
> and I want to flatten it into a one dimensional list (not a list of
> lists... which will have nested lists up to how many times I am recursing)
>
> like this
>
> [ (4,7), (8,2), (7,8) (1,2), (5,10), (3,8) (11,21), (15,10), (3,18) ]
>
>
>
RP
Ronaldo Persiano
Fri, Feb 9, 2018 1:59 AM
If your lists contain either 2D points or simple lists of 2D points, a
simpler non-recursive solution (by Parkinbot) is:
l = [[1,2],[[3,4]],[[5,6],[7,8]],[[9,10],[11,12],[13,14] ]];
function get_2D_points(L) = [for(a=L, v = (a[0][0]!=undef ? a: [a]) ) v ];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]]
2018-02-08 23:40 GMT-02:00 Ronaldo Persiano rcmpersiano@gmail.com:
If you want to collect all 2D points in a list, whatever depth it has in
it, this may help you:
function get_2D_points(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
get_2D_points(L,n+1, concat(res,[L[n]]))
: get_2D_points(L,n+1, get_2D_points(L[n],0,res));
l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
However, this function crashes if the list is not a nested list of 2D
points like [[1,2], 3] or [1,2,3].or ["a"], etc.
If your lists contain either 2D points or simple lists of 2D points, a
simpler non-recursive solution (by Parkinbot) is:
l = [[1,2],[[3,4]],[[5,6],[7,8]],[[9,10],[11,12],[13,14] ]];
function get_2D_points(L) = [for(a=L, v = (a[0][0]!=undef ? a: [a]) ) v ];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]]
2018-02-08 23:40 GMT-02:00 Ronaldo Persiano <rcmpersiano@gmail.com>:
> If you want to collect all 2D points in a list, whatever depth it has in
> it, this may help you:
>
> function get_2D_points(L,n=0,res=[]) =
> n>=len(L) ?
> res
> : L[n]*0==[0,0] ?
> get_2D_points(L,n+1, concat(res,[L[n]]))
> : get_2D_points(L,n+1, get_2D_points(L[n],0,res));
>
> l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
>
> echo( get_2D_points(l));
> // ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
>
>
> However, this function crashes if the list is not a nested list of 2D
> points like [[1,2], 3] or [1,2,3].or ["a"], etc.
>
>>
>>
NH
nop head
Fri, Feb 9, 2018 9:37 AM
One can also avoid extra nesting with the new keyword each. Here is an
example (a shortened version of Ronaldo's Bezier subdivision avoiding
concat)
function subdivBezier3(p, n=4) =
n<=0 ?
p
:
subdivBezier3( [p[0], for(i=[0:3:len(p)-4]) each _subdivB(p,i) ], n-1);
function _subdivB(p, from=0) =
[ //[1,0,0,0], // to avoid repetitions
[1/2, 1/2, 0, 0],
[1/4, 1/2, 1/4, 0],
[1/8, 3/8, 3/8, 1/8],
[0, 1/4, 1/2, 1/4],
[0, 0, 1/2, 1/2] ,
[0, 0, 0, 1] ]
* [p[from], p[from+1], p[from+2], p[from+3] ];
On 9 February 2018 at 01:59, Ronaldo Persiano rcmpersiano@gmail.com wrote:
If your lists contain either 2D points or simple lists of 2D points, a
simpler non-recursive solution (by Parkinbot) is:
l = [[1,2],[[3,4]],[[5,6],[7,8]],[[9,10],[11,12],[13,14] ]];
function get_2D_points(L) = [for(a=L, v = (a[0][0]!=undef ? a: [a]) ) v ];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]]
2018-02-08 23:40 GMT-02:00 Ronaldo Persiano rcmpersiano@gmail.com:
If you want to collect all 2D points in a list, whatever depth it has in
it, this may help you:
function get_2D_points(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
get_2D_points(L,n+1, concat(res,[L[n]]))
: get_2D_points(L,n+1, get_2D_points(L[n],0,res));
l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
echo( get_2D_points(l));
// ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
However, this function crashes if the list is not a nested list of 2D
points like [[1,2], 3] or [1,2,3].or ["a"], etc.
One can also avoid extra nesting with the new keyword each. Here is an
example (a shortened version of Ronaldo's Bezier subdivision avoiding
concat)
function subdivBezier3(p, n=4) =
n<=0 ?
p
:
subdivBezier3( [p[0], for(i=[0:3:len(p)-4]) each _subdivB(p,i) ], n-1);
function _subdivB(p, from=0) =
[ //[1,0,0,0], // to avoid repetitions
[1/2, 1/2, 0, 0],
[1/4, 1/2, 1/4, 0],
[1/8, 3/8, 3/8, 1/8],
[0, 1/4, 1/2, 1/4],
[0, 0, 1/2, 1/2] ,
[0, 0, 0, 1] ]
* [p[from], p[from+1], p[from+2], p[from+3] ];
On 9 February 2018 at 01:59, Ronaldo Persiano <rcmpersiano@gmail.com> wrote:
> If your lists contain either 2D points or simple lists of 2D points, a
> simpler non-recursive solution (by Parkinbot) is:
>
>
> l = [[1,2],[[3,4]],[[5,6],[7,8]],[[9,10],[11,12],[13,14] ]];
>
> function get_2D_points(L) = [for(a=L, v = (a[0][0]!=undef ? a: [a]) ) v ];
>
> echo( get_2D_points(l));
> // ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14]]
>
>
> 2018-02-08 23:40 GMT-02:00 Ronaldo Persiano <rcmpersiano@gmail.com>:
>
>> If you want to collect all 2D points in a list, whatever depth it has in
>> it, this may help you:
>>
>> function get_2D_points(L,n=0,res=[]) =
>> n>=len(L) ?
>> res
>> : L[n]*0==[0,0] ?
>> get_2D_points(L,n+1, concat(res,[L[n]]))
>> : get_2D_points(L,n+1, get_2D_points(L[n],0,res));
>>
>> l = [[1,2],[[3,4],[[5,6]]],[[[[7,8]],[9,10]]],[11,12]];
>>
>> echo( get_2D_points(l));
>> // ECHO: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
>>
>>
>> However, this function crashes if the list is not a nested list of 2D
>> points like [[1,2], 3] or [1,2,3].or ["a"], etc.
>>
>>>
>>>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>