discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Polygon using relative points rather than absolute?

D
droftarts
Tue, May 24, 2016 12:08 PM

I'm trying to draw a complex shape with the polygon tool, and find it would
be easier to build the correct shape if I could place each successive point
in the polygon referenced from the previous point, rather than the origin as
it normally is when using 'polygon'. This just makes resolving where each
point is easier, as it's just [+x,+y] from the previous point, rather than
having to add up all the previous points. However, as usual, how to actually
program this escapes me! For example, a simple shape would be:

points_absolute = [[0,0],[10,0],[15,10],[10,20],[0,20],[-5,10]];
polygon (points_absolute);

I'd like points to be:
points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]];

so that each subsequent point is calculated by adding up the proceeding
points.

I think there are a number of ways of doing this. Probably the easiest is to
iterate through the array, stepping through each point, and adding up the
proceeding points in a loop, and creating a new array with them added
together. I'm sure this is actually quite trivial, but I just can't quite
seem to get it right! Can anyone help?

Ian S

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I'm trying to draw a complex shape with the polygon tool, and find it would be easier to build the correct shape if I could place each successive point in the polygon referenced from the previous point, rather than the origin as it normally is when using 'polygon'. This just makes resolving where each point is easier, as it's just [+x,+y] from the previous point, rather than having to add up all the previous points. However, as usual, how to actually program this escapes me! For example, a simple shape would be: points_absolute = [[0,0],[10,0],[15,10],[10,20],[0,20],[-5,10]]; polygon (points_absolute); I'd like points to be: points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]]; so that each subsequent point is calculated by adding up the proceeding points. I think there are a number of ways of doing this. Probably the easiest is to iterate through the array, stepping through each point, and adding up the proceeding points in a loop, and creating a new array with them added together. I'm sure this is actually quite trivial, but I just can't quite seem to get it right! Can anyone help? Ian S -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Tue, May 24, 2016 12:39 PM

Not very efficient as O(n^2) but

points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]];

function sum_points(list, i) = i >= 0 ? list[i] + sum_points(list, i - 1) :
[0, 0];

function rel_to_abs(list) = [
for(i = [0 : len(list) - 1]) sum_points(list, i)
];

points_absolute = rel_to_abs(points_relative);
echo(points_absolute);

polygon(points_absolute);

On 24 May 2016 at 13:08, droftarts ginjaian@hotmail.com wrote:

I'm trying to draw a complex shape with the polygon tool, and find it would
be easier to build the correct shape if I could place each successive point
in the polygon referenced from the previous point, rather than the origin
as
it normally is when using 'polygon'. This just makes resolving where each
point is easier, as it's just [+x,+y] from the previous point, rather than
having to add up all the previous points. However, as usual, how to
actually
program this escapes me! For example, a simple shape would be:

points_absolute = [[0,0],[10,0],[15,10],[10,20],[0,20],[-5,10]];
polygon (points_absolute);

I'd like points to be:
points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]];

so that each subsequent point is calculated by adding up the proceeding
points.

I think there are a number of ways of doing this. Probably the easiest is
to
iterate through the array, stepping through each point, and adding up the
proceeding points in a loop, and creating a new array with them added
together. I'm sure this is actually quite trivial, but I just can't quite
seem to get it right! Can anyone help?

Ian S

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

Not very efficient as O(n^2) but points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]]; function sum_points(list, i) = i >= 0 ? list[i] + sum_points(list, i - 1) : [0, 0]; function rel_to_abs(list) = [ for(i = [0 : len(list) - 1]) sum_points(list, i) ]; points_absolute = rel_to_abs(points_relative); echo(points_absolute); polygon(points_absolute); On 24 May 2016 at 13:08, droftarts <ginjaian@hotmail.com> wrote: > I'm trying to draw a complex shape with the polygon tool, and find it would > be easier to build the correct shape if I could place each successive point > in the polygon referenced from the previous point, rather than the origin > as > it normally is when using 'polygon'. This just makes resolving where each > point is easier, as it's just [+x,+y] from the previous point, rather than > having to add up all the previous points. However, as usual, how to > actually > program this escapes me! For example, a simple shape would be: > > points_absolute = [[0,0],[10,0],[15,10],[10,20],[0,20],[-5,10]]; > polygon (points_absolute); > > I'd like points to be: > points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]]; > > so that each subsequent point is calculated by adding up the proceeding > points. > > I think there are a number of ways of doing this. Probably the easiest is > to > iterate through the array, stepping through each point, and adding up the > proceeding points in a loop, and creating a new array with them added > together. I'm sure this is actually quite trivial, but I just can't quite > seem to get it right! Can anyone help? > > Ian S > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
D
droftarts
Tue, May 24, 2016 12:57 PM

Damn, that was quick! It'll take me longer than that to work out what you
actually did... Thanks, nophead!

Ian S

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17416.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Damn, that was quick! It'll take me longer than that to work out what you actually did... Thanks, nophead! Ian S -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17416.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Tue, May 24, 2016 1:35 PM

nophead wrote

Not very efficient as O(n^2) but

Yeah, summing up things with OpenSCAD is not real fun.

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17417.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

nophead wrote > Not very efficient as O(n^2) but Yeah, summing up things with OpenSCAD is not real fun. -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17417.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Tue, May 24, 2016 2:25 PM

Here is a better version that should be O(n) and tail recursive, I think.
Perhaps easier to understand as well as it is more like a procedural loop.

points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]];

