Mon, 03 Apr 2017 03:15:12 +0200
objectoriz0r with separate calculation and rendering
.hgignore | file | annotate | diff | comparison | revisions | |
cylindertransport.py | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Apr 03 03:15:12 2017 +0200 @@ -0,0 +1,2 @@ +syntax: glob +*.pyc
--- a/cylindertransport.py Mon Apr 03 02:14:43 2017 +0200 +++ b/cylindertransport.py Mon Apr 03 03:15:12 2017 +0200 @@ -4,99 +4,118 @@ from data import CYLINDER, PIPES from config import FONTBASE -SCADSCRIPT = "// Color support only in compile mode (F5)\ninclude <cylindertransport.scad>\n" - def offset(r1, r2): return (2*sqrt(r1*r2)) -def calc_min(r1, r2, space_min): - # stupider annaehreungsversuch, bis sich die beiden Tauchflaschen r1 und r2 nicht mehr beruehren - 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 +class CylinderSpacerCalculator: + def __init__(self, cylinders = ["10", "10"], space_min = 10): + self.cylinders = cylinders + self.space_min = space_min + self.font = FONTBASE + "arial.ttf" + self.scad = "// Color support only in compile mode (F5)\n" +\ + "include <cylindertransport.scad>\n" + self.circles = [] + self.spacings = [] + self.margin = 20 -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): - global SCADSCRIPT - bottles = args.cylinders + def calc_min(self, r1, r2): + # stupider annaehreungsversuch, bis sich die beiden Tauchflaschen r1 und r2 nicht mehr beruehren + for p in PIPES: + i = p[1] / 2 + if i>r1 or i>r2: + return None + x1 = offset(r1, i) + x2 = offset(r2, i) + x = (x1 + x2) - (r1+r2) + if x >= self.space_min: + print "%s Pipe (%.1fmm), Cylinder spacing: %imm" % (p[0], p[1], x) + return [r1, i, r2, p[0]] + return None - 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, args.space_min) - circ(draw, x, r2, dn, 0.5) - SCADSCRIPT = SCADSCRIPT + "spacer(%i, %i, %i, %i);\n" % ( - x, r2, r3, CYLINDER[bottles[0]][1]) - x = x + offset(r2, r3) + def _circle(self, x, r, txt = "", size = 1.0): + self.circles.append([ + x, r, txt, size + ]) + + def _calculate(self): + # first bottle spacer + r1 = CYLINDER[self.cylinders[0]][0] / 2 + r2 = CYLINDER[self.cylinders[1]][0] / 2 + r1, r2, r3, dn = self.calc_min(r1, r2) + x = self.margin + r2 # start offset x + self._circle(x, r2, dn, 0.5) + self.scad += "spacer(%i, %i, %i, %i);\n" % ( + x, r2, r3, CYLINDER[self.cylinders[0]][1]) + 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, args.space_min) - # draw bottle - circ(draw, x, r1, "Tank "+bottles[i]) - SCADSCRIPT = SCADSCRIPT + "tank(%i, %i, %i);\n" % ( - x, r1, CYLINDER[bottles[i]][1]) - sx1 = x+r1 - x = x + offset(r1, r2) - # draw right spacer - circ(draw, x, r2, dn, 0.5) - SCADSCRIPT = SCADSCRIPT + "spacer(%i, %i, %i, %i);\n" % ( - x, r2, r1, CYLINDER[bottles[i]][1]) - x = x + offset(r2, r3) - sx2 = x-r3 - if i == (len(bottles)-2): - # draw last bottle - circ(draw, x, r3, "Tank "+bottles[i+1]) - SCADSCRIPT = SCADSCRIPT + "tank(%i, %i, %i);\n" % ( - x, r3, CYLINDER[bottles[i+1]][1]) + for i in range(0, len(self.cylinders)-1): + r1 = CYLINDER[self.cylinders[i]][0] / 2 + r2 = CYLINDER[self.cylinders[i+1]][0] / 2 + r1, r2, r3, dn = self.calc_min(r1, r2) + # draw cylinder + self._circle(x, r1, "Tank " + self.cylinders[i]) + self.scad += "tank(%i, %i, %i);\n" % ( + x, r1, CYLINDER[self.cylinders[i]][1]) + sx1 = x+r1 + x = x + offset(r1, r2) + # draw right spacer + self._circle(x, r2, dn, 0.5) + self.scad += "spacer(%i, %i, %i, %i);\n" % ( + x, r2, r1, CYLINDER[self.cylinders[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') + sx2 = x-r3 + if i == (len(self.cylinders) - 2): + # draw last bottle + self._circle(x, r3, "Tank " + self.cylinders[i+1]) + self.scad += "tank(%i, %i, %i);\n" % ( + x, r3, CYLINDER[self.cylinders[i+1]][1]) + x = x + offset(r2, r3) + + self.spacings.append([sx1, sx2]) + + # last bottle spacer pipe + self._circle(x, r2, dn, 0.5) + self.scad += "spacer(%i, %i, %i, %i);\n" % ( + x, r2, r3, CYLINDER[self.cylinders[i+1]][1]) + return int(x + r2 + self.margin) - # last bottle spacer - circ(draw, x, r2, dn, 0.5) - SCADSCRIPT = SCADSCRIPT + "spacer(%i, %i, %i, %i);\n" % ( - x, r2, r3, CYLINDER[bottles[i+1]][1]) + def render_image(self): + width = self._calculate() + image = Image.new('1', (width, 250)) # create new image + draw = ImageDraw.Draw(image) + # draw calculated circles + for circle in self.circles: + x, r, txt, size = circle + draw.arc([x - r, 0, x + r, 2 * r], 0, 360, 'white') + if txt != "": + font = ImageFont.truetype(self.font, int(24 * size)) + tox, toy = draw.textsize(txt, font=font) + draw.text((x - tox / 2, r - toy / 2), txt, font=font, fill='#ffffff') -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 + # draw the spacing between cylinders + spacerY1 = 200 + spacerY2 = 220 + for spacing in self.spacings: + sx1, sx2 = spacing + 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') + + return image if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Calculate spacer pipes for pressure cylinder transport\n" + + 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=10, - help='minimum space between cylinders (mm)') + parser.add_argument('cylinders', metavar = 'cylinder', + type = str, nargs = '+', help = 'cylinder types') + parser.add_argument('--space', dest='space_min', + type = int, default=10, + help='minimum space between cylinders (mm)') args = parser.parse_args() @@ -105,8 +124,11 @@ print "Cylinder type '%s' is unknown" % test sys.exit(1) - image = getimage(args) + obj = CylinderSpacerCalculator( + args.cylinders, args.space_min) + + image = obj.render_image() image.show() print "\n------------ START SCAD SCRIPT ------------" - print SCADSCRIPT + "------------ END SCAD SCRIPT ------------" + print obj.scad + "------------ END SCAD SCRIPT ------------"