# hpgl2d.py # # Copyright (c) 2009, Dan Heeks # This program is released under the BSD license. See the file COPYING for details. # import nc import math class Creator(nc.Creator): def __init__(self): nc.Creator.__init__(self) self.x = int(0) self.y = int(0) # these are in machine units, like 0.01mm or maybe 0.25mm self.metric() # set self.units_to_mc_units def imperial(self): self.units_to_mc_units = 2540 # multiplier from inches to machine units def metric(self): self.units_to_mc_units = 100 # multiplier from mm to machine units def program_begin(self, id, name=''): self.write('IN;\n') self.write('VS32,1;\n') self.write('VS32,2;\n') self.write('VS32,3;\n') self.write('VS32,4;\n') self.write('VS32,5;\n') self.write('VS32,6;\n') self.write('VS32,7;\n') self.write('VS32,8;\n') self.write('WU0;\n') self.write('PW0.349,1;\n') self.write('PW0.349,2;\n') self.write('PW0.349,3;\n') self.write('PW0.349,4;\n') self.write('PW0.349,5;\n') self.write('PW0.349,6;\n') self.write('PW0.349,7;\n') self.write('PW0.349,8;\n') self.write('SP1;\n') def program_end(self): self.write('SP0;\n') def closest_int(self, f): if math.fabs(f) < 0.3: return 0 elif f > 0: return int(f + 0.5) else: return int(f - 0.5) def get_machine_x_y(self, x=None, y=None): machine_x = self.x machine_y = self.y if x != None: machine_x = self.closest_int(x * self.units_to_mc_units) if y != None: machine_y = self.closest_int(y * self.units_to_mc_units) return machine_x, machine_y def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None): # ignore the z, any rapid will be assumed to be done with the pen up mx, my = self.get_machine_x_y(x, y) if mx != self.x or my != self.y: self.write(('PU%i' % mx) + (' %i;\n' % my)) self.x = mx self.y = my def feed(self, x=None, y=None, z=None, a=None, b=None, c=None): # ignore the z, any feed will be assumed to be done with the pen down mx, my = self.get_machine_x_y(x, y) if mx != self.x or my != self.y: self.write(('PD%i' % mx) + (' %i;\n' % my)) self.x = mx self.y = my def arc(self, cw, x=None, y=None, z=None, i=None, j=None, k=None, r=None): mx, my = self.get_machine_x_y(x, y) if mx != self.x or my != self.y: cx = float(self.x) / self.units_to_mc_units + i cy = float(self.y) / self.units_to_mc_units + j sdx = -i sdy = -j edx = x - cx edy = y - cy start_angle = math.atan2(sdy, sdx) end_angle = math.atan2(edy, edx) if cw: if start_angle < end_angle: start_angle += 2 * math.pi else: if end_angle < start_angle: end_angle += 2 * math.pi a = math.fabs(end_angle - start_angle) if cw: a = -a mcx, mcy = self.get_machine_x_y(cx, cy) self.write(('AA%i' % mcx) + (',%i' % mcy) + (',%d;\n' % (a * 180 / math.pi))) def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None): self.arc(True, x, y, z, i, j, k, r) def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None): self.arc(False, x, y, z, i, j, k, r) nc.creator = Creator()