gear mesh: fix angle math
This commit is contained in:
parent
f3b554dc14
commit
e238fb929c
1 changed files with 36 additions and 31 deletions
|
|
@ -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)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue