discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Vectors, Lists, and Strings

DS
Dan Shriver
Wed, Aug 29, 2018 6:50 PM

I'm having some issues with datatypes in OpenScad and wondering what the
best approach is.

I am recursively calling functions that return lists (or vectors) of tuples
such as: [[0,1], [5,3]] and trying to concatenate them together.  The
problem is that the nesting level increases.  What I want is one
list/vector of tuples and no subnesting.

I've tried some approaches to flattening the results but usually it ends up
getting rid of the tuples (which I want) and keeping the arbitrary nesting
above them (which I don't want).

The other thing I tried is to have the function return just the tuples (not
in a list) but that gives an error.

Could I take a string of tuples, concatenate them and do something to
transform it into a list of tuples?

I'm having some issues with datatypes in OpenScad and wondering what the best approach is. I am recursively calling functions that return lists (or vectors) of tuples such as: [[0,1], [5,3]] and trying to concatenate them together. The problem is that the nesting level increases. What I want is one list/vector of tuples and no subnesting. I've tried some approaches to flattening the results but usually it ends up getting rid of the tuples (which I want) and keeping the arbitrary nesting above them (which I don't want). The other thing I tried is to have the function return just the tuples (not in a list) but that gives an error. Could I take a string of tuples, concatenate them and do something to transform it into a list of tuples?
DM
doug moen
Wed, Aug 29, 2018 8:39 PM

Post the code that isn't working, and we will help you to fix it.

On 29 August 2018 at 14:50, Dan Shriver tabbydan@gmail.com wrote:

I'm having some issues with datatypes in OpenScad and wondering what the
best approach is.

I am recursively calling functions that return lists (or vectors) of
tuples such as: [[0,1], [5,3]] and trying to concatenate them together.
The problem is that the nesting level increases.  What I want is one
list/vector of tuples and no subnesting.

I've tried some approaches to flattening the results but usually it ends
up getting rid of the tuples (which I want) and keeping the arbitrary
nesting above them (which I don't want).

The other thing I tried is to have the function return just the tuples
(not in a list) but that gives an error.

Could I take a string of tuples, concatenate them and do something to
transform it into a list of tuples?


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

Post the code that isn't working, and we will help you to fix it. On 29 August 2018 at 14:50, Dan Shriver <tabbydan@gmail.com> wrote: > I'm having some issues with datatypes in OpenScad and wondering what the > best approach is. > > I am recursively calling functions that return lists (or vectors) of > tuples such as: [[0,1], [5,3]] and trying to concatenate them together. > The problem is that the nesting level increases. What I want is one > list/vector of tuples and no subnesting. > > I've tried some approaches to flattening the results but usually it ends > up getting rid of the tuples (which I want) and keeping the arbitrary > nesting above them (which I don't want). > > The other thing I tried is to have the function return just the tuples > (not in a list) but that gives an error. > > Could I take a string of tuples, concatenate them and do something to > transform it into a list of tuples? > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
DS
Dan Shriver
Wed, Aug 29, 2018 9:35 PM

Here is the code
If i use "flatten" on each one of the recursive calls I get all the depth
and none of the tuples.
Here I get both


// Echo expression and return it
function echoit(x) = echo(x) x;
//echo with label
function echoit2(x,y) = echo(x,y) y;

/*
function fixVector(vectorOfVectors) for(a = vectorOfVectors)a;
*/

function flatten(l) = [ for (a = l) for (b = a) b ] ;

//given nested lists of arbitrary levels, make it a list of points
function makePointList(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
makePointList(L,n+1, concat(res,[L[n]]))
: makePointList(L,n+1, makePointList(L[n],0,res));

function arcx(radius,startAngle,endAngle,pointsPerGeneration,i,offsetx=0) =
let ( span = endAngle - startAngle, step = span/pointsPerGeneration, angle
= startAngle + (step * i) ) radius * cos(angle) + offsetx;

function arcy(radius,startAngle,endAngle,pointsPerGeneration,i,offsety=0) =
let ( span = endAngle - startAngle, step = span/pointsPerGeneration, angle
= startAngle + (step * i) ) radius * sin(angle) + offsety;

function loopArc(radius, number, generations, quadrant,
pointsPerGeneration, angle, direction, offsetx=0, offsety=0) =
(generations > 1) ?
(direction > 0) ? let(newQuadrant = (quadrant + 1) % 4,
startAngle = angle,
newRadius = (radius/2) * sin(atan(2/(number -1))),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = computeAngle(number, newQuadrant))
[ for (i = [0:pointsPerGeneration])
[arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(newy,radius,startAngle,endAngle,pointsPerGeneration, i, newy),
loopArc(newRadius, number, (generations-1),newQuadrant,
pointsPerGeneration,endAngle,1,newx,newy)]]

: let( newQuadrant = (quadrant + 3) % 4,
newRadius = (radius/2) * sin(atan(2/(number -1))),
startAngle = computeAngle(number, newQuadrant),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = angle)
[ for (i = [0:pointsPerGeneration]) [ loopArc(newRadius, number,
(generations-1),newQuadrant, pointsPerGeneration,endAngle,-1,newx,newy),
arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] :

(direction > 0) ? let(newQuadrant = (quadrant + 1) % 4,
startAngle = angle,
newRadius = (radius/2) * sin(atan(2/(number -1))),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = computeAngle(number, newQuadrant))
[ for (i = [0:pointsPerGeneration])
[arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]]

: let( newQuadrant = (quadrant + 3) % 4,
newRadius = (radius/2) * sin(atan(2/(number -1))),
startAngle = echoit2("startAngle via computeAngle
",computeAngle(number, newQuadrant)),
newx = echoit2("newx ",offsetx + (newRadius * (number -1))),
newy = echoit2("newy ",offsety + newRadius),
endAngle = echoit2("endAngle ",angle))
[ for (i = [0:pointsPerGeneration]) [
arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]]
;

//there is a list of values
//[quadrant - 1] peels off the
//value from the list for returning
function computeAngle(number, quadrant) =
let(baseAngle = atan(2/(number-1)))
[
baseAngle,
180 - baseAngle,
180 + baseAngle,
360 - baseAngle
][quadrant];

echo(computeAngle(4,1));

function nextQuadrant(quadrant) = (quadrant + 1) % 4;

//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) {

numPoints = pointsPerGeneration - 1;

laterQuadrant = nextQuadrant(quadrant);

earlierQuadrant = (quadrant + 3) % 4;

startAngle = computeAngle(number,quadrant);
endAngle = computeAngle(number,laterQuadrant);

echo("start angle ",startAngle," end angle ",endAngle," quadrant

",quadrant," next quadrant ", laterQuadrant," earlier quadrant
",earlierQuadrant);

newRadius = (radius/2) * sin(atan(2/(number-1)));

points = (generations > 1) ? [ for (i = [0:(numPoints)]) [
    loopArc(newRadius, number, (generations-1),earlierQuadrant,

numPoints,endAngle,-1), arcx(radius,startAngle,endAngle,numPoints, i),
arcy(radius,startAngle,endAngle,numPoints, i), loopArc(newRadius, number,
(generations-1),laterQuadrant, numPoints,endAngle,1)]] :
[ for (i = [0:(numPoints)]) [
arcx(radius,startAngle,endAngle,numPoints, i),
arcy(radius,startAngle,endAngle,numPoints, i)]]
;

echo("POINTS ARE: ",points);

//poly = makePointList(points);

//poly = flatten(points);

echo("*****************POLY IS: ",poly);


difference() {
  offset(0.01) polygon(poly);
  polygon(poly);
  }

//make the nested lists into one flat list

/*    poly = makePointList(points);

echo(poly);

difference() {
  offset(0.01) polygon(poly);
  polygon(poly);
  }
*/

}

bCurve(30,2,2,0,10);

On Wed, Aug 29, 2018 at 4:39 PM doug moen doug@moens.org wrote:

Post the code that isn't working, and we will help you to fix it.

On 29 August 2018 at 14:50, Dan Shriver tabbydan@gmail.com wrote:

I'm having some issues with datatypes in OpenScad and wondering what the
best approach is.

I am recursively calling functions that return lists (or vectors) of
tuples such as: [[0,1], [5,3]] and trying to concatenate them together.
The problem is that the nesting level increases.  What I want is one
list/vector of tuples and no subnesting.

I've tried some approaches to flattening the results but usually it ends
up getting rid of the tuples (which I want) and keeping the arbitrary
nesting above them (which I don't want).

The other thing I tried is to have the function return just the tuples
(not in a list) but that gives an error.

Could I take a string of tuples, concatenate them and do something to
transform it into a list of tuples?


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

Here is the code If i use "flatten" on each one of the recursive calls I get all the depth and none of the tuples. Here I get both -------------------- // Echo expression and return it function echoit(x) = echo(x) x; //echo with label function echoit2(x,y) = echo(x,y) y; /* function fixVector(vectorOfVectors) for(a = vectorOfVectors)a; */ function flatten(l) = [ for (a = l) for (b = a) b ] ; //given nested lists of arbitrary levels, make it a list of points function makePointList(L,n=0,res=[]) = n>=len(L) ? res : L[n]*0==[0,0] ? makePointList(L,n+1, concat(res,[L[n]])) : makePointList(L,n+1, makePointList(L[n],0,res)); function arcx(radius,startAngle,endAngle,pointsPerGeneration,i,offsetx=0) = let ( span = endAngle - startAngle, step = span/pointsPerGeneration, angle = startAngle + (step * i) ) radius * cos(angle) + offsetx; function arcy(radius,startAngle,endAngle,pointsPerGeneration,i,offsety=0) = let ( span = endAngle - startAngle, step = span/pointsPerGeneration, angle = startAngle + (step * i) ) radius * sin(angle) + offsety; function loopArc(radius, number, generations, quadrant, pointsPerGeneration, angle, direction, offsetx=0, offsety=0) = (generations > 1) ? (direction > 0) ? let(newQuadrant = (quadrant + 1) % 4, startAngle = angle, newRadius = (radius/2) * sin(atan(2/(number -1))), newx = offsetx + (newRadius * (number -1)), newy = offsety + newRadius, endAngle = computeAngle(number, newQuadrant)) [ for (i = [0:pointsPerGeneration]) [arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), arcy(newy,radius,startAngle,endAngle,pointsPerGeneration, i, newy), loopArc(newRadius, number, (generations-1),newQuadrant, pointsPerGeneration,endAngle,1,newx,newy)]] : let( newQuadrant = (quadrant + 3) % 4, newRadius = (radius/2) * sin(atan(2/(number -1))), startAngle = computeAngle(number, newQuadrant), newx = offsetx + (newRadius * (number -1)), newy = offsety + newRadius, endAngle = angle) [ for (i = [0:pointsPerGeneration]) [ loopArc(newRadius, number, (generations-1),newQuadrant, pointsPerGeneration,endAngle,-1,newx,newy), arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] : (direction > 0) ? let(newQuadrant = (quadrant + 1) % 4, startAngle = angle, newRadius = (radius/2) * sin(atan(2/(number -1))), newx = offsetx + (newRadius * (number -1)), newy = offsety + newRadius, endAngle = computeAngle(number, newQuadrant)) [ for (i = [0:pointsPerGeneration]) [arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] : let( newQuadrant = (quadrant + 3) % 4, newRadius = (radius/2) * sin(atan(2/(number -1))), startAngle = echoit2("startAngle via computeAngle ",computeAngle(number, newQuadrant)), newx = echoit2("newx ",offsetx + (newRadius * (number -1))), newy = echoit2("newy ",offsety + newRadius), endAngle = echoit2("endAngle ",angle)) [ for (i = [0:pointsPerGeneration]) [ arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] ; //there is a list of values //[quadrant - 1] peels off the //value from the list for returning function computeAngle(number, quadrant) = let(baseAngle = atan(2/(number-1))) [ baseAngle, 180 - baseAngle, 180 + baseAngle, 360 - baseAngle ][quadrant]; echo(computeAngle(4,1)); function nextQuadrant(quadrant) = (quadrant + 1) % 4; //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) { numPoints = pointsPerGeneration - 1; laterQuadrant = nextQuadrant(quadrant); earlierQuadrant = (quadrant + 3) % 4; startAngle = computeAngle(number,quadrant); endAngle = computeAngle(number,laterQuadrant); echo("start angle ",startAngle," end angle ",endAngle," quadrant ",quadrant," next quadrant ", laterQuadrant," earlier quadrant ",earlierQuadrant); newRadius = (radius/2) * sin(atan(2/(number-1))); points = (generations > 1) ? [ for (i = [0:(numPoints)]) [ loopArc(newRadius, number, (generations-1),earlierQuadrant, numPoints,endAngle,-1), arcx(radius,startAngle,endAngle,numPoints, i), arcy(radius,startAngle,endAngle,numPoints, i), loopArc(newRadius, number, (generations-1),laterQuadrant, numPoints,endAngle,1)]] : [ for (i = [0:(numPoints)]) [ arcx(radius,startAngle,endAngle,numPoints, i), arcy(radius,startAngle,endAngle,numPoints, i)]] ; echo("POINTS ARE: ",points); //poly = makePointList(points); //poly = flatten(points); echo("*****************POLY IS: ",poly); difference() { offset(0.01) polygon(poly); polygon(poly); } //make the nested lists into one flat list /* poly = makePointList(points); echo(poly); difference() { offset(0.01) polygon(poly); polygon(poly); } */ } bCurve(30,2,2,0,10); On Wed, Aug 29, 2018 at 4:39 PM doug moen <doug@moens.org> wrote: > Post the code that isn't working, and we will help you to fix it. > > On 29 August 2018 at 14:50, Dan Shriver <tabbydan@gmail.com> wrote: > >> I'm having some issues with datatypes in OpenScad and wondering what the >> best approach is. >> >> I am recursively calling functions that return lists (or vectors) of >> tuples such as: [[0,1], [5,3]] and trying to concatenate them together. >> The problem is that the nesting level increases. What I want is one >> list/vector of tuples and no subnesting. >> >> I've tried some approaches to flattening the results but usually it ends >> up getting rid of the tuples (which I want) and keeping the arbitrary >> nesting above them (which I don't want). >> >> The other thing I tried is to have the function return just the tuples >> (not in a list) but that gives an error. >> >> Could I take a string of tuples, concatenate them and do something to >> transform it into a list of tuples? >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
RP
Ronaldo Persiano
Wed, Aug 29, 2018 11:45 PM

If I have understood well the question of your first message, the
function makePointList is the only concern here.

Depending what your input vector is, makePointList may be a correct
solution. It does work for nested lists of 2D points but it fails if
something else appears in the input list.

a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
echo(makePointList(a));
// ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ]

b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
echo(makePointList(b));
// Recursion stack overflow

c = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]];
echo(makePointList(c));
// Recursion stack overflow

The other thing I tried is to have the function return just the tuples (not

in a list) but that gives an error.

AFAIK, there is no way to represent tuples in OpenSCAD other than lists.
The function fixVector will give a sintax error.

Em qua, 29 de ago de 2018 às 22:36, Dan Shriver tabbydan@gmail.com
escreveu:

Here is the code
If i use "flatten" on each one of the recursive calls I get all the depth
and none of the tuples.
Here I get both


// Echo expression and return it
function echoit(x) = echo(x) x;
//echo with label
function echoit2(x,y) = echo(x,y) y;

/*
function fixVector(vectorOfVectors) for(a = vectorOfVectors)a;
*/

function flatten(l) = [ for (a = l) for (b = a) b ] ;

//given nested lists of arbitrary levels, make it a list of points
function makePointList(L,n=0,res=[]) =
n>=len(L) ?
res
: L[n]*0==[0,0] ?
makePointList(L,n+1, concat(res,[L[n]]))
: makePointList(L,n+1, makePointList(L[n],0,res));

function arcx(radius,startAngle,endAngle,pointsPerGeneration,i,offsetx=0)
= let ( span = endAngle - startAngle, step = span/pointsPerGeneration,
angle = startAngle + (step * i) ) radius * cos(angle) + offsetx;

function arcy(radius,startAngle,endAngle,pointsPerGeneration,i,offsety=0)
= let ( span = endAngle - startAngle, step = span/pointsPerGeneration,
angle = startAngle + (step * i) ) radius * sin(angle) + offsety;

function loopArc(radius, number, generations, quadrant,
pointsPerGeneration, angle, direction, offsetx=0, offsety=0) =
(generations > 1) ?
(direction > 0) ? let(newQuadrant = (quadrant + 1) % 4,
startAngle = angle,
newRadius = (radius/2) * sin(atan(2/(number -1))),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = computeAngle(number, newQuadrant))
[ for (i = [0:pointsPerGeneration])
[arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(newy,radius,startAngle,endAngle,pointsPerGeneration, i, newy),
loopArc(newRadius, number, (generations-1),newQuadrant,
pointsPerGeneration,endAngle,1,newx,newy)]]

: let( newQuadrant = (quadrant + 3) % 4,
newRadius = (radius/2) * sin(atan(2/(number -1))),
startAngle = computeAngle(number, newQuadrant),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = angle)
[ for (i = [0:pointsPerGeneration]) [ loopArc(newRadius, number,
(generations-1),newQuadrant, pointsPerGeneration,endAngle,-1,newx,newy),
arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] :

(direction > 0) ? let(newQuadrant = (quadrant + 1) % 4,
startAngle = angle,
newRadius = (radius/2) * sin(atan(2/(number -1))),
newx = offsetx + (newRadius * (number -1)),
newy = offsety + newRadius,
endAngle = computeAngle(number, newQuadrant))
[ for (i = [0:pointsPerGeneration])
[arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]]

: let( newQuadrant = (quadrant + 3) % 4,
newRadius = (radius/2) * sin(atan(2/(number -1))),
startAngle = echoit2("startAngle via computeAngle
",computeAngle(number, newQuadrant)),
newx = echoit2("newx ",offsetx + (newRadius * (number -1))),
newy = echoit2("newy ",offsety + newRadius),
endAngle = echoit2("endAngle ",angle))
[ for (i = [0:pointsPerGeneration]) [
arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx),
arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]]
;

//there is a list of values
//[quadrant - 1] peels off the
//value from the list for returning
function computeAngle(number, quadrant) =
let(baseAngle = atan(2/(number-1)))
[
baseAngle,
180 - baseAngle,
180 + baseAngle,
360 - baseAngle
][quadrant];

echo(computeAngle(4,1));

function nextQuadrant(quadrant) = (quadrant + 1) % 4;

//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) {

 numPoints = pointsPerGeneration - 1;

 laterQuadrant = nextQuadrant(quadrant);

 earlierQuadrant = (quadrant + 3) % 4;

 startAngle = computeAngle(number,quadrant);
 endAngle = computeAngle(number,laterQuadrant);

 echo("start angle ",startAngle," end angle ",endAngle," quadrant

",quadrant," next quadrant ", laterQuadrant," earlier quadrant
",earlierQuadrant);

 newRadius = (radius/2) * sin(atan(2/(number-1)));

 points = (generations > 1) ? [ for (i = [0:(numPoints)]) [
     loopArc(newRadius, number, (generations-1),earlierQuadrant,

numPoints,endAngle,-1), arcx(radius,startAngle,endAngle,numPoints, i),
arcy(radius,startAngle,endAngle,numPoints, i), loopArc(newRadius, number,
(generations-1),laterQuadrant, numPoints,endAngle,1)]] :
[ for (i = [0:(numPoints)]) [
arcx(radius,startAngle,endAngle,numPoints, i),
arcy(radius,startAngle,endAngle,numPoints, i)]]
;

 echo("POINTS ARE: ",points);

 //poly = makePointList(points);

 //poly = flatten(points);

 echo("*****************POLY IS: ",poly);


 difference() {
   offset(0.01) polygon(poly);
   polygon(poly);
   }

 //make the nested lists into one flat list

/*    poly = makePointList(points);

 echo(poly);

 difference() {
   offset(0.01) polygon(poly);
   polygon(poly);
   }
 */

}

bCurve(30,2,2,0,10);

On Wed, Aug 29, 2018 at 4:39 PM doug moen doug@moens.org wrote:

Post the code that isn't working, and we will help you to fix it.

On 29 August 2018 at 14:50, Dan Shriver tabbydan@gmail.com wrote:

I'm having some issues with datatypes in OpenScad and wondering what the
best approach is.

I am recursively calling functions that return lists (or vectors) of
tuples such as: [[0,1], [5,3]] and trying to concatenate them together.
The problem is that the nesting level increases.  What I want is one
list/vector of tuples and no subnesting.

I've tried some approaches to flattening the results but usually it ends
up getting rid of the tuples (which I want) and keeping the arbitrary
nesting above them (which I don't want).

The other thing I tried is to have the function return just the tuples
(not in a list) but that gives an error.

Could I take a string of tuples, concatenate them and do something to
transform it into a list of tuples?


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

If I have understood well the question of your first message, the function makePointList is the only concern here. Depending what your input vector is, makePointList may be a correct solution. It does work for nested lists of 2D points but it fails if something else appears in the input list. a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; echo(makePointList(a)); // ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ] b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; echo(makePointList(b)); // Recursion stack overflow c = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]]; echo(makePointList(c)); // Recursion stack overflow The other thing I tried is to have the function return just the tuples (not > in a list) but that gives an error. AFAIK, there is no way to represent tuples in OpenSCAD other than lists. The function fixVector will give a sintax error. Em qua, 29 de ago de 2018 às 22:36, Dan Shriver <tabbydan@gmail.com> escreveu: > Here is the code > If i use "flatten" on each one of the recursive calls I get all the depth > and none of the tuples. > Here I get both > > -------------------- > // Echo expression and return it > function echoit(x) = echo(x) x; > //echo with label > function echoit2(x,y) = echo(x,y) y; > > /* > function fixVector(vectorOfVectors) for(a = vectorOfVectors)a; > */ > > function flatten(l) = [ for (a = l) for (b = a) b ] ; > > //given nested lists of arbitrary levels, make it a list of points > function makePointList(L,n=0,res=[]) = > n>=len(L) ? > res > : L[n]*0==[0,0] ? > makePointList(L,n+1, concat(res,[L[n]])) > : makePointList(L,n+1, makePointList(L[n],0,res)); > > function arcx(radius,startAngle,endAngle,pointsPerGeneration,i,offsetx=0) > = let ( span = endAngle - startAngle, step = span/pointsPerGeneration, > angle = startAngle + (step * i) ) radius * cos(angle) + offsetx; > > function arcy(radius,startAngle,endAngle,pointsPerGeneration,i,offsety=0) > = let ( span = endAngle - startAngle, step = span/pointsPerGeneration, > angle = startAngle + (step * i) ) radius * sin(angle) + offsety; > > function loopArc(radius, number, generations, quadrant, > pointsPerGeneration, angle, direction, offsetx=0, offsety=0) = > (generations > 1) ? > (direction > 0) ? let(newQuadrant = (quadrant + 1) % 4, > startAngle = angle, > newRadius = (radius/2) * sin(atan(2/(number -1))), > newx = offsetx + (newRadius * (number -1)), > newy = offsety + newRadius, > endAngle = computeAngle(number, newQuadrant)) > [ for (i = [0:pointsPerGeneration]) > [arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), > arcy(newy,radius,startAngle,endAngle,pointsPerGeneration, i, newy), > loopArc(newRadius, number, (generations-1),newQuadrant, > pointsPerGeneration,endAngle,1,newx,newy)]] > > : let( newQuadrant = (quadrant + 3) % 4, > newRadius = (radius/2) * sin(atan(2/(number -1))), > startAngle = computeAngle(number, newQuadrant), > newx = offsetx + (newRadius * (number -1)), > newy = offsety + newRadius, > endAngle = angle) > [ for (i = [0:pointsPerGeneration]) [ loopArc(newRadius, number, > (generations-1),newQuadrant, pointsPerGeneration,endAngle,-1,newx,newy), > arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), > arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] : > > (direction > 0) ? let(newQuadrant = (quadrant + 1) % 4, > startAngle = angle, > newRadius = (radius/2) * sin(atan(2/(number -1))), > newx = offsetx + (newRadius * (number -1)), > newy = offsety + newRadius, > endAngle = computeAngle(number, newQuadrant)) > [ for (i = [0:pointsPerGeneration]) > [arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), > arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] > > : let( newQuadrant = (quadrant + 3) % 4, > newRadius = (radius/2) * sin(atan(2/(number -1))), > startAngle = echoit2("startAngle via computeAngle > ",computeAngle(number, newQuadrant)), > newx = echoit2("newx ",offsetx + (newRadius * (number -1))), > newy = echoit2("newy ",offsety + newRadius), > endAngle = echoit2("endAngle ",angle)) > [ for (i = [0:pointsPerGeneration]) [ > arcx(radius,startAngle,endAngle,pointsPerGeneration, i, newx), > arcy(radius,startAngle,endAngle,pointsPerGeneration, i, newy)]] > ; > > > //there is a list of values > //[quadrant - 1] peels off the > //value from the list for returning > function computeAngle(number, quadrant) = > let(baseAngle = atan(2/(number-1))) > [ > baseAngle, > 180 - baseAngle, > 180 + baseAngle, > 360 - baseAngle > ][quadrant]; > > echo(computeAngle(4,1)); > > function nextQuadrant(quadrant) = (quadrant + 1) % 4; > > > //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) { > > numPoints = pointsPerGeneration - 1; > > laterQuadrant = nextQuadrant(quadrant); > > earlierQuadrant = (quadrant + 3) % 4; > > startAngle = computeAngle(number,quadrant); > endAngle = computeAngle(number,laterQuadrant); > > echo("start angle ",startAngle," end angle ",endAngle," quadrant > ",quadrant," next quadrant ", laterQuadrant," earlier quadrant > ",earlierQuadrant); > > newRadius = (radius/2) * sin(atan(2/(number-1))); > > points = (generations > 1) ? [ for (i = [0:(numPoints)]) [ > loopArc(newRadius, number, (generations-1),earlierQuadrant, > numPoints,endAngle,-1), arcx(radius,startAngle,endAngle,numPoints, i), > arcy(radius,startAngle,endAngle,numPoints, i), loopArc(newRadius, number, > (generations-1),laterQuadrant, numPoints,endAngle,1)]] : > [ for (i = [0:(numPoints)]) [ > arcx(radius,startAngle,endAngle,numPoints, i), > arcy(radius,startAngle,endAngle,numPoints, i)]] > ; > > echo("POINTS ARE: ",points); > > //poly = makePointList(points); > > //poly = flatten(points); > > echo("*****************POLY IS: ",poly); > > > difference() { > offset(0.01) polygon(poly); > polygon(poly); > } > > //make the nested lists into one flat list > /* poly = makePointList(points); > > echo(poly); > > difference() { > offset(0.01) polygon(poly); > polygon(poly); > } > */ > } > > > bCurve(30,2,2,0,10); > > On Wed, Aug 29, 2018 at 4:39 PM doug moen <doug@moens.org> wrote: > >> Post the code that isn't working, and we will help you to fix it. >> >> On 29 August 2018 at 14:50, Dan Shriver <tabbydan@gmail.com> wrote: >> >>> I'm having some issues with datatypes in OpenScad and wondering what the >>> best approach is. >>> >>> I am recursively calling functions that return lists (or vectors) of >>> tuples such as: [[0,1], [5,3]] and trying to concatenate them together. >>> The problem is that the nesting level increases. What I want is one >>> list/vector of tuples and no subnesting. >>> >>> I've tried some approaches to flattening the results but usually it ends >>> up getting rid of the tuples (which I want) and keeping the arbitrary >>> nesting above them (which I don't want). >>> >>> The other thing I tried is to have the function return just the tuples >>> (not in a list) but that gives an error. >>> >>> Could I take a string of tuples, concatenate them and do something to >>> transform it into a list of tuples? >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
T
TLC123
Thu, Aug 30, 2018 4:13 PM

I'd do it like this:
ECHO: 1, [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]]
ECHO: true
ECHO: false
ECHO: false
ECHO: true
ECHO: [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]]
ECHO: [[1, 0, 0], [1, 1, 1], [1, 2, 2]]
ECHO: [[1, 1, 1], [1, 2, 1]]

effectively filtering out anything not your vertex type

a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
echo(1,makePointListvec2(a));
echo(ismytypevec2([1,1]));
echo(ismytypevec2([1,1,1]));
echo(ismytypevec3([1,1]));
echo(ismytypevec3([1,1,1]));
// ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ]

//
//b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
//echo(makePointListvec2(b));
// Recursion stack overflow

c0 = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]];
echo(makePointListvec2(c0));
c1 = [[1,0,0],[1,1,1],[[1,2,2]], [1,0, [2,3],[[3,4]]]];
echo(makePointListvec3(c1));
c2 = [[0,0],[1,1,1],[[1,2,1]], [0, [2,3],[[3,4]]]];
echo(makePointListvec3(c2));

function makePointListvec2(a,c=0,result=[])= c<len(a) ?
makePointListvec2(a,c+1,concat(result,ismytypevec2(a[c])?[a[c]]:
makePointListvec2(a[c],0,[]) ) ) :result;
function ismytypevec2(d)= len(d)==2&&len(d[0])==undef&&len(d[1])==undef

;

function makePointListvec3(a,c=0,result=[])= c<len(a) ?
makePointListvec3(a,c+1,concat(result,ismytypevec3(a[c])?[a[c]]:
makePointListvec3(a[c],0,[]) ) ) :result;
function ismytypevec3(d)=

len(d)==3&&len(d[0])==undef&&len(d[1])==undef&&len(d[2])==undef ;

--
Sent from: http://forum.openscad.org/

I'd do it like this: ECHO: 1, [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]] ECHO: true ECHO: false ECHO: false ECHO: true ECHO: [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]] ECHO: [[1, 0, 0], [1, 1, 1], [1, 2, 2]] ECHO: [[1, 1, 1], [1, 2, 1]] effectively filtering out anything not your vertex type a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; echo(1,makePointListvec2(a)); echo(ismytypevec2([1,1])); echo(ismytypevec2([1,1,1])); echo(ismytypevec3([1,1])); echo(ismytypevec3([1,1,1])); // ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ] // //b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; //echo(makePointListvec2(b)); // Recursion stack overflow c0 = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]]; echo(makePointListvec2(c0)); c1 = [[1,0,0],[1,1,1],[[1,2,2]], [1,0, [2,3],[[3,4]]]]; echo(makePointListvec3(c1)); c2 = [[0,0],[1,1,1],[[1,2,1]], [0, [2,3],[[3,4]]]]; echo(makePointListvec3(c2)); function makePointListvec2(a,c=0,result=[])= c<len(a) ? makePointListvec2(a,c+1,concat(result,ismytypevec2(a[c])?[a[c]]: makePointListvec2(a[c],0,[]) ) ) :result; function ismytypevec2(d)= len(d)==2&&len(d[0])==undef&&len(d[1])==undef ; function makePointListvec3(a,c=0,result=[])= c<len(a) ? makePointListvec3(a,c+1,concat(result,ismytypevec3(a[c])?[a[c]]: makePointListvec3(a[c],0,[]) ) ) :result; function ismytypevec3(d)= len(d)==3&&len(d[0])==undef&&len(d[1])==undef&&len(d[2])==undef ; -- Sent from: http://forum.openscad.org/
DS
Dan Shriver
Thu, Aug 30, 2018 5:05 PM

Ronaldo was right: The problem was some "naked" (no "[]") tuples.  When I
corrected that makePointList() worked.

Unfortunately, if I have generations > 1 I get lots of tuples with one
coordinate being a tiny number (-5.32907e-015) either that is throwing off
drawing the polygon or my points are in the wrong order.

On Thu, Aug 30, 2018 at 12:13 PM TLC123 torleif.ceder@gmail.com wrote:

I'd do it like this:
ECHO: 1, [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]]
ECHO: true
ECHO: false
ECHO: false
ECHO: true
ECHO: [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]]
ECHO: [[1, 0, 0], [1, 1, 1], [1, 2, 2]]
ECHO: [[1, 1, 1], [1, 2, 1]]

effectively filtering out anything not your vertex type

 a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
 echo(1,makePointListvec2(a));
 echo(ismytypevec2([1,1]));
 echo(ismytypevec2([1,1,1]));
 echo(ismytypevec3([1,1]));
 echo(ismytypevec3([1,1,1]));
 // ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ]

 //
 //b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]];
 //echo(makePointListvec2(b));
 // Recursion stack overflow

 c0 = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]];
 echo(makePointListvec2(c0));
 c1 = [[1,0,0],[1,1,1],[[1,2,2]], [1,0, [2,3],[[3,4]]]];
 echo(makePointListvec3(c1));
 c2 = [[0,0],[1,1,1],[[1,2,1]], [0, [2,3],[[3,4]]]];
 echo(makePointListvec3(c2));

 function makePointListvec2(a,c=0,result=[])= c<len(a) ?
 makePointListvec2(a,c+1,concat(result,ismytypevec2(a[c])?[a[c]]:
 makePointListvec2(a[c],0,[]) ) ) :result;
 function ismytypevec2(d)= len(d)==2&&len(d[0])==undef&&len(d[1])==undef

;

 function makePointListvec3(a,c=0,result=[])= c<len(a) ?
 makePointListvec3(a,c+1,concat(result,ismytypevec3(a[c])?[a[c]]:
 makePointListvec3(a[c],0,[]) ) ) :result;
 function ismytypevec3(d)=

