cylindertransport.py

Mon, 03 Apr 2017 09:10:41 +0200

author
mdd
date
Mon, 03 Apr 2017 09:10:41 +0200
changeset 8
63b6f80e09ef
parent 6
57f17c62c137
child 9
a01a3fd32073
permissions
-rw-r--r--

added threejs stl viewer html testing

4
mdd
parents: 3
diff changeset
1 """
mdd
parents: 3
diff changeset
2 Calculation of spacer pipes for Scuba cylinder transportation
mdd
parents: 3
diff changeset
3 2017 by NeoSoft, mdd
mdd
parents: 3
diff changeset
4 Input: see commandline help
mdd
parents: 3
diff changeset
5 Output: 2D schematic & 3D OpenSCAD script
mdd
parents: 3
diff changeset
6 """
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
7 from math import sqrt
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
8 from PIL import Image, ImageDraw, ImageFont
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
9 import argparse, sys
2
9ec8fa3d0348 cleanup
mdd
parents: 1
diff changeset
10 from data import CYLINDER, PIPES
9ec8fa3d0348 cleanup
mdd
parents: 1
diff changeset
11 from config import FONTBASE
1
14a420653a5f output openscad script
mdd
parents: 0
diff changeset
12
4
mdd
parents: 3
diff changeset
13 def offset(r_1, r_2):
mdd
parents: 3
diff changeset
14 """
mdd
parents: 3
diff changeset
15 Calculate horizontal center offset of two circles
mdd
parents: 3
diff changeset
16 so they tangent each other
mdd
parents: 3
diff changeset
17 """
mdd
parents: 3
diff changeset
18 return 2 * sqrt(r_1 * r_2)
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
19
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
20 class CylinderSpacerCalculator(object):
4
mdd
parents: 3
diff changeset
21 """
mdd
parents: 3
diff changeset
22 Class to calculate transport spacer pipes between
mdd
parents: 3
diff changeset
23 Scuba cylinders
mdd
parents: 3
diff changeset
24 """
mdd
parents: 3
diff changeset
25 def __init__(self, cylinders, space_min=10):
mdd
parents: 3
diff changeset
26 self.cylinders = cylinders
mdd
parents: 3
diff changeset
27 self.space_min = space_min
mdd
parents: 3
diff changeset
28 self.font = FONTBASE + "arial.ttf"
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
29 self.width = 0 # will be calculated
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
30 self.scad = {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
31 "tmpl": """// Color support only in compile mode (F5)
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
32 // cylindertransport.py OpenSCAD script
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
33 module tank(x, r, h) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
34 color("SteelBlue") render() { //rotate([90,0,0]) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
35 translate([x, r, r]) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
36 sphere(r = r); // bottom
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
37 cylinder(h = h-2*r, r = r);
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
38 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
39 translate([x, r, h-r]) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
40 sphere(r = r); // top
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
41 cylinder(h = r*1.4, r = r*0.25);
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
42 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
43 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
44 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
45
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
46 module spacer(x, r, rcyl, h) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
47 color("DarkGrey") render() { //rotate([90,0,0]) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
48 translate([x, r, rcyl]) {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
49 difference() {
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
50 cylinder(h = h-2*rcyl, r = r);
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
51 cylinder(h = h-2*rcyl, r = r*0.8);
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
52 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
53 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
54 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
55 }
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
56 $fn = 10;
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
57 """,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
58 "spacer": "",
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
59 "cylinder": ""
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
60 }
4
mdd
parents: 3
diff changeset
61 self.circles = []
mdd
parents: 3
diff changeset
62 self.spacings = []
mdd
parents: 3
diff changeset
63 self.margin = 20
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
64 self.scale3d = 0.1
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
65
4
mdd
parents: 3
diff changeset
66 def calc_min(self, r_1, r_2):
mdd
parents: 3
diff changeset
67 """
mdd
parents: 3
diff changeset
68 stupider annaehreungsversuch, bis sich die beiden
mdd
parents: 3
diff changeset
69 Tauchflaschen r_1 und r_2 nicht mehr beruehren
mdd
parents: 3
diff changeset
70 Rueckgabe: 3 Zylinderradien und das label der verwendeten Roehre
mdd
parents: 3
diff changeset
71 """
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
72 for pipe in PIPES:
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
73 i = pipe[1] / 2
4
mdd
parents: 3
diff changeset
74 x_1 = offset(r_1, i)
mdd
parents: 3
diff changeset
75 x_2 = offset(r_2, i)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
76 posx = (x_1 + x_2) - (r_1 + r_2)
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
77 if posx >= self.space_min:
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
78 print "// %s Pipe (%.1fmm), Cylinder spacing: %imm" % (
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
79 pipe[0], pipe[1], posx)
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
80 return [r_1, i, r_2, pipe[0]]
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
81 print "// Abort: no suitable pipe found"
4
mdd
parents: 3
diff changeset
82 sys.exit(1)
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
83
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
84 def _circle(self, posx, radius, txt="", size=1.0):
4
mdd
parents: 3
diff changeset
85 """
mdd
parents: 3
diff changeset
86 Push the circle definition for later rendering
mdd
parents: 3
diff changeset
87 """
mdd
parents: 3
diff changeset
88 self.circles.append([
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
89 posx, radius, txt, size
4
mdd
parents: 3
diff changeset
90 ])
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
91
4
mdd
parents: 3
diff changeset
92 def _calculate(self):
mdd
parents: 3
diff changeset
93 """
mdd
parents: 3
diff changeset
94 Calculate all cylinder and spacer circles
mdd
parents: 3
diff changeset
95 """
mdd
parents: 3
diff changeset
96 # first bottle spacer
mdd
parents: 3
diff changeset
97 r_1 = CYLINDER[self.cylinders[0]][0] / 2
mdd
parents: 3
diff changeset
98 r_2 = CYLINDER[self.cylinders[1]][0] / 2
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
99 r_1, r_2, r_3, label = self.calc_min(r_1, r_2)
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
100 posx = self.margin + r_2 # start offset x
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
101 self._circle(posx, r_2, label, 0.5)
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
102 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % (
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
103 posx * self.scale3d, r_2 * self.scale3d, r_3 * self.scale3d,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
104 CYLINDER[self.cylinders[0]][1] * self.scale3d)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
105 posx += offset(r_2, r_3)
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
106
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
107 for i in range(0, len(self.cylinders) - 1):
4
mdd
parents: 3
diff changeset
108 r_1 = CYLINDER[self.cylinders[i]][0] / 2
mdd
parents: 3
diff changeset
109 r_2 = CYLINDER[self.cylinders[i+1]][0] / 2
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
110 r_1, r_2, r_3, label = self.calc_min(r_1, r_2)
4
mdd
parents: 3
diff changeset
111 # draw cylinder
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
112 self._circle(posx, r_1, "Tank " + self.cylinders[i])
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
113 self.scad["cylinder"] += "tank(%f, %f, %f);\n" % (
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
114 posx * self.scale3d, r_1 * self.scale3d,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
115 CYLINDER[self.cylinders[i]][1] * self.scale3d)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
116 sx1 = posx + r_1
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
117 posx += offset(r_1, r_2)
4
mdd
parents: 3
diff changeset
118 # draw right spacer
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
119 self._circle(posx, r_2, label, 0.5)
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
120 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % (
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
121 posx * self.scale3d, r_2 * self.scale3d, r_1 * self.scale3d,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
122 CYLINDER[self.cylinders[i]][1] * self.scale3d)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
123 posx += offset(r_2, r_3)
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
124 sx2 = posx - r_3
4
mdd
parents: 3
diff changeset
125 if i == (len(self.cylinders) - 2):
mdd
parents: 3
diff changeset
126 # draw last bottle
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
127 self._circle(posx, r_3, "Tank " + self.cylinders[i + 1])
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
128 self.scad["cylinder"] += "tank(%f, %f, %f);\n" % (
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
129 posx * self.scale3d, r_3 * self.scale3d,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
130 CYLINDER[self.cylinders[i + 1]][1] * self.scale3d)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
131 posx += offset(r_2, r_3)
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
132
4
mdd
parents: 3
diff changeset
133 self.spacings.append([sx1, sx2])
mdd
parents: 3
diff changeset
134
mdd
parents: 3
diff changeset
135 # last bottle spacer pipe
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
136 self._circle(posx, r_2, label, 0.5)
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
137 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % (
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
138 posx * self.scale3d, r_2 * self.scale3d, r_3 * self.scale3d,
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
139 CYLINDER[self.cylinders[-1]][1] * self.scale3d)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
140 return int(posx + r_2 + self.margin)
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
141
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
142 def centertext(self, draw, posx, posy, txt, size):
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
143 """
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
144 Centers text at position horizontally and vertically
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
145 """
4
mdd
parents: 3
diff changeset
146 font = ImageFont.truetype(self.font, int(24 * size))
mdd
parents: 3
diff changeset
147 tox, toy = draw.textsize(txt, font=font)
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
148 draw.text((posx - tox / 2, posy - toy / 2), \
4
mdd
parents: 3
diff changeset
149 txt, font=font, fill='#ffffff')
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
150
4
mdd
parents: 3
diff changeset
151 def render_image(self):
mdd
parents: 3
diff changeset
152 """
mdd
parents: 3
diff changeset
153 Start the calculation and return rendered PIL image object
mdd
parents: 3
diff changeset
154 """
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
155 self.width = self._calculate()
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
156 image = Image.new('1', (self.width, 250)) # create new image
4
mdd
parents: 3
diff changeset
157 draw = ImageDraw.Draw(image)
mdd
parents: 3
diff changeset
158 # draw calculated circles
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
159 for posx, radius, txt, size in self.circles:
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
160 draw.arc([posx - radius, self.margin, \
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
161 posx + radius, 2 * radius + self.margin], \
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
162 0, 360, 'white')
4
mdd
parents: 3
diff changeset
163 if txt != "":
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
164 self.centertext(draw, posx, radius + self.margin, txt, size)
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
165
4
mdd
parents: 3
diff changeset
166 # draw the spacing between cylinders
mdd
parents: 3
diff changeset
167 spacer_y1 = 200
mdd
parents: 3
diff changeset
168 spacer_y2 = 220
mdd
parents: 3
diff changeset
169 for sx1, sx2 in self.spacings:
mdd
parents: 3
diff changeset
170 draw.line((sx1, spacer_y1, sx1, spacer_y2), fill='#ffffff')
mdd
parents: 3
diff changeset
171 draw.line((sx2, spacer_y1, sx2, spacer_y2), fill='#ffffff')
mdd
parents: 3
diff changeset
172 self.centertext(draw, sx1 + (sx2 - sx1) / 2, \
mdd
parents: 3
diff changeset
173 spacer_y2 + 10, "%imm" % (sx2 - sx1), 0.5)
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
174
4
mdd
parents: 3
diff changeset
175 return image
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
176
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
177 def run():
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
178 """
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
179 Command line program invocation
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
180 """
4
mdd
parents: 3
diff changeset
181 parser = argparse.ArgumentParser(description=\
mdd
parents: 3
diff changeset
182 "Calculate spacer pipes for pressure cylinder transport\n" +\
mdd
parents: 3
diff changeset
183 "Known cylinder types:\n" + ", ".join(sorted(CYLINDER.keys())))
mdd
parents: 3
diff changeset
184 parser.add_argument('cylinders', metavar='cylinder', \
mdd
parents: 3
diff changeset
185 type=str, nargs='+', help='cylinder types')
mdd
parents: 3
diff changeset
186 parser.add_argument('--space', dest='space_min', \
mdd
parents: 3
diff changeset
187 type=int, default=10, \
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
188 help='minimum space between cylinders (mm)')
6
57f17c62c137 finishing
mdd
parents: 5
diff changeset
189 parser.add_argument('--scad', dest='scad', \
57f17c62c137 finishing
mdd
parents: 5
diff changeset
190 type=str, default="", metavar='filename', \
57f17c62c137 finishing
mdd
parents: 5
diff changeset
191 help='Write OpenSCAD script file')
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
192
4
mdd
parents: 3
diff changeset
193 options = parser.parse_args()
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
194
4
mdd
parents: 3
diff changeset
195 for test in options.cylinders:
mdd
parents: 3
diff changeset
196 if not test in CYLINDER.keys():
mdd
parents: 3
diff changeset
197 print "Cylinder type '%s' is unknown" % test
mdd
parents: 3
diff changeset
198 sys.exit(1)
0
007bbb709982 cylinder transport spacer calculation
mdd
parents:
diff changeset
199
4
mdd
parents: 3
diff changeset
200 worker = CylinderSpacerCalculator(
mdd
parents: 3
diff changeset
201 options.cylinders, options.space_min)
3
d8745f771267 objectoriz0r with separate calculation and rendering
mdd
parents: 2
diff changeset
202
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
203 img = worker.render_image()
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
204 img.show()
1
14a420653a5f output openscad script
mdd
parents: 0
diff changeset
205
6
57f17c62c137 finishing
mdd
parents: 5
diff changeset
206 if (options.scad != ""):
57f17c62c137 finishing
mdd
parents: 5
diff changeset
207 with open(options.scad, "w") as fd:
8
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
208 fd.write(worker.scad["tmpl"])
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
209 fd.write("translate([%f,0,0]) {\n" % (((worker.width - 2 * worker.margin) / -2)*worker.scale3d)) # center the object
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
210 fd.write(worker.scad["cylinder"])
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
211 fd.write(worker.scad["spacer"])
63b6f80e09ef added threejs stl viewer html testing
mdd
parents: 6
diff changeset
212 fd.write("}\n")
5
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
213
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
214 if __name__ == "__main__":
c2158ae1dc05 finished cylindertransport.py
mdd
parents: 4
diff changeset
215 run()

mercurial