Vectors, Lists, and Strings

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Vectors, Lists, and Strings

DanS
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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Vectors, Lists, and Strings

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

On 29 August 2018 at 14:50, Dan Shriver <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Vectors, Lists, and Strings

DanS
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Vectors, Lists, and Strings

Ronaldo
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Vectors, Lists, and Strings

TLC123
In reply to this post by DanS
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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Vectors, Lists, and Strings

DanS
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 <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org