// Profile of standard UTS threads, with X in fractions of H and Y in fractions of P UTS=[[3/8, 0/16], [3/8, 2/16], [1, 7/16], [8/8, (11/16)] ]; //UTS=[[8/8, 1/8], [3/8, 7/16], [3/8, 9/16], [1, 7/8]]; //UTS=[[3/8, 7/16], [3/8, 9/16], [1, 7/8], [8/8, 1+(1/8)] ]; // Quick-and-dirty thread module. Imperial? Metric? It cares not as long as you give it // the right numbers. module thread(P=(1/27)*25.4, DMAJ=(5/8)*25.4, N=3, profile=UTS) { function scale2d(X,Y)=[ [X,0], [0,Y] ]; // Generates some teeth from the given array function tooth(P=1,H=1,I=1, DMAJ=0, UTS)=[ for(N=[0:I*len(UTS)]) (scale2d(H,P)*UTS[N%len(UTS)])+[(DMAJ/2)-(4/8)*H,floor(N/4)*P] ]; function slot(X)=floor(X/NP); function a(X)=slot(X)*(360/MSTEP); function d(X)=slot(X)*(P/MSTEP); function P(S,X=0, R=0)=(S*NP)+X+(len(profile)*R); function POFF(S,X)=P(S,X)*[1,1,1,1]; function 2d3d(A, V)=[V[0]*cos(A), V[1], V[0]*sin(A)]; H=cos(60/2)*P; MSTEP=floor((3.14159*DMAJ)/2); // MSTEP=16; echo("MSTEP",MSTEP); T=tooth(P,H,N,DMAJ,profile); NP=len(T); // Length of one extent PMAX=(NP*MSTEP); // Number of points in ENTIRE array MAXF=(len(profile)*N); // echo("NP",NP); // echo("PMAX",PMAX); BT=concat( [ for(X=[0:PMAX-1]) 2d3d(a(X), T[X%NP])+[0,d(X),0] ], // Top and bottom nodes [ [0,0,0], [0,(N+1)*P,0]]); // echo("len", len(BT)); TOP=PMAX; BOTTOM=PMAX+1; faces=concat( // The part of the spiral that doesn't connect to itself [ for(X=[0:((MSTEP-1)*MAXF)-1]) [0,1,NP+1]+POFF(floor(X/MAXF),X%MAXF) ], [ for(X=[0:((MSTEP-1)*MAXF)-1]) [NP,0,NP+1]+POFF(floor(X/MAXF),X%MAXF) ], // One connecting section [ for(X=[0:(N-1)*len(profile)-1]) [ len(profile)+1, len(profile), PMAX-NP ] +X*[1,1,1] ], [ for(X=[0:(N-1)*len(profile)-1]) [ len(profile)+1, PMAX-NP, 1+PMAX-NP ] +X*[1,1,1] ], // Bottom [ for(X=[0:MSTEP-2]) [ P(X, R=N), PMAX+1, P(X+1,R=N) ] ], // Top [ for(X=[0:MSTEP-2]) [ P(X+1,R=0), PMAX, P(X, R=0) ] ], // Cap for top [ for(X=[0:len(profile)-1]) [ P(0,0), TOP, P(0,1) ] + [X,0,X] ], [ [ P(0,len(profile)), TOP, P(MSTEP-1, 0) ] ], // Cap for bottom [ for(X=[0:len(profile)-1]) [ P(MSTEP-1, R=N-1, X=X+1), BOTTOM, P(MSTEP-1, R=N-1, X=X) ] ], [ [ P(MSTEP-1, R=N-1), BOTTOM, P(0, R=N) ] ] ); mirror([1,0,0]) polyhedron(points=BT, faces=faces); }