Rounding convex edges without minkowski?

classic Classic list List threaded Threaded
29 messages Options
12
jsc
Reply | Threaded
Open this post in threaded view
|

Rounding convex edges without minkowski?

jsc
I have just published my universal OpenSCAD fidget spinner model: https://www.thingiverse.com/thing:2360208

Calculating the three circle Apollonius problem in OpenSCAD was a pretty challenge, but what really frustrated me was rounding off the edges of the final profile. I finally settled on minkowski sum with a sphere on a minimal height 2D profile extrusion, but for a high resolution model it takes about ten minutes to calculate.

Is there any more efficient way to round these edges than this? I don't see how I can use hull() in this case.
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Gadgetmind
On 2017-06-02 08:48, jsc wrote:
> Is there any more efficient way to round these edges than this? I don't see
> how I can use hull() in this case.

Maybe change your current linear extrude to several of them in a for
loop and use the loop variable in some interesting way to change the
value of offset.

I put this in spinner_preview and it looks OK. Crank up slices based on
whether previewing or not?

       slices = 50;
       curve = bearing_height/2;
       for (s = [0 : 1 : slices-1])
         translate ([0, 0, bearing_height/slices*s])
             linear_extrude(height = bearing_height/slices+0.01, center
= true) offset (-curve*(1-cos((s/slices-0.5)*180))) profile();

The offset function is down to you and could easily be flat in the
middle and then just curve at top and bottom. If you can handle
Apollonius ...


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Gadgetmind
 > I put this in spinner_preview and it looks OK. Crank up slices based
on whether previewing or not?

Hmm, still pretty slow at rendering, but could use plain extrude for the
middle and just some offset slices at top and bottom?

Or change approach and use rounded cylinders to construct your spinner?


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Gadgetmind
Sorry, should be "offset (delta= ..." but maybe that's default?

You also may want to remove the bearing and weights as 2D objects and
the offset can then apply to those too so the inner holes are chamfered,
but maybe you don't actually want this?


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Ronaldo
In reply to this post by jsc
In your particular case of filleting circular forms, a faster method is to union rotated extrusions. The snapshot versions of OpenSCAD allow to prescribe an angle in the rotate_extrude to help things go easier.

2017-06-02 4:48 GMT-03:00 jsc <[hidden email]>:
I have just published my universal OpenSCAD fidget spinner model:
https://www.thingiverse.com/thing:2360208

Calculating the three circle Apollonius problem in OpenSCAD was a pretty
challenge, but what really frustrated me was rounding off the edges of the
final profile. I finally settled on minkowski sum with a sphere on a minimal
height 2D profile extrusion, but for a high resolution model it takes about
ten minutes to calculate.

Is there any more efficient way to round these edges than this? I don't see
how I can use hull() in this case.



--
View this message in context: http://forum.openscad.org/Rounding-convex-edges-without-minkowski-tp21621.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
jsc
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

jsc
In reply to this post by Gadgetmind
I simplified your code to:
     slices = 40; 
     curve_r = bearing_height/2; 
     for (s = [1 : slices])
	  linear_extrude(height = s*bearing_height/slices, center = true)
	       offset(delta = curve_r * (cos(90*(s-1)/slices) - 1))
	       profile();
Instead of translating each slice into place, I just made taller and taller extrusions working in. As you noted, it is quite slow to render, and the curve is pointier than I would have expected, for some reason.
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

jdawgaz
In reply to this post by Ronaldo
There are more ways to skin that cat.

I have sometimes, if I wanted rounded corners, done an intersection with a sphere (just big enough, to round the corners on a cube for instance).



--
Extra Ham Operator: K7AZJ
Registered Linux User: 275424
Raspberry Pi and Openscad developer

The most exciting phrase to hear in science - the one that heralds new discoveries - is not "Eureka!" but "That's funny...".
- Isaac. Asimov


