objectoriz0r with separate calculation and rendering

Mon, 03 Apr 2017 03:15:12 +0200

author
mdd
date
Mon, 03 Apr 2017 03:15:12 +0200
changeset 3
d8745f771267
parent 2
9ec8fa3d0348
child 4
f62562506053

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 ------------"

mercurial