import math from Command import * import tkinter as tk class Program: def __init__(self, commands=None): self.commands = commands self.active=True self.visible=False self.filename='' if commands: self.xmin,self.ymin,self.xmax,self.ymax=self.__simulate() def __simulate(self): (x,y) = (0,0) xy=[] for command in self.commands : if not command.args: continue elif command.name in command.abscoms: x,y=command.x,command.y xy.append((x,y)) elif command.name in command.relcoms: x,y =x+command.x,y+command.y xy.append((x,y)) elif command.name in command.arccoms: xy+=[(x+command.x,y+command.x) , ( x-command.x,y-command.x)] return [m([v[i] for v in xy]) for m, i in ((min,0),(min,1),(max,0),(max,1))] @staticmethod def parsefile(filename): with open(filename) as file: return Program.parse( file.read()) @staticmethod def parse(code): commands = [] for command in code.strip().split(";")[:-1]: name, args = command[:2], command[2:] args = [float(arg) for arg in args.split(",")] if args else [] if name in Command.movecoms and len(args)>2: for i in range(0,len(args),2): commands.append(Command(name, args[i], args[i+1])) else: commands.append(Command(name, *args)) return Program(commands) def show(self,w=None): p=self.flip() p=p.rotate(270) p=p.fitin((0,0,1024,600),(0,0)) win=tk.Tk() win.title('HPGLPLOTTER') canvas=tk.Canvas(win,width=p.winsize[0],height=p.winsize[1]) canvas.grid(row=0,column=0) x = y = 0 for command in p.commands: if command.name == 'PU': x,y = command.x,command.y elif command.name=='PD': canvas.create_line(x,y,command.x,command.y) x,y = command.x,command.y elif command.name == 'CI': r=command.args[0] canvas.create_oval(x-r,y-r,x+r,y+r) win.mainloop() def __str__(self): return "".join(str(command) for command in self.commands) def __mul__(self, arg): return Program([command * arg for command in self.commands]) def __add__(self, arg): if type(arg)== type(self): return Program( self.commands + arg.commands ) return Program([command + arg for command in self.commands]) def __sub__(self, arg): return Program([command - arg for command in self.commands]) def __len__(self): return len(str(self)) def rotate(self, angl): return Program([command.rotate(angl) for command in self.commands]) def flip(self): return Program([command.flip() for command in self.commands if command]) def scaleto(self,ab): a,b = ab return self*min(a/self.winsize[0],b/self.winsize[1]) def moveto(self,ab): a,b = ab return self-(self.xmin-a,self.ymin-b) def fitin(self,xys,fxy): # fx fy Alignment Parameter: 0 links/oben 0,5 Mitte 1 rechts/unten (x1,y1,x2,y2) = xys (fx,fy) = fxy print("fx",fx,"fy",fy) p = self.scaleto((x2-x1,y2-y1)) return p.moveto((x1+fx*(x2-x1-p.winsize[0]),y1+fy*(y2-y1-p.winsize[1]))) def multi(self,w,h): dist=40 out=self p=self.winsize for i in range(w): for j in range(h): if (w!=0 and h!=0): out=out+(self+(i*p[0]+i*dist,j*p[1]+j*dist)) else: pass return out @property def center(self): return ((self.xmin+self.xmax)/2),((self.ymin+self.ymax)/2) @property def winsize(self): return self.xmax-self.xmin , self.ymax - self.ymin