Created
April 26, 2018 18:32
-
-
Save thehans/544138d0850ce8a0a72c755a59a4a3f4 to your computer and use it in GitHub Desktop.
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
/* | |
Thrust bearing by Hans Loeblich | |
License CC BY-SA | |
*/ | |
/* [Hidden] */ | |
// constants | |
in = 25.4; | |
$fa = 0.1; | |
$fs = 0.25; | |
LOWER = 0; | |
UPPER = 1; | |
/* [Parameters] */ | |
ID = 80; | |
OD = 100; | |
dBB = 4.5; // Nominal BB diameter | |
// Clearance added to diameter of bearing race channel | |
bbClearance = 0.2; | |
// Angle between vertical and the split between upper/lower bearing races | |
offsetAngle = 30; | |
// Gap between upper and lower race after assembled and collapsed | |
gapWidth = 0.3; | |
// Thickness of flange on top race. | |
topTh = 2; | |
// Thickness of flange bottom race. | |
bottomTh = 2; | |
// Minimum thickness above/below BB, in addition to flange thickness (topTh, bottomTh) | |
verticalPadding = 0.0; | |
// Added to dBB for filler hole only, (bbClearance not used for filler) | |
fillerClearance = 0.0; | |
rFlange = 5; | |
boltFlange = false; | |
boltD = 20*sqrt(2); | |
/* [Special Views] */ | |
// View the 2d section of bearing before rotate extrude | |
view2d = false; | |
// render balls for preview/mockup (printing not recommended) | |
displayBBs = 0; // [0:none, 1:single, 2:all] | |
// remove bbClearance separation from upper and lower race | |
displayCollapsed = false; | |
// cut 90 degree section away to view inside part | |
cutaway = false; | |
// WARNINGS | |
if (topTh + verticalPadding <= 0) echo("WARNING: topTh + verticalPadding <= 0 Upper race is not whole."); | |
if (bottomTh + verticalPadding <= 0) echo("WARNING: bottomTh + verticalPadding <= 0 Lower race is not whole."); | |
// calculated values | |
dRace = (OD+ID)/2; // centered between OD and ID by default, rewrite this line for custom | |
rBB = dBB/2; | |
rRace = dRace/2; | |
minAngle = 2*atan(rBB/rRace); | |
collapsed_height = dBB + verticalPadding*2 + topTh + bottomTh; | |
section_width = (OD-ID)/2; | |
echo(ID=ID, OD=OD, section_width=section_width, collapsed_height=collapsed_height); | |
echo(str("bearing", ID, "x", OD, "x", collapsed_height, "_", dBB, "mm", bbClearance*100, "clr", offsetAngle, "deg", , gapWidth*100, "gap_", topTh, "_", bottomTh, "_", verticalPadding, "_", fillerClearance, ".stl")); | |
echo(str("Max BBs: ", 360/minAngle)); | |
// Scene | |
//translate([0,0,-1]) // make axis labels visible from overhead in 2d view | |
{ | |
bearingRace3(side=LOWER); | |
translate((displayCollapsed ? bbClearance : 0) * (view2d ? [0,-1] : [0,0,-1])) | |
bearingRace3(side=UPPER); | |
if (displayBBs) { | |
if (view2d) | |
displayBall2D(); | |
else | |
displayBalls(single=(displayBBs==1)); | |
} | |
} | |
// return the 2d point where the line equation f(x) = m*x + b intersects the given y value | |
function line2D(m, b, y=0) = let(x = (y-b)/m) [x,y]; | |
// return array containing both solutions of quadratic equation | |
function quadratic(a,b,c) = let(D=b*b-4*a*c,d=sqrt(D)) [(-b+d)/(2*a),(-b-d)/(2*a)]; | |
module bearingRace3(side=0) { | |
xInner = -rRace + ID/2; | |
xOuter = OD/2 - rRace; | |
yOffset = gapWidth/2 * sin(offsetAngle); | |
// y = m*x + b; | |
m = tan(90 - offsetAngle); | |
b = -m * gapWidth/2 - bbClearance/2; | |
// r*r = x*x + y*y | |
// r*r = x*x + (m*x+b)*(m*x+b) | |
// 0 = (m*m+1)*x*x + (2*m*b)*x + (b*b-r*r) | |
// a = m*m+1 | |
// b = 2*m*b; | |
// c = b*b-r*r; | |
r = (dBB + bbClearance)/2; | |
x0 = quadratic(a=m*m+1, b=2*m*b, c=b*b-r*r)[0]; | |
y3 = -r - verticalPadding; | |
y2 = y3 - (side==LOWER ? bottomTh : topTh); | |
y1 = -y3 - gapWidth - bbClearance; | |
points = [line2D(m,b,y1), [xOuter,y1], [xOuter,y2], [xInner,y2], [xInner, y3], line2D(m,b,y3)]; | |
//echo("line parameters (y=mx+b): ", m=m, b=b); | |
//echo("quadratic parameters: ", a=m*m+1, b=2*m*b, c=b*b-r*r); | |
//echo(points); | |
if (view2d) { | |
translate([rRace, 0]) | |
difference() { | |
if (side==LOWER) color([0,1,0]) polygon(points); | |
else color([1,0,0]) scale(-1) polygon(points); | |
circle(d=dBB+bbClearance, $fs=0.2); | |
} | |
} else { | |
union() { | |
difference() { | |
// ring, bearing race | |
rotate_extrude(convexity=6, angle=cutaway ? 270 : 360) | |
translate([rRace, 0]) difference() { | |
if (side==LOWER) color([0,1,0]) polygon(points); | |
else color([1,0,0]) scale(-1) polygon(points); | |
circle(d=dBB+bbClearance, $fs=0.2); | |
} | |
// filler hole | |
h = rRace - ID/2+1; | |
if (!view2d && side==UPPER) translate([rRace,0]) | |
translate([0,0,-gapWidth-fillerClearance/2]) rotate([0,-90]) translate([0,0,-bbClearance/2]) | |
cylinder(d=dBB+fillerClearance, h=h, $fs=0.1); | |
} | |
if (boltFlange) { | |
// bolt flange | |
flangeOffset = side ? | |
r + verticalPadding: | |
-r - verticalPadding - bottomTh; | |
translate([0,0,flangeOffset]) | |
linear_extrude(side ? topTh : bottomTh) | |
difference() { | |
poly2d(square(40, r=rFlange, center=true)); | |
circle(r=rRace); | |
} | |
} | |
} | |
} | |
} | |
// TODO, create ledge for plug to sit at correct depth, complete the design | |
module plug() { | |
// ??h = r+inner Th+1; | |
entryAngle = 5; | |
// maxClearance = | |
if (side) translate([rRace-bbClearance/2,0]) rotate([0,-90]) | |
cylinder(d1=dBB, d2=dBB+2*h*tan(entryAngle), h=h, $fs=0.1); | |
} | |
module displayBall2D() { | |
$fs = 0.1; | |
// visualize bb off to one side of race, in any direction | |
//bbAngle = -90; | |
//bbOffset = bbClearance/2*[cos(bbAngle), sin(bbAngle),0]; | |
bbOffset = displayCollapsed ? [rRace,-bbClearance/2] : [rRace,0]; | |
color("blue") translate(bbOffset) circle(d=dBB); | |
} | |
module displayBalls() { | |
fillRatio = 1; | |
minAngle = 2*atan(rBB/rRace); | |
maxSteps = floor(fillRatio*360/minAngle); | |
$fs=0.2; | |
echo(str("BBs for ", fillRatio, " fill ratio: ", maxSteps)); | |
bbAngle = 90; | |
bbOffset = bbClearance/2*[cos(bbAngle), 0, -sin(bbAngle)]; | |
echo(bbOffset); | |
color([0.8,0.8,0.8]) for(i=[single?maxSteps:1:1:maxSteps]) let(a=i*360/maxSteps) | |
rotate(a) translate([rRace-dBB*$t,0,0]+bbOffset) | |
sphere(d=dBB); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment