Nabble removed Mailing-list integration from the Forum.
This killed the Forum. This is now an ARCHIVE.
It is likely Nabble will shutdown in the future.

# Rounded Polygon Classic List Threaded 184 messages 1234 ... 10
Open this post in threaded view
|

## Rounded Polygon

 Hi all, Just sharing a tool that I think is pretty useful for rounding the points on a polygon. The idea is that along with the list of coordinates that you would normally pass to polygon(), a list of radii is also given and they are used to round the corners at each of the coordinates. code hereI normally design SCAD things mostly with primitives, but I always get frustrated when it comes to adding fillets later (internal radii in particular), I'm going to try and design things from now on by extruding these rounded polygons (where practical).
Open this post in threaded view
|

## Re: Rounded Polygon

 Oh Yes this will be used extensively , i assure you.
Open this post in threaded view
|

## Re: Rounded Polygon

 Good to hear :) I forgot to add, one current issue is that if three consecutive points are col-linear it breaks :/ It's probably easy to fix, I've just hit a wall in motivation.
Open this post in threaded view
|

## Re: Rounded Polygon

 Yeah i get some runaway error too. Not sure if its the same issue though. Co-linearity is easily fixed in function round3points. if more tha 98% collinear just return input back as is. swap the end of round3points to: swapout: ```CentreN2PointsArc(t12,t23,cen,CWorCCW,fn); ``` for: ``` //Oc test can be done before all the calculations but i made it as a singel copy/paste drop in chunk dot(un(p1-p2),(p2-p3))>0.98? // if p1,p2,p3 are more collinar than 0.98 [p1,p2,p3] // then return points as is : CentreN2PointsArc(t12,t23,cen,CWorCCW,fn); // else return the normal thing //fix using functions function dot (a,b)=a*b; // dot product is implied in * of vectors function un(v)=v/max(norm(v),1e-16);// div by zero safe unit normal ``` I think my issue occur when radius for p2 dont fit between p1 -p3. Maybe that should be left to be expected or limited so the arc never can go outside the three points? Also i probably will use [x,y,r], format points in my trials. Easy enough to separate them before calling polyRound. Any reason you selected against that? Thanks again for a great module that will com to much use. Not least with sweeps. ```module test() { p=[for(i=[0:10])[rnd(0,100),rnd(0,100),rnd(0,10)]]; po=[for(i=[0:len(p)-1])[p[i].x,p[i].y]]; pr=[for(i=[0:len(p)-1])p[i]]; R=polyRound(po,pr,3); polygon(R); } function rnd(a = 1, b = 0, s = []) = s == [] ? (rands(min(a, b), max( a, b), 1)) : (rands(min(a, b), max(a, b), 1, s)) ; ```
Open this post in threaded view
|

## Re: Rounded Polygon

 TLC123 wrote Co-linearity is easily fixed in function round3points. if more tha 98% collinear just return input back as is. swap the end of round3points to: swapout: ```CentreN2PointsArc(t12,t23,cen,CWorCCW,fn); ```for: ``` //Oc test can be done before all the calculations but i made it as a singel copy/paste drop in chunk dot(un(p1-p2),(p2-p3))>0.98? // if p1,p2,p3 are more collinar than 0.98 [p1,p2,p3] // then return points as is : CentreN2PointsArc(t12,t23,cen,CWorCCW,fn); // else return the normal thing ``` Thanks for having a look at the co-linearity problem. I've only had a quick look at your code now before bed so I mightn't understand it properly but I would think that if you test for co-linearity and the result is true, then you should return nothing and move onto the next set. My thought experiment is that if there are 5 points where points 2 , 3 and 4 are co-linear, processing points 1,2&3 together is fine likewise so is 3,4&5. If we just skip processing points 2,3&4 it should be fine. Returning the original three points might cause problems, I'll have a look at it though later. TLC123 wrote I think my issue occur when radius for p2 dont fit between p1 -p3. Maybe that should be left to be expected or limited so the arc never can go outside the three points? Your suggestion to limit the arc to stay within the three points, I'm thinking out loud now, at first I thought I wouldn't work, but now I think it could potentially work if instead of just processing the list of points three at a time like it is currently p[i],p[i+1],p[i+2] instead it grabs the last point from the previous arc so  arcpoints[last point of last arc],p[i+1],p[i+2]. it would have to do something different on the first and last iteration of the for loop, but that's seem like a nice simple solution. TLC123 wrote Also i probably will use [x,y,r], format points in my trials. Easy enough to separate them before calling polyRound.  Any reason you selected against that? Thanks again for a great module that will com to much use. Not least with sweeps. In terms of the format [[x,y,r],[x,y,r],etc], I think you're right, I think it's better. I posted this code as soon at it was mostly working so I haven't actually used it for anything other than the examples, but trying to implement it today on an actual project of mine I found it confusing as to which radius lined up with which point on the polygon. So I think I'll make this change, but with any of those three things, feel free to make a pull request. I'll have a closer look at your code soon, though probably not until Tuesday, I'm busy tomorrow.
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by TLC123 TLC123 wrote Also i probably will use [x,y,r], format points in my trials.
Easy enough to separate them before calling polyRound.
Any reason you selected against that?
Probably so he could draw the original polygon easily, independently of the script, for testing. The main reason I started the other script was to enable CSG export to FreeCAD and then into Fusion 360, as this couldn't be done using hull (read the thread here). This meant that circles and arcs keep their definition, rather than being broken up into a mesh. Your script does seem to create a mesh, ie arcs are broken up into straight segments, so it doesn't maintain the geometry of circles when you import it into FreeCAD. Unlike the other script, the points don't have to go around in a clockwise order with yours, which is nice. Ian
Open this post in threaded view
|

## Re: Rounded Polygon

 Thinking about it, an approach that is somewhere between the two scripts might be the best of both. Take the initial polygon, calculate the tangent points between each three points and the radius, redraw the polygon without the middle point but with the tangent points, then union or difference the circle from it. This would give you the same shape as your version, but constructed from a polygon with unioned or differenced circles, like my version. This would mean on CSG export that it would maintain it's geometry, rather than being converted to a mesh, so can be opened in other CAD software as a solid body, rather than a mesh. Ian
Open this post in threaded view
|

## Re: Rounded Polygon

Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by droftarts droftarts wrote Thinking about it, an approach that is somewhere between the two scripts might be the best of both. Take the initial polygon, calculate the tangent points between each three points and the radius, redraw the polygon without the middle point but with the tangent points, then union or difference the circle from it. This would give you the same shape as your version, but constructed from a polygon with unioned or differenced circles, like my version. This would mean on CSG export that it would maintain it's geometry, rather than being converted to a mesh, so can be opened in other CAD software as a solid body, rather than a mesh. Ian Hi Ian, short answer is if you use fn of 1 with my code it will draw the polygon along all the tangent points only. This was my initial approach, but I dumped it when I realised if you wanted to have a relatively large radius compare to the overall size of the shape than unioning it with a circle would mean the circle would take over. ie the radius of 10 in the example, a circle that big would be bigger than most of the shape. I thought it could be fixed by cutting the circle down before it got unioned but at that point it seemed drawing points of the circle would be easier. If you wanted go back to this like I said you can use fn of 1 or you could modify the round3points() function so that instead of passing the tangent points and circle center to CentreN2PointsArc() it just returns these values instead, that way you would also have the coordinates of the circle center for the circle unioning.
Open this post in threaded view
|

