Skip to content

Instantly share code, notes, and snippets.

@thehans
Created November 24, 2019 09:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thehans/b47ab7077c862361eb5d8f095448b2d4 to your computer and use it in GitHub Desktop.
Save thehans/b47ab7077c862361eb5d8f095448b2d4 to your computer and use it in GitHub Desktop.
OpenSCAD example of particular way to fillet when extruding a 2D profile
$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);
}
}
}
}
}
}
}
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment