3D part design with Openscad #42: Reverse engineering threads

An easy way to match an existing thread profile using openscad.

3 min read
By Bob
3D part design with  Openscad #42: Reverse engineering threads

When I was working on ideas for improving the projection module that I made in the last post I loaded an existing stl file with threads and wondered if I could use that to make new threads match an existing design with the thread module, it turns out it was pretty easy with just a simple addition to the code.

Here is a slice from the file :

I saved it as an stl file and loaded it into my main template, aligned the threads to the stl file and started making adjustments:

once I had figured out the pitch, diameter and height of the threads I adjusted the thickness but found out I didn't have a way to match the flank angle:

since all I needed was a way to size the z-axis of the inside of the thread I added a way to change the size of the cylinder on the inside and called it Flank_angle:

then added it to just the first cylinder in the code, and now I can adjust the angle:

0:00
/

and here is the updated code:

/*[Threads]*/
Show_Threads = true;
Thread_pitch = 2;//[0:.001:16]
Thread_diameter = 3;//[0:.001:100]
Thread_diameter2 = 2;//[.1:.001:100]
Thread_height = 2;//[0:.001:100]
Thread_shape = 4;//[3:1:20]
Thread_thickness = .525;//[.1:.001:12]
Flank_angle = .525;//[.1:.001:12]
Move_Threads_X = 0; // [0:.01:400]
Move_Threads_Y = 0; // [0:.01:400]
Move_Threads_Z = 0; // [-400:.01:400]
Rotate_Threads_X = 0; // [0:.01:360]
Rotate_Threads_Y = 0; // [0:.01:360]
Rotate_Threads_Z = 0; // [0:.01:360]

//***Threads***//
Inches=(Thread_height/25.4);
ThreadsPerInch =(Thread_pitch);
ImperialBoltDiameter=(Thread_diameter/25.4);
Tn=100*Thread_pitch;
Pitch_angle=360*Thread_pitch;

module Threads(){
  if(Show_Threads)  
  rotate([Rotate_Threads_X,Rotate_Threads_Y,Rotate_Threads_Z])
  translate([Move_Threads_X,Move_Threads_Y,Move_Threads_Z])
  
 for (i =[0.4:.075:Tn]){
   
 hull(){
  
   translate([Thread_diameter/2*cos(i*Pitch_angle/Tn),Thread_diameter/2*sin(i*Pitch_angle/Tn),Thread_height*(i/Tn)])
   rotate(a=180+(i*(Pitch_angle/Tn)),v=[0,0,1])
   rotate(a=90,v=[.01,0,0])
   cylinder(h=1,d1=.1,d2=Thread_thickness*Flank_angle,$fn=Thread_shape,center=false);
   translate([Thread_diameter2/2*cos((i+1)*Pitch_angle/Tn),Thread_diameter2/2*sin((i+1)*Pitch_angle/Tn),Thread_height*(i+1)/Tn])
   rotate(a=180+(i*(Pitch_angle/Tn)),v=[0,0,.1])
   rotate(a=89.7,v=[.1,0,0])
   cylinder(h=.01,d1=0,d2=Thread_thickness,$fn=Thread_shape,center=false); 
   rotate(a=0,v=[0,10,0])
   translate([Thread_diameter2/2*cos((i+1)*Pitch_angle/Tn),Thread_diameter2/2*sin((i+1)*Pitch_angle/Tn),Thread_height*(i+1)/Tn])
   rotate(a=180+(i*(Pitch_angle/Tn)),v=[0,0,1])
   rotate(a=90,v=[1,0,0])
   cylinder(h=.1,d1=0,d2=Thread_thickness,$fn=Thread_shape,center=false); 
   translate([Thread_diameter2/2*cos((i+1)*Pitch_angle/Tn),Thread_diameter2/2*sin((i+1)*Pitch_angle/Tn),Thread_height*(i+1)/Tn])
   rotate(a=180+(i*(Pitch_angle/Tn)),v=[0,0,1])
   rotate(a=89.5,v=[1,0,0])
   cylinder(h=.1,d1=0,d2=Thread_thickness,$fn=Thread_shape,center=false); 
}
}}
//

Threads();