## Re: Rounded Polygon

 Ah yes, I see the problem, and now I try it, the other script has this problem too. Though it probably shows how often it's a problem, as neither I nor anyone else has noticed it before! Thanks for the extra info, I'll take a look. Keith: I'd like to see some examples of what FreeCad can import correctly from OpenSCAD, but I think that belongs in another thread, rather than hijack this one! Ian
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by TLC123 2017-07-23 5:21 GMT-03:00 TLC123 :I think my issue occur when radius for p2 dont fit between p1 -p3. Maybe that should be left to be expected or limited so the arc never can go outside the three points?The issue is not restricted to that extreme cases. It is enough to have tangent points in an edge in reversed order.module test2(size,r) {    p = [ [0,0], [size,0],[size,size],[0,size] ];    polygon( polyRound(p,r,10));    translate([0,0,-1])%polygon(p);}    test2(100,[80,20,30,50]); If polyRound is recoded to identify those cases, either ​it should do nothing or reduce some radiuses. Unhapilly, the radius reduction problem has usually many solutions. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 As Ronaldo mentioned it is not straight forward to deal with conflicting radii. But, even a robust implemention will be quite difficult, this function is a nice-to-have if handled with care. Here is my implementation of it. It uses \$fs to control arc graining and seems to be semantically equivalents for the rest: \$fs=.2;  // graining b=[[-5,0],[5,3],[0,7],[8,7],[20,20],[10,0]]; //points br=[1,     1.5,   1,   10,     1.5,     5]; //radiuses polygon(polyRound(b,br)); %translate([0,0,0.2])polygon(b); p=[[0,0],[0,20],[15,15],[3,10],[15,0],[6,2]];//points pr=[2,     4,      3,     3,      1,   8];//radiuses translate([25,0,0])polygon(polyRound(p,pr,\$fs=.4)); %translate([25,0,0.2])polygon(p); function polyRound(b, r) = [for(i = [0:len(b)-1]) each tri(b, i, r[(i+1)%len(b)])]; function tri(L,i, r) = let(N=len(L)) // uses \$fs   let(A = L[i]) let(B=L[(i+1)%N], C=L[(i+2)%N])                   // points   let(a = (A-B)/norm((A-B)), b = (C-B)/norm((C-B)))               // vectors   let(a_= [-a, a], b_=[b,-b])                         // normals   let(m = r*(b_-a_),k=(a*m-a*m)/(b*a-b*a)) // equation stuff   let(s = sign(k), w = 2*atn([r,s*k]), w0 = atn(-s*a_))           // angles   let(n = round(abs(r*w/180*PI)/\$fs), M = B+s*k*a+s*r*a_)         // middle point   [for(z = [w0:-s*w/(n+1):w0-s*w-s*.0001]) M+r*[cos(z), sin(z)]]; // arc   // full circle atan function atn(X) = let(w = X==0?X<0?270:90:atan(X/X)) X<0?180+w:(w+360)%360;
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by irevdev I made some experiments in a fork on github. Don't know if I posted it correctly, very unused to github. First version dealt with the collinear case and radius zero case. Next i clamped tangD value to be inside either leg of the triangle. Now I'm working on reducing radius  if tangD +tangD of previous point is larger than the length of the leg or tangD +tangD of following points is larger than the length of the following leg. Then Mutiply radius by the proportional amount of that  oversize.  And repeat for all points. If no changes occured done else retry recursive with new set of radii. Currently working but a bit to eagerly with reducing radius. I think I know what part of logic that needs change and I will deal with it as soon as possible
Open this post in threaded view
|

## Re: Rounded Polygon

 TLC123 wrote Mutiply radius by the proportional amount of that  oversize.  And repeat for all points. Are you sure, it isn't better to report an error, instead of doing a silent repair?
Open this post in threaded view
|

## Re: Rounded Polygon

 Report what radius have been corrected by how much and have a option to autofix or not?
Open this post in threaded view
|

## Re: Rounded Polygon

 This post was updated on . I've got a pretty big update to the polyRound() code, some general tidying, improvements and new features, mostly notably radii conflict handling. link here again, if you don't want to scroll upFirst a big thank you to TLC123 who's made a substantial contribution. So the interface of the function has changed, instead of taking two separate lists for points and radii, it takes one list where each point takes the format [x,y,r]. TLC suggested it and it seems more intuitive to me. The radii conflict handling works by reducing two conflicting radii by a factor, this means that the two will keep their ratios, for example if two conflicting radii of 30 and 30 would be reduced to 10 and 10, but conflicting radii of 10 and 40 might be reduced to 4 and 16, ie 30/30=10/10 and 10/40=4/16. There is no way to explain how it does this with out drawing something, so here are some pictures. Not sure how well that image will turn out, here is a link for itIt's not the perfect solution but I'm happy with it for now as it seems pretty robust and isn't too complicated. For those who don't want radii conflict handling polycarious() has no protection built in. So as it stands the radii conflict handling is not an option within the same function? should I make it enable/disable-able within one function? One problem with the radii conflict handling is if you were to have 3 consecutive radii, where the 1st and 2nd radii conflict a lot and the 2nd and 3rd conflict but less so, what will happen is that the 2nd radii will reduce enough for the worst case which is the 1st and 2nd radii conflict. The problem here is that with the second radius reducing, once it has been reduced it may no longer conflict with the 3rd radius, and therefore the 3rd radius it may not need to be reduced, but the code doesn't check for this and so the 3rd radius will be reduced as if the original conflicting 2nd radius were still there. Trying to fix this would be difficult because how would it be handled? would you go through the array in order giving the first point priority? or do you write logic so that it reduces the radii at the worst conflict and then the 2nd worst, 3rd etc? I think it's fine as it is because I think the radii reduction should not be relied on in the first place, I did included a debugging option that will tell you know if any of the radii have been reduced because of a conflict. see some of the examples.
Open this post in threaded view
|

## Re: Rounded Polygon

Open this post in threaded view
|

## Re: Rounded Polygon

Open this post in threaded view
|