concat() for vectors

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

concat() for vectors

tp3
As this is quite an easy building block for lots of functionality, I've created a simple version that has not much impact on the language. I think that can help to bridge the time until the behavior and syntax of the more complex list comprehension stuff is discussed and decided (see https://github.com/openscad/openscad/pull/579).

Example:

function p(angle) = angle < 360 ? concat([[20 * sin(angle), 20 * cos(angle)]], p(angle + 45)) : [];
polygon(points = p(0));

Some examples from the test cases:

echo(concat([3, 4, "5", 6], "test"));			// ECHO: [3, 4, "5", 6, "test"]
echo(concat([3, 4, true, 6], [4:1:3]));			// ECHO: [3, 4, true, 6, [4 : 1 : 3]]

echo(concat(3, []));					// ECHO: [3]
echo(concat(3, [3, 4]));				// ECHO: [3, 3, 4]
echo(concat(true, [3, [4]]));				// ECHO: [true, 3, [4]]
echo(concat("9", [1, 2, 3]));				// ECHO: ["9", 1, 2, 3]
echo(concat([6:2:9], [3, [4]]));			// ECHO: [[6 : 2 : 9], 3, [4]]

echo(concat([[1, 0, 0], [2, 0, 0]], [3, 0, 0]));	// ECHO: [[1, 0, 0], [2, 0, 0], 3, 0, 0]
echo(concat([[1, 0, 0], [2, 0, 0]], [[3, 0, 0]]));	// ECHO: [[1, 0, 0], [2, 0, 0], [3, 0, 0]]

Note the difference between the last 2 examples. All vectors passed to
the function lose one nesting level. When adding something like single
element [x, y, z] tuples (which are actually vectors too), the tuples need
to be enclosed in a vector before the concatenation (see also the
function p() example at the top).
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

MichaelAtOz
Administrator
Yaaah! Xmas presents :)

Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

David Eccles (gringer)
In reply to this post by tp3
> As this is quite an easy building block for lots of functionality, I've
> created a simple version that has not much impact on the language.

Wonderful, thanks. Time to bring out the recursive functions:

make_next_point(old_points,points_remaining){
  if(points_remaining == 0){
    old_points;
  } else {
    make_next_point(concat(old_points, new_point_function()),
points_remaining-1);
  }
}

... or something like that.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

nophead
Yes but with function syntax and the ? operator.



On 28 December 2013 12:32, David Eccles (gringer) <[hidden email]> wrote:
> As this is quite an easy building block for lots of functionality, I've
> created a simple version that has not much impact on the language.

Wonderful, thanks. Time to bring out the recursive functions:

make_next_point(old_points,points_remaining){
  if(points_remaining == 0){
    old_points;
  } else {
    make_next_point(concat(old_points, new_point_function()),
points_remaining-1);
  }
}

... or something like that.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
tp3
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

tp3
nop head wrote
Yes but with function syntax and the ? operator.
Indeed, that makes it much more concise when not over-used ;). Just as the example shown:

function p(angle) = angle < 360   ?   concat([[20 * sin(angle), 20 * cos(angle)]], p(angle + 45))   :   [];

echo(p(0));

==> ECHO: [[0, 20], [14.1421, 14.1421], [20, 1.22465e-15], [14.1421, -14.1421], [2.44929e-15, -20], [-14.1421, -14.1421], [-20, -3.67394e-15], [-14.1421, 14.1421]]
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

kintel
Administrator
In reply to this post by tp3
A small note about concat():

It’s a simple addition to OpenSCAD, but the syntax isn’t, yet, set in stone.
It would be awesome if people could play around with concat() to figure out if it addresses their needs, and if not, what is missing.

If people are interested, we could merge it as experimental into master and build development snapshots..

 -Marius

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

nophead
In reply to this post by tp3
It would be clearer and more concise with an operator. E.g.

function p(angle) = angle < 360   ?   [[20 * sin(angle), 20 * cos(angle)]]  &  p(angle + 45)   :   [];

Incidentally, why are we getting rounding errors for sin(180), etc. Calculators working in degrees can get this exactly 0.


On 28 December 2013 17:12, tp3 <[hidden email]> wrote:
nop head wrote
> Yes but with function syntax and the ? operator.

Indeed, that makes it much more concise when not over-used ;). Just as the
example shown:

function p(angle) = angle < 360   ?   concat([[20 * sin(angle), 20 *
cos(angle)]], p(angle + 45))   :   [];

echo(p(0));

==> ECHO: [[0, 20], [14.1421, 14.1421], [20, 1.22465e-15], [14.1421,
-14.1421], [2.44929e-15, -20], [-14.1421, -14.1421], [-20, -3.67394e-15],
[-14.1421, 14.1421]]




--
View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p6355.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
tp3
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

tp3
nop head wrote
It would be clearer and more concise with an operator. E.g.

function p(angle) = angle < 360   ?   [[20 * sin(angle), 20 * cos(angle)]]
&  p(angle + 45)   :   [];
Yup (not liking the & too much but i guess it's used already for this type of operations), but maybe that one should then also behave a bit differently?

e.g:
vector & element -> add element to vector
vector & vector -> add the 2nd vector as element to the vector

(that would remove the need for double quoting the argument as in concat() where i think the current behavior makes sense)

Also it might be an error to use & with something not a vector on the left side? But then we might need reverse(vector) as only adding is possible...
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

nophead
I disagree. The operator should concatenate two lists, just the same as the function. The reason for double brackets is that in the example it is a list of coordinates, which are two element lists.

I think with just this addition you can do things like reverse and slicing, etc with recursive functions.  In fact, I think it transforms Openscad so it can do anything.


On 28 December 2013 20:51, tp3 <[hidden email]> wrote:
nop head wrote
> It would be clearer and more concise with an operator. E.g.
>
> function p(angle) = angle < 360   ?   [[20 * sin(angle), 20 * cos(angle)]]
> &  p(angle + 45)   :   [];

Yup (not liking the & too much but i guess it's used already for this type
of operations), but maybe that one should then also behave a bit
differently?

e.g:
vector & element -> add element to vector
vector & vector -> add the 2nd vector as element to the vector

(that would remove the need for double quoting the argument as in concat()
where i think the current behavior makes sense)

Also it might be an error to use & with something not a vector on the left
side? But then we might need reverse(vector) as only adding is possible...




--
View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p6358.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

MichaelAtOz
Administrator
What he said!

With it anything can be done, but, how efficient is the list processing involved?
Presumably not optimised like LISP.

Also, (just linking things)
https://github.com/openscad/openscad/issues/201?source=cc
https://github.com/openscad/openscad/wiki/List-and-Array-operations (suggests '~')
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
tp3
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

tp3
True, it's possible to probably implement almost everything using recursive functions then (as the wiki page already suggests). I still think OpenSCAD should provide such features in a more obvious way (could be a scad script too of cause).
Maybe i can try some speed comparison between maybe a recursive reverse(list) in scad and one implemented as builtin.

I know how to implement those recursive functions as I have quite some years background as software developer. But I think that OpenSCAD can easily target non-programmers due to the declarative nature it uses for most things. So having at least some library to help this target audience would be a great addition, i think.

I've checked how to do it with an operator and that's actually easy too. Both "&" and "~" are not yet used as far as I can see. It's just a matter of definition which way to go. So toss in your vote to help the maintainers decide :). I'll can change the patch if something else than the concat() it currently has is chosen.

-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

nophead
Well & has the natural meaning of "and" so has some relation to concatenation, i.e. join this and this. On the other hand ~ looks like a minus so is normally used for negation.




On 29 December 2013 17:18, tp3 <[hidden email]> wrote:
True, it's possible to probably implement almost everything using recursive
functions then (as the wiki page already suggests). I still think OpenSCAD
should provide such features in a more obvious way (could be a scad script
too of cause).
Maybe i can try some speed comparison between maybe a recursive
reverse(list) in scad and one implemented as builtin.

I know how to implement those recursive functions as I have quite some years
background as software developer. But I think that OpenSCAD can easily
target non-programmers due to the declarative nature it uses for most
things. So having at least some library to help this target audience would
be a great addition, i think.

I've checked how to do it with an operator and that's actually easy too.
Both "&" and "~" are not yet used as far as I can see. It's just a matter of
definition which way to go. So toss in your vote to help the maintainers
decide :). I'll can change the patch if something else than the concat() it
currently has is chosen.





--
View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p6365.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

Johan Kristensen
I've been using a "cat()" (or "concat()" as you call it) for a year now. It is truly a powerful addition to OpenSCAD. In my experience concatenation is often reserved for the case where two lists are concatenated and not when adding a scalar value to a list, however I can't, from the top of my head, see how this would cause ambiguity.

Regarding the question of function as opposed to a binary operator, I can't see any benefits of making it a operator. This would make the language syntax more complex and at the same time with certainty make a possible implementation more inefficient. A function can take more than two arguments and therefore handle more concatenations at the same time which should be more efficient than concatenating two vectors at a time.

regards
Johan


2013/12/29 nop head <[hidden email]>
Well & has the natural meaning of "and" so has some relation to concatenation, i.e. join this and this. On the other hand ~ looks like a minus so is normally used for negation.




On 29 December 2013 17:18, tp3 <[hidden email]> wrote:
True, it's possible to probably implement almost everything using recursive
functions then (as the wiki page already suggests). I still think OpenSCAD
should provide such features in a more obvious way (could be a scad script
too of cause).
Maybe i can try some speed comparison between maybe a recursive
reverse(list) in scad and one implemented as builtin.

I know how to implement those recursive functions as I have quite some years
background as software developer. But I think that OpenSCAD can easily
target non-programmers due to the declarative nature it uses for most
things. So having at least some library to help this target audience would
be a great addition, i think.

