diff --git a/prototype/circles.py b/prototype/circles.py index 9ca6600..6652f77 100644 --- a/prototype/circles.py +++ b/prototype/circles.py @@ -19,7 +19,7 @@ def svg_circle(id, name, c, r): return text -def svg_half_circle(id, name, c, r, angle): +def svg_half_circle(id, name, c, r, angle, orientation_flag=1): # draws half a circle centered at c with radius r # angle specifies how the half circle should be rotated # for the default angle of zero, it draws the top half of the circle @@ -30,29 +30,35 @@ def svg_half_circle(id, name, c, r, angle): # compute starting point v = np.array([np.cos(angle), np.sin(angle)]) begin = c + r * v # in millimeters - begin *= scale # in pixel units + begin *= scale # in svg units # compute end point end = c - r * v # in millimeters - end *= scale # in pixel units + end *= scale # in svg units - radius_scaled = r * scale + radius_scaled = r * scale # radius in svg units - text = [' \n ' - ' \n' - ' \n' - ' \n'.format(begin[0], begin[1], radius_scaled, radius_scaled, 0, end[0], end[1])] + ' d="M {} {} A {} {} 0 {} {} {} {}"' + ' />\n'.format(begin[0], begin[1], radius_scaled, radius_scaled, orientation_flag, orientation_flag, + end[0], end[1])] return text +def svg_arc(p1, p2, r, large_arc, sweep): + begin = p1 * scale + end = p2 * scale + radius_scaled = r * scale + text = [' \n'.format(begin[0], begin[1], radius_scaled, radius_scaled, large_arc, sweep, + end[0], end[1])] + + return text def svg_rectangle(id, name, c, width, heigth, angle): x = np.sqrt(c[0]**2 + c[1]**2) - width/2 @@ -469,26 +475,144 @@ class PlateLayout: output_all = False if output_all: - N = len(self.tube_1_coords.items()) + f_lines = self.output_whole(f_lines) else: - N = 1 + f_lines = self.output_segment(f_lines, 2) + f_lines.append('\n') + + # write new svg image + fw = open('output.svg', 'w') + fw.writelines(f_lines) + fw.close() + + pass + + def output_segment(self, f_lines, k): + + # k = which segment? + k_next = (k + 1) % 5 + + # 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 + + 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 + + text = svg_arc(p1, p2, self.target_center_hole_radius, 0, 1) + f_lines = f_lines + text + + + # big circles arcs + c = self.tube_1_coords[k] + angle = self.tube_1_angles[k] + text = svg_half_circle(k, 'big circle', c, self.target_radius_1, angle) + f_lines = f_lines + text + + c = self.tube_1_coords[k_next] + angle = self.tube_1_angles[k_next] + text = svg_half_circle(k_next, 'big circle', c, self.target_radius_1, angle, orientation_flag=0) + f_lines = f_lines + text + + # small circle + c = self.tube_2_coords[k] + text = svg_circle(k, 'small circle', c, self.target_radius_2) + f_lines = f_lines + text + + # gear pos for big circle + c = self.tube_1_tangents[k_next] + circle_midpoint = self.tube_1_coords[k_next] + v = np.array(c[0]) - np.array(circle_midpoint) + v = v / np.linalg.norm(v) + + marking_length = 5.0 + + p1 = c[0] + p2 = c[0] + v * marking_length + + text = svg_line(p1, p2) + f_lines = f_lines + text + + # rectangle for big circles + c = self.tube_1_cuts[k_next] + text = svg_rectangle(k_next, 'cut', c['center'], c['length'], c['width'], c['angle_deg']) + f_lines = f_lines + text + + # gear pos for small circle + c = self.tube_2_tangents[k] + circle_midpoint = self.tube_2_coords[k] + v = np.array(c[0]) - np.array(circle_midpoint) + v = v/np.linalg.norm(v) + + marking_length = 5.0 + + p1 = c[0] + p2 = c[0] + v * marking_length + + text = svg_line(p1, p2) + f_lines = f_lines + text + + # rectangle for small circles + c = self.tube_2_cuts[k] + text = svg_rectangle(k, 'cut', c['center'], c['length'], c['width'], c['angle_deg']) + f_lines = f_lines + text + + # segment border (right) + a = self.tube_1_angles[k] + a = a / 360.0 * 2.0 * np.pi + r1 = np.linalg.norm(np.array(self.tube_1_coords[k])) - self.target_radius_1 + vunit = np.array([np.cos(a), np.sin(a)]) + p1 = vunit * self.target_center_hole_radius + p2 = vunit * r1 + text = svg_line(p1, p2, 0.1) + f_lines = f_lines + text + + r2 = np.linalg.norm(np.array(self.tube_1_coords[k])) + self.target_radius_1 + p3 = vunit * r2 + r3 = self.target_plate_radius - self.plate_module + p4 = vunit * r3 + text = svg_line(p3, p4, 0.1) + f_lines = f_lines + text + + # segment border (left) + a = self.tube_1_angles[k_next] + a = a / 360.0 * 2.0 * np.pi + r1 = np.linalg.norm(np.array(self.tube_1_coords[k_next])) - self.target_radius_1 + vunit = np.array([np.cos(a), np.sin(a)]) + p1 = vunit * self.target_center_hole_radius + p2 = vunit * r1 + text = svg_line(p1, p2, 0.1) + f_lines = f_lines + text + + r2 = np.linalg.norm(np.array(self.tube_1_coords[k_next])) + self.target_radius_1 + p3 = vunit * r2 + r3 = self.target_plate_radius - self.plate_module + p4 = vunit * r3 + text = svg_line(p3, p4, 0.1) + f_lines = f_lines + text + + return f_lines + + def output_whole(self, f_lines): # output big circles as svg - for k, c in self.tube_1_coords.items()[0:N]: - #text = svg_circle(k, 'big circle', c, self.target_radius_1) - angle = self.tube_1_angles[k] - text = svg_half_circle(k, 'big circle', c, self.target_radius_1, angle) + for k, c in self.tube_1_coords.items(): + text = svg_circle(k, 'big circle', c, self.target_radius_1) f_lines = f_lines + text pass # output small circles as svg - for k, c in self.tube_2_coords.items()[0:N]: + for k, c in self.tube_2_coords.items(): text = svg_circle(k, 'small circle', c, self.target_radius_2) f_lines = f_lines + text pass # gear markings for big cirlces and small circles - for k, c in self.tube_1_tangents.items()[0:N]: + for k, c in self.tube_1_tangents.items(): circle_midpoint = self.tube_1_coords[k] v = np.array(c[0]) - np.array(circle_midpoint) v = v/np.linalg.norm(v) @@ -500,9 +624,8 @@ class PlateLayout: text = svg_line(p1, p2) f_lines = f_lines + text - pass - for k, c in self.tube_2_tangents.items()[0:N]: + for k, c in self.tube_2_tangents.items(): circle_midpoint = self.tube_2_coords[k] v = np.array(c[0]) - np.array(circle_midpoint) v = v/np.linalg.norm(v) @@ -517,19 +640,19 @@ class PlateLayout: pass # output cuts for big circles - for k, c in self.tube_1_cuts.items()[0:N]: + for k, c in self.tube_1_cuts.items(): text = svg_rectangle(k, 'cut', c['center'], c['length'], c['width'], c['angle_deg']) f_lines = f_lines + text pass # output cuts for small circles - for k, c in self.tube_2_cuts.items()[0:N]: + for k, c in self.tube_2_cuts.items(): text = svg_rectangle(k, 'cut', c['center'], c['length'], c['width'], c['angle_deg']) f_lines = f_lines + text pass # lines for manufacturing out of multiple pieces - for k, a in self.tube_1_angles.items()[0:N]: + for k, a in self.tube_1_angles.items(): a = a/360.0 * 2.0 * np.pi r1 = np.linalg.norm(np.array(self.tube_1_coords[k])) - self.target_radius_1 vunit = np.array([np.cos(a), np.sin(a)]) @@ -547,11 +670,6 @@ class PlateLayout: pass - f_lines.append('\n') + return f_lines - # write new svg image - fw = open('output.svg', 'w') - fw.writelines(f_lines) - fw.close() - pass