cylindertransport.py

changeset 5
c2158ae1dc05
parent 4
f62562506053
child 6
57f17c62c137
equal deleted inserted replaced
4:f62562506053 5:c2158ae1dc05
15 Calculate horizontal center offset of two circles 15 Calculate horizontal center offset of two circles
16 so they tangent each other 16 so they tangent each other
17 """ 17 """
18 return 2 * sqrt(r_1 * r_2) 18 return 2 * sqrt(r_1 * r_2)
19 19
20 class CylinderSpacerCalculator(): 20 class CylinderSpacerCalculator(object):
21 """ 21 """
22 Class to calculate transport spacer pipes between 22 Class to calculate transport spacer pipes between
23 Scuba cylinders 23 Scuba cylinders
24 """ 24 """
25 def __init__(self, cylinders, space_min=10): 25 def __init__(self, cylinders, space_min=10):
36 """ 36 """
37 stupider annaehreungsversuch, bis sich die beiden 37 stupider annaehreungsversuch, bis sich die beiden
38 Tauchflaschen r_1 und r_2 nicht mehr beruehren 38 Tauchflaschen r_1 und r_2 nicht mehr beruehren
39 Rueckgabe: 3 Zylinderradien und das label der verwendeten Roehre 39 Rueckgabe: 3 Zylinderradien und das label der verwendeten Roehre
40 """ 40 """
41 for p in PIPES: 41 for pipe in PIPES:
42 i = p[1] / 2 42 i = pipe[1] / 2
43 x_1 = offset(r_1, i) 43 x_1 = offset(r_1, i)
44 x_2 = offset(r_2, i) 44 x_2 = offset(r_2, i)
45 x = (x_1 + x_2) - (r_1 + r_2) 45 posx = (x_1 + x_2) - (r_1 + r_2)
46 if x >= self.space_min: 46 if posx >= self.space_min:
47 print "%s Pipe (%.1fmm), Cylinder spacing: %imm" % ( 47 print "// %s Pipe (%.1fmm), Cylinder spacing: %imm" % (
48 p[0], p[1], x) 48 pipe[0], pipe[1], posx)
49 return [r_1, i, r_2, p[0]] 49 return [r_1, i, r_2, pipe[0]]
50 print "Abort: no suitable pipe found" 50 print "// Abort: no suitable pipe found"
51 sys.exit(1) 51 sys.exit(1)
52 52
53 def _circle(self, x, r, txt="", size=1.0): 53 def _circle(self, posx, radius, txt="", size=1.0):
54 """ 54 """
55 Push the circle definition for later rendering 55 Push the circle definition for later rendering
56 """ 56 """
57 self.circles.append([ 57 self.circles.append([
58 x, r, txt, size 58 posx, radius, txt, size
59 ]) 59 ])
60 60
61 def _calculate(self): 61 def _calculate(self):
62 """ 62 """
63 Calculate all cylinder and spacer circles 63 Calculate all cylinder and spacer circles
64 """ 64 """
65 # first bottle spacer 65 # first bottle spacer
66 r_1 = CYLINDER[self.cylinders[0]][0] / 2 66 r_1 = CYLINDER[self.cylinders[0]][0] / 2
67 r_2 = CYLINDER[self.cylinders[1]][0] / 2 67 r_2 = CYLINDER[self.cylinders[1]][0] / 2
68 r_1, r_2, r_3, dn = self.calc_min(r_1, r_2) 68 r_1, r_2, r_3, label = self.calc_min(r_1, r_2)
69 x = self.margin + r_2 # start offset x 69 posx = self.margin + r_2 # start offset x
70 self._circle(x, r_2, dn, 0.5) 70 self._circle(posx, r_2, label, 0.5)
71 self.scad += "spacer(%i, %i, %i, %i);\n" % ( 71 self.scad += "spacer(%i, %i, %i, %i);\n" % (
72 x, r_2, r_3, CYLINDER[self.cylinders[0]][1]) 72 posx, r_2, r_3, CYLINDER[self.cylinders[0]][1])
73 x = x + offset(r_2, r_3) 73 posx += offset(r_2, r_3)
74 74
75 for i in range(0, len(self.cylinders)-1): 75 for i in range(0, len(self.cylinders) - 1):
76 r_1 = CYLINDER[self.cylinders[i]][0] / 2 76 r_1 = CYLINDER[self.cylinders[i]][0] / 2
77 r_2 = CYLINDER[self.cylinders[i+1]][0] / 2 77 r_2 = CYLINDER[self.cylinders[i+1]][0] / 2
78 r_1, r_2, r_3, dn = self.calc_min(r_1, r_2) 78 r_1, r_2, r_3, label = self.calc_min(r_1, r_2)
79 # draw cylinder 79 # draw cylinder
80 self._circle(x, r_1, "Tank " + self.cylinders[i]) 80 self._circle(posx, r_1, "Tank " + self.cylinders[i])
81 self.scad += "tank(%i, %i, %i);\n" % ( 81 self.scad += "tank(%i, %i, %i);\n" % (
82 x, r_1, CYLINDER[self.cylinders[i]][1]) 82 posx, r_1, CYLINDER[self.cylinders[i]][1])
83 sx1 = x + r_1 83 sx1 = posx + r_1
84 x = x + offset(r_1, r_2) 84 posx += offset(r_1, r_2)
85 # draw right spacer 85 # draw right spacer
86 self._circle(x, r_2, dn, 0.5) 86 self._circle(posx, r_2, label, 0.5)
87 self.scad += "spacer(%i, %i, %i, %i);\n" % ( 87 self.scad += "spacer(%i, %i, %i, %i);\n" % (
88 x, r_2, r_1, CYLINDER[self.cylinders[i]][1]) 88 posx, r_2, r_1, CYLINDER[self.cylinders[i]][1])
89 x = x + offset(r_2, r_3) 89 posx += offset(r_2, r_3)
90 sx2 = x - r_3 90 sx2 = posx - r_3
91 if i == (len(self.cylinders) - 2): 91 if i == (len(self.cylinders) - 2):
92 # draw last bottle 92 # draw last bottle
93 self._circle(x, r_3, "Tank " + self.cylinders[i + 1]) 93 self._circle(posx, r_3, "Tank " + self.cylinders[i + 1])
94 self.scad += "tank(%i, %i, %i);\n" % ( 94 self.scad += "tank(%i, %i, %i);\n" % (
95 x, r_3, CYLINDER[self.cylinders[i + 1]][1]) 95 posx, r_3, CYLINDER[self.cylinders[i + 1]][1])
96 x = x + offset(r_2, r_3) 96 posx += offset(r_2, r_3)
97 97
98 self.spacings.append([sx1, sx2]) 98 self.spacings.append([sx1, sx2])
99 99
100 # last bottle spacer pipe 100 # last bottle spacer pipe
101 self._circle(x, r_2, dn, 0.5) 101 self._circle(posx, r_2, label, 0.5)
102 self.scad += "spacer(%i, %i, %i, %i);\n" % ( 102 self.scad += "spacer(%i, %i, %i, %i);\n" % (
103 x, r_2, r_3, CYLINDER[self.cylinders[len(self.cylinders)]][1]) 103 posx, r_2, r_3, CYLINDER[self.cylinders[-1]][1])
104 return int(x + r_2 + self.margin) 104 return int(posx + r_2 + self.margin)
105 105
106 def centertext(self, draw, x, y, txt, size): 106 def centertext(self, draw, posx, posy, txt, size):
107 """
108 Centers text at position horizontally and vertically
109 """
107 font = ImageFont.truetype(self.font, int(24 * size)) 110 font = ImageFont.truetype(self.font, int(24 * size))
108 tox, toy = draw.textsize(txt, font=font) 111 tox, toy = draw.textsize(txt, font=font)
109 draw.text((x - tox / 2, y - toy / 2), \ 112 draw.text((posx - tox / 2, posy - toy / 2), \
110 txt, font=font, fill='#ffffff') 113 txt, font=font, fill='#ffffff')
111 114
112 def render_image(self): 115 def render_image(self):
113 """ 116 """
114 Start the calculation and return rendered PIL image object 117 Start the calculation and return rendered PIL image object
115 """ 118 """
116 width = self._calculate() 119 width = self._calculate()
117 image = Image.new('1', (width, 250)) # create new image 120 image = Image.new('1', (width, 250)) # create new image
118 draw = ImageDraw.Draw(image) 121 draw = ImageDraw.Draw(image)
119 # draw calculated circles 122 # draw calculated circles
120 for circle in self.circles: 123 for posx, radius, txt, size in self.circles:
121 x, r, txt, size = circle 124 draw.arc([posx - radius, self.margin, \
122 draw.arc([x - r, 0, x + r, 2 * r], 0, 360, 'white') 125 posx + radius, 2 * radius + self.margin], \
126 0, 360, 'white')
123 if txt != "": 127 if txt != "":
124 self.centertext(draw, x, r, txt, size) 128 self.centertext(draw, posx, radius + self.margin, txt, size)
125 129
126 # draw the spacing between cylinders 130 # draw the spacing between cylinders
127 spacer_y1 = 200 131 spacer_y1 = 200
128 spacer_y2 = 220 132 spacer_y2 = 220
129 for sx1, sx2 in self.spacings: 133 for sx1, sx2 in self.spacings:
132 self.centertext(draw, sx1 + (sx2 - sx1) / 2, \ 136 self.centertext(draw, sx1 + (sx2 - sx1) / 2, \
133 spacer_y2 + 10, "%imm" % (sx2 - sx1), 0.5) 137 spacer_y2 + 10, "%imm" % (sx2 - sx1), 0.5)
134 138
135 return image 139 return image
136 140
137 if __name__ == "__main__": 141 def run():
142 """
143 Command line program invocation
144 """
138 parser = argparse.ArgumentParser(description=\ 145 parser = argparse.ArgumentParser(description=\
139 "Calculate spacer pipes for pressure cylinder transport\n" +\ 146 "Calculate spacer pipes for pressure cylinder transport\n" +\
140 "Known cylinder types:\n" + ", ".join(sorted(CYLINDER.keys()))) 147 "Known cylinder types:\n" + ", ".join(sorted(CYLINDER.keys())))
141 parser.add_argument('cylinders', metavar='cylinder', \ 148 parser.add_argument('cylinders', metavar='cylinder', \
142 type=str, nargs='+', help='cylinder types') 149 type=str, nargs='+', help='cylinder types')
152 sys.exit(1) 159 sys.exit(1)
153 160
154 worker = CylinderSpacerCalculator( 161 worker = CylinderSpacerCalculator(
155 options.cylinders, options.space_min) 162 options.cylinders, options.space_min)
156 163
157 image = worker.render_image() 164 img = worker.render_image()
158 image.show() 165 img.show()
159 166
160 print "\n------------ START SCAD SCRIPT ------------" 167 print "\n// ------------ START SCAD SCRIPT ------------"
161 print worker.scad + "------------ END SCAD SCRIPT ------------" 168 print worker.scad + "// ------------ END SCAD SCRIPT ------------"
169
170
171 if __name__ == "__main__":
172 run()

mercurial