Sun, 02 Apr 2017 23:59:00 +0200
cylinder transport spacer calculation
cylindertransport.py | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cylindertransport.py Sun Apr 02 23:59:00 2017 +0200 @@ -0,0 +1,133 @@ +from math import sqrt +from PIL import Image, ImageDraw, ImageFont +import argparse, sys + +# pfad zu den TTF files (arial.ttf) +FONTBASE = "/usr/share/fonts/truetype/msttcorefonts/" + +SPACE_MIN = 10 # minimum offset between bottles + +# Durchmesser, Laenge, Volumen und Gewicht der verfuegbaren Tauchflaschen +CYLINDER = { + "03" : [100, 515, 3, 4.7], + "05" : [140, 466, 5, 5.7], + "07" : [140, 605, 7, 8.8], + "08" : [171, 490, 8, 10.4], + "10" : [171, 595, 10, 12.4], + "12S" : [204, 550, 12, 15.4], + "12L" : [171, 690, 12, 14.5], + "15" : [204, 640, 15, 18.1], +} + +PIPES = [ + ["DN8", 13.5], + ["DN10", 17.2], + ["DN15", 21.3], + ["DN20", 26.9], + ["DN25", 33.7], + ["DN32", 42.4], + ["DN40", 48.3], + ["DN50", 60.3], + ["DN65", 76.1], + ["DN80", 88.9], + ["DN100", 114.3], + ["DN125", 139.7], + ["DN150", 168.3], +] + + + +def offset(r1, r2): + o = (2*sqrt(r1*r2)) + #print "offset %i" % o + return o + +def calc_min(r1, r2): + # stupider annaehreungsversuch, bis sich die beiden Tauchflaschen r1 und r2 nicht mehr beruehren + #print "r1=%.0f r2=%.0f" % (r1, r2) + for p in PIPES: + i = p[1] / 2 + if i>r1 or i>r2: + print "spacer radius > r1 or r2, abort" + return None + x1 = offset(r1, i) + x2 = offset(r2, i) + x = (x1 + x2) - (r1+r2) + if x >= SPACE_MIN: + print "%s Pipe (%.1fmm), Cylinder spacing: %imm" % (p[0], p[1], x) + return [r1, i, r2, p[0]] + return None + +def circ(draw, x, r, txt = "", txtfactor = 1.0): + draw.arc([x-r, 0, x + r, 2 * r], 0, 360, 'white') + if txt != "": + font = ImageFont.truetype(FONTBASE+"arial.ttf", int(24*txtfactor)) + tox, toy = draw.textsize(txt, font=font) + draw.text((x-tox/2, r-toy/2), txt, font=font, fill='#ffffff') + + +def draw_bottles(draw, args): + bottles = args.cylinders + SPACE_MIN = args.space_min + + spacerY1 = 200 + spacerY2 = 220 + # first bottle spacer + r1 = CYLINDER[bottles[0]][0] / 2 + r2 = CYLINDER[bottles[1]][0] / 2 + x = 20 + r1 # start offset x + r1, r2, r3, dn = calc_min(r1, r2) + circ(draw, x, r2, dn, 0.5) + x = x + offset(r2, r3) + + for i in range(0, len(bottles)-1): + r1 = CYLINDER[bottles[i]][0] / 2 + r2 = CYLINDER[bottles[i+1]][0] / 2 + r1, r2, r3, dn = calc_min(r1, r2) + # draw bottle + circ(draw, x, r1, "Tank "+bottles[i]) + sx1 = x+r1 + x = x + offset(r1, r2) + # draw right spacer + circ(draw, x, r2, dn, 0.5) + x = x + offset(r2, r3) + sx2 = x-r3 + if i == (len(bottles)-2): + # draw last bottle + circ(draw, x, r3, "Tank "+bottles[i+1]) + x = x + offset(r2, r3) + # draw the space between bottles + draw.line((sx1, spacerY1, sx1, spacerY2), fill='#ffffff') + draw.line((sx2, spacerY1, sx2, spacerY2), fill='#ffffff') + txt = "%imm" % (sx2-sx1) + font = ImageFont.truetype(FONTBASE+"arial.ttf", 12) + tox, toy = draw.textsize(txt, font=font) + draw.text((sx1+(sx2-sx1)/2-(tox/2), spacerY2+toy/2), txt, font=font, fill='#ffffff') + + # last bottle spacer + circ(draw, x, r2, dn, 0.5) + +def getimage(args): + image = Image.new('1', (1000, 250)) #create new image, 1000x500 pixels, 1 bit per pixel + draw = ImageDraw.Draw(image) + draw_bottles(draw, args) + return image + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Calculate spacer pipes for pressure cylinder transport\n" + + "Known cylinder types:\n" + ", ".join(sorted(CYLINDER.keys())) ) + parser.add_argument('cylinders', metavar='cylinder', type=str, nargs='+', + help='cylinder types') + parser.add_argument('--space', dest='space_min', type=int, + default=SPACE_MIN, + help='minimum space between cylinders (mm)') + + args = parser.parse_args() + + for test in args.cylinders: + if not test in CYLINDER.keys(): + print "Cylinder type '%s' is unknown" % test + sys.exit(1) + + image = getimage(args) + image.show() \ No newline at end of file