function rel_to_abs(list, i = 0, sum = [0,0], result = []) =
i == len(list) ? result : rel_to_abs(list, i + 1, sum + list[i],
concat(result, [sum + list[i]]));

points_absolute = rel_to_abs(points_relative);
echo(points_absolute);

polygon(points_absolute);

On 24 May 2016 at 14:35, Parkinbot rudolf@parkinbot.com wrote:

nophead wrote

Not very efficient as O(n^2) but

Yeah, summing up things with OpenSCAD is not real fun.

--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17417.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

Here is a better version that should be O(n) and tail recursive, I think. Perhaps easier to understand as well as it is more like a procedural loop. points_relative = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]]; function rel_to_abs(list, i = 0, sum = [0,0], result = []) = i == len(list) ? result : rel_to_abs(list, i + 1, sum + list[i], concat(result, [sum + list[i]])); points_absolute = rel_to_abs(points_relative); echo(points_absolute); polygon(points_absolute); On 24 May 2016 at 14:35, Parkinbot <rudolf@parkinbot.com> wrote: > nophead wrote > > Not very efficient as O(n^2) but > > Yeah, summing up things with OpenSCAD is not real fun. > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17417.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
R
Ronaldo
Tue, May 24, 2016 4:15 PM

@nophead
The original problem is O(n^2). There are n*(n+1)/2 sums to be done, where n
is the size of the array of points. So there is no O(n) algorithm for it.
Your first solution is better because it is clearer. To avoid recursion, you
may consider:

 function sum_list(list, to=0) =
 [ for(i=[0:len(list)-1]) (i<=to) ? 1 : 0 ] * list ;

which is very general and applies to list of numbers, vectors, matrices,
etc.
But that is a question of taste. :)

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17419.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

@nophead The original problem is O(n^2). There are n*(n+1)/2 sums to be done, where n is the size of the array of points. So there is no O(n) algorithm for it. Your first solution is better because it is clearer. To avoid recursion, you may consider: > function sum_list(list, to=0) = > [ for(i=[0:len(list)-1]) (i<=to) ? 1 : 0 ] * list ; which is very general and applies to list of numbers, vectors, matrices, etc. But that is a question of taste. :) -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17419.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Tue, May 24, 2016 4:23 PM

Sorry, my analysis is completely wrong. The problem is O(n).

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17420.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Sorry, my analysis is completely wrong. The problem is O(n). -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17420.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Tue, May 24, 2016 4:55 PM

However, rel_to_abs may be defined with less parameters:

function rel_to_abs2(list, result = []) =
len(result) == len(list) ?
result :
rel_to_abs2(list, concat(result,
len(result)==0 ?
[ list[0] ] :
[result[len(result)-1] + list[len(result)]]));

--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17421.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

However, rel_to_abs may be defined with less parameters: > function rel_to_abs2(list, result = []) = > len(result) == len(list) ? > result : > rel_to_abs2(list, concat(result, > len(result)==0 ? > [ list[0] ] : > [result[len(result)-1] + list[len(result)]])); -- View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17421.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Tue, May 24, 2016 5:22 PM

That is an interesting way of summing a vector by using a dot product with
a vector of ones.

I think the tail recursive version will be the fastest because my
understanding is OpenScad will optimise it into a loop. It is equivalent to

i = 0;
sum = [0, 0];
result = [];
while(i < len(list))  {
result = concat(result, sum + list[i]);
sum = sum + list([i]);
i = i + 1;
}

Yes you can use less parameters but it makes it less readable and less
efficient. Is there any advantage?

On 24 May 2016 at 17:55, Ronaldo rcmpersiano@gmail.com wrote:

However, rel_to_abs may be defined with less parameters:

function rel_to_abs2(list, result = []) =
len(result) == len(list) ?
result :
rel_to_abs2(list, concat(result,
len(result)==0 ?
[ list[0] ] :
[result[len(result)-1] + list[len(result)]]));

That is an interesting way of summing a vector by using a dot product with a vector of ones. I think the tail recursive version will be the fastest because my understanding is OpenScad will optimise it into a loop. It is equivalent to i = 0; sum = [0, 0]; result = []; while(i < len(list)) { result = concat(result, sum + list[i]); sum = sum + list([i]); i = i + 1; } Yes you can use less parameters but it makes it less readable and less efficient. Is there any advantage? On 24 May 2016 at 17:55, Ronaldo <rcmpersiano@gmail.com> wrote: > However, rel_to_abs may be defined with less parameters: > > > function rel_to_abs2(list, result = []) = > > len(result) == len(list) ? > > result : > > rel_to_abs2(list, concat(result, > > len(result)==0 ? > > [ list[0] ] : > > [result[len(result)-1] + list[len(result)]])); > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17421.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
TP
Torsten Paul
Tue, May 24, 2016 5:51 PM

Using the c-style for() this can be expressed by:

pr = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]];

points = [ for (idx = 0, p = pr[0];idx < len(pr);idx = idx + 1, p = p + pr[idx]) p ];
polygon(points);

Note that this is an experimental feature in the dev snapshots
and needs to be enabled in the preferences ("lc-for-c").

ciao,
Torsten.

Using the c-style for() this can be expressed by: pr = [[0,0],[10,0],[5,10],[-5,10],[-10,0],[-5,-10]]; points = [ for (idx = 0, p = pr[0];idx < len(pr);idx = idx + 1, p = p + pr[idx]) p ]; polygon(points); Note that this is an experimental feature in the dev snapshots and needs to be enabled in the preferences ("lc-for-c"). ciao, Torsten.