Compare commits
3 Commits
d59117c101
...
903fbdba07
Author | SHA1 | Date | |
---|---|---|---|
903fbdba07 | |||
7d828f5fbf | |||
441d733935 |
|
@ -5,7 +5,7 @@ import operator
|
|||
|
||||
# scale in inkscape
|
||||
# 1 unit = 0.283 mm
|
||||
scale = 1000.0/282.222
|
||||
svg_scale = 1000.0/282.222
|
||||
|
||||
def svg_circle(id, name, c, r):
|
||||
# create circle object in svg notation
|
||||
|
@ -48,12 +48,12 @@ def svg_puzzle(p, size, angle):
|
|||
p4 = p - size * v1
|
||||
|
||||
# convert to svg units
|
||||
p1 *= scale
|
||||
p2 *= scale
|
||||
p3 *= scale
|
||||
p4 *= scale
|
||||
p1 *= svg_scale
|
||||
p2 *= svg_scale
|
||||
p3 *= svg_scale
|
||||
p4 *= svg_scale
|
||||
|
||||
radius_scaled = 1.25 * size * scale
|
||||
radius_scaled = 1.25 * size * svg_scale
|
||||
|
||||
text = [' <path \n '
|
||||
' id="path666" \n '
|
||||
|
@ -63,6 +63,60 @@ def svg_puzzle(p, size, angle):
|
|||
|
||||
return text
|
||||
|
||||
def svg_line_puzzle(start, end, puzzle_scale=1.0, linewidth=0.50):
|
||||
# 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
|
||||
"""
|
||||
v1 and v2 are orthogonal vectors
|
||||
|
||||
construction of points (starting at p (middle between start and end)):
|
||||
|
||||
p2 ------- 2 v1 -----> p3
|
||||
^
|
||||
|
|
||||
v2
|
||||
|
|
||||
|
|
||||
start --- p1 <-- -v1 -- p -- v1 --> p4 --- end
|
||||
|
||||
then between points p2 and p3 with draw an arc
|
||||
"""
|
||||
v = end - start
|
||||
dist = np.linalg.norm(v)
|
||||
size = dist / 10.0 * puzzle_scale # size of the cutout
|
||||
v = v / dist
|
||||
angle = math.atan2(v[1], v[0]) # angle of v
|
||||
|
||||
# midpoint between start and end
|
||||
p = np.mean([start, end], axis=0)
|
||||
|
||||
v1 = np.array([np.cos(angle), np.sin(angle)])
|
||||
v2 = np.array([v1[1], -v1[0]])
|
||||
p1 = p - size * v1
|
||||
p2 = p1 + size * v2
|
||||
p3 = p2 + 2.0 * size * v1
|
||||
p4 = p + size * v1
|
||||
|
||||
# convert to svg units
|
||||
p1 *= svg_scale
|
||||
p2 *= svg_scale
|
||||
p3 *= svg_scale
|
||||
p4 *= svg_scale
|
||||
start *= svg_scale
|
||||
end *= svg_scale
|
||||
|
||||
radius_scaled = 1.25 * size * svg_scale
|
||||
|
||||
text = [' <path \n '
|
||||
' id="path666" \n '
|
||||
' style="fill:none;stroke:#000000;stroke-width:{}mm" \n'
|
||||
' d="M {} {} L {} {} L {} {} A {} {} 0 1 1 {} {} L {} {} L {} {}"'
|
||||
' />\n'.format(linewidth, start[0], start[1], p1[0], p1[1], p2[0], p2[1], radius_scaled, radius_scaled,
|
||||
p3[0], p3[1], p4[0], p4[1], end[0], end[1])]
|
||||
|
||||
return text
|
||||
|
||||
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
|
||||
|
@ -74,17 +128,17 @@ def svg_half_circle(id, name, c, r, angle, orientation_flag=1):
|
|||
# compute starting point
|
||||
v = np.array([np.cos(angle), np.sin(angle)])
|
||||
begin = c + r * v # in millimeters
|
||||
begin *= scale # in svg units
|
||||
begin *= svg_scale # in svg units
|
||||
|
||||
# compute end point
|
||||
end = c - r * v # in millimeters
|
||||
end *= scale # in svg units
|
||||
end *= svg_scale # in svg units
|
||||
|
||||
radius_scaled = r * scale # radius in svg units
|
||||
radius_scaled = r * svg_scale # radius in svg units
|
||||
|
||||
text = [' <path \n '
|
||||
' id="path666" \n '
|
||||
' style="fill:none;stroke:#ff0000;stroke-width:0.60000002" \n'
|
||||
' style="fill:none;stroke:#000000;stroke-width:0.60000002" \n'
|
||||
' d="M {} {} A {} {} 0 {} {} {} {}"'
|
||||
' />\n'.format(begin[0], begin[1], radius_scaled, radius_scaled, orientation_flag, orientation_flag,
|
||||
end[0], end[1])]
|
||||
|
@ -92,12 +146,12 @@ def svg_half_circle(id, name, c, r, angle, orientation_flag=1):
|
|||
return text
|
||||
|
||||
def svg_arc(p1, p2, r, large_arc, sweep):
|
||||
begin = p1 * scale
|
||||
end = p2 * scale
|
||||
radius_scaled = r * scale
|
||||
begin = p1 * svg_scale
|
||||
end = p2 * svg_scale
|
||||
radius_scaled = r * svg_scale
|
||||
text = [' <path \n '
|
||||
' id="path666" \n '
|
||||
' style="fill:none;stroke:#ff0000;stroke-width:0.60000002" \n'
|
||||
' style="fill:none;stroke:#000000;stroke-width:0.60000002" \n'
|
||||
' d="M {} {} A {} {} 0 {} {} {} {}"'
|
||||
' />\n'.format(begin[0], begin[1], radius_scaled, radius_scaled, large_arc, sweep,
|
||||
end[0], end[1])]
|
||||
|
@ -535,7 +589,7 @@ class PlateLayout:
|
|||
def output_segment(self, f_lines, k):
|
||||
|
||||
# k = which segment?
|
||||
k_next = (k + 1) % 5
|
||||
k_next = (k + 1) % self.N
|
||||
|
||||
# center hole
|
||||
a = self.tube_1_angles[k]
|
||||
|
@ -613,18 +667,18 @@ class PlateLayout:
|
|||
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)
|
||||
#text = svg_line(p1, p2, 0.1)
|
||||
text = svg_line_puzzle(p1, p2)
|
||||
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)
|
||||
text = svg_line_puzzle(p3, p4)
|
||||
#text = svg_line(p3, p4, 0.1)
|
||||
f_lines = f_lines + text
|
||||
|
||||
outer_point_1 = p4
|
||||
|
||||
# segment border (left)
|
||||
a = self.tube_1_angles[k_next]
|
||||
a = a / 360.0 * 2.0 * np.pi
|
||||
|
@ -632,17 +686,26 @@ class PlateLayout:
|
|||
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)
|
||||
#text = svg_line(p1, p2, 0.1)
|
||||
text = svg_line_puzzle(p1, p2)
|
||||
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)
|
||||
#text = svg_line(p3, p4, 0.1)
|
||||
text = svg_line_puzzle(p3, p4)
|
||||
f_lines = f_lines + text
|
||||
|
||||
outer_point_2 = p4
|
||||
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
|
||||
|
||||
# truncate gear path
|
||||
for j in range(len(f_lines)):
|
||||
|
@ -663,8 +726,25 @@ class PlateLayout:
|
|||
coordinates.append(c_running)
|
||||
pass
|
||||
|
||||
dist_1 = [np.linalg.norm(c - outer_point_1*scale) for c in coordinates]
|
||||
dist_2 = [np.linalg.norm(c - outer_point_2 * scale) for c in coordinates]
|
||||
dist_1 = [np.linalg.norm(c - outer_point_1 * svg_scale) for c in coordinates]
|
||||
dist_2 = [np.linalg.norm(c - outer_point_2 * svg_scale) for c in coordinates]
|
||||
|
||||
min_dist_index_1 = np.argmin(dist_1)
|
||||
min_dist_index_2 = np.argmin(dist_2)
|
||||
|
||||
if min_dist_index_2 > min_dist_index_1:
|
||||
coordinates = coordinates[min_dist_index_1:min_dist_index_2+1]
|
||||
else:
|
||||
coordinates = coordinates[min_dist_index_1:] + coordinates[0:min_dist_index_2]
|
||||
print("TODO: check this")
|
||||
|
||||
coordinates_data_raw_new = "".join(['{},{} '.format(c[0], c[1]) for c in coordinates])
|
||||
|
||||
gear_data_new = gear_data[0:index_start] + "M " + coordinates_data_raw_new + gear_data[index_end+1:]
|
||||
f_lines[j] = gear_data_new
|
||||
|
||||
|
||||
|
||||
|
||||
# find minimum distance and keep only points between the two distances
|
||||
# problem: does not consider manual rotation of the plate
|
||||
|
@ -674,11 +754,6 @@ class PlateLayout:
|
|||
pass
|
||||
#f_lines[k] = gear_data[0:index+1] + gear_data[-2:]
|
||||
|
||||
c = self.tube_1_coords[k]
|
||||
angle = self.tube_1_angles[k]
|
||||
text = svg_puzzle(c, 4, angle)
|
||||
f_lines = f_lines + text
|
||||
|
||||
return f_lines
|
||||
|
||||
def output_whole(self, f_lines):
|
||||
|
|
Loading…
Reference in New Issue
Block a user