128 lines
3.9 KiB
Python
Executable File
128 lines
3.9 KiB
Python
Executable File
|
|
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
|