diff --git a/pygears/__init__.py b/pygears/__init__.py index 73fab10..ffd1f61 100644 --- a/pygears/__init__.py +++ b/pygears/__init__.py @@ -16,4 +16,4 @@ # * * # *************************************************************************** -__version__ = "0.0.4" \ No newline at end of file +__version__ = "0.0.4" diff --git a/pygears/_functions.py b/pygears/_functions.py index 3369a53..cddd399 100644 --- a/pygears/_functions.py +++ b/pygears/_functions.py @@ -22,55 +22,61 @@ from numpy.linalg import solve, norm def reflection(angle): - mat = array( - [[cos(2 * angle), -sin(2 * angle)], [-sin(2 * angle), -cos(2 * angle)]]) + mat = array([[cos(2 * angle), -sin(2 * angle)], [-sin(2 * angle), -cos(2 * angle)]]) def func(x): - return(dot(x, mat)) - return(func) + return dot(x, mat) + + return func def reflection3D(angle): - mat = array([[cos(2 * angle), -sin(2 * angle), 0.], - [-sin(2 * angle), -cos(2 * angle), 0.], [0., 0., 1.]]) + mat = array( + [ + [cos(2 * angle), -sin(2 * angle), 0.0], + [-sin(2 * angle), -cos(2 * angle), 0.0], + [0.0, 0.0, 1.0], + ] + ) def func(x): - return(dot(x, mat)) - return(func) + return dot(x, mat) + + return func def rotation(angle, midpoint=None): - midpoint = midpoint or [0., 0.] - mat = array([[cos(angle), -sin(angle)], - [sin(angle), cos(angle)]]) + midpoint = midpoint or [0.0, 0.0] + mat = array([[cos(angle), -sin(angle)], [sin(angle), cos(angle)]]) midpoint = array(midpoint) vec = midpoint - dot(midpoint, mat) trans = translation(vec) def func(xx): - return(trans(dot(xx, mat))) - return(func) + return trans(dot(xx, mat)) + + return func def rotation3D(angle): mat = array( - [ - [cos(angle), -sin(angle), 0.], - [sin(angle), cos(angle), 0.], - [0., 0., 1.]]) + [[cos(angle), -sin(angle), 0.0], [sin(angle), cos(angle), 0.0], [0.0, 0.0, 1.0]] + ) def func(xx): - return(dot(xx, mat)) - return(func) + return dot(xx, mat) + + return func def translation(vec): def trans(x): - return([x[0] + vec[0], x[1] + vec[1]]) + return [x[0] + vec[0], x[1] + vec[1]] def func(x): - return(array(list(map(trans, x)))) - return(func) + return array(list(map(trans, x))) + + return func def trim(p1, p2, p3, p4): @@ -80,31 +86,31 @@ def trim(p1, p2, p3, p4): a4 = array(p4) if all(a1 == a2) or all(a3 == a4): if all(a1 == a3): - return(a1) + return a1 else: - return(False) + return False elif all(a1 == a3): if all(a2 == a4): - return((a1 + a2) / 2) + return (a1 + a2) / 2 else: - return(a1) + return a1 elif all(a1 == a4): if all(a2 == a3): - return((a1 + a2) / 2) + return (a1 + a2) / 2 else: - return(a1) + return a1 elif all(a2 == a3) or all(a2 == a4): - return(p2) + return p2 try: g, h = solve(transpose([-a2 + a1, a4 - a3]), a1 - a3) except Exception as e: print(e) - return(False) + return False else: - if 0. < g < 1. and 0. < h < 1.: - return(a1 + g * (a2 - a1)) + if 0.0 < g < 1.0 and 0.0 < h < 1.0: + return a1 + g * (a2 - a1) else: - return(False) + return False def trimfunc(l1, l2): @@ -124,12 +130,12 @@ def trimfunc(l1, l2): l2 == [l2[0]] else: l2 = l2[jk::-1] - return([vstack([l1, [s]]), vstack([[s], l2])]) + return [vstack([l1, [s]]), vstack([[s], l2])] j0 = j jk += 1 i0 = i ik += 1 - return(False) + return False def diff_norm(vec1, vec2): @@ -141,7 +147,7 @@ def nearestpts(evolv, underc): ik = 0 iout = 0 jout = 0 - outmin = 1000. + outmin = 1000.0 for i in array(evolv[1:]): jk = 0 for j in array(underc[1:]): @@ -154,17 +160,17 @@ def nearestpts(evolv, underc): iout, jout = [ik, jk] jk += 1 ik += 1 - return([vstack([underc[:jout], evolv[iout]]), evolv[iout:]]) + return [vstack([underc[:jout], evolv[iout]]), evolv[iout:]] def intersection_line_circle(p1, p2, r): - """return the intersection point of a line from p1 to p2 and a sphere of radius 1 and + """return the intersection point of a line from p1 to p2 and a sphere of radius 1 and midpoint 0,0,0""" d = p2 - p1 d /= norm(d) p_half = d.dot(p1) - q = p1.dot(p1) - r ** 2 - t = -p_half + sqrt(p_half ** 2 - q) + q = p1.dot(p1) - r**2 + t = -p_half + sqrt(p_half**2 - q) return p1 + d * t @@ -176,5 +182,3 @@ def arc_from_points_and_center(p_1, p_2, m): v /= norm(v) p_12 = m + v * r return (p_1, p_12, p_2) - - \ No newline at end of file diff --git a/pygears/bevel_tooth.py b/pygears/bevel_tooth.py index 1d4246e..ea1153a 100644 --- a/pygears/bevel_tooth.py +++ b/pygears/bevel_tooth.py @@ -18,13 +18,32 @@ from __future__ import division from __future__ import division -from numpy import cos, sin, tan, arccos, arctan, pi, array, linspace, transpose, vstack, sqrt +from numpy import ( + cos, + sin, + tan, + arccos, + arctan, + pi, + array, + linspace, + transpose, + vstack, + sqrt, +) from ._functions import rotation3D, reflection3D, intersection_line_circle class BevelTooth(object): - def __init__(self, pressure_angle=70 * pi / 180, pitch_angle=pi / 4, clearance=0.1, - z=21, backlash=0.00, module=0.25): + def __init__( + self, + pressure_angle=70 * pi / 180, + pitch_angle=pi / 4, + clearance=0.1, + z=21, + backlash=0.00, + module=0.25, + ): self.pressure_angle = pressure_angle self.pitch_angle = pitch_angle self.z = z @@ -34,58 +53,146 @@ class BevelTooth(object): self.module = module self.involute_end = arccos( - 1 / sqrt(2) * sqrt((42. + 16.*cos(2.*self.pressure_angle) + - 6.*cos(4.*self.pressure_angle) + cos(4.*self.pressure_angle - 4.*self.pitch_angle) - 8.*cos(2.*self.pressure_angle - 2.*self.pitch_angle) - - 4.*cos(4.*self.pressure_angle - 2.*self.pitch_angle) + 24.*cos(2.*self.pitch_angle) - 2.*cos(4.*self.pitch_angle) - - 8.*cos(2.*(self.pressure_angle + self.pitch_angle)) + cos(4.*(self.pressure_angle + self.pitch_angle)) - - 4.*cos(4.*self.pressure_angle + 2.*self.pitch_angle) + 24.*cos((4.*sin(self.pitch_angle))/self.z) + - 4.*cos(2.*self.pressure_angle - (4.*sin(self.pitch_angle))/self.z) + 4.*cos(2.*self.pressure_angle - - 4.*self.pitch_angle - (4.*sin(self.pitch_angle))/self.z) - 8.*cos(2.*self.pressure_angle - 2.*self.pitch_angle - - (4.*sin(self.pitch_angle))/self.z) + 24.*cos(4.*(self.pitch_angle + sin(self.pitch_angle)/self.z)) - - 8.*cos(2.*(self.pressure_angle + self.pitch_angle + (2.*sin(self.pitch_angle))/self.z)) + 4.*cos(2.*self.pressure_angle + - (4.*sin(self.pitch_angle))/self.z) + 16.*cos(2.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z) + - 4.*cos(2.*self.pressure_angle + 4.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z) + 32.*abs(cos(self.pitch_angle + - (2.*sin(self.pitch_angle))/self.z))*cos(self.pressure_angle)*sqrt(4.*cos(2.*self.pressure_angle) - - 2.*(-2. + cos(2.*self.pressure_angle - 2.*self.pitch_angle) - 2.*cos(2.*self.pitch_angle) + cos(2.*(self.pressure_angle + self.pitch_angle)) + - 4.*cos(2.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z)))*sin(2.*self.pitch_angle))/(-6. - 2.*cos(2.*self.pressure_angle) + - cos(2.*self.pressure_angle - 2.*self.pitch_angle) - 2.*cos(2.*self.pitch_angle) + cos(2.*(self.pressure_angle + self.pitch_angle)))**2)) + 1 + / sqrt(2) + * sqrt( + ( + 42.0 + + 16.0 * cos(2.0 * self.pressure_angle) + + 6.0 * cos(4.0 * self.pressure_angle) + + cos(4.0 * self.pressure_angle - 4.0 * self.pitch_angle) + - 8.0 * cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle) + - 4.0 * cos(4.0 * self.pressure_angle - 2.0 * self.pitch_angle) + + 24.0 * cos(2.0 * self.pitch_angle) + - 2.0 * cos(4.0 * self.pitch_angle) + - 8.0 * cos(2.0 * (self.pressure_angle + self.pitch_angle)) + + cos(4.0 * (self.pressure_angle + self.pitch_angle)) + - 4.0 * cos(4.0 * self.pressure_angle + 2.0 * self.pitch_angle) + + 24.0 * cos((4.0 * sin(self.pitch_angle)) / self.z) + + 4.0 + * cos( + 2.0 * self.pressure_angle + - (4.0 * sin(self.pitch_angle)) / self.z + ) + + 4.0 + * cos( + 2.0 * self.pressure_angle + - 4.0 * self.pitch_angle + - (4.0 * sin(self.pitch_angle)) / self.z + ) + - 8.0 + * cos( + 2.0 * self.pressure_angle + - 2.0 * self.pitch_angle + - (4.0 * sin(self.pitch_angle)) / self.z + ) + + 24.0 + * cos(4.0 * (self.pitch_angle + sin(self.pitch_angle) / self.z)) + - 8.0 + * cos( + 2.0 + * ( + self.pressure_angle + + self.pitch_angle + + (2.0 * sin(self.pitch_angle)) / self.z + ) + ) + + 4.0 + * cos( + 2.0 * self.pressure_angle + + (4.0 * sin(self.pitch_angle)) / self.z + ) + + 16.0 + * cos( + 2.0 * self.pitch_angle + (4.0 * sin(self.pitch_angle)) / self.z + ) + + 4.0 + * cos( + 2.0 * self.pressure_angle + + 4.0 * self.pitch_angle + + (4.0 * sin(self.pitch_angle)) / self.z + ) + + 32.0 + * abs( + cos(self.pitch_angle + (2.0 * sin(self.pitch_angle)) / self.z) + ) + * cos(self.pressure_angle) + * sqrt( + 4.0 * cos(2.0 * self.pressure_angle) + - 2.0 + * ( + -2.0 + + cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle) + - 2.0 * cos(2.0 * self.pitch_angle) + + cos(2.0 * (self.pressure_angle + self.pitch_angle)) + + 4.0 + * cos( + 2.0 * self.pitch_angle + + (4.0 * sin(self.pitch_angle)) / self.z + ) + ) + ) + * sin(2.0 * self.pitch_angle) + ) + / ( + -6.0 + - 2.0 * cos(2.0 * self.pressure_angle) + + cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle) + - 2.0 * cos(2.0 * self.pitch_angle) + + cos(2.0 * (self.pressure_angle + self.pitch_angle)) + ) + ** 2 + ) + ) - self.involute_start = -pi/2. + \ - arctan(1/tan(self.pitch_angle)*1/cos(self.pressure_angle)) + self.involute_start = -pi / 2.0 + arctan( + 1 / tan(self.pitch_angle) * 1 / cos(self.pressure_angle) + ) self.involute_start_radius = self.get_radius(self.involute_start) - self.r_f = sin(self.pitch_angle - sin(pitch_angle) * 2 / - self.z) - self.clearance * sin(self.pitch_angle) + self.r_f = sin( + self.pitch_angle - sin(pitch_angle) * 2 / self.z + ) - self.clearance * sin(self.pitch_angle) self.z_f = cos(self.pitch_angle - sin(pitch_angle) * 2 / self.z) self.add_foot = True def involute_function_x(self): def func(s): - return(( - -(cos(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))*sin(self.pressure_angle)*sin(s)) + - (cos(s)*sin(self.pitch_angle) + cos(self.pressure_angle)*cos(self.pitch_angle)*sin(s)) * - sin(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle)))) - return(func) + return -( + cos(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle)) + * sin(self.pressure_angle) + * sin(s) + ) + ( + cos(s) * sin(self.pitch_angle) + + cos(self.pressure_angle) * cos(self.pitch_angle) * sin(s) + ) * sin(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle)) + + return func def involute_function_y(self): def func(s): - return(( - cos(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))*(cos(s)*sin(self.pitch_angle) + - cos(self.pressure_angle)*cos(self.pitch_angle)*sin(s)) + sin(self.pressure_angle)*sin(s) * - sin(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle)))) - return(func) + return cos(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle)) * ( + cos(s) * sin(self.pitch_angle) + + cos(self.pressure_angle) * cos(self.pitch_angle) * sin(s) + ) + sin(self.pressure_angle) * sin(s) * sin( + s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle) + ) + + return func def involute_function_z(self): def func(s): - return(( - cos(self.pitch_angle)*cos(s) - cos(self.pressure_angle)*sin(self.pitch_angle)*sin(s))) - return(func) + return cos(self.pitch_angle) * cos(s) - cos(self.pressure_angle) * sin( + self.pitch_angle + ) * sin(s) + + return func def get_radius(self, s): x = self.involute_function_x() y = self.involute_function_y() rx = x(s) ry = y(s) - return(sqrt(rx**2 + ry**2)) + return sqrt(rx**2 + ry**2) def involute_points(self, num=10): pts = linspace(self.involute_start, self.involute_end, num=num) @@ -102,36 +209,40 @@ class BevelTooth(object): r_cut = self.r_f / self.z_f for i, point in enumerate(xy[1:]): - if point.dot(point) >= r_cut ** 2: + if point.dot(point) >= r_cut**2: break if i > 0: self.add_foot = False intersection_point = intersection_line_circle(xy[i], point, r_cut) - xy = array([intersection_point] + list(xy[i+1:])) + xy = array([intersection_point] + list(xy[i + 1 :])) xyz = [[p[0], p[1], 1] for p in xy] backlash_rot = rotation3D(self.angular_backlash / 2) xyz = backlash_rot(xyz) - return(xyz) + return xyz def points(self, num=10): pts = self.involute_points(num=num) - rot = rotation3D(-pi/self.z/2) + rot = rotation3D(-pi / self.z / 2) pts = rot(pts) - ref = reflection3D(pi/2) + ref = reflection3D(pi / 2) pts1 = ref(pts)[::-1] if self.add_foot: - return([ + return [ array([pts[0], pts[1]]), array(pts[1:]), array([pts[-1], pts1[0]]), array(pts1[:-1]), - array([pts1[-2], pts1[-1]]) - ]) + array([pts1[-2], pts1[-1]]), + ] else: - return([pts, array([pts[-1], pts1[0]]), pts1]) + return [pts, array([pts[-1], pts1[0]]), pts1] def _update(self): - self.__init__(z=self.z, clearance=self.clearance, - pressure_angle=self.pressure_angle, - pitch_angle=self.pitch_angle, - backlash=self.backlash, module=self.module) + self.__init__( + z=self.z, + clearance=self.clearance, + pressure_angle=self.pressure_angle, + pitch_angle=self.pitch_angle, + backlash=self.backlash, + module=self.module, + ) diff --git a/pygears/computation.py b/pygears/computation.py index 084154d..bb0e1a8 100644 --- a/pygears/computation.py +++ b/pygears/computation.py @@ -33,7 +33,8 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2): Returns: (float, float): distance between gears [length], pressure angle of the assembly [rad] """ - def inv(x): + + def inv(x): return np.tan(x) - x inv_alpha_w = inv(alpha) + 2 * np.tan(alpha) * (x1 + x2) / (t1 + t2) @@ -42,7 +43,7 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2): return inv(x) - inv_alpha_w def d_root_inv(x): - return 1. / np.cos(x) - 1 + return 1.0 / np.cos(x) - 1 alpha_w = find_root(alpha, root_inv, d_root_inv) dist = m * (t1 + t2) / 2 * np.cos(alpha) / np.cos(alpha_w) @@ -61,4 +62,4 @@ def find_root(x0, f, df, epsilon=2e-10, max_iter=100): return None else: x_n = x_n - f_xn / df_xn / 2 # adding (/ 2) to avoid oscillation - return None \ No newline at end of file + return None diff --git a/pygears/cycloid_tooth.py b/pygears/cycloid_tooth.py index 342a30d..8907ff4 100644 --- a/pygears/cycloid_tooth.py +++ b/pygears/cycloid_tooth.py @@ -21,7 +21,7 @@ from numpy import cos, sin, arccos, pi, array, linspace, transpose, vstack from ._functions import rotation, reflection -class CycloidTooth(): +class CycloidTooth: def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.25, backlash=0.00, head=0.0): self.m = m self.z = z @@ -44,40 +44,58 @@ class CycloidTooth(): def epicycloid_x(self): def func(t): - return(((self.d2 + self.d) * cos(t))/2. - (self.d2 * cos((1 + self.d / self.d2) * t))/2.) - return(func) + return ((self.d2 + self.d) * cos(t)) / 2.0 - ( + self.d2 * cos((1 + self.d / self.d2) * t) + ) / 2.0 + + return func def epicycloid_y(self): def func(t): - return(((self.d2 + self.d) * sin(t))/2. - (self.d2 * sin((1 + self.d / self.d2) * t))/2.) - return(func) + return ((self.d2 + self.d) * sin(t)) / 2.0 - ( + self.d2 * sin((1 + self.d / self.d2) * t) + ) / 2.0 + + return func def hypocycloid_x(self): def func(t): - return((self.d - self.d1)*cos(t)/2 + self.d1/2 * cos((self.d / self.d1 - 1) * t)) - return(func) + return (self.d - self.d1) * cos(t) / 2 + self.d1 / 2 * cos( + (self.d / self.d1 - 1) * t + ) + + return func def hypocycloid_y(self): def func(t): - return((self.d - self.d1)*sin(t)/2 - self.d1/2 * sin((self.d/self.d1 - 1)*t)) - return(func) + return (self.d - self.d1) * sin(t) / 2 - self.d1 / 2 * sin( + (self.d / self.d1 - 1) * t + ) + + return func def inner_end(self): - return( - -((self.d1*arccos((2*self.d1**2 - self.di**2 - - 2*self.d1*self.d + self.d**2)/(2.*self.d1 * - (self.d1 - self.d))))/self.d) + return -( + ( + self.d1 + * arccos( + (2 * self.d1**2 - self.di**2 - 2 * self.d1 * self.d + self.d**2) + / (2.0 * self.d1 * (self.d1 - self.d)) + ) + ) + / self.d ) def outer_end(self): - return( - (self.d2*arccos((2*self.d2**2 - self.da**2 + - 2*self.d2*self.d + self.d**2) / - (2.*self.d2*(self.d2 + self.d))))/self.d - ) + return ( + self.d2 + * arccos( + (2 * self.d2**2 - self.da**2 + 2 * self.d2 * self.d + self.d**2) + / (2.0 * self.d2 * (self.d2 + self.d)) + ) + ) / self.d def points(self, num=10): - inner_x = self.hypocycloid_x() inner_y = self.hypocycloid_y() outer_x = self.epicycloid_x() @@ -95,12 +113,18 @@ class CycloidTooth(): pts1 = vstack([pts_inner[:-2], pts_outer]) rot = rotation(self.phipart / 4 - self.angular_backlash / 2) pts1 = rot(pts1) - ref = reflection(0.) + ref = reflection(0.0) pts2 = ref(pts1)[::-1] one_tooth = [pts1, array([pts1[-1], pts2[0]]), pts2] - return(one_tooth) + return one_tooth def _update(self): - self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2, - clearance=self.clearance, backlash=self.backlash, head=self.head) - + self.__init__( + m=self.m, + z=self.z, + z1=self.z1, + z2=self.z2, + clearance=self.clearance, + backlash=self.backlash, + head=self.head, + ) diff --git a/pygears/involute_tooth.py b/pygears/involute_tooth.py index c171412..6733406 100644 --- a/pygears/involute_tooth.py +++ b/pygears/involute_tooth.py @@ -17,13 +17,43 @@ # *************************************************************************** from __future__ import division -from numpy import tan, cos, sin, sqrt, arctan, pi, array, linspace, transpose, vstack, ndarray -from ._functions import nearestpts, rotation, reflection, trimfunc, diff_norm, translation +from numpy import ( + tan, + cos, + sin, + sqrt, + arctan, + pi, + array, + linspace, + transpose, + vstack, + ndarray, +) +from ._functions import ( + nearestpts, + rotation, + reflection, + trimfunc, + diff_norm, + translation, +) -class InvoluteTooth(): - def __init__(self, m=5, z=15, pressure_angle=20 * pi / 180., clearance=0.12, shift=0.5, beta=0., - undercut=False, backlash=0.00, head=0.00, properties_from_tool=False): +class InvoluteTooth: + def __init__( + self, + m=5, + z=15, + pressure_angle=20 * pi / 180.0, + clearance=0.12, + shift=0.5, + beta=0.0, + undercut=False, + backlash=0.00, + head=0.00, + properties_from_tool=False, + ): self.pressure_angle = pressure_angle self.beta = beta self.m_n = m @@ -32,14 +62,13 @@ class InvoluteTooth(): self.shift = shift self.clearance = clearance self.backlash = backlash - self.head = head # factor, rename!!! + self.head = head # factor, rename!!! self.properties_from_tool = properties_from_tool self._calc_gear_factors() def _calc_gear_factors(self): if self.properties_from_tool: - self.pressure_angle_t = arctan( - tan(self.pressure_angle) / cos(self.beta)) + self.pressure_angle_t = arctan(tan(self.pressure_angle) / cos(self.beta)) self.m = self.m_n / cos(self.beta) else: self.pressure_angle_t = self.pressure_angle @@ -47,32 +76,47 @@ class InvoluteTooth(): self.pitch = self.m * pi self.c = self.clearance * self.m_n - self.midpoint = [0., 0.] + self.midpoint = [0.0, 0.0] self.d = self.z * self.m self.dw = self.m * self.z - self.da = self.dw + 2. * self.m_n + 2. * \ - (self.shift + self.head) * self.m_n - self.df = self.dw - 2. * self.m_n - \ - 2 * self.c + 2. * self.shift * self.m_n + self.da = self.dw + 2.0 * self.m_n + 2.0 * (self.shift + self.head) * self.m_n + self.df = self.dw - 2.0 * self.m_n - 2 * self.c + 2.0 * self.shift * self.m_n self.dg = self.d * cos(self.pressure_angle_t) self.phipart = 2 * pi / self.z - self.undercut_end = sqrt(-self.df ** 2 + self.da ** 2) / self.da - self.undercut_rot = (-self.df / self.dw * tan(arctan((2 * ((self.m * pi) / 4. - - (self.c + self.m_n) * tan(self.pressure_angle_t))) / self.df))) + self.undercut_end = sqrt(-(self.df**2) + self.da**2) / self.da + self.undercut_rot = ( + -self.df + / self.dw + * tan( + arctan( + ( + 2 + * ( + (self.m * pi) / 4.0 + - (self.c + self.m_n) * tan(self.pressure_angle_t) + ) + ) + / self.df + ) + ) + ) - self.involute_end = sqrt(self.da ** 2 - self.dg ** 2) / self.dg - self.involute_rot1 = sqrt(-self.dg ** 2 + (self.dw) ** 2) / self.dg - arctan( - sqrt(-self.dg ** 2 + (self.dw) ** 2) / self.dg) - self.involute_rot2 = self.m / \ - (self.d) * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) - self.involute_rot2 = 1 / self.z * \ - (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) + self.involute_end = sqrt(self.da**2 - self.dg**2) / self.dg + self.involute_rot1 = sqrt(-(self.dg**2) + (self.dw) ** 2) / self.dg - arctan( + sqrt(-(self.dg**2) + (self.dw) ** 2) / self.dg + ) + self.involute_rot2 = ( + self.m / (self.d) * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) + ) + self.involute_rot2 = ( + 1 / self.z * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) + ) self.involute_rot = self.involute_rot1 + self.involute_rot2 self.angular_backlash = self.backlash / (self.d / 2) - self.involute_start = 0. + self.involute_start = 0.0 if self.dg <= self.df: - self.involute_start = sqrt(self.df ** 2 - self.dg ** 2) / self.dg + self.involute_start = sqrt(self.df**2 - self.dg**2) / self.dg def undercut_points(self, num=10): pts = linspace(0, self.undercut_end, num=num) @@ -82,9 +126,10 @@ class InvoluteTooth(): y = array(list(map(fy, pts))) xy = transpose([x, y]) rotate = rotation( - self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2) + self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2 + ) xy = rotate(xy) - return(array(xy)) + return array(xy) def involute_points(self, num=10): pts = linspace(self.involute_start, self.involute_end, num=num) @@ -94,7 +139,7 @@ class InvoluteTooth(): y = array(list(map(fy, pts))) rot = rotation(self.involute_rot - self.angular_backlash / 2) xy = rot(transpose(array([x, y]))) - return(xy) + return xy def points(self, num=10): l1 = self.undercut_points(num=num) @@ -109,7 +154,8 @@ class InvoluteTooth(): u1 = False if self.dg > self.df: u1 = vstack( - [[l2[0] * self.df / (diff_norm(l2[0], [0, 0]) * 2)], [l2[0]]]) + [[l2[0] * self.df / (diff_norm(l2[0], [0, 0]) * 2)], [l2[0]]] + ) e1 = l2 else: e1 = l2 @@ -121,35 +167,39 @@ class InvoluteTooth(): else: u2 = reflect(u1)[::-1] one_tooth = [u1, e1, [e1[-1], e2[0]], e2, u2] - return(one_tooth) + return one_tooth def gearfunc(self, x): rot = rotation(2 * x / self.dw, self.midpoint) - return(rot) + return rot def undercut_function_x(self): def func(psi): - return( - cos(psi - (self.df * tan(psi)) / self.dw) * sqrt(self.df ** 2 / 4 + - (self.df ** 2 * tan(psi) ** 2) / 4.)) - return(func) + return cos(psi - (self.df * tan(psi)) / self.dw) * sqrt( + self.df**2 / 4 + (self.df**2 * tan(psi) ** 2) / 4.0 + ) + + return func def undercut_function_y(self): def func(psi): - return( - sin(psi - (self.df * tan(psi)) / self.dw) * sqrt(self.df ** 2 / 4 + - (self.df ** 2 * tan(psi) ** 2) / 4.)) - return(func) + return sin(psi - (self.df * tan(psi)) / self.dw) * sqrt( + self.df**2 / 4 + (self.df**2 * tan(psi) ** 2) / 4.0 + ) + + return func def involute_function_x(self): def func(phi): - return(self.dg / 2 * cos(phi) + phi * self.dg / 2 * sin(phi)) - return(func) + return self.dg / 2 * cos(phi) + phi * self.dg / 2 * sin(phi) + + return func def involute_function_y(self): def func(phi): - return(self.dg / 2 * sin(phi) - phi * self.dg / 2 * cos(phi)) - return(func) + return self.dg / 2 * sin(phi) - phi * self.dg / 2 * cos(phi) + + return func def _update(self): if not hasattr(self, "properties_from_tool"): @@ -158,8 +208,19 @@ class InvoluteTooth(): class InvoluteRack(object): - def __init__(self, m=5, z=15, pressure_angle=20 * pi / 180., thickness=5, beta=0, head=0, clearance=0.25, - properties_from_tool=False, add_endings=False, simplified=False): + def __init__( + self, + m=5, + z=15, + pressure_angle=20 * pi / 180.0, + thickness=5, + beta=0, + head=0, + clearance=0.25, + properties_from_tool=False, + add_endings=False, + simplified=False, + ): self.pressure_angle = pressure_angle self.thickness = thickness self.m = m @@ -171,8 +232,7 @@ class InvoluteRack(object): self.add_endings = add_endings self.simplified = simplified - -# this is not good. Find better way to stay backward compatible -> versions + # this is not good. Find better way to stay backward compatible -> versions def _update(self): if not hasattr(self, "add_endings"): self.add_endings = True @@ -188,10 +248,10 @@ class InvoluteRack(object): [-m_n * (1 + self.clearance), -a - b], [m_n * (1 + self.head), -b], [m_n * (1 + self.head), b], - [-m_n * (1 + self.clearance), a + b] + [-m_n * (1 + self.clearance), a + b], ] teeth = [tooth] - trans = translation([0., pitch, 0.]) + trans = translation([0.0, pitch, 0.0]) for i in range(self.z - 1): if self.simplified and i > 3 and i < (self.z - 6): tooth = trans(tooth).tolist() @@ -202,7 +262,7 @@ class InvoluteRack(object): teeth[-1].pop() teeth[-1].pop() teeth[-1][-1][0] = 0 - teeth[-1][-1][1] -= a / 2 + teeth[-1][-1][1] -= a / 2 if self.simplified and (i == self.z - 6): teeth[-1].pop(0) teeth[-1].pop(0) @@ -211,14 +271,18 @@ class InvoluteRack(object): teeth = array([v for t in teeth for v in t]) # flattening if self.add_endings: - ext1 = teeth[0] + array([0., a + b - pitch / 2]) - ext2 = teeth[-1] - array([0., a + b - pitch / 2]) - teeth = [ext1.tolist(), ext1.tolist()] + teeth.tolist() + [ext2.tolist(), ext2.tolist()] + ext1 = teeth[0] + array([0.0, a + b - pitch / 2]) + ext2 = teeth[-1] - array([0.0, a + b - pitch / 2]) + teeth = ( + [ext1.tolist(), ext1.tolist()] + + teeth.tolist() + + [ext2.tolist(), ext2.tolist()] + ) else: teeth = [teeth[0].tolist()] + teeth.tolist() + [teeth[-1].tolist()] - #teeth.append(list(teeth[-1])) + # teeth.append(list(teeth[-1])) teeth[0][0] -= self.thickness - #teeth.append(list(teeth[0])) + # teeth.append(list(teeth[0])) teeth[-1][0] -= self.thickness teeth.append(teeth[0]) return array(teeth) @@ -231,7 +295,7 @@ class InvoluteRack(object): else: pressure_angle_t = self.pressure_angle m = self.m - m_n = self.m + m_n = self.m pitch = m * pi return m, m_n, pitch, pressure_angle_t diff --git a/pygears/profile.py b/pygears/profile.py index 2a5970a..4d8e597 100644 --- a/pygears/profile.py +++ b/pygears/profile.py @@ -7,13 +7,14 @@ from ._functions import rotation, rotation3D class _GearProfile(object): rot3D = False + def profile(self, num=10): tooth = self.points(num=num) tooth = [list(point) for wire in tooth for point in wire] if self.rot3D: - rot = rotation3D( np.pi * 2 / self.z) + rot = rotation3D(np.pi * 2 / self.z) else: - rot = rotation(- np.pi * 2 / self.z) + rot = rotation(-np.pi * 2 / self.z) profile = tooth for i in range(self.z - 1): tooth = rot(tooth).tolist() @@ -21,19 +22,19 @@ class _GearProfile(object): profile.append(profile[0]) return np.array(profile) + class InvoluteProfile(InvoluteTooth, _GearProfile): pass + class CycloidProfile(CycloidTooth, _GearProfile): pass + class BevelProfile(BevelTooth, _GearProfile): rot3D = True + class InvoluteRackProfile(InvoluteRack): def profile(self): return self.points() - - - -