On Fri, Jun 2, 2017 at 10:56 AM, Ronaldo Persiano <[hidden email]> wrote:
In your particular case of filleting circular forms, a faster method is to union rotated extrusions. The snapshot versions of OpenSCAD allow to prescribe an angle in the rotate_extrude to help things go easier.

2017-06-02 4:48 GMT-03:00 jsc <[hidden email]>:
I have just published my universal OpenSCAD fidget spinner model:
https://www.thingiverse.com/thing:2360208

Calculating the three circle Apollonius problem in OpenSCAD was a pretty
challenge, but what really frustrated me was rounding off the edges of the
final profile. I finally settled on minkowski sum with a sphere on a minimal
height 2D profile extrusion, but for a high resolution model it takes about
ten minutes to calculate.

Is there any more efficient way to round these edges than this? I don't see
how I can use hull() in this case.



--
View this message in context: http://forum.openscad.org/Rounding-convex-edges-without-minkowski-tp21621.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



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

thehans
In reply to this post by Ronaldo
My star knob design has the same sort of profile as your spinner and
rounded edges all over, you can maybe get some ideas from how I
modeled that.  Its basically what ronaldo says, just do a bunch of
partial rotate_extrudes.
https://www.thingiverse.com/thing:1562501

There are some primitive fillet related functions in the star knob
script that I think originated from here:
https://github.com/jfhbrook/openscad-fillets/blob/master/fillets.scad
But IIRC I ended up modifying the functions many times to fit specific
things I needed that they no longer resemble to original code.

If I were to re-write it today I would probably replace those fillet
functions with some polygon generating functions that incorporate the
"arc" function from my FunctionalOpenSCAD library (
https://github.com/thehans/FunctionalOpenSCAD/blob/master/functional.scad
)


Also, I wish this sort of geometry problem was referred to as the
Appolonius problem when I was solving it myself!

Hans

On Fri, Jun 2, 2017 at 12:56 PM, Ronaldo Persiano <[hidden email]> wrote:

> In your particular case of filleting circular forms, a faster method is to
> union rotated extrusions. The snapshot versions of OpenSCAD allow to
> prescribe an angle in the rotate_extrude to help things go easier.
>
> 2017-06-02 4:48 GMT-03:00 jsc <[hidden email]>:
>>
>> I have just published my universal OpenSCAD fidget spinner model:
>> https://www.thingiverse.com/thing:2360208
>>
>> Calculating the three circle Apollonius problem in OpenSCAD was a pretty
>> challenge, but what really frustrated me was rounding off the edges of the
>> final profile. I finally settled on minkowski sum with a sphere on a
>> minimal
>> height 2D profile extrusion, but for a high resolution model it takes
>> about
>> ten minutes to calculate.
>>
>> Is there any more efficient way to round these edges than this? I don't
>> see
>> how I can use hull() in this case.
>>
>>
>>
>> --
>> View this message in context:
>> http://forum.openscad.org/Rounding-convex-edges-without-minkowski-tp21621.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
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
jsc
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

jsc
In reply to this post by jsc
jsc wrote
... the curve is pointier than I would have expected, for some reason.
Oh, right, must base the curve on angle, not z height:

     slices = 40;
     curve_r = bearing_height/2;
     for (s = [1 : slices]) {
          h = s*bearing_height/slices;
          theta = asin(h / bearing_height);
          linear_extrude(height = h, center = true)
               offset(delta = curve_r * (cos(theta) - 1))
               profile();
     }

I will try out some of the suggestions other people have made to this thread, too.
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Ronaldo
Your code spent more then 28 min. to render in my rather old notebook. The following code is a redesign of spinner_solid() using rotate_extrude instead of minkovsky. Now, it renders in 4 min in my computer.

module spinner_solid()
{
    // from body()
    poly = [[0, bearing_to_weight_centers_dist],
            [tc[0], tc[1]],
            [cos(30)*bearing_to_weight_centers_dist, -sin(30)*bearing_to_weight_centers_dist],
            [0, -sqrt(tc[0]*tc[0] + tc[1]*tc[1])],
            [-cos(30)*bearing_to_weight_centers_dist, -sin(30)*bearing_to_weight_centers_dist],
            [-tc[0], tc[1]]];
    r   = bearing_height/2;
    x1 = bearing_to_weight_centers_dist;
    R  = lobe_r;
    x2 = norm([tc[0],tc[1]]);

    // the three lobes
    rotate( 90) translate([x1,0,0]) filled_torus(R,r);
    rotate(-30) translate([x1,0,0]) filled_torus(R,r);
    rotate(210) translate([x1,0,0]) filled_torus(R,r);

    // the concave section
    intersection(){
        translate([0,0,-r])
            linear_extrude(height=2*r) polygon(poly);
        union(){
            rotate( 30) translate([x2,0,0]) torus(tc[2],r);
            rotate(-90) translate([x2,0,0]) torus(tc[2],r);
            rotate(150) translate([x2,0,0]) torus(tc[2],r);
        }
    }

    // the center filling
    translate([0,0,-r])
    difference(){
        linear_extrude(height=2*r) body();
        rotate( 30) translate([x2,0,r]) cylinder(r=tc[2],h=2*r+1,center=true);
        rotate(-90) translate([x2,0,r]) cylinder(r=tc[2],h=2*r+1,center=true);
        rotate(150) translate([x2,0,r]) cylinder(r=tc[2],h=2*r+1,center=true);
    }
}



2017-06-02 16:02 GMT-03:00 jsc <[hidden email]>:
jsc wrote

I will try out some of the suggestions other people have made to this
thread, too.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Neon22
The functions filled_torus and torus are missing ?
jsc
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

jsc
In reply to this post by Ronaldo
Excellent. I had to adjust some of the parameters to get the dimensions to work out correctly, but the general scheme worked out very well. Rendering is much faster, and the preview version is no longer needed. I updated the script and credited you in the code, although only as "Ronaldo". Thank you.
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

caterpillar
This post was updated on .
In reply to this post by jsc
I tried to come up with my solution. First, I created a two_connected_circles module:

include <rotate_p.scad>;
include <bezier_curve.scad>;
include <rounded_extrude.scad>;

$fn = 36;

radius = 10;
leng = 40;
t_step = 0.1;
tangent_angle = 40;

module two_connected_circles(radius, dist, tangent_angle, t_step) {
    half_dist = dist / 2;

    p1 = rotate_p([0, -radius], tangent_angle) + [-half_dist, 0];
    p2 = rotate_p([radius * tan(tangent_angle), -radius], tangent_angle) + [-half_dist, 0];

    p3 = [-p1[0], p1[1]];
    p4 = [-p2[0], p2[1]];

    curve_pts = bezier_curve(t_step, [p1, p2, p4, p3]);
    leng_pts = len(curve_pts);

    upper_curve_pts =
        [
            for(i = [0:leng_pts - 1])
                curve_pts[leng_pts - i - 1]
        ];
    lower_curve_pts =
        [
            for(pt = curve_pts)
                [pt[0], -pt[1]]
        ];
   
    translate([-half_dist, 0])
        circle(radius);
    translate([half_dist, 0])
        circle(radius);
       
    polygon(
        concat(
            upper_curve_pts,
            lower_curve_pts
        )
    );
}

two_connected_circles(
    radius, leng, tangent_angle, t_step
);



After that, I created a tri_connected_circles module:

module tri_connected_circles(radius, leng, tangent_angle, t_step) {
    angle = 60;
    half_leng = leng / 2;
   
    module two_circles() {
        two_connected_circles(radius, leng, tangent_angle, t_step, round_r);
    }
   
    translate([0, -half_leng * tan(30), 0]) union() {
        two_circles();

        translate([-half_leng, 0, 0])
            rotate(angle)
                translate([half_leng, 0, 0])
                    two_circles();

        translate([half_leng, 0, 0])
            rotate(-angle)
                translate([-half_leng, 0, 0])
                    two_circles();
    }
}

tri_connected_circles(radius, leng, tangent_angle, t_step);