len(d)==3&&len(d[0])==undef&&len(d[1])==undef&&len(d[2])==undef ;

--
Sent from: http://forum.openscad.org/


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

Ronaldo was right: The problem was some "naked" (no "[]") tuples. When I corrected that makePointList() worked. Unfortunately, if I have generations > 1 I get lots of tuples with one coordinate being a tiny number (-5.32907e-015) either that is throwing off drawing the polygon or my points are in the wrong order. On Thu, Aug 30, 2018 at 12:13 PM TLC123 <torleif.ceder@gmail.com> wrote: > I'd do it like this: > ECHO: 1, [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]] > ECHO: true > ECHO: false > ECHO: false > ECHO: true > ECHO: [[0, 0], [1, 1], [1, 2], [2, 3], [3, 4]] > ECHO: [[1, 0, 0], [1, 1, 1], [1, 2, 2]] > ECHO: [[1, 1, 1], [1, 2, 1]] > > effectively filtering out anything not your vertex type > > > > > > > a = [[0,0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; > echo(1,makePointListvec2(a)); > echo(ismytypevec2([1,1])); > echo(ismytypevec2([1,1,1])); > echo(ismytypevec3([1,1])); > echo(ismytypevec3([1,1,1])); > // ECHO : [ [0,0], [1,1], [1,2], [2,3],[[3,4] ] > > // > //b = [["x",0],[1,1],[[1,2]], [[2,3],[[3,4]]]]; > //echo(makePointListvec2(b)); > // Recursion stack overflow > > c0 = [[0,0],[1,1],[[1,2]], [0, [2,3],[[3,4]]]]; > echo(makePointListvec2(c0)); > c1 = [[1,0,0],[1,1,1],[[1,2,2]], [1,0, [2,3],[[3,4]]]]; > echo(makePointListvec3(c1)); > c2 = [[0,0],[1,1,1],[[1,2,1]], [0, [2,3],[[3,4]]]]; > echo(makePointListvec3(c2)); > > function makePointListvec2(a,c=0,result=[])= c<len(a) ? > makePointListvec2(a,c+1,concat(result,ismytypevec2(a[c])?[a[c]]: > makePointListvec2(a[c],0,[]) ) ) :result; > function ismytypevec2(d)= len(d)==2&&len(d[0])==undef&&len(d[1])==undef > ; > > > function makePointListvec3(a,c=0,result=[])= c<len(a) ? > makePointListvec3(a,c+1,concat(result,ismytypevec3(a[c])?[a[c]]: > makePointListvec3(a[c],0,[]) ) ) :result; > function ismytypevec3(d)= > len(d)==3&&len(d[0])==undef&&len(d[1])==undef&&len(d[2])==undef ; > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >