// Parametric Involute Bevel and Spur Gears by GregFrost // It is licensed under the Creative Commons - GNU LGPL 2.1 license. // © 2010 by GregFrost, thingiverse.com/Amp // http://www.thingiverse.com/thing:3575 and http://www.thingiverse.com/thing:3752 // Simple Test: //gear (circular_pitch=700, // gear_thickness = 12, // rim_thickness = 15, // hub_thickness = 17, // circles=8); //Complex Spur Gear Test: //test_gears (); // Meshing Double Helix: //test_meshing_double_helix (); module test_meshing_double_helix(){ meshing_double_helix (); } // Demonstrate the backlash option for Spur gears. //test_backlash (); // Demonstrate how to make meshing bevel gears. //test_bevel_gear_pair(); module test_bevel_gear_pair(){ bevel_gear_pair (); } module test_bevel_gear(){bevel_gear();} //bevel_gear(); pi=3.1415926535897932384626433832795; //================================================== // Bevel Gears: // Two gears with the same cone distance, circular pitch (measured at the cone distance) // and pressure angle will mesh. module bevel_gear_pair ( gear1_teeth = 41, gear2_teeth = 7, axis_angle = 90, outside_circular_pitch=1000) { outside_pitch_radius1 = gear1_teeth * outside_circular_pitch / 360; outside_pitch_radius2 = gear2_teeth * outside_circular_pitch / 360; pitch_apex1=outside_pitch_radius2 * sin (axis_angle) + (outside_pitch_radius2 * cos (axis_angle) + outside_pitch_radius1) / tan (axis_angle); cone_distance = sqrt (pow (pitch_apex1, 2) + pow (outside_pitch_radius1, 2)); pitch_apex2 = sqrt (pow (cone_distance, 2) - pow (outside_pitch_radius2, 2)); echo ("cone_distance", cone_distance); pitch_angle1 = asin (outside_pitch_radius1 / cone_distance); pitch_angle2 = asin (outside_pitch_radius2 / cone_distance); echo ("pitch_angle1, pitch_angle2", pitch_angle1, pitch_angle2); echo ("pitch_angle1 + pitch_angle2", pitch_angle1 + pitch_angle2); rotate([0,0,90]) translate ([0,0,pitch_apex1+20]) { translate([0,0,-pitch_apex1]) bevel_gear ( number_of_teeth=gear1_teeth, cone_distance=cone_distance, pressure_angle=30, outside_circular_pitch=outside_circular_pitch); rotate([0,-(pitch_angle1+pitch_angle2),0]) translate([0,0,-pitch_apex2]) bevel_gear ( number_of_teeth=gear2_teeth, cone_distance=cone_distance, pressure_angle=30, outside_circular_pitch=outside_circular_pitch); } } //Bevel Gear Finishing Options: bevel_gear_flat = 0; bevel_gear_back_cone = 1; module bevel_gear ( number_of_teeth=11, cone_distance=100, face_width=20, outside_circular_pitch=1000, pressure_angle=30, clearance = 0.2, bore_diameter=5, gear_thickness = 15, backlash = 0, involute_facets=0, finish = -1) { echo ("bevel_gear", "teeth", number_of_teeth, "cone distance", cone_distance, face_width, outside_circular_pitch, pressure_angle, clearance, bore_diameter, involute_facets, finish); // Pitch diameter: Diameter of pitch circle at the fat end of the gear. outside_pitch_diameter = number_of_teeth * outside_circular_pitch / 180; outside_pitch_radius = outside_pitch_diameter / 2; // The height of the pitch apex. pitch_apex = sqrt (pow (cone_distance, 2) - pow (outside_pitch_radius, 2)); pitch_angle = asin (outside_pitch_radius/cone_distance); echo ("Num Teeth:", number_of_teeth, " Pitch Angle:", pitch_angle); finish = (finish != -1) ? finish : (pitch_angle < 45) ? bevel_gear_flat : bevel_gear_back_cone; apex_to_apex=cone_distance / cos (pitch_angle); back_cone_radius = apex_to_apex * sin (pitch_angle); // Calculate and display the pitch angle. This is needed to determine the angle to mount two meshing cone gears. // Base Circle for forming the involute teeth shape. base_radius = back_cone_radius * cos (pressure_angle); // Diametrial pitch: Number of teeth per unit length. pitch_diametrial = number_of_teeth / outside_pitch_diameter; // Addendum: Radial distance from pitch circle to outside circle. addendum = 1 / pitch_diametrial; // Outer Circle outer_radius = back_cone_radius + addendum; // Dedendum: Radial distance from pitch circle to root diameter dedendum = addendum + clearance; dedendum_angle = atan (dedendum / cone_distance); root_angle = pitch_angle - dedendum_angle; root_cone_full_radius = tan (root_angle)*apex_to_apex; back_cone_full_radius=apex_to_apex / tan (pitch_angle); back_cone_end_radius = outside_pitch_radius - dedendum * cos (pitch_angle) - gear_thickness / tan (pitch_angle); back_cone_descent = dedendum * sin (pitch_angle) + gear_thickness; // Root diameter: Diameter of bottom of tooth spaces. root_radius = back_cone_radius - dedendum; half_tooth_thickness = outside_pitch_radius * sin (360 / (4 * number_of_teeth)) - backlash / 4; half_thick_angle = asin (half_tooth_thickness / back_cone_radius); face_cone_height = apex_to_apex-face_width / cos (pitch_angle); face_cone_full_radius = face_cone_height / tan (pitch_angle); face_cone_descent = dedendum * sin (pitch_angle); face_cone_end_radius = outside_pitch_radius - face_width / sin (pitch_angle) - face_cone_descent / tan (pitch_angle); // For the bevel_gear_flat finish option, calculate the height of a cube to select the portion of the gear that includes the full pitch face. bevel_gear_flat_height = pitch_apex - (cone_distance - face_width) * cos (pitch_angle); // translate([0,0,-pitch_apex]) difference () { intersection () { union() { rotate (half_thick_angle) translate ([0,0,pitch_apex-apex_to_apex]) cylinder ($fn=number_of_teeth*2, r1=root_cone_full_radius,r2=0,h=apex_to_apex); for (i = [1:number_of_teeth]) // for (i = [1:1]) { rotate ([0,0,i*360/number_of_teeth]) { involute_bevel_gear_tooth ( back_cone_radius = back_cone_radius, root_radius = root_radius, base_radius = base_radius, outer_radius = outer_radius, pitch_apex = pitch_apex, cone_distance = cone_distance, half_thick_angle = half_thick_angle, involute_facets = involute_facets); } } } if (finish == bevel_gear_back_cone) { translate ([0,0,-back_cone_descent]) cylinder ( $fn=number_of_teeth*2, r1=back_cone_end_radius, r2=back_cone_full_radius*2, h=apex_to_apex + back_cone_descent); } else { translate ([-1.5*outside_pitch_radius,-1.5*outside_pitch_radius,0]) cube ([3*outside_pitch_radius, 3*outside_pitch_radius, bevel_gear_flat_height]); } } if (finish == bevel_gear_back_cone) { translate ([0,0,-face_cone_descent]) cylinder ( r1=face_cone_end_radius, r2=face_cone_full_radius * 2, h=face_cone_height + face_cone_descent+pitch_apex); } translate ([0,0,pitch_apex - apex_to_apex]) cylinder (r=bore_diameter/2,h=apex_to_apex); } } module involute_bevel_gear_tooth ( back_cone_radius, root_radius, base_radius, outer_radius, pitch_apex, cone_distance, half_thick_angle, involute_facets) { // echo ("involute_bevel_gear_tooth", // back_cone_radius, // root_radius, // base_radius, // outer_radius, // pitch_apex, // cone_distance, // half_thick_angle); min_radius = max (base_radius*2,root_radius*2); pitch_point = involute ( base_radius*2, involute_intersect_angle (base_radius*2, back_cone_radius*2)); pitch_angle = atan2 (pitch_point[1], pitch_point[0]); centre_angle = pitch_angle + half_thick_angle; start_angle = involute_intersect_angle (base_radius*2, min_radius); stop_angle = involute_intersect_angle (base_radius*2, outer_radius*2); res=(involute_facets!=0)?involute_facets:($fn==0)?5:$fn/4; translate ([0,0,pitch_apex]) rotate ([0,-atan(back_cone_radius/cone_distance),0]) translate ([-back_cone_radius*2,0,-cone_distance*2]) union () { for (i=[1:res]) { assign ( point1= involute (base_radius*2,start_angle+(stop_angle - start_angle)*(i-1)/res), point2= involute (base_radius*2,start_angle+(stop_angle - start_angle)*(i)/res)) { assign ( 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))) { polyhedron ( points=[ [back_cone_radius*2+0.1,0,cone_distance*2], [side1_point1[0],side1_point1[1],0], [side1_point2[0],side1_point2[1],0], [side2_point2[0],side2_point2[1],0], [side2_point1[0],side2_point1[1],0], [0.1,0,0]], triangles=[[0,2,1],[0,3,2],[0,4,3],[0,1,5],[1,2,5],[2,3,5],[3,4,5],[0,5,4]]); } } } } } 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) { // Check for undefined circular pitch (happens when neither circular_pitch or diametral_pitch are specified) if (circular_pitch==undef) echo("MCAD ERROR: gear module needs either a diametral_pitch or circular_pitch"); //Convert diametrial pitch to our native circular pitch circular_pitch = (circular_pitch!=false?circular_pitch:pi/diametral_pitch); // Pitch diameter: Diameter of pitch circle. pitch_diameter = number_of_teeth * circular_pitch / pi; pitch_radius = pitch_diameter/2; echo ("Teeth:", number_of_teeth, " Pitch radius:", pitch_radius); // 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); } translate ([0,0,-1]) linear_exturde_flat_option(flat =flat, height=2+max(rim_thickness,hub_thickness,gear_thickness)) 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) { if(flat==false) { linear_extrude(height = height, center = center, convexity = convexity, twist= twist) child(0); } else { child(0); } } 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) { 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]) assign ( 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)) { assign ( 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))) { polygon ( points=[[0,0],side1_point1,side1_point2,side2_point2,side2_point1], paths=[[0,1,2,3,4,0]]); } } } } // Mathematical Functions //=============== // Finds the angle of the involute about the base radius at the given distance (radius) from it's center. //source: http://www.mathhelpforum.com/math-help/geometry/136011-circle-involute-solving-y-any-given-x.html function involute_intersect_angle (base_radius, radius) = sqrt (pow (radius/base_radius, 2) - 1) * 180 / pi; // Calculate the involute position for a given base radius and involute angle. function rotated_involute (rotate, base_radius, involute_angle) = [ cos (rotate) * involute (base_radius, involute_angle)[0] + sin (rotate) * involute (base_radius, involute_angle)[1], cos (rotate) * involute (base_radius, involute_angle)[1] - sin (rotate) * involute (base_radius, involute_angle)[0] ]; function mirror_point (coord) = [ coord[0], -coord[1] ]; function rotate_point (rotate, coord) = [ cos (rotate) * coord[0] + sin (rotate) * coord[1], cos (rotate) * coord[1] - sin (rotate) * coord[0] ]; function involute (base_radius, involute_angle) = [ base_radius*(cos (involute_angle) + involute_angle*pi/180*sin (involute_angle)), base_radius*(sin (involute_angle) - involute_angle*pi/180*cos (involute_angle)) ]; // Test Cases //=============== module test_gears() { translate([17,-15]) { gear (number_of_teeth=17, circular_pitch=500, circles=8); rotate ([0,0,360*4/17]) translate ([39.088888,0,0]) { gear (number_of_teeth=11, circular_pitch=500, hub_diameter=0, rim_width=65); translate ([0,0,8]) { gear (number_of_teeth=6, circular_pitch=300, hub_diameter=0, rim_width=5, rim_thickness=6, pressure_angle=31); rotate ([0,0,360*5/6]) translate ([22.5,0,1]) gear (number_of_teeth=21, circular_pitch=300, bore_diameter=2, hub_diameter=4, rim_width=1, hub_thickness=4, rim_thickness=4, gear_thickness=3, pressure_angle=31); } } translate ([-61.1111111,0,0]) { gear (number_of_teeth=27, circular_pitch=500, circles=5, hub_diameter=2*8.88888889); translate ([0,0,10]) { gear ( number_of_teeth=14, circular_pitch=200, pressure_angle=5, clearance = 0.2, gear_thickness = 10, rim_thickness = 10, rim_width = 15, bore_diameter=5, circles=0); translate ([13.8888888,0,1]) gear ( number_of_teeth=11, circular_pitch=200, pressure_angle=5, clearance = 0.2, gear_thickness = 10, rim_thickness = 10, rim_width = 15, hub_thickness = 20, hub_diameter=2*7.222222, bore_diameter=5, circles=0); } } rotate ([0,0,360*-5/17]) translate ([44.444444444,0,0]) gear (number_of_teeth=15, circular_pitch=500, hub_diameter=10, rim_width=5, rim_thickness=5, gear_thickness=4, hub_thickness=6, circles=9); rotate ([0,0,360*-1/17]) translate ([30.5555555,0,-1]) gear (number_of_teeth=5, circular_pitch=500, hub_diameter=0, rim_width=5, rim_thickness=10); } } module meshing_double_helix () { test_double_helix_gear (); mirror ([0,1,0]) translate ([58.33333333,0,0]) test_double_helix_gear (teeth=13,circles=6); } module test_double_helix_gear ( teeth=17, circles=8) { //double helical gear { twist=200; height=20; pressure_angle=30; gear (number_of_teeth=teeth, circular_pitch=700, pressure_angle=pressure_angle, clearance = 0.2, gear_thickness = height/2*0.5, rim_thickness = height/2, rim_width = 5, hub_thickness = height/2*1.2, hub_diameter=15, bore_diameter=5, circles=circles, twist=twist/teeth); mirror([0,0,1]) gear (number_of_teeth=teeth, circular_pitch=700, pressure_angle=pressure_angle, clearance = 0.2, gear_thickness = height/2, rim_thickness = height/2, rim_width = 5, hub_thickness = height/2, hub_diameter=15, bore_diameter=5, circles=circles, twist=twist/teeth); } } module test_backlash () { backlash = 2; teeth = 15; translate ([-29.166666,0,0]) { translate ([58.3333333,0,0]) rotate ([0,0,-360/teeth/4]) gear ( number_of_teeth = teeth, circular_pitch=700, gear_thickness = 12, rim_thickness = 15, rim_width = 5, hub_thickness = 17, hub_diameter=15, bore_diameter=5, backlash = 2, circles=8); rotate ([0,0,360/teeth/4]) gear ( number_of_teeth = teeth, circular_pitch=700, gear_thickness = 12, rim_thickness = 15, rim_width = 5, hub_thickness = 17, hub_diameter=15, bore_diameter=5, backlash = 2, circles=8); } color([0,0,128,0.5]) translate([0,0,-5]) cylinder ($fn=20,r=backlash / 4,h=25); }