I've checked how to do it with an operator and that's actually easy too.
Both "&" and "~" are not yet used as far as I can see. It's just a matter of
definition which way to go. So toss in your vote to help the maintainers
decide :). I'll can change the patch if something else than the concat() it
currently has is chosen.





--
View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p6365.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

Chalmes
I keep hitting this thread when trying to find a good example of using concat for a particular task, which i've just figured out, so thought i'd post my example.

I was wanting to generate a polygon given a start point, and a vector of offset vectors.  I used the pseudo-code provided above and came up with this:
startPoint =  [  [0, 40] ];
polyOffsets = [  [10,0]    // 1
                ,[0, -5]   // 2
                ,[4.2,0]   // 3
                ,[0,-6]    // 4
                ,[-1.2,0]  // 5
                ,[0,-2]    // 6
                ,[1.2,0]   // 7
                ,[0,-5]    // 8
                ,[3.6,0]   // 9
                ,[0,5]     // 10
                ,[1.2,0]   // 11
                ,[0,2]     // 12
                ,[-1.2,0]  // 13
                ,[0,6]     // 14
                ,[14.4,0]  // 15
                ,[0,-6]    // 16
                ,[-1.2,0]  // 17
                ,[0,-2]    // 18
                ,[1.2,0]   // 19
                ,[0,-5]    // 20
                ,[3.6,0]   // 21
                ,[0,5]     // 22
                ,[1.2,0]   // 23
                ,[0,2]     // 24
                ,[-1.2,0]  // 25
                ,[0,6]     // 26
                ,[4.2,0]   // 27
                ,[0,5]     // 28
                ,[10,0]    // 29
                ,[0,-20]   // 30
                ,[-12,-20] // 31
                ,[-26,0]   // 31
                ,[-12,20]  // 33
];

// Generate our vector of point vectors based on our vector of offset vectors and the start point
calculatedPoints = addOffsets(startPoint, len(polyOffsets) + 1);

linear_extrude(height = 5, steps = 1) {
    polygon(points = calculatedPoints);
}


// Functions //

// Recursively add offset vectors to build up generated position vectors
function addOffsets(old_points, points_remaining) =  
  points_remaining == 1 ? old_points : 
    addOffsets(concat(old_points, [
        addVectors(
            old_points[len(old_points)-1],
            polyOffsets[len(polyOffsets)-points_remaining+1]
        )
    ]), points_remaining-1);


// Function added for clarity above
function addVectors(vec1, vec2) = vec1 + vec2;  
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

MichaelAtOz
Administrator
That's handy, thanks for sharing.

Note that using 'raw text' causes that bit to not go to the mailing list, just the forum, unless you tick the 'Message is in HTML Format' box. (bug with Nabble IMO)
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

MichaelAtOz
Administrator
In reply to this post by Chalmes
This is handy for debugging.

numeratePoints(calculatedPoints,every=2,start=1);

module numeratePoints(pointList,every=1,size=2,start=0) {
// every=2 gives even points
// every=2 & start=1 gives odd points
        for(i=[start:every:len(pointList)])
        translate([pointList[i].x,pointList[i].y,10])
                %text(str(i),size=size,halign="center",valign="center");
}

Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

Chalmes
Very cool, thanks for that.


-----Original Message-----
From: Discuss [mailto:[hidden email]] On Behalf Of MichaelAtOz
Sent: Tuesday, 1 September 2015 3:18 p.m.
To: [hidden email]
Subject: Re: [OpenSCAD] concat() for vectors

This is handy for debugging.

numeratePoints(calculatedPoints,every=2,start=1);

module numeratePoints(pointList,every=1,size=2,start=0) { // every=2 gives even points // every=2 & start=1 gives odd points
        for(i=[start:every:len(pointList)])
        translate([pointList[i].x,pointList[i].y,10])
                %text(str(i),size=size,halign="center",valign="center");
}





-----
Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :) Inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”   Fight it! http://www.ourfairdeal.org/
--
View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p13670.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
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: concat() for vectors

MichaelAtOz
Administrator
In reply to this post by MichaelAtOz
Oops that should be

len(pointList)-1

Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

MichaelAtOz
Administrator
In reply to this post by Chalmes
Hi Chalmes,

Do you have any particular licensing of you contribution? Or public domain?


Michael
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: concat() for vectors

Chalmes
Oh, public domain, free for all. Just use it already! :)

> On 2/09/2015, at 3:21 pm, MichaelAtOz <[hidden email]> wrote:
>
> Hi Chalmes,
>
> Do you have any particular licensing of you contribution? Or public domain?
>
>
> Michael
>
>
>
> -----
> Newly minted Admin - PM me if you need anything, or if I've done something stupid...
>
> Unless specifically shown otherwise above, my contribution is in the Public Domain; To the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. This work is published globally via the internet. :)  - Obviously inclusion of works of previous authors is not included in the above.
>
> The TPP is no simple “trade agreement.”   Fight it! http://www.ourfairdeal.org/   time is running out!
> --
> View this message in context: http://forum.openscad.org/concat-for-vectors-tp6348p13684.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> 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