diff --git a/gear_mesh_planning.py b/gear_mesh_planning.py index 287c95b..698838e 100644 --- a/gear_mesh_planning.py +++ b/gear_mesh_planning.py @@ -251,6 +251,8 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th x = (offset**2 - r2**2 + r1**2) / (2*offset) a1 = math.asin(chord/(2*r1)) a2 = math.asin(chord/(2*r2)) + if offset > x: + a2 = math.pi - a2 c1, c2 = red(40, 70), blue(40, 70) center_1, center_2 = (0, 0), (offset, 0) @@ -259,8 +261,7 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th tags.append(circle(center_2, r2, c2)) dim_tags += dimension((x, chord/2), (x, -chord/2), h=offset/2+5) tags += angular_dimension(center_1, a1, -a1, large_arc=False) - off = math.pi if x < offset else 0 - tags += angular_dimension(center_2, off + a2, -(off + a2), large_arc=False) + tags += angular_dimension(center_2, a2, -a2, large_arc=False) tags.append(Tag('path', fill='none', stroke_width=0.2, stroke=c1, d=f'M {x} {chord/2} L 0 0 L {x} {-chord/2}')) tags.append(Tag('path', fill='none', stroke_width=0.2, stroke=c2, d=f'M {x} {chord/2} L {offset} 0 L {x} {-chord/2}')) @@ -349,17 +350,6 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th plots.append(list(plot_angles(angles_1, c1, 'url(#hatch_1)', title='Mesh 1'))) plots.append(list(plot_angles(angles_2, c2, 'url(#hatch_2)', title='Mesh 2'))) - plots.append([ - *plot_angles(shift_angles(angles_1, a1), c1, 'url(#hatch_1)', title='First intersection'), - *plot_angles(shift_angles(angles_2, -a2 if counterrotation else a2), c2, 'url(#hatch_2)', axes=False), - ]) - - plots.append([ - *plot_angles(shift_angles(angles_1, -a1), c1, 'url(#hatch_1)', title='Second intersection'), - Tag('g', [*plot_angles(shift_angles(angles_2, a2 if counterrotation else -a2), c2, 'url(#hatch_2)', axes=False)], - style='mix-blend-mode:screen'), - ]) - def collide_schedules(sch_a, sch_b): boundaries = [] for a1, a2 in sch_a: @@ -407,13 +397,19 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th if rd == 2: yield prev, boundaries[0][0] - collided = list(collide_schedules(angles_1, angles_2)) + print(f'Shifting by {math.degrees(a1):.2f}° and {math.degrees(a2):.2f}°') + angles_1_intersection_1 = shift_angles(angles_1, -a1) + angles_1_intersection_2 = shift_angles(angles_1, a1) + angles_2_intersection_1 = shift_angles(angles_2, -a2) + angles_2_intersection_2 = shift_angles(angles_2, a2) + collided_1 = list(collide_schedules(angles_1_intersection_1, angles_2_intersection_1)) + collided_2 = list(collide_schedules(angles_1_intersection_2, angles_2_intersection_2)) best_solution = None def plot_centers(collided): nonlocal best_solution - widths = sorted(((end-start)%tau, start, end) for start, end in collided) + widths = sorted((((end-start)%tau, start, end) for start, end in collided), reverse=True) if collided: print('Best phases:') @@ -432,35 +428,26 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th print(' === One-sided schedule === ') plots.append([ - *plot_angles(collided, 'black', 'url(#hatch_b)', title='Valid shifts for first intersection'), - *plot_centers(collided) + *plot_angles(collided_1, 'black', 'url(#hatch_b)', title='Valid shifts for first intersection'), + *plot_centers(collided_1) ]) print() print(' === Two-sided schedule === ') - if counterrotation: - angle_delta = 2*a1 + 2*a2 - else: - angle_delta = 2*a1 - 2*a2 - intersected = list(intersect_schedules(collided, shift_angles(collided, angle_delta))) + intersected = list(intersect_schedules(collided_1, collided_2)) plots.append([ *plot_angles(intersected, 'black', 'url(#hatch_b)', title='Valid shifts for both intersections'), *plot_centers(intersected) ]) - pitch = 20 - for i, children in enumerate(plots): - tags.append(Tag('g', children, transform=f'translate(0 {(i + .2)*pitch})')) - - out_svg_2.write_text(str(Tag.setup_svg(tags + dim_tags, bounds=((0, 0), (100, (i+.8)*pitch)), margin=3))) - + tags2 = tags tags = [] tags.append(Tag('defs', defs)) dim_tags = [] for cx, cy, r, th, sched, stroke, fill in [ - ( 0, 0, r1, th1, shift_angles(angles_1, a1), c1, 'url(#hatch_1)'), - (offset, 0, r2, th2, shift_angles(angles_2, math.pi - a2 - best_solution), c2, 'url(#hatch_2)')]: + ( 0, 0, r1, th1, angles_1, c1, 'url(#hatch_1)'), + (offset, 0, r2, th2, shift_angles(angles_2, best_solution), c2, 'url(#hatch_2)')]: max_a = max((a2 - a1) % tau for a1, a2 in sched) max_w = math.tan(max_a) * (r-th/2) @@ -482,7 +469,25 @@ def cli(out_svg_1, out_svg_2, out_svg_3, radius, num_meshes, mesh_width, mesh_th group.append(Tag('animateTransform', attributeName='transform', attributeType='XML', type='rotate', _from=f'360 {cx} {cy}', to=f'0 {cx} {cy}', dur='10s', repeatCount='indefinite')) tags.append(Tag('g', group)) - print(math.degrees(best_solution)) + print(f'Phase of best solution: {math.degrees(best_solution):.2f}°') + + plots.append([ + *plot_angles(angles_1_intersection_1, c1, 'url(#hatch_1)', title='First intersection'), + *plot_angles(shift_angles(angles_2_intersection_1, best_solution), c2, 'url(#hatch_2)', axes=False), + ]) + + plots.append([ + *plot_angles(angles_1_intersection_2, c1, 'url(#hatch_1)', title='Second intersection'), + Tag('g', [*plot_angles(shift_angles(angles_2_intersection_2, best_solution), c2, 'url(#hatch_2)', axes=False)], + style='mix-blend-mode:screen'), + ]) + + pitch = 20 + for i, children in enumerate(plots): + tags2.append(Tag('g', children, transform=f'translate(0 {(i + .2)*pitch})')) + + out_svg_2.write_text(str(Tag.setup_svg(tags2 + dim_tags, bounds=((0, 0), (100, (i+.8)*pitch)), margin=3))) + out_svg_3.write_text(str(Tag.setup_svg(tags + dim_tags, bounds=( (min(-r1, -r2+offset), min(-r1, -r2)),