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

## Re: Rounded Polygon

 Hi, I now have a bezier patch in 3d:         Roger. -- ** [hidden email] ** https://www.BitWizard.nl/ ** +31-15-2049110 ** **    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    ** The plan was simple, like my brother-in-law Phil. But unlike Phil, this plan just might work. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org bezier_3d.png (28K) Download Attachment
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by adrianv adrianv <[hidden email]> wrote:I'm a little puzzled.  Maybe you are using the word degree differently than I think?  I was thinking a degree 3 Bezier is a cubic polynomial and has 4 control points.  It can be set to zero curvature at both ends but has only one degree of freedom, which just controls the size of the curve.  That isn't enough.  It appears to me that degree 4, with 5 control points, is sufficient.  Yes, you do need to put p2 on the vertex.  This doesn't seem to cause any undesirable restriction, and it is definitely possible to satisfy the zero curvature condition.   One parameter remains that controls the degree of curvature, as I noted in my previous message.  Having fewer parameters is often better than more, so I'm not sure about what the value of more degrees of freedom is of going to the case with 6 control points (which is a 5th degree polynomial).  I did experiment a bit with your code and you can get some rather sharp cornered results.  It seemed like r1 usually had little effect.  You are right regarding the degrees. I wrongly said 5 instead of 4 and 6 instead of 5. A degree n Bezier curve has n+1 control points.However I disagree that you could meet the zero curvature constraint at both end with degree 3 curves. To have a zero curvature at the beginning of the arc, the first 3 control points should co-linear. The same is true for the ending point. If we require zero curvature at both ends all four control points should be co-linear and the arc reduces to a straight segment.Degree 4 is in fact the minimal degree for zero curvature at both ends for a non-straight line Bezier arc. However degree 5 solution give us not only more degrees of freedom but a better arc shape as will see bellow. Degree 4 solution produces an arc with a greater curvature variation and a more pointed arc. Degree 5 shape is able to produce arcs that resemble circular arcs.I have revised my codes in order to generate alternatively both solutions. The two missed functions and line() module are defined as before.q = [ [0,0], [30,0], [30,30], [0,30] ];color("blue")   roundedPoly(q, 20, 4, 1/3);color("yellow") roundedPoly(q, 20, 4, 2/3);color("red")    roundedPoly(q, 20, 4,   1);translate([35,0,0]) {  color("blue")   roundedPoly(q, 20, 5, 1/3, 17/32);  color("yellow") roundedPoly(q, 20, 5, 2/3, 17/32);  color("red")    roundedPoly(q, 20, 5,   1, 17/32);  color("green")  translate([15,15,-1]) circle(15);}    module roundedPoly(p, n=20, degree=4, r=1/4, r0=2/3, r1=17/32) {  assert(len(p)>2, "polygonal has less than 3 points");  assert(r>0 && r<=1, "r out of range");  assert(r0>0 && r<=1, "r0 out of range");  assert(degree==4 || degree==5, "degree should be 4 or 5");  assert(degree==5 || (r1>0 && r1<=1), "r1 out of range");  l = len(p);  q = [for(i=[0:l-1])          let( p0 = (1-r/2)*p[i] + r*p[(i+l-1)%l]/2 ,              p1 = p[i],              p2 = (1-r/2)*p[i] + r*p[(i+1)%l]/2 )         each BZeroCurvature(p0,p1,p2,n,degree,r0,r1) ];  line(q, closed=true,w=0.2);}    // a Bezier arc of degree 4 or 5 from p0 to p2, tangent to// [p0,p1] at p0, tangent to [p1,p2) at p2 and// with zero curvature at p0 and p2// n  - # of points in the arc// r0 - form factor in the interval [0,1] // r1 - form factor in the interval [0,1] (for degree=5 only)function BZeroCurvature(p0,p1,p2,n=20,degree=4,r0=2/3,r1=1/2) =  assert(r0>0 && r0<=1, "r0 out of range")  assert(degree==4 || degree==5, "degree should be 4 or 5")  assert(degree==5 || (r1>0 && r1<=1), "r1 out of range")  let( r1 = degree==4 ? 1 : r1,       p  = [ p0,               p0 + r0*(p1-p0)*r1,              each degree==4 ?                    [p1] :                    [p0 + r0*(p1-p0), p2 + r0*(p1-p2)],               p2 + r0*(p1-p2)*r1,              p2 ] )  BezierCurve(p,n);And got the following image: At left we have the arcs of degree 4 and at right the degree 5 alternative for similar form factors. With r=1, which means that the straight lines between arcs reduce to a point, drawn here with red lines, the degree 4 solution keeps the middle point of each arc much nearer to the polygon vertex. With degree 5 on the other hand it is possible to get a good approximation of a circular arc with r1~= 17/32, a value I got empirically. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 I played around a little bit with Bezier curves in OpenSCAD before, and its fairly trivial to write a recursive bezier curve function that can handle arbitrary curve orders.  They are also agnostic to the dimension of points 2D/3D(or higher dimension?)Here are the functions I have used:// return point along curve at position "t" in range [0,1]// use ctlPts[index] as the first control point// Bezier curve has order == nfunction BezierPoint(ctlPts, t, index, n) =   let (    l = len(ctlPts),    end = index+n  )  //assert(end < l)  (n > 0) ?     BezierPoint([      for (i = [index:end])         let (p1 = ctlPts[i], p2 = ctlPts[i+1]) p1 + t * (p2 - p1)    ], t, 0, n-1) :    ctlPts;function flatten(l) = [ for (a = l) for (b = a) b ];// n sets the order of the Bezier curves that will be stitched together// if no parameter n is given, points will be generated for a single curve of order == len(ctlPts) - 1function BezierPath(ctlPts, index, n) =   let (    l1 = \$fn > 3 ? \$fn-1 : 200,    index = index == undef ? 0 : index,    l2 = len(ctlPts),    n = (n == undef || n > l2-1) ? l2 - 1 : n  )  //assert(n > 0)  flatten([for (segment = [index:1:l2-1-n])    [for (i = [0:l1] ) BezierPoint(ctlPts, i / l1, index+segment*n, n)]  ]);On Thu, Mar 14, 2019 at 1:53 PM Ronaldo Persiano <[hidden email]> wrote:adrianv <[hidden email]> wrote:I'm a little puzzled.  Maybe you are using the word degree differently than I think?  I was thinking a degree 3 Bezier is a cubic polynomial and has 4 control points.  It can be set to zero curvature at both ends but has only one degree of freedom, which just controls the size of the curve.  That isn't enough.  It appears to me that degree 4, with 5 control points, is sufficient.  Yes, you do need to put p2 on the vertex.  This doesn't seem to cause any undesirable restriction, and it is definitely possible to satisfy the zero curvature condition.   One parameter remains that controls the degree of curvature, as I noted in my previous message.  Having fewer parameters is often better than more, so I'm not sure about what the value of more degrees of freedom is of going to the case with 6 control points (which is a 5th degree polynomial).  I did experiment a bit with your code and you can get some rather sharp cornered results.  It seemed like r1 usually had little effect.  You are right regarding the degrees. I wrongly said 5 instead of 4 and 6 instead of 5. A degree n Bezier curve has n+1 control points.However I disagree that you could meet the zero curvature constraint at both end with degree 3 curves. To have a zero curvature at the beginning of the arc, the first 3 control points should co-linear. The same is true for the ending point. If we require zero curvature at both ends all four control points should be co-linear and the arc reduces to a straight segment.Degree 4 is in fact the minimal degree for zero curvature at both ends for a non-straight line Bezier arc. However degree 5 solution give us not only more degrees of freedom but a better arc shape as will see bellow. Degree 4 solution produces an arc with a greater curvature variation and a more pointed arc. Degree 5 shape is able to produce arcs that resemble circular arcs.I have revised my codes in order to generate alternatively both solutions. The two missed functions and line() module are defined as before.q = [ [0,0], [30,0], [30,30], [0,30] ];color("blue")   roundedPoly(q, 20, 4, 1/3);color("yellow") roundedPoly(q, 20, 4, 2/3);color("red")    roundedPoly(q, 20, 4,   1);translate([35,0,0]) {  color("blue")   roundedPoly(q, 20, 5, 1/3, 17/32);  color("yellow") roundedPoly(q, 20, 5, 2/3, 17/32);  color("red")    roundedPoly(q, 20, 5,   1, 17/32);  color("green")  translate([15,15,-1]) circle(15);}    module roundedPoly(p, n=20, degree=4, r=1/4, r0=2/3, r1=17/32) {  assert(len(p)>2, "polygonal has less than 3 points");  assert(r>0 && r<=1, "r out of range");  assert(r0>0 && r<=1, "r0 out of range");  assert(degree==4 || degree==5, "degree should be 4 or 5");  assert(degree==5 || (r1>0 && r1<=1), "r1 out of range");  l = len(p);  q = [for(i=[0:l-1])          let( p0 = (1-r/2)*p[i] + r*p[(i+l-1)%l]/2 ,              p1 = p[i],              p2 = (1-r/2)*p[i] + r*p[(i+1)%l]/2 )         each BZeroCurvature(p0,p1,p2,n,degree,r0,r1) ];  line(q, closed=true,w=0.2);}    // a Bezier arc of degree 4 or 5 from p0 to p2, tangent to// [p0,p1] at p0, tangent to [p1,p2) at p2 and// with zero curvature at p0 and p2// n  - # of points in the arc// r0 - form factor in the interval [0,1] // r1 - form factor in the interval [0,1] (for degree=5 only)function BZeroCurvature(p0,p1,p2,n=20,degree=4,r0=2/3,r1=1/2) =  assert(r0>0 && r0<=1, "r0 out of range")  assert(degree==4 || degree==5, "degree should be 4 or 5")  assert(degree==5 || (r1>0 && r1<=1), "r1 out of range")  let( r1 = degree==4 ? 1 : r1,       p  = [ p0,               p0 + r0*(p1-p0)*r1,              each degree==4 ?                    [p1] :                    [p0 + r0*(p1-p0), p2 + r0*(p1-p2)],               p2 + r0*(p1-p2)*r1,              p2 ] )  BezierCurve(p,n);And got the following image: At left we have the arcs of degree 4 and at right the degree 5 alternative for similar form factors. With r=1, which means that the straight lines between arcs reduce to a point, drawn here with red lines, the degree 4 solution keeps the middle point of each arc much nearer to the polygon vertex. With degree 5 on the other hand it is possible to get a good approximation of a circular arc with r1~= 17/32, a value I got empirically. _______________________________________________ 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: Rounded Polygon

 In reply to this post by Ronaldo Ronaldo wrote > adrianv < > avm4@ > > wrote: > > > However I disagree that you could meet the zero curvature constraint at > both end with degree 3 curves. To have a zero curvature at the beginning > of > the arc, the first 3 control points should co-linear. The same is true for > the ending point. If we require zero curvature at both ends all four > control points should be co-linear and the arc reduces to a straight > segment. No it doesn't.  I posted graphs a few messages back showing zero curvature order 3 beziers, and I had directly verified that the curvature was indeed zero by calculating the derivatives both symbolically and numerically, so I am reasonably sure it was correct.   With p0=p3 set to the endpoints of the arc you then set p1=p2 equal to the point of the corner.  You achieve the co-linearity condition in a degenerate fashion, since p1 and p2 are on both lines.   > Degree 4 is in fact the minimal degree for zero curvature at both ends for > a non-straight line Bezier arc. However degree 5 solution give us not only > more degrees of freedom but a better arc shape as will see bellow. Degree > 4 > solution produces an arc with a greater curvature variation and a more > pointed arc. Degree 5 shape is able to produce arcs that resemble circular > arcs. It appears that your degree 4 code can also generate a nearly circular arc: just set r1 very small, like .01 and you get something visually indistinguishable from a circle.  In fact, it looks very similar to your empirically determined 17/32 value.  I wonder what are the parameters for the order 5 bezier that reduce it to the order 4. On the left is order 4 with r1=0.01 and on the right, order 5 with r1=17/32.   -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 Well I'm a bit embarrassed after playing with the Bezier code I previously posted(hadn't messed with it in a while).  I realized it had some bugs and some inefficiencies. I fixed it up a bit and included a more complete example with example of various orders along random path, and a classic circle approximation.Posting gist this time in case I need to update it again, but I believe the code is correct now :On Thu, Mar 14, 2019 at 5:03 PM adrianv <[hidden email]> wrote:Ronaldo wrote > adrianv < > avm4@ > > wrote: > > > However I disagree that you could meet the zero curvature constraint at > both end with degree 3 curves. To have a zero curvature at the beginning > of > the arc, the first 3 control points should co-linear. The same is true for > the ending point. If we require zero curvature at both ends all four > control points should be co-linear and the arc reduces to a straight > segment. No it doesn't.  I posted graphs a few messages back showing zero curvature order 3 beziers, and I had directly verified that the curvature was indeed zero by calculating the derivatives both symbolically and numerically, so I am reasonably sure it was correct.   With p0=p3 set to the endpoints of the arc you then set p1=p2 equal to the point of the corner.  You achieve the co-linearity condition in a degenerate fashion, since p1 and p2 are on both lines.  > Degree 4 is in fact the minimal degree for zero curvature at both ends for > a non-straight line Bezier arc. However degree 5 solution give us not only > more degrees of freedom but a better arc shape as will see bellow. Degree > 4 > solution produces an arc with a greater curvature variation and a more > pointed arc. Degree 5 shape is able to produce arcs that resemble circular > arcs. It appears that your degree 4 code can also generate a nearly circular arc: just set r1 very small, like .01 and you get something visually indistinguishable from a circle.  In fact, it looks very similar to your empirically determined 17/32 value.  I wonder what are the parameters for the order 5 bezier that reduce it to the order 4. On the left is order 4 with r1=0.01 and on the right, order 5 with r1=17/32.  -- Sent from: http://forum.openscad.org/ _______________________________________________ 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: Rounded Polygon

 In reply to this post by adrianv No it doesn't.  I posted graphs a few messages back showing zero curvature order 3 beziers, and I had directly verified that the curvature was indeed zero by calculating the derivatives both symbolically and numerically, so I am reasonably sure it was correct.   With p0=p3 set to the endpoints of the arc you then set p1=p2 equal to the point of the corner.  You achieve the co-linearity condition in a degenerate fashion, since p1 and p2 are on both lines.You are right. Putting both intermediate control points at the corner will meet the conditions of zero curvature at the two ends of a degree 3 Bezier arc. I could not imagine that solution before. And certainly this is a very constrained alternative.   It appears that your degree 4 code can also generate a nearly circular arc: just set r1 very small, like .01 and you get something visually indistinguishable from a circle.  In fact, it looks very similar to your empirically determined 17/32 value.  I wonder what are the parameters for the order 5 bezier that reduce it to the order 4. I have confirmed your statement about the approximation of circular arcs by degree 4 curves. It seems even better than the degree 5 arc with r0=17/32.I have applied the degree elevation formulas to deduce algebraically the conditions r0 and r1 should satisfy in order the degree 4 and degree 5 curves be equal. From my math exercise, we should have:degree 5 with  r0 = 3/5  and r1=0 will be equivalent todegree 4 with r0=0I also found that r0 may be set to 0 for degree 4 and r1 may be set to 0 for degree 5 but r0 should not be 0 for degree 5 because the arc degenerate into a line segment. I have changed the assert conditions in the my functions accordingly.I agree that rounding corners with degree 4 Bezier arcs give us enough flexibility and there is no point to use greater degree. In my functions, the parameter r of roundedPoly() controls how much the corner is rounded like your proposed d parameter. That parameter sets the end points relatively to the polygon edge length instead of an absolute value. The problem with this solution is that the arc will not be symmetrical when the two edges meeting a corner have different length. But the alternative of a absolute value d requires a validation to avoid that two arcs rounding the two corners of an edge intercept.Finally, I have checked that my code works well even with not convex polygons as can be seen in the image. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org nonConvexCase.PNG (8K) Download Attachment
Open this post in threaded view
|

## Re: Rounded Polygon

 Going back to the apple article I don't think the change in shade is anything to do with curvature. Reflected light is related to the surface angle and that doesn't change discontinuously. It's rate of change does but I don't see how that would affect reflected light. It looks like the left corner is lit from both sides and the right corner is lit from right side only.On Fri, 15 Mar 2019 at 03:15, Ronaldo Persiano <[hidden email]> wrote:No it doesn't.  I posted graphs a few messages back showing zero curvature order 3 beziers, and I had directly verified that the curvature was indeed zero by calculating the derivatives both symbolically and numerically, so I am reasonably sure it was correct.   With p0=p3 set to the endpoints of the arc you then set p1=p2 equal to the point of the corner.  You achieve the co-linearity condition in a degenerate fashion, since p1 and p2 are on both lines.You are right. Putting both intermediate control points at the corner will meet the conditions of zero curvature at the two ends of a degree 3 Bezier arc. I could not imagine that solution before. And certainly this is a very constrained alternative.   It appears that your degree 4 code can also generate a nearly circular arc: just set r1 very small, like .01 and you get something visually indistinguishable from a circle.  In fact, it looks very similar to your empirically determined 17/32 value.  I wonder what are the parameters for the order 5 bezier that reduce it to the order 4. I have confirmed your statement about the approximation of circular arcs by degree 4 curves. It seems even better than the degree 5 arc with r0=17/32.I have applied the degree elevation formulas to deduce algebraically the conditions r0 and r1 should satisfy in order the degree 4 and degree 5 curves be equal. From my math exercise, we should have:degree 5 with  r0 = 3/5  and r1=0 will be equivalent todegree 4 with r0=0I also found that r0 may be set to 0 for degree 4 and r1 may be set to 0 for degree 5 but r0 should not be 0 for degree 5 because the arc degenerate into a line segment. I have changed the assert conditions in the my functions accordingly.I agree that rounding corners with degree 4 Bezier arcs give us enough flexibility and there is no point to use greater degree. In my functions, the parameter r of roundedPoly() controls how much the corner is rounded like your proposed d parameter. That parameter sets the end points relatively to the polygon edge length instead of an absolute value. The problem with this solution is that the arc will not be symmetrical when the two edges meeting a corner have different length. But the alternative of a absolute value d requires a validation to avoid that two arcs rounding the two corners of an edge intercept.Finally, I have checked that my code works well even with not convex polygons as can be seen in the image. _______________________________________________ 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: Rounded Polygon

 I understand your point because I am also unable to perceive visually curvature discontinuities. But people from visual arts have training eye to perceive it. However, even for people like us it may be noticible on shinning and reflecting surfaces.The following YouTube video gives an idea of the effect of different kinds of continuity.It was clearer to me the effect of the various kinds of continuity with the stripe view. Designers from automobile industry are very concerned with the effect of shadows and light reflexions on the surface of their models.Besides, curvature continuity is a requeriment on the design of a road track. Any discontinuity on the track is prone to an accident because a sudden wheel turn is needed to keep the vehicle on track when you cross the discontinuity. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by nophead nophead wrote > Going back to the apple article I don't think the change in shade is > anything to do with curvature. Reflected light is related to the surface > angle and that doesn't change discontinuously. It's rate of change does > but > I don't see how that would affect reflected light. It looks like the left > corner is lit from both sides and the right corner is lit from right side > only. You wouldn't see it on completely mat or reflected surface. But on brushed or structured surfaces a lot of additional effects accumulate. Neverless, DIY-people like most of us in this forum, me including, with a "function first" attitude usually have only a poor understanding of surface erotics. Only after having read "Zen And The Art Of Motorcycle Maintenance" I could develop a first poor understandig about what kind of gears seem to purr within Apple customer brains. In Open Source based 3D printing, where 90% of the prints are done with layers >= 0.2 mm and nozzles >= 0.4mm there is no point in trying to optimize curvatures to C3 or more. -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by Ronaldo On 15/03/2019 14:07, Ronaldo Persiano wrote: Besides, curvature continuity is a requeriment on the design of a road track. Any discontinuity on the track is prone to an accident because a sudden wheel turn is needed to keep the vehicle on track when you cross the discontinuity. Railways used to be designed with straight and curves, and it made them uncomfortable and restricted speeds, and ditto "loop the loop" on roller coasters as the sudden changes in acceleration (high jerk) caused neck injuries. Then along came what I still call clothoid curves, but wikipedia prefers Euler Spirals. https://en.wikipedia.org/wiki/Euler_spiral They are used to link straights to circles on railways, rollercoasters, and much more. https://en.wikipedia.org/wiki/Track_transition_curve _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 Interesting stuff. I wonder if we should use Euler spirals instead of Bezier splines to round polygons.On Fri, 15 Mar 2019 at 19:45, Gadgetmind <[hidden email]> wrote: On 15/03/2019 14:07, Ronaldo Persiano wrote: Besides, curvature continuity is a requeriment on the design of a road track. Any discontinuity on the track is prone to an accident because a sudden wheel turn is needed to keep the vehicle on track when you cross the discontinuity. Railways used to be designed with straight and curves, and it made them uncomfortable and restricted speeds, and ditto "loop the loop" on roller coasters as the sudden changes in acceleration (high jerk) caused neck injuries. Then along came what I still call clothoid curves, but wikipedia prefers Euler Spirals. https://en.wikipedia.org/wiki/Euler_spiral They are used to link straights to circles on railways, rollercoasters, and much more. https://en.wikipedia.org/wiki/Track_transition_curve _______________________________________________ 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: Rounded Polygon

 In reply to this post by Gadgetmind On 15.03.2019 17:39, Gadgetmind wrote: > Railways used to be designed with straight and curves, and it made them > uncomfortable and restricted speeds, and ditto "loop the loop" on roller > coasters as the sudden changes in acceleration (high jerk) caused neck > injuries. > > Then along came what I still call clothoid curves, but wikipedia prefers > Euler Spirals. Ditto, I learned about clothoid curves 35 years ago. A railway track with immediate transition from a straight segment with zero curvature to 1/r in a circular segment will introduce a sudden sideways acceleration. Not good. Railway tracks and motorways therefore use clothoid transition curves. I agree with those who say this does not matter for 3d printing though. Carsten Arnholm _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 In reply to this post by nophead nophead wrote > Interesting stuff. I wonder if we should use Euler spirals instead of > Bezier splines to round polygons. It looks to me like the Bezier solution is probably easier than trying to fit a fragment of an Euler spiral to transition between a flat section and a circular arc.   I compared a 4th order bezier smoothed square to a circle rounded square and they didn't look very different.  I asked myself why not?  And after some investigation, reached a conclusion that I think is interesting.  I also wonder if, perhaps, I was too quick to deny the utility of 5th order bezier for this application.  Here are three examples.  The left uses circular arcs.  The center uses 4th order bezier with the control points chosen for the flattest arc, which is closest to circular.  It sure looks a lot like the left hand image.  It looks like there are little corners where the roundover meets the side.  The right hand example is a 4th order bezier with different parameters and it looks smooth. I would say that the difference is apparent, and I think it would be apparent if I printed the three squares. (Maybe I should do a test print.)   So what's going on.  Do I have continuous curvature or not?  Using a curvature parameter that goes from [0,1] where 1 places p1=p0 and p3=4, and 0 places p1=p2=p3, I calculated the endpoint curvature and it is zero on [0,1).  At 1 I have a problem because the derivative is zero, so it's a bad parametrization.   But then I graphed the curvature for different parameter values: The graphs show the curvature across half the bezier curve.  Of course the other half is a mirror image.  So what I find is that when the parameter is close to 1 the curvature starts at 0 but there is a big spike.  So it's continuous technically, but not really practically.  It seems like a parameter value in the range of [.5,.8] or so should give a moderate derivative of the curvature.   If you go smaller the curvature rises a lot in the middle of the curve, so the curve becomes pointed.   Note also that if you want the curve to approximate a circle it's clear that this is accomplished best when the parameter is close to 1, because then the curvature is constant across most of the range.   So why am I having second thoughts about wanting order 5?  Well, it seems that with order 4, once you scale the curves to be the same size (to cut off the same amount of the corner) there is very little variation in that middle range.   I felt like the full range of curves coming out of the 5th order bezier was producing some weird looking flat stuff, but maybe some more limited parameter set would be interesting.    I may plot more graphs later. Also from this graph I can justify why we shouldn't bother with the Euler spiral.  The Euler spiral's nice property is that the curvature starts at zero and increases linearly.  The 0.7 curve and 0.5 curves look like reasonable approximations to linear.  So the results wouldn't be much different.   And this bezier approach is very easy to work with.  I have done an implementation that does both bezier 4th order and circular arcs, where I allow the user to specify the size of each corner's curve independently, and I check for collisions (i.e. you pick too large of a curve to fit).  My intention was that it could do closed paths (polygons) but also open paths, and paths in 3d.   And the circular arc code was more difficult to write than the bezier code, where once you've picked the control points, you're basically done.  Once I've done a bit more testing I'll post it here for comment.   Is there any mechanism other than assert() to generate warning or error messages?  Assert seems kind of clumsy, since it prints the test, and it is always a fatal error instead of a warning.   -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 Very nice research! I am already waiting for the episode 2 :)Is there any mechanism other than assert() to generate warning or error messages?  Assert seems kind of clumsy, since it prints the test, and it is always a fatal error instead of a warning.  Yes, you may insert an echo. I usually do something like this:let( x = test? echo(a,b,c) 0 : 0 )As echo() accepts HTML codes you are able to use a background color similar to the OpenSCAD warnings. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 Ronaldo wrote > Very nice research! I am already waiting for the episode 2 :) Maybe not as exciting as the first plot, but I did plot the shape of the curve as I varied the curvature parameter.  It changes so slightly that it's hard to see if I put too many curves on the graph, so I'm showing curvature parameters of just 0, 0.5, and 1.  What changes a lot is the location of p0 and p4.  For this case, I have set the tip of the rounded corner to be 2 units back from the corner.  The bezier curve intersects the edge of the right angle corner 4.5 units away from the corner when the curve parameter is 1 (red line), 7.5 units when the parameter is 0.5 (green line), and a whopping 22.6 units if you set the parameter to zero (blue line).  So choosing a smaller curvature parameter causes it to really vary the curvature slowly.  This I think makes those small values not very useful, since you are very likely to run out of room on your object for the curve.     > Is there any mechanism other than assert() to generate warning or error >> messages?  Assert seems kind of clumsy, since it prints the test, and it >> is >> always a fatal error instead of a warning. >> > > Yes, you may insert an echo. I usually do something like this: So with tagging I can get the color, but it's not going to be included in the warning count.  I normally find that all the warning message scroll off the message area due to the statistics report at the end.  Has anybody ever talked about adding a warning command to the language, or extending echo to have a warning flag that makes it count on the warning list? -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 Here's the current version of my code, which appears to be working.  It can round over each corner with an independently set rounding parameter (including no rounding), and it can handle open and closed paths in 2d or 3d.   use use // TODO: //   remove colinear points? // // roundcorners(path, curve, type, all, closed) // // path: a list of 2d or 3d points, possibly with an extra coordinate giving smoothing parameters, e.g. //      ex:  [[0,0],[0,1],[1,1],[0,1]]    2d point list //           [[0,0,0], [0,1,1], [1,1,2], [0,1,3]]    3d point list //           [[0,0,.2],[0,1,.1],[1,1,0],[0,1,.3]]    2d point list with smoothing parameters //           [[0,0,0,.2], [0,1,1,.1], [1,1,2,0], [0,1,3,.3]]    3d point list with smooth parameters //           [[0,0,[.3,.5], [4,0,[.2,.6]], [4,4,0], [0,4,[ // curve: set to "smooth" to get continuous curvature 4th order bezier curves //        set to "circle" to get circular arcs // type: set to "cut" with either curve type to specify how much of the corner to "cut" off.  The //                    smoothing parameter will be the distance from the corner to the tip of the rounded curve //       set to "radius" to use with curve=="circle" to specify the curve radius //       set to "joint" to use with curve=="smooth" to specify the distance from the corner at which //                    the curve joints the shape // all: set this to a curvature parameter to apply to all points on the list.  If this is set then all //      of the values given in the path are assumed to be geometrical coordinates.  If you don't set it //      then the last value of each entry in path is assumed to be the smoothing parameters // closed: set to true (the default) if the curve is closed and false if the curve is open at the ends // // If you select curve=="smooth" then there are two smoothing parameters. The first one // is the cut or joint distance as given type "type".  The second one is a curvature // parameter which is a number in [0,1], where larger numbers have a more abrupt // transition and smaller ones a more gradual transition.  If the curvature parameter is // close to zero the transition is so gradual that it may take a very large distance. // // If you select curves that are too large to fit the code will fail with an error.  It displays a set // of scale factors that you can apply to the (first) smoothing parameter which will reduce the size of the // curves so that they will fit on the shape.  If the scale factors are larger than one then they // indicate how much you can increase the curve size before collisions will occur. // function roundcorners(path, curve, type, all=undef,  closed=true) =   let(     default_curvature = 0.7,   // default curvature for "smooth" curves     typeok = type == "cut" || (curve=="circle" && type=="radius") ||                               (curve=="smooth" && type=="joint")   )   assert(curve=="smooth" || curve=="circle", "Unknown 'curve' setting in roundcorners")   assert(typeok, curve=="circle" ? "In roundcorners curve==\"circle\" requires 'type' of 'radius' or 'cut'":                                    "In roundcorners curve==\"smooth\" requires 'type' of 'joint' or 'cut'")   let(     pathfixed= all == undef ? path : array_zip([path, replist([all],len(path))]),     dim = len(pathfixed)-1,     points = array_subindex(pathfixed, [0:dim-1]),     parm = array_subindex(pathfixed, dim),     // dk will be a list of parameters, for the "smooth" type the distance and curvature parameter pair,     // and for the circle type, distance and radius.       dk = [for(i=[0:len(points)-1]) let(         angle = pathangle(wrap_range(points,i-1,i+1))/2,       parm0 = is_list(parm[i]) ? parm[i] : parm[i],       k = curve=="circle" && type=="radius" ? parm0 :           curve=="circle" && type=="cut" ? parm0 / (1/sin(angle) - 1) :             is_list(parm[i]) && len(parm[i])==2 ? parm[i] : default_curvature       ) !closed && (i==0 || i==len(points)-1) ? [0,0] :         curve=="circle" ? [k/tan(angle), k] :         curve=="smooth" && type=="joint" ? [parm0,k] :               [8*parm0/cos(angle)/(1+4*k),k]     ],     lengths = [for(i=[0:len(points)]) norm(flatten(diff(wrap_range(points, i-1,i))))],     scalefactors = [for(i=[0:len(points)-1])       min(lengths[i]/sum(array_subindex(wrap_range(dk,i-1,i),0)),           lengths[i+1]/sum(array_subindex(wrap_range(dk,i,i+1),0)))]   )   echo("Roundover scale factors:",scalefactors)   assert(min(scalefactors)>=1,"Curves are too big for the path")   [ for(i=[0:len(points)-1])         each  dk[i] == 0 ? [points[i]] :               curve=="smooth" ? bezcorner(wrap_range(points,i-1,i+1), dk[i]) :                                 circlecorner(wrap_range(points,i-1,i+1), dk[i])   ]; function bezcorner(points, parm) =   let(      d = parm,      k = parm,      prev = normalize(points-points),      next = normalize(points-points),      P = [points+d*prev,           points+k*d*prev,           points,           points+k*d*next,           points+d*next])     bezier_curve(P,20); function circlecorner(points, parm) =   let(     angle = pathangle(points)/2,     d = parm,     r = parm,     prev = normalize(points-points),     next = normalize(points-points),     center = r/sin(angle) * normalize(prev+next)+points     )   circular_arc(center, points+prev*d, points+next*d, 20); function circular_arc(center, p1, p2, N) = let(    angle = pathangle([p1,center,p2]),    v1 = p1-center,    v2 = p2-center)    len(center)==2 ?        let ( start = atan2(v1,v1),              end = atan2(v2,v2),              r=norm(v1))          [for(i=[0:N-1]) let(theta=(end-start)*i/(N-1)+start) r*[cos(theta),sin(theta)]+center] :        let(axis = cross(v1,v2))          [for(i=[0:N-1]) matrix3_rot_by_axis(axis, i*angle/(N-1)) * v1 + center]; function bezier_curve(P,N) =    [for(i=[0:N-1]) bez_point(P, i/(N-1))]; function pathangle(pts) =   let( d = [for(i=[0:2]) norm(flatten(diff(wrap_range(pts,i,i+1))))] )   acos(constrain(       (d*d + d*d - d*d) / 2 / d / d, -1,1)); function array_subindex(vect, index) =     [for(entry=vect)          let(value=[for(i=index) entry[i]])              len(value)==1 ? value : value]; function array_zip(vecs,v2,v3) =   v3!=undef ? array_zip([vecs,v2,v3]) :   v2!=undef ? array_zip([vecs,v2]) :   let(     length = len(vecs),     samesize = [for (v=vecs) len(v)==length?0:1],     dummy=assert(sum(samesize)==0,"Input vectors must have the same length")   )   [for(i=[0:length-1])      [for(v=vecs) each v[i]]   ]; function replist(list, N) = [for(i=[0:N-1]) list]; function diff(v) =   [for(i=[0:len(v)-2]) v[i+1]-v[i]]; sq = [[0,0],[2,0],[2,2],[0,2]]; polygon(roundcorners(sq, curve="circle", type="cut", all=.2)); translate([2.5,0,0])polygon(roundcorners(sq, all=[.2,.5], curve="smooth", type="cut")); -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 This may be more graphs than anyone wants to look at, but I did an analysis of order 5 smoothing to see if it presented any obvious benefits.  Since there are now two parameters, it's more to look at.  I'm defining has h1 the location of P1 and P4 as the fraction of the distance away from the apex towards P0 and P5, and I define h2 as the fractional distance from the apex to P1 or P4.   In this case, unlike the previous plot the curvatures are calculated for the *scaled* roundovers that are shown on the left side.   It looks to me like the cases h2=0.5 and maybe h2=0.7 are the most promising, so focusing on those and comparing to the order 4 case I have the following: After examining these various plots I am hard pressed to see an obvious benefit to using order 5.  There is only one matter left to consider.  It turns out that if you like h2=0.7 you may be able to achieve a roundover in a shorter space by using order 5.  But note that this is only true for h1 values above about 0.4.  If h1 gets small then order 4 is much more efficient.   Here is a comparison of a few selected "nice" looking parameter sets, where d gives the location of p0 relative to the apex (so smaller is better).   So maybe the argument could be made for the blue curve, which gives d 5% smaller than the next best option.  But really it's not much difference. Again, it seems hard to justify using 5th order, and especially with the worsening behavior as the h1 parameter shrinks.   So have I beat this to death yet?   -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 adrianv wrote > So have I beat this to death yet?   I realized that the curvature plots should really be done as arc-length vs curvature instead of Bezier parameter vs curvature.  The curves with larger parameter value have parameterizations that move very slowly near the end points, so my previous plots underestimate the slope of the curvature there. Also plotting based on arc-length makes it easier to understand the trade off of really long curves to shorter ones.  I can post updated plots if anybody actually wants to see them.   -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: Rounded Polygon

 I would like to see them. I would expect a parametric slow down where the curvature is greater due to smaller norms of the parametric derivatives there. adrianv <[hidden email]> wrote: The curves with larger parameter value have parameterizations that move very slowly near the end points, so my previous plots underestimate the slope of the curvature there. Also plotting based on arc-length makes it easier to understand the trade off of really long curves to shorter ones.  I can post updated plots if anybody actually wants to see them.  _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
 Ronaldo wrote I would like to see them. Ok. Here they are. These are the same plots posted before, but the curvature graph (right side) is now plotted as arc length of the bezier curve against the curvature. I placed the center of the bezier curve at 0 and only show half the curve, so the curves start at some negative number equal to half their length. Some of the curves with small h parameters are very long indeed (up to about length 40) so I plotted everything on the same scale and cut off some of them so it's easier to compare between graphs. I don't feel like the new graphs lead to any change in the conclusions. There's not a big difference between the order 4 and order 5 curves, but the order 5 do manage with slightly shorter lengths. The graphs do highlight the poor properties of the curves with h1 close to 1---worse than using a circle in terms of smoothness due to the overshoot at the ends. I also do wonder how much the derivative of the curvature matters. Will I be able to feel the difference between cases where the curvature plot has a steeper slope? Or does matching curvature really suffice and seeking higher levels of continuity is just unnecessary. I was thinking I need to print out some tests. The final graph has a different scale for the curvatures to make it easier to compare between the rather similar lines that appear on the plot.         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