OpenFlexure Microscope OpenSCAD docs
libs/MCAD/involute_gears.scad
function gear_outer_radius(pitch_r, n_teeth)
[Source]
function gear_outer_radius(pitch_r, n_teeth) = pitch_r*(1 + 2/n_teeth);
* * Calculate the outer radius for a gear from pitch radius and number of teeth
function gear_pitch_radius(circular_pitch, n_teeth)
[Source]
function gear_pitch_radius(circular_pitch, n_teeth) = n_teeth*circular_pitch/360;
* * Calculate the pitch radius for a gear the circular pitch and the number of teeth * The pitch radius is the ditance from the centre of gear to the meshing point. * This is calcualted as: * pitch radius = Nteeth * circular_pitch / 360
module gear( number_of_teeth=15, circular_pitch=false, diametral_pitch=false, pressure_angle=28, clearance=0.2, gear_thickness=5, rim_thickness=8, rim_width=5, hub_thickness=10, hub_diameter=15, bore_diameter=5, circles=0, backlash=0, twist=0, involute_facets=0, flat=false )
[Source]
module gear(number_of_teeth=15, circular_pitch=false, diametral_pitch=false, pressure_angle=28, clearance = 0.2, gear_thickness=5, rim_thickness=8, rim_width=5, hub_thickness=10, hub_diameter=15, bore_diameter=5, circles=0, backlash=0, twist=0, involute_facets=0, flat=false){ assert(!(circular_pitch==false && diametral_pitch==false), "MCAD ERROR: gear module needs either a diametral_pitch or circular_pitch"); assert(circular_pitch==false || diametral_pitch==false, "MCAD ERROR: cannot specify diametral_pitch and circular_pitch"); //Convert diametrial pitch to our native circular pitch circ_pitch = circular_pitch!=false ? circular_pitch : 180/diametral_pitch; // Pitch diameter: Diameter of pitch circle. pitch_diameter = number_of_teeth * circ_pitch / 180; pitch_radius = pitch_diameter/2; // Base Circle base_radius = pitch_radius*cos(pressure_angle); // Diametrial pitch: Number of teeth per unit length. pitch_diametrial = number_of_teeth / pitch_diameter; // Addendum: Radial distance from pitch circle to outside circle. addendum = 1/pitch_diametrial; //Outer Circle outer_radius = pitch_radius+addendum; // Dedendum: Radial distance from pitch circle to root diameter dedendum = addendum + clearance; // Root diameter: Diameter of bottom of tooth spaces. root_radius = pitch_radius-dedendum; backlash_angle = backlash / pitch_radius * 180 / PI; half_thick_angle = (360 / number_of_teeth - backlash_angle) / 4; // Variables controlling the rim. rim_radius = root_radius - rim_width; // Variables controlling the circular holes in the gear. circle_orbit_diameter=hub_diameter/2+rim_radius; circle_orbit_curcumference=PI*circle_orbit_diameter; // Limit the circle size to 90% of the gear face. circle_diameter = min(0.70*circle_orbit_curcumference/circles, (rim_radius-hub_diameter/2)*0.9); difference(){ union(){ difference(){ linear_exturde_flat_option(flat=flat, height=rim_thickness, convexity=10, twist=twist){ gear_shape(number_of_teeth, pitch_radius = pitch_radius, root_radius = root_radius, base_radius = base_radius, outer_radius = outer_radius, half_thick_angle = half_thick_angle, involute_facets=involute_facets); } if(gear_thickness < rim_thickness){ translate([0, 0, gear_thickness]){ cylinder(r=rim_radius,h=rim_thickness-gear_thickness+1); } } } if(gear_thickness > rim_thickness){ linear_exturde_flat_option(flat=flat, height=gear_thickness){ circle(r=rim_radius); } } if(flat == false && hub_thickness > gear_thickness){ translate([0, 0, gear_thickness]){ linear_exturde_flat_option(flat=flat, height=hub_thickness-gear_thickness){ circle(r=hub_diameter/2); } } } } if (bore_diameter>0){ translate([0, 0, -1]){ bore_h = 2+max(rim_thickness,hub_thickness,gear_thickness); linear_exturde_flat_option(flat =flat, height=bore_h){ circle(r=bore_diameter/2); } } } if(circles>0){ for(i=[0:circles-1]){ rotate([0, 0, i*360/circles]){ translate([circle_orbit_diameter/2,0,-1]){ linear_exturde_flat_option(flat =flat, height=max(gear_thickness,rim_thickness)+3){ circle(r=circle_diameter/2); } } } } } } }
module linear_exturde_flat_option(flat=false, height=10, center=false, convexity=2, twist=0)
[Source]
module linear_exturde_flat_option(flat =false, height = 10, center = false, convexity = 2, twist = 0){ if(flat==false){ linear_extrude(height = height, center = center, convexity = convexity, twist= twist){ children(0); } } else{ children(0); } }
module gear_shape( number_of_teeth, pitch_radius, root_radius, base_radius, outer_radius, half_thick_angle, involute_facets )
[Source]
module gear_shape(number_of_teeth, pitch_radius, root_radius, base_radius, outer_radius, half_thick_angle, involute_facets){ union(){ rotate(half_thick_angle){ circle($fn=number_of_teeth*2, r=root_radius); } for(i = [1:number_of_teeth]){ rotate([0, 0, i*360/number_of_teeth]){ involute_gear_tooth(pitch_radius = pitch_radius, root_radius = root_radius, base_radius = base_radius, outer_radius = outer_radius, half_thick_angle = half_thick_angle, involute_facets=involute_facets); } } } }
module involute_gear_tooth( pitch_radius, root_radius, base_radius, outer_radius, half_thick_angle, involute_facets )
[Source]
module involute_gear_tooth(pitch_radius, root_radius, base_radius, outer_radius, half_thick_angle, involute_facets){ min_radius = max(base_radius,root_radius); pitch_point = involute(base_radius, involute_intersect_angle(base_radius, pitch_radius)); pitch_angle = atan2(pitch_point[1], pitch_point[0]); centre_angle = pitch_angle + half_thick_angle; start_angle = involute_intersect_angle(base_radius, min_radius); stop_angle = involute_intersect_angle(base_radius, outer_radius); res=(involute_facets!=0)?involute_facets:($fn==0)?5:$fn/4; union() { for(i=[1:res]) { point1=involute(base_radius,start_angle+(stop_angle - start_angle)*(i-1)/res); point2=involute(base_radius,start_angle+(stop_angle - start_angle)*i/res); side1_point1=rotate_point(centre_angle, point1); side1_point2=rotate_point(centre_angle, point2); side2_point1=mirror_point(rotate_point(centre_angle, point1)); side2_point2=mirror_point(rotate_point(centre_angle, point2)); points = [[0, 0], side1_point1, side1_point2, side2_point2, side2_point1]; polygon(points=points, paths=[[0,1,2,3,4,0]]); } } }
function involute_intersect_angle(base_radius, radius)
[Source]
function involute_intersect_angle(base_radius, radius) = sqrt(pow(radius/base_radius, 2) - 1) * 180 / PI;
function rotated_involute(rotate, base_radius, involute_angle)
[Source]
function rotated_involute(rotate, base_radius, involute_angle) = let( unrotated_involute = involute(base_radius, involute_angle) ) [ cos(rotate) * unrotated_involute.x + sin(rotate) * unrotated_involute.y, cos(rotate) * unrotated_involute.y - sin(rotate) * unrotated_involute.x ];
function mirror_point(coord)
[Source]
function mirror_point(coord) = [coord.x, -coord.y];
function rotate_point(rotate, coord)
[Source]
function rotate_point(rotate, coord) = [ cos(rotate) * coord.x + sin(rotate) * coord.y, cos(rotate) * coord.y - sin(rotate) * coord.x ];
function involute(base_radius, involute_angle)
[Source]
function involute(base_radius, involute_angle) = let( angle_radian = involute_angle*PI/180 ) [ base_radius*(cos(involute_angle) + angle_radian*sin(involute_angle)), base_radius*(sin(involute_angle) - angle_radian*cos(involute_angle)) ];