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.
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
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.
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.
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
@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.
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.
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.
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
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.