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.
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 here I 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). |
Oh Yes this will be used extensively , i assure you.
|
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. |
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][2]]; R=polyRound(po,pr,3); polygon(R); } function rnd(a = 1, b = 0, s = []) = s == [] ? (rands(min(a, b), max( a, b), 1)[0]) : (rands(min(a, b), max(a, b), 1, s)[0]) ; |
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. 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. 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. |
In reply to this post by TLC123
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 |
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 |
This post was updated on .
There seem's to be some miss understandings about FreeCAD's import of SCAD and CSG files.
1) FreeCAD does try and support hull and minkowski requests. For it to work FreeCAD must be able to find the OpenSCAD executable. The path to the OpenSCAD executable is an option of the OpenSCAD work bench. ( It can be very slow.) 2) For hull & minkowski to work with 2D objects the option to allow FreeCAD to download and update DXF libraries must be enabled see general import/export preference, The downloadable library is in general no longer used by FreeCAD but IS used by importCSG for hull & Minkowski requests involving 2D objects. There was a bug with LWPOLYINE in the DXF library that has not long been fixed. 3) polyhedron should also be supported, but again there was a bug until recently. 4) offset should work as of FreeCAD 0.17 So if you have problems then please try the latest 0.17 version and if still, problems please report in the FreeCAD forum. |
In reply to this post by droftarts
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. |
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 |
In reply to this post by TLC123
2017-07-23 5:21 GMT-03:00 TLC123 <[hidden email]>: I think my issue occur when radius for p2 dont fit between p1 -p3. 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 |
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:
|
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 |
Are you sure, it isn't better to report an error, instead of doing a silent repair? |
Report what radius have been corrected by how much and have a
option to autofix or not? |
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 up
First 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 it It'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. |
I really like this capability and have been examining the code, thinking it
would be desirable to have a cleaned up version (which I'm willing to work to produce). It seems like it would be nice to change the interface a bit, to eliminate the cryptic numeric "mode" and replace it either with booleans, (return_adjustments=true/false, allow_conflicts=true/false) or with text (mode="handle_conflicts", mode="return_adjustments", mode="allow_conflicts"). What is better? (The word "debug" is a little vague, but my ideas are a little long.) Another thing that seems desirable is making the naming systematic. Why do I use polyround.scad to get the polyRound module? And is the library round-anything or Round-Anything? (Under Linux case matters.) The polyround.scad file contains a bunch of extra stuff, much of which is undocumented. I've tried to use RailCustomiser and have not really figured it out. Sometimes it returns nan. I don't know why. Also it appears that the colinearity handling in polyRound has a bug, namely that it doesn't do anything at all. The code is: p=getpoints(radiipoints), //make list of coordinates without radii Lp=len(p), //remove the middle point of any three colinear points newrp=[ for(i=[0:len(p)-1]) if(isColinear(p[wrap(i-1,Lp)],p[wrap(i+0,Lp)],p[wrap(i+1,Lp)])==0*||p[wrap(i+0,Lp)].z!=0*)radiipoints[wrap(i+0,Lp)] ], and the second part of the test is always true because p[i].z==undef, so you never delete any points. I tried deleting that second part of the test and that appears to fix it. Have I missed something here? Is there some reason to retain colinear points if they have a nonzero radius, which appears to be the intention of that extra test. I did notice that I get different results when colinear points are retained: because there are more points, it appears that the conflict resolution applies in my example and I get a smaller roundover than requested. This behavior seems undesirable. What does processRadiiPoints do? In the cases I've tried it on, I just get back an output equal to the input. Is there some other way to specify the radius of rounding than a direct value? -- Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
In reply to this post by irevdev
Here's my take on a similar subject, incidentally also named polyround. It's
not as powerful (all corners have the same radius), but it works on any 2D object. You can select if it will affect inside corners, outside corners or both. If you just want, say, to round the corners of a square (or some other shape), it's simpler to use. Known bugs is that if the radius is big enough, it might snip off narrow parts of the object. Don't make the radius more than 2 times the narrowest part and you'll be fine. When I get some spare time, I'll refactor it a bit to make it cleaner (two internal modules for inside() and outside(), so I don't need to duplicate code). module polyround(radius,inside=true,outside=true){ if(inside==true){ if(outside==true){ //Inside corners offset(r=-radius) offset(delta=radius) //Outside corners offset(r=radius) offset(delta=-radius) children(); }else{ //Inside corners offset(r=-radius) offset(delta=radius) children(); } }else{ if(outside==true){ //Outside corners offset(r=radius) offset(delta=-radius) children(); }else{ children(); } } } -- Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
Yes I always round 2D shapes with a single radius using two or three offsets but I haven't grouped it into a module. I don't use delta though. I just use offset(-rad) offset(2 * rad) offset(-rad). Not sure what difference it makes. On Tue, 12 Mar 2019 at 06:44, Troberg <[hidden email]> wrote: Here's my take on a similar subject, incidentally also named polyround. It's _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
Your variant does both inside and outside corners. Mine has them separated.
Apart from that, they are the same. -- Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
Free forum by Nabble | Edit this page |