1//////////////////////////////////////////////////////////////////////
2// LibFile: threading.scad
3// Provides generic threading support and specialized support for standard triangular (UTS/ISO) threading,
4// trapezoidal threading (ACME), pipe threading, buttress threading, square threading and ball screws.
5// Includes:
6// include <BOSL2/std.scad>
7// include <BOSL2/threading.scad>
8// FileGroup: Threaded Parts
9// FileSummary: Various types of threaded rods and nuts.
10//////////////////////////////////////////////////////////////////////
11
12// Section: Standard (UTS/ISO) Threading
13
14// Module: threaded_rod()
15// Usage:
16// threaded_rod(d, l|length, pitch, [internal=], ...) [ATTACHMENTS];
17// Description:
18// Constructs a standard ISO (metric) or UTS (English) threaded rod. These threads are close to triangular,
19// with a 60 degree thread angle. You can give the outer diameter and get the "basic form" or you can
20// set d to a triplet [d_min, d_pitch, d_major] where are parameters determined by the ISO and UTS specifications
21// that define clearance sizing for the threading. See screws.scad for how to make screws
22// using the specification parameters.
23// Arguments:
24// d = Outer diameter of threaded rod, or a triplet of [d_min, d_pitch, d_major].
25// l / length = length of threaded rod.
26// pitch = Length between threads.
27// ---
28// left_handed = if true, create left-handed threads. Default = false
29// starts = The number of lead starts. Default: 1
30// bevel = if true, bevel the thread ends. Default: false
31// bevel1 = if true bevel the bottom end.
32// bevel2 = if true bevel the top end.
33// internal = If true, make this a mask for making internal threads.
34// d1 = Bottom outside diameter of threads.
35// d2 = Top outside diameter of threads.
36// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
37// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
38// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
39// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
40// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
41// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
42// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
43// Example(2D):
44// projection(cut=true)
45// threaded_rod(d=10, l=15, pitch=1.5, orient=BACK);
46// Examples(Med):
47// threaded_rod(d=10, l=20, pitch=1.25, left_handed=true, $fa=1, $fs=1);
48// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1);
49// threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, bevel=true);
50// rot(90)threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1, higbee=true);
51// Example: Diamond threading where both left-handed and right-handed nuts travel (in the same direction) on the threaded rod:
52// $slop = 0.075;
53// d = 3/8*INCH;
54// pitch = 1/16*INCH;
55// starts=3;
56// xdistribute(19){
57// intersection(){
58// threaded_rod(l=40, pitch=pitch, d=d,starts=starts,anchor=BOTTOM);
59// threaded_rod(l=40, pitch=pitch, d=d, left_handed=true,starts=starts,anchor=BOTTOM);
60// }
61// threaded_nut(nutwidth=4.5/8*INCH,id=d,h=3/8*INCH,pitch=pitch,starts=starts,anchor=BOTTOM);
62// threaded_nut(nutwidth=4.5/8*INCH,id=d,h=3/8*INCH,pitch=pitch,starts=starts,left_handed=true,anchor=BOTTOM);
63// }
64function threaded_rod(
65 d, l, pitch,
66 left_handed=false,
67 bevel,bevel1,bevel2,starts=1,
68 internal=false,
69 d1, d2,
70 higbee, higbee1, higbee2,
71 anchor, spin, orient
72) = no_function("threaded_rod");
73
74module threaded_rod(
75 d, l, pitch,
76 left_handed=false,
77 bevel,bevel1,bevel2,starts=1,
78 internal=false,
79 d1, d2, length,
80 higbee, higbee1, higbee2,
81 anchor, spin, orient
82) {
83 dummy1=
84 assert(all_positive(pitch))
85 assert(all_positive(d))
86 assert(all_positive(l));
87 basic = is_num(d) || is_undef(d) || is_def(d1) || is_def(d2);
88 dummy2 = assert(basic || is_vector(d,3));
89 depth = basic ? cos(30) * 5/8
90 : (d[2] - d[0])/2/pitch;
91 crestwidth = basic ? 1/8 : 1/2 - (d[2]-d[1])/sqrt(3)/pitch;
92 profile = [
93 [-depth/sqrt(3)-crestwidth/2, -depth],
94 [ -crestwidth/2, 0],
95 [ crestwidth/2, 0],
96 [ depth/sqrt(3)+crestwidth/2, -depth]
97 ];
98 oprofile = internal? [
99 [-6/16, -depth],
100 [-1/16, 0],
101 [-1/32, 0.02],
102 [ 1/32, 0.02],
103 [ 1/16, 0],
104 [ 6/16, -depth]
105 ] : [
106 [-7/16, -depth*1.07],
107 [-6/16, -depth],
108 [-1/16, 0],
109 [ 1/16, 0],
110 [ 6/16, -depth],
111 [ 7/16, -depth*1.07]
112 ];
113 generic_threaded_rod(
114 d=basic ? d : d[2], d1=d1, d2=d2, l=l,
115 pitch=pitch,
116 profile=profile,starts=starts,
117 left_handed=left_handed,
118 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
119 internal=internal, length=length,
120 higbee=higbee,
121 higbee1=higbee1,
122 higbee2=higbee2,
123 anchor=anchor,
124 spin=spin,
125 orient=orient
126 ) children();
127}
128
129
130
131// Module: threaded_nut()
132// Usage:
133// threaded_nut(nutwidth, id, h|height|thickness, pitch,...) [ATTACHMENTS];
134// Description:
135// Constructs a hex nut or square nut for an ISO (metric) or UTS (English) threaded rod.
136// Arguments:
137// nutwidth = flat to flat width of nut
138// id = diameter of threaded rod to screw onto.
139// h / height / thickness = height/thickness of nut.
140// pitch = Distance between threads, or zero for no threads.
141// ---
142// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
143// left_handed = if true, create left-handed threads. Default = false
144// starts = The number of lead starts. Default: 1
145// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
146// bevel1 = if true, bevel the outside of the nut bottom.
147// bevel2 = if true, bevel the outside of the nut top.
148// bevang = set the angle for the outside nut bevel. Default: 30
149// ibevel = if true, bevel the inside (the hole). Default: true
150// ibevel1 = if true bevel the inside, bottom end.
151// ibevel2 = if true bevel the inside, top end.
152// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
153// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
154// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
155// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
156// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
157// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
158// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
159// Examples(Med):
160// threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, $slop=0.05, $fa=1, $fs=1);
161// threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, left_handed=true, bevel=false, $slop=0.1, $fa=1, $fs=1);
162// threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, $slop=0.1, $fa=1, $fs=1);
163// threaded_nut(shape="square", nutwidth=16, id=8, h=8, pitch=1.25, bevel2=true, $slop=0.1, $fa=1, $fs=1);
164// rot(90)threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25,higbee=true, $slop=0.1, $fa=1, $fs=1);
165function threaded_nut(
166 nutwidth, id, h,
167 pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
168 ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
169 anchor, spin, orient
170)=no_function("threaded_nut");
171module threaded_nut(
172 nutwidth, id, h,
173 pitch, starts=1, shape="hex", left_handed=false, bevel, bevel1, bevel2, id1,id2,
174 ibevel1, ibevel2, ibevel, bevang=30, thickness, height,
175 higbee, higbee1, higbee2,
176 anchor, spin, orient
177) {
178 dummy1=
179 assert(all_nonnegative(pitch), "Nut pitch must be nonnegative")
180 assert(all_positive(id), "Nut inner diameter must be positive")
181 assert(all_positive(h),"Nut thickness must be positive");
182 basic = is_num(id) || is_undef(id) || is_def(id1) || is_def(id2);
183 dummy2 = assert(basic || is_vector(id,3));
184 depth = basic ? cos(30) * 5/8
185 : (id[2] - id[0])/2/pitch;
186 crestwidth = basic ? 1/8 : 1/2 - (id[2]-id[1])/sqrt(3)/pitch;
187 profile = [
188 [-depth/sqrt(3)-crestwidth/2, -depth],
189 [ -crestwidth/2, 0],
190 [ crestwidth/2, 0],
191 [ depth/sqrt(3)+crestwidth/2, -depth]
192 ];
193 oprofile = [
194 [-6/16, -depth/pitch],
195 [-1/16, 0],
196 [-1/32, 0.02],
197 [ 1/32, 0.02],
198 [ 1/16, 0],
199 [ 6/16, -depth/pitch]
200 ];
201 generic_threaded_nut(
202 nutwidth=nutwidth,
203 id=basic ? id : id[2], id1=id1, id2=id2,
204 h=h,
205 pitch=pitch,
206 profile=profile,starts=starts,shape=shape,
207 left_handed=left_handed,
208 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
209 ibevel1=ibevel1, ibevel2=ibevel2, ibevel=ibevel,
210 height=height, thickness=thickness, bevang=bevang,
211 higbee=higbee, higbee1=higbee1, higbee2=higbee2,
212 anchor=anchor, spin=spin,
213 orient=orient
214 ) children();
215}
216
217// Section: Trapezoidal Threading
218
219
220// Module: trapezoidal_threaded_rod()
221// Usage:
222// trapezoidal_threaded_rod(d, l|length, pitch, [thread_angle], [thread_depth], [internal=], ...) [ATTACHMENTS];
223// Description:
224// Constructs a threaded rod with a symmetric trapezoidal thread. Trapezoidal threads are used for lead screws because
225// they are one of the strongest symmetric profiles. This tooth shape is stronger than a similarly
226// sized square thread becuase of its wider base. However, it does place a radial load on the nut, unlike the square thread.
227// For loads in only one direction the asymmetric buttress thread profile can bear greater loads.
228// .
229// By default produces the nominal dimensions
230// for metric trapezoidal threads: a thread angle of 30 degrees and a depth set to half the pitch.
231// You can also specify your own trapezoid parameters. For ACME threads see acme_threaded_rod().
232// Figure(2D,Med,NoAxes):
233// pa_delta = tan(15)/4;
234// rr1 = -1/2;
235// z1 = 1/4-pa_delta;
236// z2 = 1/4+pa_delta;
237// profile = [
238// [-z2, rr1],
239// [-z1, 0],
240// [ z1, 0],
241// [ z2, rr1],
242// ];
243// fullprofile = 50*left(1/2,p=concat(profile, right(1, p=profile)));
244// stroke(fullprofile,width=1);
245// dir = fullprofile[2]-fullprofile[3];
246// dir2 = fullprofile[5]-fullprofile[4];
247// curve = arc(32,angle=[75,105],r=67.5);
248// avgpt = mean([fullprofile[5]+.1*dir2, fullprofile[5]+.4*dir2]);
249// color("red"){
250// stroke([fullprofile[2]+.1*dir, fullprofile[2]+.4*dir], width=1);
251// stroke([fullprofile[5]+.1*dir2, fullprofile[5]+.4*dir2], width=1);
252// stroke(move(-curve[0]+avgpt,p=curve), width=1,endcaps="arrow2");
253// back(10)text("thread",size=4,halign="center");
254// back(3)text("angle",size=4,halign="center");
255// }
256// Arguments:
257// d = Outer diameter of threaded rod.
258// l / length = Length of threaded rod.
259// pitch = Thread spacing.
260// thread_angle = Angle between two thread faces. Default: 30
261// thread_depth = Depth of threads. Default: pitch/2
262// ---
263// left_handed = If true, create left-handed threads. Default: false
264// starts = The number of lead starts. Default: 1
265// bevel = if true, bevel the thread ends. Default: false
266// bevel1 = if true bevel the bottom end.
267// bevel2 = if true bevel the top end.
268// internal = If true, make this a mask for making internal threads. Default: false
269// d1 = Bottom outside diameter of threads.
270// d2 = Top outside diameter of threads.
271// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
272// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
273// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
274// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
275// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
276// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
277// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
278// Example(2D):
279// projection(cut=true)
280// trapezoidal_threaded_rod(d=10, l=15, pitch=2, orient=BACK);
281// Examples(Med):
282// trapezoidal_threaded_rod(d=10, l=40, pitch=2, $fn=32); // Standard metric threading
283// rot(-65)trapezoidal_threaded_rod(d=10, l=17, pitch=2, higbee=25, $fn=32); // Standard metric threading
284// trapezoidal_threaded_rod(d=10, l=17, pitch=2, bevel=true, $fn=32); // Standard metric threading
285// trapezoidal_threaded_rod(d=10, l=30, pitch=2, left_handed=true, $fa=1, $fs=1); // Standard metric threading
286// trapezoidal_threaded_rod(d=10, l=40, pitch=3, left_handed=true, starts=3, $fn=36);
287// trapezoidal_threaded_rod(l=25, d=10, pitch=2, starts=3, $fa=1, $fs=1, bevel=true, orient=RIGHT, anchor=BOTTOM);
288// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, $fa=2, $fs=2);
289// trapezoidal_threaded_rod(d=60, l=16, pitch=8, thread_depth=3, thread_angle=90, left_handed=true, starts=4, $fa=2, $fs=2);
290// trapezoidal_threaded_rod(d=16, l=40, pitch=2, thread_angle=60);
291// trapezoidal_threaded_rod(d=25, l=40, pitch=10, thread_depth=8/3, thread_angle=100, starts=4, anchor=BOT, $fa=2, $fs=2);
292// trapezoidal_threaded_rod(d=50, l=35, pitch=8, thread_angle=60, starts=11, higbee=true,$fn=120);
293// Example(Med): Using as a Mask to Make Internal Threads
294// bottom_half() difference() {
295// cube(50, center=true);
296// trapezoidal_threaded_rod(d=40, l=51, pitch=5, thread_angle=30, internal=true, bevel=true, orient=RIGHT, $fn=36);
297// }
298function trapezoidal_threaded_rod(
299 d, l, pitch,
300 thread_angle=30,
301 thread_depth=undef,
302 left_handed=false,
303 bevel,bevel1,bevel2,
304 starts=1, length,
305 internal=false,
306 higbee, higbee1, higbee2,d1,d2,
307 anchor, spin, orient
308) = no_function("trapezoidal_threaded_rod");
309module trapezoidal_threaded_rod(
310 d, l, pitch,
311 thread_angle=30,
312 thread_depth=undef,
313 left_handed=false,
314 bevel,bevel1,bevel2,
315 starts=1, length,
316 internal=false,
317 higbee, higbee1, higbee2,d1,d2,
318 anchor, spin, orient
319) {
320 dummy0 = assert(all_positive(pitch));
321 dummy1 = assert(thread_angle>=0 && thread_angle<180);
322 depth = first_defined([thread_depth, pitch/2]);
323 pa_delta = 0.5*depth*tan(thread_angle/2) / pitch;
324 dummy2 = assert(pa_delta<1/4, "Specified thread geometry is impossible");
325 rr1 = -depth/pitch;
326 z1 = 1/4-pa_delta;
327 z2 = 1/4+pa_delta;
328 profile = [
329 [-z2, rr1],
330 [-z1, 0],
331 [ z1, 0],
332 [ z2, rr1],
333 ];
334 generic_threaded_rod(d=d,l=l,pitch=pitch,profile=profile,
335 left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts,internal=internal,d1=d1,d2=d2,
336 higbee=higbee,higbee1=higbee1,higbee2=higbee2,anchor=anchor,spin=spin,orient=orient,length=length)
337 children();
338}
339
340
341// Module: trapezoidal_threaded_nut()
342// Usage:
343// trapezoidal_threaded_nut(nutwidth, id, h|height|thickness, pitch, [thread_angle], [thread_depth], ...) [ATTACHMENTS];
344// Description:
345// Constructs a hex nut or square nut for a symmetric trapzoidal threaded rod.
346// By default produces the nominal dimensions
347// for metric trapezoidal threads: a thread angle of 30 degrees and a depth set to half the pitch.
348// You can also specify your own trapezoid parameters. For ACME threads see acme_threaded_nut().
349// Arguments:
350// nutwidth = flat to flat width of nut
351// id = diameter of threaded rod to screw onto.
352// h / height / thickness = height/thickness of nut.
353// pitch = Thread spacing.
354// thread_angle = Angle between two thread faces. Default: 30
355// thread_depth = Depth of the threads. Default: pitch/2
356// ---
357// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
358// left_handed = if true, create left-handed threads. Default = false
359// starts = The number of lead starts. Default = 1
360// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
361// bevel1 = if true, bevel the outside of the nut bottom.
362// bevel2 = if true, bevel the outside of the nut top.
363// bevang = set the angle for the outside nut bevel. Default: 30
364// ibevel = if true, bevel the inside (the hole). Default: true
365// ibevel1 = if true bevel the inside, bottom end.
366// ibevel2 = if true bevel the inside, top end.
367// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
368// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
369// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
370// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
371// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
372// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
373// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
374// Examples(Med):
375// trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, $slop=0.1, anchor=UP);
376// trapezoidal_threaded_nut(nutwidth=16, id=8, h=8, pitch=2, bevel=true, $slop=0.05, anchor=UP);
377// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, $slop=0.1, left_handed=true);
378// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15);
379// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=2, starts=3, $fa=1, $fs=1, $slop=0.15, higbee=true);
380// trapezoidal_threaded_nut(nutwidth=17.4, id=10, h=10, pitch=0, $slop=0.2); // No threads
381function trapezoidal_threaded_nut(
382 nutwidth,
383 id,
384 h,
385 pitch,
386 thread_angle=30,
387 thread_depth, shape="hex",
388 left_handed=false,
389 starts=1,
390 bevel,bevel1,bevel2,bevang=30,
391 ibevel1,ibevel2,ibevel,
392 thickness,height,
393 id1,id2,
394 higbee,higbee1,higbee2,
395 anchor, spin, orient
396) = no_function("trapezoidal_threaded_nut");
397module trapezoidal_threaded_nut(
398 nutwidth,
399 id,
400 h,
401 pitch,
402 thread_angle=30,
403 thread_depth, shape="hex",
404 left_handed=false,
405 starts=1,
406 bevel,bevel1,bevel2,bevang=30,
407 ibevel1,ibevel2,ibevel,
408 thickness,height,
409 id1,id2,
410 higbee,higbee1,higbee2,
411 anchor, spin, orient
412) {
413 dummy1 = assert(is_num(pitch) && pitch>=0 && thread_angle>=0 && thread_angle<180);
414 depth = first_defined([thread_depth, pitch/2]);
415 pa_delta = 0.5*depth*tan(thread_angle/2) / pitch;
416 dummy2 = assert(pitch==0 || pa_delta<1/4, "Specified thread geometry is impossible");
417 rr1 = -depth/pitch;
418 z1 = 1/4-pa_delta;
419 z2 = 1/4+pa_delta;
420 profile = [
421 [-z2, rr1],
422 [-z1, 0],
423 [ z1, 0],
424 [ z2, rr1],
425 ];
426 generic_threaded_nut(nutwidth=nutwidth,id=id,h=h,pitch=pitch,profile=profile,id1=id1,id2=id2,
427 shape=shape,left_handed=left_handed,bevel=bevel,bevel1=bevel1,bevel2=bevel2,starts=starts,
428 ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,bevang=bevang,height=height,thickness=thickness,
429 higbee=higbee, higbee1=higbee1, higbee2=higbee2,
430 anchor=anchor,spin=spin,orient=orient)
431 children();
432}
433
434
435// Module: acme_threaded_rod()
436// Usage:
437// acme_threaded_rod(d, l|length, tpi|pitch=, [internal=], ...) [ATTACHMENTS];
438// Description:
439// Constructs an ACME trapezoidal threaded screw rod. This form has a 29 degree thread angle with a
440// symmetric trapezoidal thread.
441// Arguments:
442// d = Outer diameter of threaded rod.
443// l / length = length of threaded rod.
444// tpi = threads per inch.
445// ---
446// pitch = thread spacing (alternative to tpi)
447// starts = The number of lead starts. Default = 1
448// left_handed = if true, create left-handed threads. Default = false
449// bevel = if true, bevel the thread ends. Default: false
450// bevel1 = if true bevel the bottom end.
451// bevel2 = if true bevel the top end.
452// internal = If true, this is a mask for making internal threads.
453// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
454// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
455// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
456// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
457// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
458// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
459// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
460// Example(2D):
461// projection(cut=true)
462// acme_threaded_rod(d=10, l=15, pitch=2, orient=BACK);
463// Examples(Med):
464// acme_threaded_rod(d=3/8*INCH, l=20, pitch=1/8*INCH, $fn=32);
465// acme_threaded_rod(d=10, l=30, pitch=2, starts=3, $fa=1, $fs=1);
466function acme_threaded_rod(
467 d, l, tpi, pitch,
468 starts=1,
469 left_handed=false,
470 bevel,bevel1,bevel2,
471 internal=false, length,
472 higbee, higbee1, higbee2,
473 anchor, spin, orient
474) = no_function("acme_threaded_rod");
475module acme_threaded_rod(
476 d, l, tpi, pitch,
477 starts=1,
478 left_handed=false,
479 bevel,bevel1,bevel2,
480 internal=false, length,
481 higbee, higbee1, higbee2,
482 anchor, spin, orient
483) {
484 dummy = assert(num_defined([pitch,tpi])==1,"Must give exactly one of pitch and tpi");
485 pitch = is_undef(pitch) ? INCH/tpi : pitch;
486 trapezoidal_threaded_rod(
487 d=d, l=l, pitch=pitch,
488 thread_angle=29,
489 thread_depth=pitch/2,
490 starts=starts,
491 left_handed=left_handed,
492 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
493 internal=internal, length=length,
494 higbee=higbee,
495 anchor=anchor,
496 spin=spin,
497 orient=orient
498 ) children();
499}
500
501
502
503// Module: acme_threaded_nut()
504// Usage:
505// acme_threaded_nut(nutwidth, id, h|height|thickness, tpi|pitch=, [shape=], ...) [ATTACHMENTS];
506// Description:
507// Constructs a hexagonal or square nut for an ACME threaded screw rod.
508// Arguments:
509// nutwidth = flat to flat width of nut.
510// id = diameter of threaded rod to screw onto.
511// h / height / thickness = height/thickness of nut.
512// tpi = threads per inch
513// ---
514// pitch = Thread spacing (alternative to tpi)
515// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
516// left_handed = if true, create left-handed threads. Default = false
517// starts = Number of lead starts. Default: 1
518// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
519// bevel1 = if true, bevel the outside of the nut bottom.
520// bevel2 = if true, bevel the outside of the nut top.
521// bevang = set the angle for the outside nut bevel. Default: 30
522// ibevel = if true, bevel the inside (the hole). Default: true
523// ibevel1 = if true bevel the inside, bottom end.
524// ibevel2 = if true bevel the inside, top end.
525// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
526// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
527// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
528// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
529// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
530// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
531// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
532// Examples(Med):
533// acme_threaded_nut(nutwidth=16, id=3/8*INCH, h=8, tpi=8, $slop=0.05);
534// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1);
535// acme_threaded_nut(nutwidth=16, id=1/2*INCH, h=10, tpi=12, starts=3, $slop=0.1, $fa=1, $fs=1,ibevel=false,higbee=true);
536function acme_threaded_nut(
537 nutwidth, id, h, tpi, pitch,
538 starts=1,
539 left_handed=false,shape="hex",
540 bevel,bevel1,bevel2,bevang=30,
541 ibevel,ibevel1,ibevel2,
542 height,thickness,
543 higbee,higbee1,higbee2,
544 anchor, spin, orient
545) = no_function("acme_threaded_nut");
546module acme_threaded_nut(
547 nutwidth, id, h, tpi, pitch,
548 starts=1,
549 left_handed=false,shape="hex",
550 bevel,bevel1,bevel2,bevang=30,
551 ibevel,ibevel1,ibevel2,
552 height,thickness,
553 higbee,higbee1,higbee2,
554 anchor, spin, orient
555) {
556 dummy = assert(num_defined([pitch,tpi])==1,"Must give exactly one of pitch and tpi");
557 pitch = is_undef(pitch) ? INCH/tpi : pitch;
558 dummy2=assert(is_num(pitch) && pitch>=0);
559 trapezoidal_threaded_nut(
560 nutwidth=nutwidth, id=id, h=h, pitch=pitch,
561 thread_depth = pitch/2,
562 thread_angle=29,shape=shape,
563 left_handed=left_handed,
564 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
565 ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
566 height=height,thickness=thickness,
567 starts=starts,
568 higbee=higbee, higbee1=higbee1, higbee2=higbee2,
569 anchor=anchor,
570 spin=spin,
571 orient=orient
572 ) children();
573}
574
575
576
577
578// Section: Pipe Threading
579
580// Module: npt_threaded_rod()
581// Usage:
582// npt_threaded_rod(size, [internal=], ...) [ATTACHMENTS];
583// Description:
584// Constructs a standard NPT pipe end threading. If `internal=true`, creates a mask for making
585// internal pipe threads. Tapers smaller upwards if `internal=false`. Tapers smaller downwards
586// if `internal=true`. If `hollow=true` and `internal=false`, then the pipe threads will be
587// hollowed out into a pipe with the apropriate internal diameter.
588// Arguments:
589// size = NPT standard pipe size in inches. 1/16", 1/8", 1/4", 3/8", 1/2", 3/4", 1", 1+1/4", 1+1/2", or 2". Default: 1/2"
590// ---
591// left_handed = If true, create left-handed threads. Default = false
592// bevel = if true, bevel the thread ends. Default: false
593// bevel1 = if true bevel the bottom end.
594// bevel2 = if true bevel the top end.
595// hollow = If true, create a pipe with the correct internal diameter.
596// internal = If true, make this a mask for making internal threads.
597// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
598// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
599// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
600// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
601// Example(2D): The straight gray rectangle reveals the tapered threads.
602// projection(cut=true) npt_threaded_rod(size=1/4, orient=BACK);
603// right(.533*INCH/2) color("gray") rect([2,0.5946*INCH],anchor=LEFT);
604// Examples(Med):
605// npt_threaded_rod(size=3/8, $fn=72);
606// npt_threaded_rod(size=1/2, $fn=72, bevel=true);
607// npt_threaded_rod(size=1/2, left_handed=true, $fn=72);
608// npt_threaded_rod(size=3/4, hollow=true, $fn=96);
609// Example:
610// diff("remove"){
611// cuboid([40,40,40])
612// tag("remove"){
613// up(.01)position(TOP)
614// npt_threaded_rod(size=3/4, $fn=96, internal=true, $slop=0.1, anchor=TOP);
615// cyl(d=3/4*INCH, l=42, $fn=32);
616// }
617// }
618function npt_threaded_rod(
619 size=1/2,
620 left_handed=false,
621 bevel,bevel1,bevel2,
622 hollow=false,
623 internal=false,
624 anchor, spin, orient
625)=no_function("npt_threaded_rod");
626module npt_threaded_rod(
627 size=1/2,
628 left_handed=false,
629 bevel,bevel1,bevel2,
630 hollow=false,
631 internal=false,
632 anchor, spin, orient
633) {
634 assert(is_finite(size));
635 assert(is_bool(left_handed));
636 assert(is_undef(bevel) || is_bool(bevel));
637 assert(is_bool(hollow));
638 assert(is_bool(internal));
639 assert(!(internal&&hollow), "Cannot created a hollow internal threads mask.");
640 info_table = [
641 // Size len OD TPI
642 [ 1/16, [ 0.3896, 0.308, 27 ]],
643 [ 1/8, [ 0.3924, 0.401, 27 ]],
644 [ 1/4, [ 0.5946, 0.533, 18 ]],
645 [ 3/8, [ 0.6006, 0.668, 18 ]],
646 [ 1/2, [ 0.7815, 0.832, 14 ]],
647 [ 3/4, [ 0.7935, 1.043, 14 ]],
648 [ 1, [ 0.9845, 1.305, 11.5]],
649 [ 1+1/4, [ 1.0085, 1.649, 11.5]],
650 [ 1+1/2, [ 1.0252, 1.888, 11.5]],
651 [ 2, [ 1.0582, 2.362, 11.5]],
652 ];
653 info = [for (data=info_table) if(approx(size,data[0])) data[1]][0];
654 dummy1 = assert(is_def(info), "Unsupported NPT size. Try one of 1/16, 1/8, 1/4, 3/8, 1/2, 3/4, 1, 1+1/4, 1+1/2, 2");
655 l = INCH * info[0];
656 d = INCH * info[1];
657 pitch = INCH / info[2];
658 rr = d/2;
659 rr2 = rr - l/32;
660 r1 = internal? rr2 : rr;
661 r2 = internal? rr : rr2;
662 depth = pitch * cos(30) * 5/8;
663 profile = internal? [
664 [-6/16, -depth/pitch],
665 [-1/16, 0],
666 [-1/32, 0.02],
667 [ 1/32, 0.02],
668 [ 1/16, 0],
669 [ 6/16, -depth/pitch]
670 ] : [
671 [-7/16, -depth/pitch*1.07],
672 [-6/16, -depth/pitch],
673 [-1/16, 0],
674 [ 1/16, 0],
675 [ 6/16, -depth/pitch],
676 [ 7/16, -depth/pitch*1.07]
677 ];
678 attachable(anchor,spin,orient, l=l, r1=r1, r2=r2) {
679 difference() {
680 generic_threaded_rod(
681 d1=2*r1, d2=2*r2, l=l,
682 pitch=pitch,
683 profile=profile,
684 left_handed=left_handed,
685 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
686 internal=internal,
687 higbee=true
688 );
689 if (hollow) cylinder(l=l+1, d=size*INCH, center=true);
690 }
691 children();
692 }
693}
694
695
696
697// Section: Buttress Threading
698
699// Module: buttress_threaded_rod()
700// Usage:
701// buttress_threaded_rod(d, l|length, pitch, [internal=], ...) [ATTACHMENTS];
702// Description:
703// Constructs a simple buttress threaded rod with a 45 degree angle. The buttress thread or sawtooth thread has low friction and high loading
704// in one direction at the cost of higher friction and inferior loading in the other direction. Buttress threads are sometimes used on
705// vises, which are loaded only in one direction.
706// Arguments:
707// d = Outer diameter of threaded rod.
708// l / length = length of threaded rod.
709// pitch = Thread spacing.
710// ---
711// left_handed = if true, create left-handed threads. Default = false
712// starts = Number of lead starts. Default: 1
713// bevel = if true, bevel the thread ends. Default: false
714// bevel1 = if true bevel the bottom end.
715// bevel2 = if true bevel the top end.
716// internal = If true, this is a mask for making internal threads.
717// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
718// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
719// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
720// d1 = Bottom outside diameter of threads.
721// d2 = Top outside diameter of threads.
722// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
723// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
724// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
725// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
726// Example(2D):
727// projection(cut=true)
728// buttress_threaded_rod(d=10, l=15, pitch=2, orient=BACK);
729// Examples(Med):
730// buttress_threaded_rod(d=10, l=20, pitch=1.25, left_handed=true, $fa=1, $fs=1);
731// buttress_threaded_rod(d=25, l=20, pitch=2, $fa=1, $fs=1);
732function buttress_threaded_rod(
733 d, l, pitch,
734 left_handed=false,
735 bevel,bevel1,bevel2,
736 internal=false,
737 higbee, higbee1, higbee2,
738 d1,d2,starts=1,length,
739 anchor, spin, orient
740) = no_function("buttress_threaded_rod");
741module buttress_threaded_rod(
742 d, l, pitch,
743 left_handed=false,
744 bevel,bevel1,bevel2,
745 internal=false,
746 higbee,higbee1,higbee2,
747 d1,d2,starts=1,length,
748 anchor, spin, orient
749) {
750 depth = pitch * 3/4;
751 profile = [
752 [ -7/16, -0.75],
753 [ 5/16, 0],
754 [ 7/16, 0],
755 [ 7/16, -0.75],
756 [ 1/ 2, -0.77],
757 ];
758 higbee2 = !internal || (!higbee && !higbee2) ? higbee2
759 : let (higval = first_defined([higbee2,higbee]))
760 is_num(higval) ? higval + 270
761 : 270;
762 generic_threaded_rod(
763 d=d, l=l, pitch=pitch,
764 profile=profile,
765 left_handed=left_handed,
766 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
767 internal=internal,
768 higbee=higbee,
769 higbee1=higbee1,
770 higbee2=higbee2,
771 d1=d1,d2=d2,
772 anchor=anchor,length=length,
773 spin=spin,starts=starts,
774 orient=orient
775 ) children();
776}
777
778
779
780// Module: buttress_threaded_nut()
781// Usage:
782// buttress_threaded_nut(nutwidth, id, h|height|thickness, pitch, ...) [ATTACHMENTS];
783// Description:
784// Constructs a hexagonal or square nut for a simple buttress threaded screw rod.
785// Arguments:
786// nutwidth = diameter of the nut.
787// id = diameter of threaded rod to screw onto.
788// h = height/thickness of nut.
789// pitch = Thread spacing.
790// ---
791// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
792// left_handed = if true, create left-handed threads. Default = false
793// starts = The number of lead starts. Default: 1
794// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
795// bevel1 = if true, bevel the outside of the nut bottom.
796// bevel2 = if true, bevel the outside of the nut top.
797// bevang = set the angle for the outside nut bevel. Default: 30
798// ibevel = if true, bevel the inside (the hole). Default: true
799// ibevel1 = if true bevel the inside, bottom end.
800// ibevel2 = if true bevel the inside, top end.
801// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
802// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
803// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
804// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
805// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
806// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
807// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
808// Examples(Med):
809// buttress_threaded_nut(nutwidth=16, id=8, h=8, pitch=1.25, left_handed=true, $slop=0.05, $fa=1, $fs=1);
810function buttress_threaded_nut(
811 nutwidth, id, h,
812 pitch, shape="hex", left_handed=false,
813 bevel,bevel1,bevel2,bevang=30,starts=1,
814 ibevel,ibevel1,ibevel2,height,thickness,
815 higbee,higbee1,higbee2,
816 anchor, spin, orient
817) = no_function("buttress_threaded_nut");
818module buttress_threaded_nut(
819 nutwidth, id, h,
820 pitch, shape="hex", left_handed=false,
821 bevel,bevel1,bevel2,bevang=30,starts=1,
822 ibevel,ibevel1,ibevel2,height,thickness,
823 higbee,higbee1,higbee2,
824 anchor, spin, orient
825) {
826 depth = pitch * 3/4;
827 profile = [
828 [ -7/16, -0.75],
829 [ 5/16, 0],
830 [ 7/16, 0],
831 [ 7/16, -0.75],
832 [ 1/ 2, -0.77],
833 ];
834 higbee2 = !higbee && !higbee2 ? higbee2
835 : let (higval = first_defined([higbee2,higbee]))
836 is_num(higval) ? higval + 270
837 : 270;
838 generic_threaded_nut(
839 nutwidth=nutwidth, id=id, h=h,
840 pitch=pitch,
841 profile=profile,
842 shape=shape,
843 left_handed=left_handed,starts=starts,
844 bevel=bevel,bevel1=bevel1,bevel2=bevel2,bevang=bevang,
845 ibevel=ibevel,ibevel1=ibevel1,ibevel2=ibevel2,
846 higbee=higbee, higbee1=higbee1, higbee2=higbee2,
847 anchor=anchor, spin=spin, height=height, thickness=thickness,
848 orient=orient
849 ) children();
850}
851
852
853
854// Section: Square Threading
855
856// Module: square_threaded_rod()
857// Usage:
858// square_threaded_rod(d, l|length, pitch, [internal=], ...) [ATTACHMENTS];
859// Description:
860// Constructs a square profile threaded screw rod. The greatest advantage of square threads is that they have the least friction and a much higher intrinsic efficiency than trapezoidal threads.
861// They produce no radial load on the nut. However, square threads cannot carry as much load as trapezoidal threads.
862// Arguments:
863// d = Outer diameter of threaded rod.
864// l / length = length of threaded rod.
865// pitch = Thread spacing.
866// ---
867// left_handed = if true, create left-handed threads. Default = false
868// starts = The number of lead starts. Default = 1
869// bevel = if true, bevel the thread ends. Default: false
870// bevel1 = if true bevel the bottom end.
871// bevel2 = if true bevel the top end.
872// internal = If true, this is a mask for making internal threads.
873// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
874// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
875// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
876// d1 = Bottom outside diameter of threads.
877// d2 = Top outside diameter of threads.
878// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
879// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
880// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
881// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
882// Example(2D):
883// projection(cut=true)
884// square_threaded_rod(d=10, l=15, pitch=2, orient=BACK);
885// Examples(Med):
886// square_threaded_rod(d=10, l=20, pitch=2, starts=2, $fn=32);
887function square_threaded_rod(
888 d, l, pitch,
889 left_handed=false,
890 bevel,bevel1,bevel2,
891 starts=1,
892 internal=false,
893 higbee, higbee1, higbee2,
894 d1,d2,
895 anchor, spin, orient
896) = no_function("square_threaded_rod");
897module square_threaded_rod(
898 d, l, pitch,
899 left_handed=false,
900 bevel,bevel1,bevel2,
901 starts=1,
902 internal=false,
903 higbee=0, higbee1, higbee2,
904 d1,d2,length,
905 anchor, spin, orient
906) {
907 trapezoidal_threaded_rod(
908 d=d, l=l, pitch=pitch,
909 thread_angle=0.1,
910 left_handed=left_handed,
911 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
912 starts=starts,
913 internal=internal,
914 higbee=higbee,
915 higbee1=higbee1,
916 higbee2=higbee2,
917 d1=d1,
918 d2=d2,
919 length=length,
920 anchor=anchor,
921 spin=spin,
922 orient=orient
923 ) children();
924}
925
926
927
928// Module: square_threaded_nut()
929// Usage:
930// square_threaded_nut(nutwidth, id, h|height|thickness, pitch, ...) [ATTACHMENTS];
931// Description:
932// Constructs a hexagonal or square nut for a square profile threaded screw rod.
933// Arguments:
934// nutwidth = diameter of the nut.
935// id = diameter of threaded rod to screw onto.
936// h / height / thickness = height/thickness of nut.
937// pitch = Length between threads.
938// ---
939// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
940// left_handed = if true, create left-handed threads. Default = false
941// starts = The number of lead starts. Default = 1
942// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
943// bevel1 = if true, bevel the outside of the nut bottom.
944// bevel2 = if true, bevel the outside of the nut top.
945// bevang = set the angle for the outside nut bevel. Default: 30
946// ibevel = if true, bevel the inside (the hole). Default: true
947// ibevel1 = if true bevel the inside, bottom end.
948// ibevel2 = if true bevel the inside, top end.
949// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
950// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
951// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
952// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
953// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
954// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
955// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
956// Examples(Med):
957// square_threaded_nut(nutwidth=16, id=10, h=10, pitch=2, starts=2, $slop=0.1, $fn=32);
958function square_threaded_nut(
959 nutwidth, id, h,
960 pitch,
961 left_handed=false,
962 bevel,bevel1,bevel2,bevang=30,
963 ibevel,ibevel1,ibevel2,
964 height,thickness,
965 starts=1,
966 higbee,higbee1,higbee2,
967 anchor, spin, orient
968) = no_function("square_threaded_nut");
969module square_threaded_nut(
970 nutwidth, id, h,
971 pitch,
972 left_handed=false,
973 bevel,bevel1,bevel2,bevang=30,
974 ibevel,ibevel1,ibevel2,
975 height,thickness,
976 higbee,higbee1,higbee2,
977 starts=1,
978 anchor, spin, orient
979) {
980 assert(is_num(pitch) && pitch>=0)
981 trapezoidal_threaded_nut(
982 nutwidth=nutwidth, id=id, h=h, pitch=pitch,
983 thread_angle=0,
984 left_handed=left_handed,
985 bevel=bevel,bevel1=bevel1,bevel2=bevel2, bevang=bevang,
986 ibevel=ibevel, ibevel1=ibevel1, ibevel2=ibevel2,
987 height=height,thickness=thickness,
988 starts=starts,
989 higbee=higbee, higbee1=higbee1, higbee2=higbee2,
990 anchor=anchor,
991 spin=spin,
992 orient=orient
993 ) children();
994}
995
996
997// Section: Ball Screws
998
999// Module: ball_screw_rod()
1000// Usage:
1001// ball_screw_rod(d, l|length, pitch, [ball_diam], [ball_arc], [internal=], ...) [ATTACHMENTS];
1002// Description:
1003// Constructs a ball screw rod. This type of rod is used with ball bearings.
1004// Arguments:
1005// d = Outer diameter of threaded rod.
1006// l / length = length of threaded rod.
1007// pitch = Thread spacing. Also, the diameter of the ball bearings used.
1008// ball_diam = The diameter of the ball bearings to use with this ball screw.
1009// ball_arc = The arc portion that should touch the ball bearings. Default: 120 degrees.
1010// ---
1011// left_handed = if true, create left-handed threads. Default = false
1012// starts = The number of lead starts. Default = 1
1013// bevel = if true, bevel the thread ends. Default: false
1014// bevel1 = if true bevel the bottom end.
1015// bevel2 = if true bevel the top end.
1016// internal = If true, make this a mask for making internal threads.
1017// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
1018// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
1019// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
1020// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
1021// Example(2D): Thread Profile, ball_diam=4, ball_arc=100
1022// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=100, orient=BACK, $fn=24);
1023// Example(2D): Thread Profile, ball_diam=4, ball_arc=120
1024// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=4, ball_arc=120, orient=BACK, $fn=24);
1025// Example(2D): Thread Profile, ball_diam=3, ball_arc=120
1026// projection(cut=true) ball_screw_rod(d=10, l=15, pitch=5, ball_diam=3, ball_arc=120, orient=BACK, $fn=24);
1027// Examples(Med):
1028// ball_screw_rod(d=15, l=20, pitch=8, ball_diam=5, ball_arc=120, $fa=1, $fs=0.5);
1029// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, $fa=1, $fs=0.5);
1030// ball_screw_rod(d=15, l=20, pitch=5, ball_diam=4, ball_arc=120, left_handed=true, $fa=1, $fs=0.5);
1031function ball_screw_rod(
1032 d, l, pitch,
1033 ball_diam=5, ball_arc=100,
1034 starts=1,
1035 left_handed=false,
1036 internal=false,
1037 bevel,bevel1,bevel2, length,
1038 anchor, spin, orient
1039) = no_function("ball_screw_rod");
1040module ball_screw_rod(
1041 d, l, pitch,
1042 ball_diam=5, ball_arc=100,
1043 starts=1,
1044 left_handed=false,
1045 internal=false,
1046 bevel,bevel1,bevel2, length,
1047 anchor, spin, orient
1048) {
1049 n = max(3,ceil(segs(ball_diam/2)*ball_arc/2/360));
1050 depth = ball_diam * (1-cos(ball_arc/2))/2;
1051 cpy = ball_diam/2/pitch*cos(ball_arc/2);
1052 profile = [
1053 each arc(n=n, d=ball_diam/pitch, cp=[-0.5,cpy], start=270, angle=ball_arc/2),
1054 each arc(n=n, d=ball_diam/pitch, cp=[+0.5,cpy], start=270-ball_arc/2, angle=ball_arc/2)
1055 ];
1056 generic_threaded_rod(
1057 d=d, l=l, pitch=pitch,
1058 profile=profile,
1059 left_handed=left_handed,
1060 starts=starts,
1061 bevel=bevel,bevel1=bevel1,bevel2=bevel2,
1062 internal=internal,
1063 higbee=0, length=length,
1064 anchor=anchor,
1065 spin=spin,
1066 orient=orient
1067 ) children();
1068}
1069
1070
1071
1072// Section: Generic Threading
1073
1074// Module: generic_threaded_rod()
1075// Usage:
1076// generic_threaded_rod(d, l|length, pitch, profile, [internal=], ...) [ATTACHMENTS];
1077// Description:
1078// Constructs a generic threaded rod using an arbitrary thread profile that you supply. The rod can be tapered (e.g. for pipe threads).
1079// For specific thread types use other modules that supply the appropriate profile.
1080// .
1081// You give the profile as a 2D path that will be scaled by the pitch to produce the final thread shape. The profile X values
1082// must be between -1/2 and 1/2. The Y=0 point will align with the specified rod diameter, so generally you want a Y value of zero at the peak (which
1083// makes your specified diameter the outer diameter of the threads).
1084// The value in the valleys of the thread should then be `-depth/pitch` due to the scaling by the thread pitch. The segment between the end
1085// of one thread and the start of the next is added automatically, so you should not have the path start and end at equivalent points (X = ±1/2 with the same Y value).
1086// Generally you should center the profile horizontally in the interval [-1/2, 1/2].
1087// .
1088// If internal is true then produce a thread mask to difference from an object.
1089// When internal is true the rod diameter is enlarged to correct for the polygonal nature of circles to ensure that the internal diameter is the specified size.
1090// The diameter is also increased by `4 * $slop` to create clearance for threading by allowing a `2 * $slop` gap on each side.
1091// If bevel is set to true and internal is false then the ends of the rod will be beveled. When bevel is true and internal is true the ends of the rod will
1092// be filled in so that the rod mask will create a bevel when subtracted from an object. The bevel is at 45 deg and is the depth of the threads.
1093// .
1094// Higbee or blunt start threading specifies that the thread ends abruptly at its full width instead of running off the end of the shaft and leaving a sharp edged partial
1095// thread at the end of the screw. This makes screws easier to start and
1096// prevents cross threading. If you set `higbee=true` then the blunt start applies to both ends. The blunt start cuts the thread end in a single facet,
1097// so if you use lots of facets it will be close to perpendicular to the screw surface, but if you use fewer facets, it will be a more sloped cut.
1098// The place to cut the threads is calculated to try to leave a 1/4 thread gap from the end of the screw, but depending on your profile, you may
1099// wish to adjust this. If you set higbee to a numerical value it will be added to the computed higbee angle, so a positive value will cut the thread back farther
1100// giving more space at the end. Higbee works on both internal and external threads.
1101// Arguments:
1102// d = Outer diameter of threaded rod.
1103// l / length = Length of threaded rod.
1104// pitch = Thread spacing.
1105// profile = A 2D path giving the shape of a thread
1106// ---
1107// left_handed = If true, create left-handed threads. Default: false
1108// starts = The number of lead starts. Default: 1
1109// bevel = if true, bevel the thread ends. Default: false
1110// bevel1 = if true bevel the bottom end.
1111// bevel2 = if true bevel the top end.
1112// internal = If true, make this a mask for making internal threads. Default: false
1113// d1 = Bottom outside diameter of threads.
1114// d2 = Top outside diameter of threads.
1115// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
1116// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
1117// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
1118// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
1119// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
1120// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
1121// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
1122// Example(2DMed): Example Tooth Profile
1123// pitch = 2;
1124// depth = pitch * cos(30) * 5/8;
1125// profile = [
1126// [-7/16, -depth/pitch*1.07],
1127// [-6/16, -depth/pitch],
1128// [-1/16, 0],
1129// [ 1/16, 0],
1130// [ 6/16, -depth/pitch],
1131// [ 7/16, -depth/pitch*1.07]
1132// ];
1133// stroke(profile, width=0.02);
1134// Example:
1135// pitch = 2;
1136// depth = pitch * cos(30) * 5/8;
1137// profile = [
1138// [-7/16, -depth/pitch*1.07],
1139// [-6/16, -depth/pitch],
1140// [-1/16, 0],
1141// [ 1/16, 0],
1142// [ 6/16, -depth/pitch],
1143// [ 7/16, -depth/pitch*1.07]
1144// ];
1145// generic_threaded_rod(d=10, l=40, pitch=2, profile=profile);
1146function generic_threaded_rod(
1147 d, l, pitch, profile,
1148 left_handed=false,
1149 bevel,
1150 bevel1, bevel2,
1151 starts=1,
1152 internal=false,
1153 d1, d2, length,
1154 higbee, higbee1, higbee2,
1155 anchor, spin, orient
1156) = no_function("generic_threaded_rod");
1157module generic_threaded_rod(
1158 d, l, pitch, profile,
1159 left_handed=false,
1160 bevel,
1161 bevel1, bevel2,
1162 starts=1,
1163 internal=false,
1164 d1, d2, length,
1165 higbee, higbee1, higbee2,
1166 anchor, spin, orient
1167) {
1168 l = one_defined([l,length],"l,length");
1169 bevel1 = first_defined([bevel1,bevel,false]);
1170 bevel2 = first_defined([bevel2,bevel,false]);
1171 thigbee1 = first_defined([higbee1,higbee,false]);
1172 thigbee2 = first_defined([higbee2,higbee,false]);
1173 // Zero higbee should be treated as "true", default angle, but it tests as false so adjust
1174 higbee1 = thigbee1==0 ? true : thigbee1;
1175 higbee2 = thigbee2==0 ? true : thigbee2;
1176 dummy0 =
1177 assert(all_positive([pitch]),"Thread pitch must be a positive value")
1178 assert(all_positive([l]),"Length must be a postive value")
1179 assert(is_path(profile),"Profile must be a path")
1180 assert(is_finite(higbee1) || is_bool(higbee1), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
1181 assert(is_finite(higbee2) || is_bool(higbee2), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
1182 assert(is_bool(left_handed));
1183 r1 = get_radius(d1=d1, d=d);
1184 r2 = get_radius(d1=d2, d=d);
1185 sides = quantup(segs(max(r1,r2)), starts);
1186 rsc = internal? (1/cos(180/sides)) : 1;
1187 islop = internal? 2*get_slop() : 0;
1188 _r1 = r1 * rsc + islop;
1189 _r2 = r2 * rsc + islop;
1190 threads = quantup(l/pitch+2,1); // Was quantup(1/pitch+2,2*starts);
1191 dir = left_handed? -1 : 1;
1192 twist = 360 * l / pitch / starts;
1193 profile = !internal ? profile
1194 : [
1195 for(entry=profile) if (entry.x>=0) [entry.x-1/2,entry.y],
1196 for(entry=profile) if (entry.x<0) [entry.x+1/2,entry.y]
1197 ];
1198 gap = 0.25;
1199 thread_minx = min(column(profile,0));
1200 thread_maxx = max(column(profile,0));
1201 // Compute higbee cut angles, or set to large negative value if higbee is not enabled
1202 higang1 = !higbee1 ? -1000
1203 : (180+(gap-(thread_minx+.5))*360)/starts + (is_num(higbee1) ? higbee1 : 0);
1204 higang2 = !higbee2 ? -1000
1205 : (180+(gap-(.5-thread_maxx))*360)/starts + (is_num(higbee2) ? higbee2 : 0);
1206 prof3d = path3d(profile);
1207 pdepth = -min(column(profile,1));
1208 pmax = pitch * max(column(profile,1));
1209 rmax = max(_r1,_r2)+pmax;
1210 depth = pdepth * pitch;
1211 dummy1 = assert(_r1>depth && _r2>depth, "Screw profile deeper than rod radius");
1212 map_threads = right((_r1 + _r2) / 2) // Shift profile out to thread radius
1213 * affine3d_skew(sxz=(_r2-_r1)/l) // Skew correction for tapered threads
1214 * frame_map(x=[0,0,1], y=[1,0,0]) // Map profile to 3d, parallel to z axis
1215 * scale(pitch); // scale profile by pitch
1216 start_steps = sides / starts;
1217 thread_verts = [
1218 // Outer loop constructs a vertical column of the screw at each angle
1219 // covering 1/starts * 360 degrees of the cylinder.
1220 for (step = [0:1:start_steps]) let(
1221 ang = 360 * step/sides,
1222 dz = step / start_steps, // z offset for threads at this angle
1223 rot_prof = zrot(ang*dir)*map_threads, // Rotate profile to correct angular location
1224 full_profile = [ // profile for the entire rod
1225 for (thread = [-threads/2:1:threads/2-1]) let(
1226 tang = (thread/starts) * 360 + ang,
1227 adjusted_prof3d = tang < -twist/2+higang1 || tang > twist/2-higang2
1228 ? [for(v=prof3d) [v.x,internal?pmax/pitch:-pdepth,v.z]]
1229 : prof3d
1230 )
1231 // The right movement finds the position of the thread along
1232 // what will be the z axis after the profile is mapped to 3d
1233 each apply(right(dz + thread) , adjusted_prof3d)
1234 ]
1235 ) [
1236 [0, 0, -l/2-pitch],
1237 each apply(rot_prof , full_profile),
1238 [0, 0, +l/2+pitch]
1239 ]
1240 ];
1241 style=internal?"concave":"convex";
1242
1243 thread_vnfs = vnf_join([
1244 // Main thread faces
1245 for (i=[0:1:starts-1])
1246 zrot(i*360/starts, p=vnf_vertex_array(thread_verts, reverse=left_handed, style=style)),
1247 // Top closing face(s) of thread
1248 for (i=[0:1:starts-1]) let(
1249 rmat = zrot(i*360/starts),
1250 pts = deduplicate(list_head(thread_verts[0], len(prof3d)+1)),
1251 faces = [for (i=idx(pts,e=-2)) left_handed ? [0, i, i+1] : [0, i+1, i]]
1252 ) [apply(rmat,pts), faces],
1253 // Bottom closing face(s) of thread
1254 for (i=[0:1:starts-1]) let(
1255 rmat = zrot(i*360/starts),
1256 pts = deduplicate(list_tail(last(thread_verts), -len(prof3d)-2)),
1257 faces = [for (i=idx(pts,e=-2)) left_handed ? [len(pts)-1, i+1, i] : [len(pts)-1, i, i+1]]
1258 ) [apply(rmat,pts), faces]
1259 ]);
1260
1261 slope = (_r1-_r2)/l;
1262 maxlen = 2*pitch;
1263
1264 attachable(anchor,spin,orient, r1=_r1, r2=_r2, l=l) {
1265 union(){
1266
1267 // This method is faster but more complex code and it produces green tops
1268 difference() {
1269 vnf_polyhedron(vnf_quantize(thread_vnfs),convexity=10);
1270
1271 if (!internal){
1272 if (bevel1 || bevel2)
1273 rotate_extrude(){
1274 if (bevel2) polygon([[ 0, l/2],
1275 [_r2+pmax-depth, l/2],
1276 [_r2+pmax+slope*depth, l/2-depth],
1277 [ rmax+1, l/2-depth],
1278 [rmax+1, l/2+maxlen],
1279 [ 0, l/2+maxlen]]);
1280 if (bevel1) polygon([[ 0,-l/2],
1281 [_r1+pmax-depth, -l/2],
1282 [_r1+pmax-slope*depth, -l/2+depth],
1283 [ rmax+1, -l/2+depth],
1284 [rmax+1, -l/2-maxlen],
1285 [ 0, -l/2-maxlen]]);
1286 }
1287 }
1288 if (!bevel1 || internal)
1289 down(l/2) cuboid([2*rmax+1,2*rmax+1, maxlen], anchor=TOP);
1290 if (!bevel2 || internal)
1291 up(l/2) cuboid([2*rmax+1,2*rmax+1, maxlen], anchor=BOTTOM);
1292 }
1293
1294 /* // slower, simpler approach for beveling
1295 intersection(){
1296 //vnf_validate(vnf_quantize(thread_vnfs), size=0.1);
1297 vnf_polyhedron(vnf_quantize(thread_vnfs), convexity=10);
1298 cyl(l=l, r1=_r1+pmax, r2=_r2+pmax, chamfer1=bevel1?depth:undef, chamfer2=bevel2?depth:undef);
1299 }
1300 */
1301
1302 // Add bevel for internal thread mask
1303 if (internal) {
1304 if (bevel1)
1305 down(l/2+.001)cyl(l=depth, r1=_r1+pmax, r2=_r1+pmax-slope*depth-depth,anchor=BOTTOM);
1306 if (bevel2)
1307 up(l/2+.001)cyl(l=depth, r2=_r2+pmax, r1=_r2+pmax+slope*depth-depth,anchor=TOP);
1308 }
1309 }
1310 children();
1311 }
1312}
1313
1314
1315
1316// Module: generic_threaded_nut()
1317// Usage:
1318// generic_threaded_nut(nutwidth, id, h|height|thickness, pitch, profile, [$slop], ...) [ATTACHMENTS];
1319// Description:
1320// Constructs a hexagonal or square nut for an generic threaded rod using a user-supplied thread profile.
1321// See {{generic_threaded_rod()}} for details on the profile specification.
1322// Arguments:
1323// nutwidth = outer dimension of nut from flat to flat.
1324// id = diameter of threaded rod to screw onto.
1325// h / height / thickness = height/thickness of nut.
1326// pitch = Thread spacing.
1327// profile = Thread profile.
1328// ---
1329// shape = specifies shape of nut, either "hex" or "square". Default: "hex"
1330// left_handed = if true, create left-handed threads. Default = false
1331// starts = The number of lead starts. Default = 1
1332// bevel = if true, bevel the outside of the nut. Default: true for hex nuts, false for square nuts
1333// bevel1 = if true, bevel the outside of the nut bottom.
1334// bevel2 = if true, bevel the outside of the nut top.
1335// bevang = set the angle for the outside nut bevel. Default: 30
1336// ibevel = if true, bevel the inside (the hole). Default: true
1337// ibevel1 = if true bevel the inside, bottom end.
1338// ibevel2 = if true bevel the inside, top end.
1339// higbee = If true apply higbee thread truncation at both ends, or set to an angle to adjust higbee cut point. Default: false
1340// higbee1 = If true apply higbee thread truncation at bottom end, or set to an angle to adjust higbee cut point.
1341// higbee2 = If true apply higbee thread truncation at top end, or set to an angle to adjust higbee cut point.
1342// id1 = inner diameter at the bottom
1343// id2 = inner diameter at the top
1344// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
1345// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
1346// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
1347// $slop = The printer-specific slop value, which adds clearance (`4*$slop`) to internal threads.
1348function generic_threaded_nut(
1349 nutwidth,
1350 id,
1351 h,
1352 pitch,
1353 profile,
1354 shape="hex",
1355 left_handed=false,
1356 starts=1,
1357 bevel,bevel1,bevel2,bevang=30,
1358 ibevel, ibevel1, ibevel2,
1359 id1,id2, height, thickness,
1360 higbee,higbee1,higbee2,
1361 anchor, spin, orient
1362) = no_function("generic_threaded_nut");
1363module generic_threaded_nut(
1364 nutwidth,
1365 id,
1366 h,
1367 pitch,
1368 profile,
1369 shape="hex",
1370 left_handed=false,
1371 starts=1,
1372 bevel,bevel1,bevel2,bevang=30,
1373 ibevel, ibevel1, ibevel2,
1374 id1,id2, height, thickness,
1375 higbee,higbee1,higbee2,
1376 anchor, spin, orient
1377) {
1378
1379 extra = 0.01;
1380 id1 = first_defined([id1,id]);
1381 id2 = first_defined([id2,id]);
1382 h = one_defined([h,height,thickness],"h,height,thickness");
1383 dummyA = assert(is_num(pitch) && pitch>=0, "pitch must be a nonnegative number")
1384 assert(is_num(h) && h>0, "height/thickness must be a positive number")
1385 assert(in_list(shape,["square","hex"]), "shape must be \"hex\" or \"square\"")
1386 assert(all_positive([id1,id2]), "Inner diameter(s) of nut must be positive number(s)");
1387 slope = (id2-id1)/h;
1388 full_id1 = id1-slope*extra/2;
1389 full_id2 = id2+slope*extra/2;
1390 ibevel1 = first_defined([ibevel1,ibevel,true]);
1391 ibevel2 = first_defined([ibevel2,ibevel,true]);
1392 bevel1 = first_defined([bevel1,bevel,shape=="hex"?true:false]);
1393 bevel2 = first_defined([bevel2,bevel,shape=="hex"?true:false]);
1394 depth = -pitch*min(column(profile,1));
1395 IBEV=0.05;
1396 vnf = linear_sweep(hexagon(id=nutwidth), height=h, center=true);
1397 attachable(anchor,spin,orient, size=shape=="square" ? [nutwidth,nutwidth,h] : undef, vnf=shape=="hex" ? vnf : undef) {
1398 difference() {
1399 _nutshape(nutwidth,h, shape,bevel1,bevel2);
1400 if (pitch==0)
1401 cyl(l=h+extra, d1=full_id1+4*get_slop(), d2=full_id2+4*get_slop(), chamfer1=ibevel1?-IBEV*full_id1:undef, chamfer2=ibevel2?-IBEV*full_id2:undef);
1402 else
1403 generic_threaded_rod(
1404 d1=full_id1,d2=full_id2,
1405 l=h+extra,
1406 pitch=pitch,
1407 profile=profile,
1408 left_handed=left_handed,
1409 starts=starts,
1410 internal=true,
1411 bevel1=ibevel1,bevel2=ibevel2,
1412 higbee=higbee, higbee1=higbee1, higbee2=higbee2
1413 );
1414 }
1415 children();
1416 }
1417}
1418
1419
1420module _nutshape(nutwidth, h, shape, bevel1, bevel2)
1421{
1422 bevel_d=0.9;
1423 intersection(){
1424 if (shape=="hex")
1425 cyl(d=nutwidth, circum=true, $fn=6, l=h, chamfer1=bevel1?0:nutwidth*.01, chamfer2=bevel2?0:nutwidth*.01);
1426 //vnf_polyhedron(vnf);
1427 else
1428 cuboid([nutwidth,nutwidth,h],chamfer=nutwidth*.01, except=[if (bevel1) BOT, if(bevel2) TOP]);
1429 fn = quantup(segs(r=nutwidth/2),shape=="hex"?6:4);
1430 d = shape=="hex" ? 2*nutwidth/sqrt(3) : sqrt(2)*nutwidth;
1431 chamfsize = (d-nutwidth)/2/bevel_d;
1432 cyl(d=d*.99,h=h+.01,realign=true,circum=true,$fn=fn,chamfer1=bevel1?chamfsize:0,chamfer2=bevel2?chamfsize:0,chamfang=30);
1433 }
1434}
1435
1436
1437// Module: thread_helix()
1438// Usage:
1439// thread_helix(d, pitch, [thread_depth], [flank_angle], [turns], [profile=], [left_handed=], [higbee=], [internal=]);
1440// Description:
1441// Creates a right-handed helical thread with optional end tapering. Unlike
1442// {{generic_threaded_rod()}, this module just generates the thread, and you specify the total
1443// angle of threading that you want, which makes it easy to put complete threads onto a longer
1444// shaft. It also optionally makes a finely divided taper at the thread ends. However, it takes
1445// 2-3 times as long to render compared to {{generic_threaded_rod()}}. This module was designed
1446// to handle threads found in plastic and glass bottles.
1447// .
1448// You can specify a thread_depth and flank_angle, in which case you get a symmetric trapezoidal
1449// thread, whose inner diameter (the base of the threads for external threading) is d (so the
1450// total diameter will be d + thread_depth). This differs from the threaded_rod modules, where
1451// the specified diameter is the outer diameter. Alternatively you can give a profile, following
1452// the same rules as for general_threaded_rod. The Y=0 point will align with the specified
1453// diameter, and the profile should range in X from -1/2 to 1/2. You cannot specify both the
1454// profile and the thread_depth or flank_angle.
1455// .
1456// Unlike {{generic_threaded_rod()}, when internal=true this module generates the threads, not a thread mask.
1457// The profile needs to be inverted to produce the proper thread form. If you use the built-in trapezoidal
1458// thread you get the inverted thread, designed so that the inner diameter is d. If you supply a custom profile
1459// you must invert it yourself to get internal threads. With adequate clearance
1460// this thread will mate with the thread that uses the same parameters but has internal=false. Note that
1461// unlike the threaded_rod modules, thread_helix does not adjust the diameter for faceting, nor does it
1462// subtract any $slop for clearance.
1463// .
1464// The taper options specify tapering at of the threads at each end, and is given as the linear distance
1465// over which to taper. If taper is positive the threads are lengthened by the specified distance; if taper
1466// is negative, the taper is included in the thread length specified by `turns`. Tapering works on both internal and external threads.
1467// Arguments:
1468// d = Inside base diameter of threads. Default: 10
1469// pitch = Distance between threads. Default: 2
1470// thread_depth = Depth of threads from top to bottom.
1471// flank_angle = Angle of thread faces to plane perpendicular to screw. Default: 15 degrees.
1472// turns = Number of revolutions to rotate thread around.
1473// ---
1474// profile = If an asymmetrical thread profile is needed, it can be specified here.
1475// starts = The number of thread starts. Default: 1
1476// left_handed = If true, thread has a left-handed winding.
1477// internal = if true make internal threads. The only effect this has is to change how the threads taper if tapering is selected. When true, threads taper towards the outside; when false, they taper towards the inside. Default: false
1478// d1 = Bottom inside base diameter of threads.
1479// d2 = Top inside base diameter of threads.
1480// taper = Length of tapers for thread ends. Positive to add taper to threads, negative to taper within specified length. Default: 0
1481// taper1 = Length of taper for bottom thread end
1482// taper2 = Length of taper for top thread end
1483// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
1484// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
1485// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
1486// Example(2DMed): Typical Tooth Profile
1487// pitch = 2;
1488// depth = pitch * cos(30) * 5/8;
1489// profile = [
1490// [-6/16, 0 ],
1491// [-1/16, depth/pitch ],
1492// [ 1/16, depth/pitch ],
1493// [ 6/16, 0 ],
1494// ];
1495// stroke(profile, width=0.02);
1496// Figure(2D,Med):
1497// pa_delta = tan(15)/4;
1498// rr1 = -1/2;
1499// z1 = 1/4-pa_delta;
1500// z2 = 1/4+pa_delta;
1501// profile = [
1502// [-z2, rr1],
1503// [-z1, 0],
1504// [ z1, 0],
1505// [ z2, rr1],
1506// ];
1507// fullprofile = 50*left(1/2,p=concat(profile, right(1, p=profile)));
1508// stroke(fullprofile,width=1);
1509// dir = fullprofile[2]-fullprofile[3];
1510// dir2 = fullprofile[5]-fullprofile[4];
1511// curve = arc(15,angle=[75,87],r=40 /*67.5*/);
1512// avgpt = mean([fullprofile[5]+.1*dir2, fullprofile[5]+.4*dir2]);
1513// color("red"){
1514// stroke([fullprofile[4]+[0,1], fullprofile[4]+[0,37]], width=1);
1515// stroke([fullprofile[5]+.1*dir2, fullprofile[5]+.4*dir2], width=1);
1516// stroke(move(-curve[0]+avgpt,p=curve), width=0.71,endcaps="arrow2");
1517// right(14)back(19)text("flank",size=4,halign="center");
1518// right(14)back(14)text("angle",size=4,halign="center");
1519// }
1520// Examples:
1521// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, $fn=72);
1522// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2.5, taper=1, $fn=72);
1523// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=2, taper=2, internal=true, $fn=72);
1524// thread_helix(d=10, pitch=2, thread_depth=0.75, flank_angle=15, turns=1, left_handed=true, taper=1, $fn=36);
1525function thread_helix(
1526 d, pitch, thread_depth, flank_angle, turns,
1527 profile, starts=1, left_handed=false, internal=false,
1528 d1, d2, taper, taper1, taper2,
1529 anchor, spin, orient
1530) = no_function("thread_helix");
1531module thread_helix(
1532 d, pitch, thread_depth, flank_angle, turns=2,
1533 profile, starts=1, left_handed=false, internal=false,
1534 d1, d2, taper, taper1, taper2,
1535 anchor, spin, orient
1536) {
1537 dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile");
1538 h = pitch*starts*turns;
1539 r1 = get_radius(d1=d1, d=d, dflt=10);
1540 r2 = get_radius(d1=d2, d=d, dflt=10);
1541 profile = is_def(profile) ? profile :
1542 let(
1543 tdp = thread_depth / pitch,
1544 dz = tdp * tan(flank_angle),
1545 cap = (1 - 2*dz)/2
1546 )
1547 internal?
1548 [
1549 [-cap/2-dz, tdp],
1550 [-cap/2, 0 ],
1551 [+cap/2, 0 ],
1552 [+cap/2+dz, tdp],
1553 ]
1554 :
1555 [
1556 [+cap/2+dz, 0 ],
1557 [+cap/2, tdp],
1558 [-cap/2, tdp],
1559 [-cap/2-dz, 0 ],
1560 ];
1561 pline = mirror([-1,1], p = profile * pitch);
1562 dir = left_handed? -1 : 1;
1563 attachable(anchor,spin,orient, r1=r1, r2=r2, l=h) {
1564 zrot_copies(n=starts) {
1565 spiral_sweep(pline, h=h, r1=r1, r2=r2, turns=turns*dir, taper=taper, taper1=taper1, taper2=taper2, internal=internal, anchor=CENTER);
1566 }
1567 children();
1568 }
1569}
1570
1571
1572
1573// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
1574
1575// Questions
1576// Should nut modules take d1/d2 for tapered nuts?
1577//
1578// Need explanation of what exactly the diff is between threaded_rod and helix_threads.
1579// Higbee is different, angle in one and length in another. Need to reconcile