diff --git a/prototype/circles.py b/prototype/circles.py index d8d9e55..625a3ca 100644 --- a/prototype/circles.py +++ b/prototype/circles.py @@ -370,8 +370,8 @@ class PlateLayout: f_lines = f.readlines() f.close() - - circle_found = False + circle_def_start = None + circle_def_end = None for k in range(len(f_lines)): current_line = f_lines[k] @@ -388,12 +388,14 @@ class PlateLayout: f_lines[k] = gear_data[0:index+1] + gear_data[-2:] + # find begin and end of center circle definition if '' in current_line: + circle_def_end = k - if circle_found and 'r=' in current_line: - # adjust center hole radius - f_lines[k] = ' r="{}mm"\n'.format(self.target_center_hole_radius) + # remove center circle + del f_lines[circle_def_start:circle_def_end + 1] # delete last line with command f_lines.remove(f_lines[-1]) @@ -406,7 +408,7 @@ class PlateLayout: if output_all: f_lines = self.output_whole(f_lines) else: - f_lines = self.output_segment(f_lines, 2) + f_lines = self.output_segment(f_lines, 2, split_at_big_circles=False) f_lines.append('\n') @@ -418,67 +420,130 @@ class PlateLayout: pass - def output_segment(self, f_lines, k): + def output_segment(self, f_lines, k, split_at_big_circles=True): # k = which segment? k_next = (k + 1) % self.N + k_next_next = (k + 2) % self.N - # center hole - a = self.tube_1_angles[k] - a = a / 360.0 * 2.0 * np.pi - vunit = np.array([np.cos(a), np.sin(a)]) - p1 = vunit * self.target_center_hole_radius + if split_at_big_circles: - a2 = self.tube_1_angles[k_next] - a2 = a2 / 360.0 * 2.0 * np.pi - vunit2 = np.array([np.cos(a2), np.sin(a2)]) - p2 = vunit2 * self.target_center_hole_radius + # center hole + a = self.tube_1_angles[k] + a = a / 360.0 * 2.0 * np.pi + vunit = np.array([np.cos(a), np.sin(a)]) + p1 = vunit * self.target_center_hole_radius - f_lines += svg_arc(p1, p2, self.target_center_hole_radius, 0, 1) + a2 = self.tube_1_angles[k_next] + a2 = a2 / 360.0 * 2.0 * np.pi + vunit2 = np.array([np.cos(a2), np.sin(a2)]) + p2 = vunit2 * self.target_center_hole_radius - # big circles arcs - f_lines += svg_half_circle(k, 'big circle', self.tube_1_coords[k], self.target_radius_1, self.tube_1_angles[k]) - f_lines += svg_half_circle(k_next, 'big circle', self.tube_1_coords[k_next], self.target_radius_1, - self.tube_1_angles[k_next], orientation_flag=0) + f_lines += svg_arc(p1, p2, self.target_center_hole_radius, 0, 1) - # small circle - f_lines += svg_circle(k, 'small circle', self.tube_2_coords[k], self.target_radius_2) + # big circles arcs + f_lines += svg_half_circle(k, 'big circle', self.tube_1_coords[k], self.target_radius_1, self.tube_1_angles[k]) + f_lines += svg_half_circle(k_next, 'big circle', self.tube_1_coords[k_next], self.target_radius_1, + self.tube_1_angles[k_next], orientation_flag=0) - # gear pos for big circle - f_lines += svg_gear_marking(self.tube_1_tangents[k_next], self.tube_1_coords[k_next]) + # small circle + f_lines += svg_circle(k, 'small circle', self.tube_2_coords[k], self.target_radius_2) - # cutout rectangle for big circles - f_lines += svg_rectangle(k_next, 'cut', self.tube_1_cuts[k_next]) + # gear pos for big circle + f_lines += svg_gear_marking(self.tube_1_tangents[k_next], self.tube_1_coords[k_next]) - # gear pos for small circle - f_lines += svg_gear_marking(self.tube_2_tangents[k], self.tube_2_coords[k]) + # cutout rectangle for big circles + f_lines += svg_rectangle(k_next, 'cut', self.tube_1_cuts[k_next]) - # cutout rectangle for small circles - f_lines += svg_rectangle(k, 'cut', self.tube_2_cuts[k]) + # gear pos for small circle + f_lines += svg_gear_marking(self.tube_2_tangents[k], self.tube_2_coords[k]) - # first segment border - f_lines += svg_segment_border_inner(self.tube_1_angles[k], self.target_center_hole_radius, - self.tube_1_coords[k], self.target_radius_1) - f_lines += svg_segment_border_outer(self.tube_1_angles[k], self.target_plate_radius, self.plate_module, - self.tube_1_coords[k], self.target_radius_1) + # cutout rectangle for small circles + f_lines += svg_rectangle(k, 'cut', self.tube_2_cuts[k]) - # second segment border - f_lines += svg_segment_border_inner(self.tube_1_angles[k_next], self.target_center_hole_radius, - self.tube_1_coords[k_next], self.target_radius_1) - f_lines += svg_segment_border_outer(self.tube_1_angles[k_next], self.target_plate_radius, self.plate_module, - self.tube_1_coords[k_next], self.target_radius_1) + # first segment border + f_lines += svg_segment_border_inner(self.tube_1_angles[k], self.target_center_hole_radius, + self.tube_1_coords[k], self.target_radius_1) + f_lines += svg_segment_border_outer(self.tube_1_angles[k], self.target_plate_radius, self.plate_module, + self.tube_1_coords[k], self.target_radius_1) + + # second segment border + f_lines += svg_segment_border_inner(self.tube_1_angles[k_next], self.target_center_hole_radius, + self.tube_1_coords[k_next], self.target_radius_1) + f_lines += svg_segment_border_outer(self.tube_1_angles[k_next], self.target_plate_radius, self.plate_module, + self.tube_1_coords[k_next], self.target_radius_1) + + # find outmost points for segment cut lines + # in addition we rotate the points by 0.9 degrees because we also rotated the gear path + # by this amount above + r_pitch_minus_module = self.target_plate_radius - self.plate_module + a1 = (self.tube_1_angles[k] - 0.9) / 360.0 * 2.0 * np.pi + vunit1 = np.array([np.cos(a1), np.sin(a1)]) + outer_point_1 = vunit1 * r_pitch_minus_module + + a2 = (self.tube_1_angles[k_next] - 0.9) / 360.0 * 2.0 * np.pi + vunit2 = np.array([np.cos(a2), np.sin(a2)]) + outer_point_2 = vunit2 * r_pitch_minus_module + + else: + # center hole + a = self.tube_2_angles[k] + a = a / 360.0 * 2.0 * np.pi + vunit = np.array([np.cos(a), np.sin(a)]) + p1 = vunit * self.target_center_hole_radius + + a2 = self.tube_2_angles[k_next] + a2 = a2 / 360.0 * 2.0 * np.pi + vunit2 = np.array([np.cos(a2), np.sin(a2)]) + p2 = vunit2 * self.target_center_hole_radius + + f_lines += svg_arc(p1, p2, self.target_center_hole_radius, 0, 1) + + # small circles arcs + f_lines += svg_half_circle(k, 'small circle', self.tube_2_coords[k], self.target_radius_2, + self.tube_2_angles[k]) + f_lines += svg_half_circle(k_next, 'small circle', self.tube_2_coords[k_next], self.target_radius_2, + self.tube_2_angles[k_next], orientation_flag=0) + + # big circle + f_lines += svg_circle(k, 'big circle', self.tube_1_coords[k_next], self.target_radius_1) + + # gear pos for big circle + f_lines += svg_gear_marking(self.tube_1_tangents[k_next], self.tube_1_coords[k_next]) + + # cutout rectangle for big circles + f_lines += svg_rectangle(k, 'cut', self.tube_1_cuts[k_next]) + f_lines += svg_rectangle(k, 'cut', self.tube_1_cuts[k_next_next]) + + # gear pos for small circle + f_lines += svg_gear_marking(self.tube_2_tangents[k_next], self.tube_2_coords[k_next]) + + # cutout rectangle for small circles + f_lines += svg_rectangle(k_next, 'cut', self.tube_2_cuts[k_next]) + + # first segment border + f_lines += svg_segment_border_inner(self.tube_2_angles[k], self.target_center_hole_radius, + self.tube_2_coords[k], self.target_radius_2, puzzle_scale=0.5, placement=0.25) + f_lines += svg_segment_border_outer(self.tube_2_angles[k], self.target_plate_radius, self.plate_module, + self.tube_2_coords[k], self.target_radius_2) + + # second segment border + f_lines += svg_segment_border_inner(self.tube_2_angles[k_next], self.target_center_hole_radius, + self.tube_2_coords[k_next], self.target_radius_2, puzzle_scale=0.5, placement=0.25) + f_lines += svg_segment_border_outer(self.tube_2_angles[k_next], self.target_plate_radius, self.plate_module, + self.tube_2_coords[k_next], self.target_radius_2) - # find outmost points for segment cut lines - # in addition we rotate the points by 0.9 degrees because we also rotated the gear path - # by this amount above - r_pitch_minus_module = self.target_plate_radius - self.plate_module - a1 = (self.tube_1_angles[k] - 0.9) / 360.0 * 2.0 * np.pi - vunit1 = np.array([np.cos(a1), np.sin(a1)]) - outer_point_1 = vunit1 * r_pitch_minus_module + # find outmost points for segment cut lines + # in addition we rotate the points by 0.9 degrees because we also rotated the gear path + # by this amount above + r_pitch_minus_module = self.target_plate_radius - self.plate_module + a1 = (self.tube_2_angles[k] - 0.9) / 360.0 * 2.0 * np.pi + vunit1 = np.array([np.cos(a1), np.sin(a1)]) + outer_point_1 = vunit1 * r_pitch_minus_module - a2 = (self.tube_1_angles[k_next] - 0.9) / 360.0 * 2.0 * np.pi - vunit2 = np.array([np.cos(a2), np.sin(a2)]) - outer_point_2 = vunit2 * r_pitch_minus_module + a2 = (self.tube_2_angles[k_next] - 0.9) / 360.0 * 2.0 * np.pi + vunit2 = np.array([np.cos(a2), np.sin(a2)]) + outer_point_2 = vunit2 * r_pitch_minus_module # truncate gear path for j in range(len(f_lines)): diff --git a/prototype/svg_utils.py b/prototype/svg_utils.py index 0984c53..43bf64e 100644 --- a/prototype/svg_utils.py +++ b/prototype/svg_utils.py @@ -63,7 +63,7 @@ def svg_puzzle(p, size, angle): return text -def svg_line_puzzle(start, end, puzzle_scale=1.0, linewidth=0.50): +def svg_line_puzzle(start, end, puzzle_scale=1.0, linewidth=0.50, placement=0.5): # draws a line from start to end with a simple jigsaw puzzle style cutout in the middle # the size of the cutout can be controlled with the puzzle_scale parameter # compute points @@ -89,7 +89,8 @@ def svg_line_puzzle(start, end, puzzle_scale=1.0, linewidth=0.50): angle = math.atan2(v[1], v[0]) # angle of v # midpoint between start and end - p = np.mean([start, end], axis=0) + p = (1.0 - placement) * start + placement * end + #p = np.mean([start, end], axis=0) v1 = np.array([np.cos(angle), np.sin(angle)]) v2 = np.array([v1[1], -v1[0]]) @@ -198,18 +199,19 @@ def svg_gear_marking(tangent_coord, circle_midpoint, marking_length=5.0): return text -def svg_segment_border_inner(angle, center_hole_radius, circle_pos, circle_radius): +def svg_segment_border_inner(angle, center_hole_radius, circle_pos, circle_radius, puzzle_scale=1.0, placement=0.5): a = angle a = a / 360.0 * 2.0 * np.pi r1 = np.linalg.norm(np.array(circle_pos)) - circle_radius vunit = np.array([np.cos(a), np.sin(a)]) p1 = vunit * center_hole_radius p2 = vunit * r1 - text = svg_line_puzzle(p1, p2) + text = svg_line_puzzle(p1, p2, puzzle_scale=puzzle_scale, placement=placement) return text -def svg_segment_border_outer(angle, plate_pitch_radius, plate_gear_module, circle_pos, circle_radius): +def svg_segment_border_outer(angle, plate_pitch_radius, plate_gear_module, circle_pos, circle_radius, puzzle_scale=1.0, + placement=0.5): a = angle a = a / 360.0 * 2.0 * np.pi vunit = np.array([np.cos(a), np.sin(a)]) @@ -217,6 +219,6 @@ def svg_segment_border_outer(angle, plate_pitch_radius, plate_gear_module, circl p3 = vunit * r2 r3 = plate_pitch_radius - plate_gear_module p4 = vunit * r3 - text = svg_line_puzzle(p3, p4) + text = svg_line_puzzle(p3, p4, puzzle_scale=puzzle_scale, placement=placement) return text \ No newline at end of file