Created
November 24, 2019 09:51
-
-
Save thehans/b47ab7077c862361eb5d8f095448b2d4 to your computer and use it in GitHub Desktop.
OpenSCAD example of particular way to fillet when extruding a 2D profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$fs=0.5; | |
$fa=1; | |
// example usage | |
fillet_extrude(height=10,r1=3,r2=-3) { | |
hull() { | |
translate([-10,0]) circle(5); | |
translate([10,0]) circle(5); | |
} | |
rotate(90) hull() { | |
translate([-10,0]) circle(5); | |
translate([10,0]) circle(5); | |
} | |
} | |
// linear_extrude with optional fillet radius on each end | |
// Parameters: | |
// height - total extrusion length including radii | |
// r1 - bottom radius | |
// r2 - top radius | |
// positive radii will expand outward towards their end | |
// negative will shrink inward towards their end | |
// Limitations: | |
// - individual children of fillet_extrude should be convex | |
// - only straight extrudes with no twist or scaling supported | |
// - fillets only for 90 degress betweeen Z axis and top/bottom surface | |
module fillet_extrude(height=100, r1=0, r2=0) { | |
function fragments(r=1) = | |
($fn > 0) ? ($fn >= 3 ? $fn : 3) : ceil(max(min(360.0 / $fa, r*2*PI / $fs), 5)); | |
assert(abs(r1)+abs(r2) <= height); | |
midh = height-abs(r1)-abs(r2); | |
eps = 1/1024; | |
union() { | |
if (r1!=0) { | |
fn1 = ceil(fragments(abs(r1))/4); // only covering 90 degrees | |
for(i=[0:1:$children-1], j=[1:1:fn1]) { | |
a1 = 90*(j-1)/fn1; a2 = 90*j/fn1; | |
h1 = abs(r1)*(1-cos(a1)); h2 = abs(r1)*(1-cos(a2)); | |
off1 = r1*(1-sin(a1)); off2 = r1*(1-sin(a2)); | |
hull() { | |
translate([0,0,h1]) { | |
// in case radius*2 matches width of object, don't make first layer zero width | |
off1 = r1 < 0 && j==1 ? off1*(1-eps) : off1; | |
linear_extrude(eps) offset(r=off1) children(i); | |
} | |
translate([0,0,h2]) | |
linear_extrude(eps) offset(r=off2) children(i); | |
} | |
} | |
} | |
if (midh > 0) { | |
translate([0,0,abs(r1)]) | |
for(i=[0:1:$children-1]) linear_extrude(midh) children(i); | |
} | |
if (r2!=0) { | |
fn2 = ceil(fragments(abs(r2))/4); // only covering 90 degrees | |
translate([0,0,height-abs(r2)-eps]) { | |
for(i=[0:1:$children-1], j=[1:1:fn2]) { | |
a1 = 90*(j-1)/fn2; a2 = 90*j/fn2; | |
h1 = abs(r2)*(sin(a1)); h2 = abs(r2)*(sin(a2)); | |
off1 = r2*(1-cos(a1)); off2 = r2*(1-cos(a2)); | |
hull() { | |
translate([0,0,h1]) | |
linear_extrude(eps) offset(r=off1) children(i); | |
translate([0,0,h2]) { | |
// in case radius*2 matches width of object, don't make last layer zero width | |
off2 = r2 < 0 && j==fn2 ? off2*(1-eps) : off2; | |
linear_extrude(eps) offset(r=off2) children(i); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment