3D-prints/Thread_Library.scad

286 lines
11 KiB
OpenSCAD
Raw Normal View History

2023-12-24 13:37:46 -06:00
module threadPiece(Xa, Ya, Za, Xb, Yb, Zb, radiusa, radiusb, tipRatioa, tipRatiob, threadAngleTop, threadAngleBottom)
{
angleZ=atan2(Ya, Xa);
twistZ=atan2(Yb, Xb)-atan2(Ya, Xa);
polyPoints=[
[Xa+ radiusa*cos(+angleZ), Ya+ radiusa*sin(+angleZ), Za ],
[Xa+ radiusa*cos(+angleZ), Ya+ radiusa*sin(+angleZ), Za + radiusa*tipRatioa ],
[Xa , Ya , Za+ radiusa*(tipRatioa+sin(threadAngleTop)) ],
[Xa , Ya , Za ],
[Xa , Ya , Za+ radiusa*sin(threadAngleBottom) ],
[Xb+ radiusb*cos(angleZ+twistZ), Yb+ radiusb*sin(angleZ+twistZ), Zb ],
[Xb+ radiusb*cos(angleZ+twistZ), Yb+ radiusb*sin(angleZ+twistZ), Zb+ radiusb*tipRatiob ],
[Xb , Yb , Zb+ radiusb*(tipRatiob+sin(threadAngleTop)) ],
[Xb , Yb , Zb ],
[Xb , Yb , Zb+ radiusb*sin(threadAngleBottom)] ];
polyTriangles=[
[ 0, 1, 6 ], [ 0, 6, 5 ], // tip of profile
[ 1, 7, 6 ], [ 1, 2, 7 ], // upper side of profile
[ 0, 5, 4 ], [ 4, 5, 9 ], // lower side of profile
[ 4, 9, 3 ], [ 9, 8, 3 ], [ 3, 8, 2 ], [ 8, 7, 2 ], // back of profile
[ 0, 4, 3 ], [ 0, 3, 2 ], [ 0, 2, 1 ], // a side of profile
[ 5, 8, 9 ], [ 5, 7, 8 ], [ 5, 6, 7 ] // b side of profile
];
polyhedron( polyPoints, polyTriangles );
}
module shaftPiece(Xa, Ya, Za, Xb, Yb, Zb, radiusa, radiusb, tipRatioa, tipRatiob, threadAngleTop, threadAngleBottom)
{
angleZ=atan2(Ya, Xa);
twistZ=atan2(Yb, Xb)-atan2(Ya, Xa);
threadAngleTop=15;
threadAngleBottom=-15;
shaftRatio=0.5;
polyPoints1=[
[Xa, Ya, Za + radiusa*sin(threadAngleBottom) ],
[Xa, Ya, Za + radiusa*(tipRatioa+sin(threadAngleTop)) ],
[Xa*shaftRatio, Ya*shaftRatio , Za + radiusa*(tipRatioa+sin(threadAngleTop)) ],
[Xa*shaftRatio , Ya*shaftRatio , Za ],
[Xa*shaftRatio , Ya*shaftRatio , Za + radiusa*sin(threadAngleBottom) ],
[Xb, Yb, Zb + radiusb*sin(threadAngleBottom) ],
[Xb, Yb, Zb + radiusb*(tipRatiob+sin(threadAngleTop)) ],
[Xb*shaftRatio , Yb*shaftRatio , Zb + radiusb*(tipRatiob+sin(threadAngleTop)) ],
[Xb*shaftRatio , Yb*shaftRatio , Zb ],
[Xb*shaftRatio , Yb*shaftRatio , Zb + radiusb*sin(threadAngleBottom) ] ];
polyTriangles1=[
[ 0, 1, 6 ], [ 0, 6, 5 ], // tip of profile
[ 1, 7, 6 ], [ 1, 2, 7 ], // upper side of profile
[ 0, 5, 4 ], [ 4, 5, 9 ], // lower side of profile
[ 3, 4, 9 ], [ 9, 8, 3 ], [ 2, 3, 8 ], [ 8, 7, 2 ], // back of profile
[ 0, 4, 3 ], [ 0, 3, 2 ], [ 0, 2, 1 ], // a side of profile
[ 5, 8, 9 ], [ 5, 7, 8 ], [ 5, 6, 7 ] // b side of profile
];
// this is the back of the raised part of the profile
polyhedron( polyPoints1, polyTriangles1 );
}
module trapezoidThread(
length=45, // axial length of the threaded rod
pitch=10, // axial distance from crest to crest
pitchRadius=10, // radial distance from center to mid-profile
threadHeightToPitch=0.5, // ratio between the height of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
profileRatio=0.5, // ratio between the lengths of the raised part of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
threadAngle=30, // angle between the two faces of the thread
// std value for Acme is 29 or for metric lead screw is 30
RH=true, // true/false the thread winds clockwise looking along shaft, i.e.follows the Right Hand Rule
clearance=0.1, // radial clearance, normalized to thread height
backlash=0.1, // axial clearance, normalized to pitch
stepsPerTurn=24 // number of slices to create per turn
)
{
numberTurns=length/pitch;
steps=stepsPerTurn*numberTurns;
trapezoidRatio= 2*profileRatio*(1-backlash);
function threadAngleTop(i)= threadAngle/2;
function threadAngleBottom(i)= -threadAngle/2;
function threadHeight(i)= pitch*threadHeightToPitch;
function pitchRadius(i)= pitchRadius;
function minorRadius(i)= pitchRadius(i)-0.5*threadHeight(i);
function X(i)= minorRadius(i)*cos(i*360*numberTurns);
function Y(i)= minorRadius(i)*sin(i*360*numberTurns);
function Z(i)= pitch*numberTurns*i;
function tip(i)= trapezoidRatio*(1-0.5*sin(threadAngleTop(i))+0.5*sin(threadAngleBottom(i)));
// this is the threaded rod
if (RH==true)
translate([0,0,-threadHeight(0)*sin(threadAngleBottom(0))])
for (i=[0:steps-1])
{
threadPiece(
Xa= X(i/steps),
Ya= Y(i/steps),
Za= Z(i/steps),
Xb= X((i+1)/steps),
Yb= Y((i+1)/steps),
Zb= Z((i+1)/steps),
radiusa= threadHeight(i/steps),
radiusb= threadHeight((i+1)/steps),
tipRatioa= tip(i/steps),
tipRatiob= tip((i+1)/steps),
threadAngleTop= threadAngleTop(i),
threadAngleBottom= threadAngleBottom(i)
);
shaftPiece(
Xa= X(i/steps),
Ya= Y(i/steps),
Za= Z(i/steps),
Xb= X((i+1)/steps),
Yb= Y((i+1)/steps),
Zb= Z((i+1)/steps),
radiusa= threadHeight(i/steps),
radiusb= threadHeight((i+1)/steps),
tipRatioa= tip(i/steps),
tipRatiob= tip((i+1)/steps),
threadAngleTop= threadAngleTop(i),
threadAngleBottom= threadAngleBottom(i)
);
}
if (RH==false)
translate([0,0,-threadHeight(0)*sin(threadAngleBottom(0))])
mirror([0,1,0])
for (i=[0:steps-1])
{
threadPiece(
Xa= X(i/steps),
Ya= Y(i/steps),
Za= Z(i/steps),
Xb= X((i+1)/steps),
Yb= Y((i+1)/steps),
Zb= Z((i+1)/steps),
radiusa= threadHeight(i/steps),
radiusb= threadHeight((i+1)/steps),
tipRatioa= tip(i/steps),
tipRatiob= tip((i+1)/steps),
threadAngleTop= threadAngleTop(i),
threadAngleBottom= threadAngleBottom(i)
);
shaftPiece(
Xa= X(i/steps),
Ya= Y(i/steps),
Za= Z(i/steps),
Xb= X((i+1)/steps),
Yb= Y((i+1)/steps),
Zb= Z((i+1)/steps),
radiusa= threadHeight(i/steps),
radiusb= threadHeight((i+1)/steps),
tipRatioa= tip(i/steps),
tipRatiob= tip((i+1)/steps),
threadAngleTop= threadAngleTop(i),
threadAngleBottom= threadAngleBottom(i)
);
}
rotate([0,0,180/stepsPerTurn])
cylinder(
h=length+threadHeight(1)*(tip(1)+sin( threadAngleTop(1) )-1*sin( threadAngleBottom(1) ) ),
r1=minorRadius(0)-clearance*threadHeight(0),
r2=minorRadius(0)-clearance*threadHeight(0),
$fn=stepsPerTurn
);
}
module trapezoidThreadNegativeSpace(
length=45, // axial length of the threaded rod
pitch=10, // axial distance from crest to crest
pitchRadius=10, // radial distance from center to mid-profile
threadHeightToPitch=0.5, // ratio between the height of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
profileRatio=0.5, // ratio between the lengths of the raised part of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
threadAngle=30, // angle between the two faces of the thread
// std value for Acme is 29 or for metric lead screw is 30
RH=true, // true/false the thread winds clockwise looking along shaft, i.e.follows the Right Hand Rule
countersunk=0, // depth of 45 degree chamfered entries, normalized to pitch
clearance=0.1, // radial clearance, normalized to thread height
backlash=0.1, // axial clearance, normalized to pitch
stepsPerTurn=24 // number of slices to create per turn
)
{
translate([0,0,-countersunk*pitch])
cylinder(
h=2*countersunk*pitch,
r2=pitchRadius+clearance*pitch+0.25*pitch,
r1=pitchRadius+clearance*pitch+0.25*pitch+2*countersunk*pitch,
$fn=24
);
translate([0,0,countersunk*pitch])
translate([0,0,-pitch])
trapezoidThread(
length=length+0.5*pitch, // axial length of the threaded rod
pitch=pitch, // axial distance from crest to crest
pitchRadius=pitchRadius+clearance*pitch, // radial distance from center to mid-profile
threadHeightToPitch=threadHeightToPitch, // ratio between the height of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
profileRatio=profileRatio, // ratio between the lengths of the raised part of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
threadAngle=threadAngle, // angle between the two faces of the thread
// std value for Acme is 29 or for metric lead screw is 30
RH=true, // true/false the thread winds clockwise looking along shaft
// i.e.follows Right Hand Rule
clearance=0, // radial clearance, normalized to thread height
backlash=-backlash, // axial clearance, normalized to pitch
stepsPerTurn=stepsPerTurn // number of slices to create per turn
);
translate([0,0,length-countersunk*pitch])
cylinder(
h=2*countersunk*pitch,
r1=pitchRadius+clearance*pitch+0.25*pitch,
r2=pitchRadius+clearance*pitch+0.25*pitch+2*countersunk*pitch,$fn=24,
$fn=24
);
}
module trapezoidNut(
length=45, // axial length of the threaded rod
radius=25, // outer radius of the nut
pitch=10, // axial distance from crest to crest
pitchRadius=10, // radial distance from center to mid-profile
threadHeightToPitch=0.5, // ratio between the height of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
profileRatio=0.5, // ratio between the lengths of the raised part of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
threadAngle=30, // angle between the two faces of the thread
// std value for Acme is 29 or for metric lead screw is 30
RH=true, // true/false the thread winds clockwise looking along shaft, i.e.follows the Right Hand Rule
countersunk=0, // depth of 45 degree chamfered entries, normalized to pitch
clearance=0.1, // radial clearance, normalized to thread height
backlash=0.1, // axial clearance, normalized to pitch
stepsPerTurn=24 // number of slices to create per turn
)
{
difference()
{
cylinder(
h=length,
r1=radius,
r2=radius,
$fn=6
);
trapezoidThreadNegativeSpace(
length=length, // axial length of the threaded rod
pitch=pitch, // axial distance from crest to crest
pitchRadius=pitchRadius, // radial distance from center to mid-profile
threadHeightToPitch=threadHeightToPitch, // ratio between the height of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
profileRatio=profileRatio, // ratio between the lengths of the raised part of the profile and the pitch
// std value for Acme or metric lead screw is 0.5
threadAngle=threadAngle, // angle between the two faces of the thread
// std value for Acme is 29 or for metric lead screw is 30
RH=true, // true/false the thread winds clockwise looking along shaft
// i.e.follows Right Hand Rule
countersunk=countersunk, // depth of 45 degree countersunk entries, normalized to pitch
clearance=clearance, // radial clearance, normalized to thread height
backlash=backlash, // axial clearance, normalized to pitch
stepsPerTurn=stepsPerTurn // number of slices to create per turn
);
}
2023-12-17 12:40:52 -06:00
}