Files
mimaki/Program.py
Lukas Cremer cd846577a4 add webui
2026-02-03 22:41:29 +01:00

131 lines
4.2 KiB
Python
Executable File

import math
from Command import *
class Program:
def __init__(self, commands=None):
self.commands = commands if commands is not None else []
self.active = True
self.visible = False
self.filename = ''
if self.commands:
self.xmin, self.ymin, self.xmax, self.ymax = self.__simulate()
else:
self.xmin = self.ymin = self.xmax = self.ymax = 0
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)]
if not xy:
return [0, 0, 0, 0]
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):
import tkinter as tk
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
w, h = self.winsize
if w == 0 or h == 0:
return self
return self * min(a / w, b / h)
def moveto(self, ab):
a, b = ab
return self - (self.xmin - a, self.ymin - b)
def fitin(self, xys, fxy):
(x1, y1, x2, y2) = xys
(fx, fy) = fxy
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))
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