# Polygon using relative points rather than absolute?

35 messages
12
Open this post in threaded view
|

## Polygon using relative points rather than absolute?

 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
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 Damn, that was quick! It'll take me longer than that to work out what you actually did... Thanks, nophead! Ian S
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 In reply to this post by nophead nophead wrote Not very efficient as O(n^2) but Yeah, summing up things with OpenSCAD is not real fun.
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 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 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 [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
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 @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. :)
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 Sorry, my analysis is completely wrong. The problem is O(n).
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 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)]]));
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 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. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Torsten
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 Wow, not surprising I was having trouble with this! I know there is a lot of functionality in functions, but I really don't have the programming skills to make this work, and barely understand the logic behind what you guys have written anyway! However, I'll take a good look at it with the Openscad manual in hand, and work out what you've done, as a way of educating myself (slowly). Thanks! Ian S
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 In reply to this post by nophead nophead wrote 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 have understood you are comparing here my proposal of sum_list without recursion with your recursive sum_points. First of all, your sum_points is not tail recursive and always returns [0,0]. A tail recursive version of it might be: function sum_points2(list, i, sum=[0,0]) =     i < 0 ?         sum:         sum_points2(list, i - 1, sum + list[i]); I could not compare the running time of both alternatives (tail recursion X non recursion) because my sum_list is limited to lists of less than 1000000 points due to the for inside. Thats is an advantage of a tail-recursive solution indeed. I did compared the running time of my rel_to_abs2 with your rel_to_abs. They both required approximately the same running time. However, what bugged me was that the running time seems to be a lot more than O(n). May be O(n^2). Anyway, ll those alternatives are toys compared with the Torsten's code! It runs a lot faster and I could not find a limit of it.
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 In reply to this post by droftarts droftarts wrote However, I'll take a good look at it with the Openscad manual in hand, and work out what you've done, as a way of educating myself (slowly). Ian, to understand the codes people have posted in the thread I would suggest that you study the following topics and their examples: a) OpenSCAD User Manual/For C/Java/Python Programmersb) user defined functions, c) list comprehensionList comprehension is very powerful specially combined with recursive functions and there are some basic techniques of its use that should be learned. Study people code from other threads as well. To understand Torsten's code you will need to understand the experimental features of the latest snapshot version. Finally, to understand tail recursion technique in OpenSCAD read the thread on Tail recursion.
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 In reply to this post by tp3 Thorsten, you are cheating. You use the only imperative backdoor OpenSCAD is equipped with ;-) Giving examples like this might suck all desperate OpenSCAD programmers forever into a little black hole. Once pandora's box has been opened ... I can see endlessly nested and expanded C-style for-loops coming up like black clouds on the horizon. Rudolf
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 > Von: Parkinbot <[hidden email]> > you are cheating. You use the only imperative backdoor OpenSCAD > is equipped with ;-) > Nah, if lisp can have a loop macro, we should also have something controversial to discuss about :-). > Giving examples like this might suck all desperate OpenSCAD > programmers forever into a little black hole. Once pandora's > box has been opened ... I can see endlessly nested and > expanded C-style for-loops coming up like black clouds on > the horizon. > Yeah, it's possible to abuse it and make horrible code, but that's probably true for most constructs in pretty much all languages. Right now the feature is still marked as experimental so it would not go automatically into the next release, so there's still a chance to discuss it. But it seems to help expressing some things easily that require much more effort from people who are not so much into functional programming. You also said: "Yeah, summing up things with OpenSCAD is not real fun." Which language construct could make it fun again? With the current list of language changes, it might be easy to just add another change if it makes things easier. ciao,   Torsten. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Torsten
Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

Open this post in threaded view
|

## Re: Polygon using relative points rather than absolute?

 In reply to this post by tp3 tp3 wrote Yeah, it's possible to abuse it and make horrible code, but that's probably true for most constructs in pretty much all languages. Ok, but this languages offer proper constructs, which are neglected for horribleness, OpenSCAD doesn't. tp3 wrote Which language construct could make it fun again? With the current list of language changes, it might be easy to just add another change if it makes things easier. Good point. Seriously spoken, I'd be happy to have this imperative backdoor as a feature to do exactly what you do, but NOT within the head of the forloop. Say as a feature of let: echo (pandora(10));   function pandora(n) =  let(a = 1)  [for (i=[1:n])    let(a = a+i) [i, a]]; Currently this code answers with functional semantics: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]] so it uses outer scope 'a' as R-value set an inner scope L-value 'a'. with imperative semantics you'd obviously get (and that's the aim of the game): [[1, 2], [2, 4], [3, 7], [4, 11], [5, 16], [6, 22], [7, 29], [8, 37], [9, 46], [10, 56]] To discriminate between definition (with implicit declaration) and (now forbidden) update of a local outer (or even inner) scope variable, pandora could introduce a 'set' keyword for the new semantics. And the expression with imperative semantics would be: function pandora(n) =  let(a = 1)  [for (i=[1:n])    set(a = a+i) [i, a]];
Open this post in threaded view
|