diff --git a/README.md b/README.md index 9ae49c5..5742490 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ A place to share CadQuery scripts, modules, tutorials and projects * [3D_Printer_Extruder_Support.py](examples/3D_Printer_Extruder_Support.py) - Designed for mounting hotend to an i3 X-carriage inspired by the P3steel Toolson +* [Involute_Gear.py](examples/Involute_Gear.py) - Fast involute gear generator. + + + ### Tutorials * [Ex000 Start Here.ipynb](tutorials/Ex000%20Start%20Here.ipynb) - iPython notebook that is the entry point for a set of CadQuery tutorials diff --git a/examples/Involute_Gear.py b/examples/Involute_Gear.py new file mode 100644 index 0000000..9cbf740 --- /dev/null +++ b/examples/Involute_Gear.py @@ -0,0 +1,81 @@ +from cadquery import Workplane, Edge, Wire, Vector +from math import * + + +def involute_gear(m, z, alpha=20, shift=0, N=20): + ''' + See https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html + for math + ''' + + alpha = radians(alpha) + + # radii + r_ref = m*z/2 + r_top = r_ref + m*(1+shift) + r_base = r_ref*cos(alpha) + r_d = r_ref - 1.25*m + + inv = lambda a: tan(a) - a + + # angles of interest + alpha_inv = inv(alpha) + alpha_tip = acos(r_base/r_top) + alpha_tip_inv = inv(alpha_tip) + + a = 90/z+degrees(alpha_inv) + a2 = 90/z++degrees(alpha_inv)-degrees(alpha_tip_inv) + a3 = 360/z-a + + # involute curve (radius based parametrization) + def involute_curve(r_b,sign=1): + + def f(r): + alpha = sign*acos(r_b/r) + x = r*cos(tan(alpha) - alpha) + y = r*sin(tan(alpha) - alpha) + + return x,y + + return f + + # construct all the profiles + right = ( + Workplane() + .transformed(rotate=(0,0,a)) + .parametricCurve(involute_curve(r_base,-1), start=r_base, stop = r_top, makeWire=False, N=N) + .val() + ) + + left = ( + Workplane() + .transformed(rotate=(0,0,-a)) + .parametricCurve(involute_curve(r_base), start=r_base, stop = r_top, makeWire=False, N=N) + .val() + ) + + top = Edge.makeCircle(r_top,angle1=-a2, angle2=a2) + bottom = Edge.makeCircle(r_d, angle1=-a3, angle2=-a) + + side = Edge.makeLine( cq.Vector(r_d,0), cq.Vector(r_base,0)) + side1 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a) + side2 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a3) + + # single tooth profile + profile = Wire.assembleEdges([left,top,right,side1,bottom,side2]) + profile = profile.chamfer2D(m/4, profile.Vertices()[-3:-1]) + + # complete gear + res = ( + Workplane() + .polarArray(0,0,360,z) + .each(lambda loc: profile.located(loc)) + .consolidateWires() + ) + + return res.val() + + +show_object( + Workplane(obj=involute_gear(1, 20)).toPending().twistExtrude(20, 30) +) \ No newline at end of file diff --git a/examples/images/Involute_Gear.png b/examples/images/Involute_Gear.png new file mode 100644 index 0000000..d88c258 Binary files /dev/null and b/examples/images/Involute_Gear.png differ