output cuts for dispenser gears, markings for the placement of the gears and cut lines for assembly from multiple parts
This commit is contained in:
parent
8940f5965f
commit
850fe69847
|
@ -9,13 +9,31 @@ def svg_circle(id, name, c, r):
|
|||
text = [' <circle\n',
|
||||
' id="circle{}"\n'.format(id),
|
||||
' inkscape:label="{}"\n'.format(name),
|
||||
' style="fill:none;stroke:#000000;stroke-width:1.0mm"\n',
|
||||
' style="fill:none;stroke:#000000;stroke-width:0.1mm"\n',
|
||||
' r="{}mm"\n'.format(r),
|
||||
' cy="{}mm"\n'.format(c[1]),
|
||||
' cx="{}mm" />\n'.format(c[0])]
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def svg_rectangle(id, name, c, width, heigth, angle):
|
||||
x = np.sqrt(c[0]**2 + c[1]**2) - width/2
|
||||
y = - heigth
|
||||
text = ['<g transform="rotate({})">\n '
|
||||
'<rect x="{}mm" y="{}mm" width="{}mm" height="{}mm" style="fill:none;stroke-width:0.1mm;stroke:rgb(0,0,0)" />\n '
|
||||
'</g>\n'
|
||||
.format(angle, x, y ,width, heigth)]
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def svg_line(p1, p2, width=1.0):
|
||||
text = ['<line x1="{}mm" y1="{}mm" x2="{}mm" y2="{}mm" style="stroke:rgb(0,0,0);stroke-width:{}mm" />'.format(p1[0], p1[1], p2[0], p2[1], width)]
|
||||
|
||||
return text
|
||||
|
||||
|
||||
# this function reads and processes data for optimal circle packaging obtained form packomania.com
|
||||
def read_circle_data(N):
|
||||
coords_raw = open('cci/cci{}.txt'.format(N))
|
||||
|
@ -37,6 +55,7 @@ def read_circle_data(N):
|
|||
|
||||
return radii[N], coords
|
||||
|
||||
|
||||
# this function sorts enclosed circle coordinates counter-clockwise w.r.t. the center point
|
||||
# TODO: there is a problem when circles are present that are not touching the boundary of the enclosing circle (e.g. N = 7)
|
||||
def sort_ccw(coords, center):
|
||||
|
@ -51,6 +70,7 @@ def sort_ccw(coords, center):
|
|||
|
||||
return coords_sort
|
||||
|
||||
|
||||
# compute the two tangential points at the circle with center c and radius r intersecting the point p
|
||||
def compute_tangent_points(p, c, r):
|
||||
b = sqrt((p[0] - c[0]) ** 2 + (p[1] - c[1]) ** 2)
|
||||
|
@ -172,13 +192,13 @@ class PlateLayout:
|
|||
print(" diameter = {:6.3} m = {:6.2f} mm".format(2*tube2_radius, 2*tube2_radius * 1000))
|
||||
|
||||
# compute coordinates and various measurements for fixed radii of plate and tubes
|
||||
self.target_plate_radius = 155.0
|
||||
self.target_plate_radius = 160.0
|
||||
self.target_radius_1 = 50.0
|
||||
self.target_radius_2 = 20.0
|
||||
teeth = 200
|
||||
|
||||
D = 2 * self.target_plate_radius
|
||||
m = D/teeth
|
||||
self.plate_module = D/teeth
|
||||
|
||||
print("plate radius = {:6.2f} mm".format(self.target_plate_radius))
|
||||
print("big circle radius = {:6.2f} mm".format(self.target_radius_1))
|
||||
|
@ -186,13 +206,13 @@ class PlateLayout:
|
|||
|
||||
print("number of teeth: N = {}".format(teeth))
|
||||
print("pitch diameter: D = {} mm".format(D))
|
||||
print("module: M = {} mm".format(m))
|
||||
print("module: M = {} mm".format(self.plate_module))
|
||||
|
||||
|
||||
# parameters for dispenser gears
|
||||
self.dispenser_module = 1.5
|
||||
dispenser_1_target_pitch_diameter_big = 80.0
|
||||
dispenser_1_target_pitch_diameter_small = 25.0
|
||||
self.dispenser_module = 1.0
|
||||
dispenser_1_target_pitch_diameter_big = 50.0
|
||||
dispenser_1_target_pitch_diameter_small = 15.0
|
||||
dispenser_1_teeth_big = int(dispenser_1_target_pitch_diameter_big/self.dispenser_module)
|
||||
dispenser_1_teeth_small = int(dispenser_1_target_pitch_diameter_small/ self.dispenser_module)
|
||||
|
||||
|
@ -201,8 +221,8 @@ class PlateLayout:
|
|||
dispenser_1_pitch_diameter_small = self.dispenser_module * dispenser_1_teeth_small
|
||||
dispenser_1_outer_diameter_small = dispenser_1_pitch_diameter_small + 2 * self.dispenser_module
|
||||
|
||||
dispenser_2_target_pitch_diameter_big = 40.0
|
||||
dispenser_2_target_pitch_diameter_small = 25.0
|
||||
dispenser_2_target_pitch_diameter_big = 20.0
|
||||
dispenser_2_target_pitch_diameter_small = 15.0
|
||||
dispenser_2_teeth_big = int(dispenser_2_target_pitch_diameter_big / self.dispenser_module)
|
||||
dispenser_2_teeth_small = int(dispenser_2_target_pitch_diameter_small / self.dispenser_module)
|
||||
|
||||
|
@ -210,6 +230,19 @@ class PlateLayout:
|
|||
dispenser_2_outer_diameter_big = dispenser_2_pitch_diameter_big + 2 * self.dispenser_module
|
||||
dispenser_2_pitch_diameter_small = self.dispenser_module * dispenser_2_teeth_small
|
||||
dispenser_2_outer_diameter_small = dispenser_2_pitch_diameter_small + 2 * self.dispenser_module
|
||||
print("parameters for dispenser gears:")
|
||||
print(" big container:")
|
||||
print(" module = {}".format(self.dispenser_module))
|
||||
print(" pitch diameter big gear = {}".format(dispenser_1_pitch_diameter_big))
|
||||
print(" number of teeth big gear = {}".format(dispenser_1_teeth_big))
|
||||
print(" pitch diameter small gear = {}".format(dispenser_1_pitch_diameter_small))
|
||||
print(" number of teeth small gear = {}".format(dispenser_1_teeth_small))
|
||||
print(" small container:")
|
||||
print(" module = {}".format(self.dispenser_module))
|
||||
print(" pitch diameter big gear = {}".format(dispenser_2_pitch_diameter_big))
|
||||
print(" number of teeth big gear = {}".format(dispenser_2_teeth_big))
|
||||
print(" pitch diameter small gear = {}".format(dispenser_2_pitch_diameter_small))
|
||||
print(" number of teeth small gear = {}".format(dispenser_2_teeth_small))
|
||||
|
||||
# plot plate
|
||||
plt.figure(2)
|
||||
|
@ -225,10 +258,14 @@ class PlateLayout:
|
|||
|
||||
self.tube_1_coords = {}
|
||||
self.tube_2_coords = {}
|
||||
self.tube_1_angles = {}
|
||||
self.tube_2_angles = {}
|
||||
self.tube_1_tangents = {}
|
||||
self.tube_1_tangent_angles = {}
|
||||
self.tube_1_cuts = {}
|
||||
self.tube_2_tangents = {}
|
||||
self.tube_2_tangent_angles = {}
|
||||
self.tube_2_cuts = {}
|
||||
|
||||
print(" big circle coordinates:")
|
||||
for k in range(0,self.N):
|
||||
|
@ -238,6 +275,7 @@ class PlateLayout:
|
|||
angle = arctan2(y, x) * 360.0 / (2.0 * math.pi)
|
||||
|
||||
self.tube_1_coords[k] = (x,y)
|
||||
self.tube_1_angles[k] = angle
|
||||
|
||||
print(" k = {}, (x,y) = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg".format(k, x, y, angle))
|
||||
|
||||
|
@ -258,19 +296,38 @@ class PlateLayout:
|
|||
|
||||
t1, t2 = compute_tangent_points((0, 0), (x, y), self.target_radius_1)
|
||||
|
||||
angle1 = arctan2(t1[1], t1[0]) * 360.0 / (2.0 * math.pi)
|
||||
angle2 = arctan2(t2[1], t2[0]) * 360.0 / (2.0 * math.pi)
|
||||
angle1_rad = arctan2(t1[1], t1[0])
|
||||
angle2_rad = arctan2(t2[1], t2[0])
|
||||
angle1_deg = angle1_rad * 360.0 / (2.0 * math.pi)
|
||||
angle2_deg = angle2_rad * 360.0 / (2.0 * math.pi)
|
||||
|
||||
self.tube_1_tangents[k] = (t1, t2)
|
||||
self.tube_1_tangent_angles[k] = (angle1, angle2)
|
||||
self.tube_1_tangent_angles[k] = (angle1_deg, angle2_deg)
|
||||
|
||||
print(
|
||||
" k = {}, t1 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg\n t2 = ({:8.3f}, {:8.3f}), angle "
|
||||
"= {:8.3f} deg".format(k, t1[0], t1[1], angle1, t2[0], t2[1], angle2))
|
||||
"= {:8.3f} deg".format(k, t1[0], t1[1], angle1_deg, t2[0], t2[1], angle2_deg))
|
||||
|
||||
plt.plot(t1[0], t1[1], 'o')
|
||||
plt.plot(t2[0], t2[1], 'o')
|
||||
|
||||
## compute position of cut for dispenser gear
|
||||
# vector pointing from center in direction of tangent point
|
||||
v = np.array([math.cos(angle1_rad), math.sin(angle1_rad)])
|
||||
|
||||
cut_center = np.array(t1) - v * (offset_1 + dispenser_1_outer_diameter_small/2.0)
|
||||
self.tube_1_cuts[k] = {}
|
||||
self.tube_1_cuts[k]['center'] = cut_center
|
||||
self.tube_1_cuts[k]['tangent_point'] = t1
|
||||
self.tube_1_cuts[k]['angle_deg'] = angle1_deg
|
||||
self.tube_1_cuts[k]['length'] = dispenser_1_outer_diameter_small
|
||||
self.tube_1_cuts[k]['width'] = 5.0
|
||||
|
||||
plt.plot(cut_center[0], cut_center[1], 'o')
|
||||
|
||||
|
||||
pass
|
||||
|
||||
|
||||
print(" small circle coordinates:")
|
||||
for k in range(0,self.N):
|
||||
|
@ -280,6 +337,7 @@ class PlateLayout:
|
|||
angle = arctan2(y, x) * 360.0 / (2.0 * math.pi)
|
||||
|
||||
self.tube_2_coords[k] = (x, y)
|
||||
self.tube_2_angles[k] = angle
|
||||
|
||||
print(" k = {}, (x,y) = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg".format(k, x, y, angle))
|
||||
|
||||
|
@ -299,17 +357,34 @@ class PlateLayout:
|
|||
y = coords_2[k][1] * outer_radius
|
||||
|
||||
t1, t2 = compute_tangent_points((0, 0), (x, y), self.target_radius_2)
|
||||
angle1 = arctan2(t1[1], t1[0]) * 360.0 / (2.0 * math.pi)
|
||||
angle2 = arctan2(t2[1], t2[0]) * 360.0 / (2.0 * math.pi)
|
||||
angle1_rad = arctan2(t1[1], t1[0])
|
||||
angle2_rad = arctan2(t2[1], t2[0])
|
||||
angle1_deg = angle1_rad * 360.0 / (2.0 * math.pi)
|
||||
angle2_deg = angle2_rad * 360.0 / (2.0 * math.pi)
|
||||
self.tube_2_tangents[k] = (t1, t2)
|
||||
self.tube_2_tangent_angles[k] = (angle1, angle2)
|
||||
self.tube_2_tangent_angles[k] = (angle1_deg, angle2_deg)
|
||||
|
||||
print(" k = {}, t1 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg\n t2 = ({:8.3f}, {:8.3f}), angle "
|
||||
"= {:8.3f} deg".format(k, t1[0], t1[1], angle1, t2[0], t2[1], angle2))
|
||||
"= {:8.3f} deg".format(k, t1[0], t1[1], angle1_deg, t2[0], t2[1], angle2_deg))
|
||||
|
||||
plt.plot(t1[0], t1[1], 'o')
|
||||
plt.plot(t2[0], t2[1], 'o')
|
||||
|
||||
## compute position of cut for dispenser gear
|
||||
# vector pointing from center in direction of tangent point
|
||||
v = np.array([math.cos(angle1_rad), math.sin(angle1_rad)])
|
||||
|
||||
cut_center = np.array(t1) + v * (offset_2 + dispenser_2_outer_diameter_small/2.0)
|
||||
self.tube_2_cuts[k] = {}
|
||||
self.tube_2_cuts[k]['center'] = cut_center
|
||||
self.tube_2_cuts[k]['tangent_point'] = t1
|
||||
self.tube_2_cuts[k]['angle_deg'] = angle1_deg
|
||||
self.tube_2_cuts[k]['length'] = dispenser_2_outer_diameter_small
|
||||
self.tube_2_cuts[k]['width'] = 5.0
|
||||
|
||||
plt.plot(cut_center[0], cut_center[1], 'o')
|
||||
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
|
@ -340,6 +415,68 @@ class PlateLayout:
|
|||
f_lines = f_lines + text
|
||||
pass
|
||||
|
||||
# gear markings for big cirlces and small circles
|
||||
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)
|
||||
|
||||
marking_length = 5.0
|
||||
|
||||
p1 = c[0]
|
||||
p2 = c[0] + v * marking_length
|
||||
|
||||
text = svg_line(p1, p2)
|
||||
f_lines = f_lines + text
|
||||
pass
|
||||
|
||||
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)
|
||||
|
||||
marking_length = 5.0
|
||||
|
||||
p1 = c[0]
|
||||
p2 = c[0] + v * marking_length
|
||||
|
||||
text = svg_line(p1, p2)
|
||||
f_lines = f_lines + text
|
||||
pass
|
||||
|
||||
|
||||
# output cuts for big circles
|
||||
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():
|
||||
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():
|
||||
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 = np.zeros(2)
|
||||
p2 = p1 + 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
|
||||
|
||||
pass
|
||||
|
||||
|
||||
f_lines.append('</svg>\n')
|
||||
|
||||
# write new svg image
|
||||
|
|
Loading…
Reference in New Issue
Block a user