Then, I can rounded it by the following code:

round_r = 3;

rounded_extrude([leng + 2 * radius, leng * tan(60) + 2 * radius], round_r, 180)
    union() {
        circle(radius * 1.5);
        tri_connected_circles(radius, leng, tangent_angle, t_step);
    }



The complete code:

include <rotate_p.scad>;
include <bezier_curve.scad>;
include <rounded_extrude.scad>;

$fn = 36;

radius = 10;
leng = 40;
t_step = 0.1;
tangent_angle = 40;
round_r = 3;

module two_connected_circles(radius, dist, tangent_angle, t_step) {
    half_dist = dist / 2;

    p1 = rotate_p([0, -radius], tangent_angle) + [-half_dist, 0];
    p2 = rotate_p([radius * tan(tangent_angle), -radius], tangent_angle) + [-half_dist, 0];

    p3 = [-p1[0], p1[1]];
    p4 = [-p2[0], p2[1]];

    curve_pts = bezier_curve(t_step, [p1, p2, p4, p3]);
    leng_pts = len(curve_pts);

    upper_curve_pts =
        [
            for(i = [0:leng_pts - 1])
                curve_pts[leng_pts - i - 1]
        ];
    lower_curve_pts =
        [
            for(pt = curve_pts)
                [pt[0], -pt[1]]
        ];
   
    translate([-half_dist, 0])
        circle(radius);
    translate([half_dist, 0])
        circle(radius);
       
    polygon(
        concat(
            upper_curve_pts,
            lower_curve_pts
        )
    );
   
}

module tri_connected_circles(radius, leng, tangent_angle, t_step) {
    angle = 60;
    half_leng = leng / 2;
   
    module two_circles() {
        two_connected_circles(radius, leng, tangent_angle, t_step, round_r);
    }
   
    translate([0, -half_leng * tan(30), 0]) union() {
        two_circles();

        translate([-half_leng, 0, 0])
            rotate(angle)
                translate([half_leng, 0, 0])
                    two_circles();

        translate([half_leng, 0, 0])
            rotate(-angle)
                translate([-half_leng, 0, 0])
                    two_circles();
    }
}

* two_connected_circles(
    radius, leng, tangent_angle, t_step
);

* tri_connected_circles(radius, leng, tangent_angle, t_step);

rounded_extrude([leng + 2 * radius, leng * tan(60) + 2 * radius], round_r, 180)
    union() {
        circle(radius * 1.5);
        tri_connected_circles(radius, leng, tangent_angle, t_step);
    }

You can find rotate_p.scad, bezier_curve.scad, rounded_extrude.scad here:
https://justinsdk.github.io/dotSCAD/
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Ronaldo
In reply to this post by Neon22
You are right. Here they are:

module torus(R,r) rotate_extrude() translate([R,0,0]) circle(r);

module filled_torus(R,r) { torus(R,r); cylinder(r=R,h=2*r, center=true); }



2017-06-02 19:20 GMT-03:00 Neon22 <[hidden email]>:
The functions filled_torus and torus are missing ?



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

caterpillar
In reply to this post by caterpillar
I added a shape_glued2circles function into my library. Now, we can simplify the code:

include <rotate_p.scad>;
include <bezier_curve.scad>;
include <shape_pie.scad>;
include <shape_glued2circles.scad>;
include <rounded_extrude.scad>;

$fn = 48;

radius = 10;
leng = 40;
tangent_angle = 40;
round_r = 3;

module tri_connected_circles(radius, leng, tangent_angle) {
    angle = 60;
    half_leng = leng / 2;
   
    module two_circles() {
        polygon(
            shape_glued2circles(radius, leng, tangent_angle = tangent_angle)
        );
    }
   
    translate([0, -half_leng * tan(30), 0]) union() {
        two_circles();

        translate([-half_leng, 0, 0])
            rotate(angle)
                translate([half_leng, 0, 0])
                    two_circles();

        translate([half_leng, 0, 0])
            rotate(-angle)
                translate([-half_leng, 0, 0])
                    two_circles();
    }
}


rounded_extrude([leng + 2 * radius, leng * tan(60) + 2 * radius], round_r, 180)
    union() {
        circle(radius * 1.5);
        tri_connected_circles(radius, leng, tangent_angle);
    }    
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Parkinbot
In reply to this post by caterpillar
here a nice and simple constructor:
offset(-15) offset(12) forN(r=26, N=3) circle(20);
module forN(r, N) for(i=[0:N-1]) rotate([0,0,i*360/N]) translate([r, 0, 0]) children();
WITH minkowski the code for the fidget is quite straight forward. 4 minute render time is not at all bad.

$fn=40;          // use 10 for experiments, 40 for finals (4min)
fidget(22,7);   // call with bearing diameter and height in mm

module fidget(d, h)
{
  r=d/2;
  r3 = r/3;
  r8 = r3*8;
  difference()
  {
    minkowski()
    {
      linear_extrude(height = .01, convexity = 4)
         offset(-r3*4-h/2) offset(r3*4) forN(r8, 3) circle(r3*5);
      sphere(h/2);
    }
    forN(r8, 3) cylinder(r=r, h=r, center=true);
    cylinder(r=r, h=r, center=true);
  }
}
module forN(r, N) for(i=[0:N-1]) rotate([0,0,i*360/N]) translate([r, 0, 0]) children();
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Ronaldo
Very clever use of offset that avoids the Apollonius circle computation. However, except for the generation of the profile, your code is essentially the same as the original spinner_solid and the running time should be about the same.

2017-06-04 20:19 GMT-03:00 Parkinbot <[hidden email]>:
WITH minkowski the code for the fidget is quite straight forward. 4 minute
render time is not at all bad.


> $fn=40;          // use 10 for experiments, 40 for finals (4min)
> fidget(22,7);   // call with bearing diameter and height in mm
>
> module fidget(d, h)
> {
>   r=d/2;
>   r3 = r/3;
>   r8 = r3*8;
>   difference()
>   {
>     minkowski()
>     {
>       linear_extrude(height = .01, convexity = 4)
>          offset(-r3*4-h/2) offset(r3*4) forN(r8, 3) circle(r3*5);
>       sphere(h/2);
>     }
>     forN(r8, 3) cylinder(r=r, h=r, center=true);
>     cylinder(r=r, h=r, center=true);
>   }
> }
> module forN(r, N) for(i=[0:N-1]) rotate([0,0,i*360/N]) translate([r, 0,
> 0]) children();


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Parkinbot
If you use the constructor with a circle you can even omit the first offset and enlarge the circle radius of course.

offset(-r3*4-h/2) forN(r8, 3) circle(r3*9);
What a pity that we don't get hands on the coordinates  ...
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

Gadgetmind
On 2017-06-05 10:30, Parkinbot wrote:
> What a pity that we don't get hands on the coordinates  ...

I've started creating lots of objects with functions that return points
(some my own, some using shapes and transform from SCAD utils) for
exactly this reason, and because I get rounding almost for free.

For instance, this function gives me the points for a rounded rectangle,
and I call it from a RoundedBox function (1) that uses similar loops to
round in the other dimensions. Throw the points into Skin () and the job
is done.

function RoundedRect (xsize=10, ysize=10, r=1, fa=$fa) = [
     let (xo=(xsize/2)-r,yo=(ysize/2)-r)
     for (a = [0: fa : 360-1]) [cos(a)*r + xo * sign(cos(a)), sin(a)*r +
yo * sign(sin(a))]
];

(1) - I'd supply the code but I haven't made generic yet and just have
one for my rather special case.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rounding convex edges without minkowski?

caterpillar
For the same reason, I also created several 2D shapes in my library :)

- shape_taiwan
- shape_arc
- shape_pie
- shape_ellipse
- shape_square
- shape_trapezium
- shape_cyclicpolygon
- shape_pentagram
- shape_superformula
- shape_glued2circles
- shape_path_extend
12