89 lines
3.4 KiB
Python
89 lines
3.4 KiB
Python
import pygame
|
|
import sys
|
|
from colorama import Fore, Style
|
|
|
|
class Visualizer:
|
|
def __init__(self, positions : list[tuple[float, float, float]], screen_dimensions : tuple[int, int], gcode_size : tuple[float, float]):
|
|
self.positions = positions
|
|
self.screen = None
|
|
self.clock = None
|
|
self.drawn_lines = []
|
|
self.travel_moves = []
|
|
self.screen_dimensions = screen_dimensions
|
|
self.gcode_size = gcode_size
|
|
self._init_pygame()
|
|
|
|
self.prev_x, self.prev_y, self.prev_z = self._transform_coordinates(positions[0])
|
|
self.idx = 1
|
|
|
|
def _transform_coordinates(self, pos : tuple[float, float, float]) -> tuple[float, float, float]:
|
|
x, y, z = pos
|
|
# Invert y-axis for screen coordinates
|
|
y = -y
|
|
|
|
# Transform the coordinates to fit the screen
|
|
screen_x = x/self.gcode_size[0] * self.screen.get_width()
|
|
screen_y = y/self.gcode_size[1] * self.screen.get_height()
|
|
screen_y += self.screen.get_height()
|
|
return screen_x, screen_y, z
|
|
|
|
def _init_pygame(self) -> None:
|
|
pygame.init()
|
|
self.screen = pygame.display.set_mode(self.screen_dimensions)
|
|
self.clock = pygame.time.Clock()
|
|
|
|
def _print_status(self) -> None:
|
|
normalized_x = self.prev_x / self.screen.get_width()
|
|
normalized_y = self.prev_y / self.screen.get_height()
|
|
pen_active = self.prev_z < 0
|
|
|
|
# Clear the terminal with ANSI code
|
|
print("\033c", end="")
|
|
|
|
# X-axis bar
|
|
x_bar = f"{Fore.GREEN}{'#'*int(normalized_x*100)}{Style.RESET_ALL}{' '*int((1.0-normalized_x)*100)}"
|
|
print(f"X: |{x_bar}| {(normalized_x*100):.2f}%")
|
|
|
|
# Y-axis bar
|
|
y_bar = f"{Fore.BLUE}{'#'*int(normalized_y*100)}{Style.RESET_ALL}{' '*int((1.0-normalized_y)*100)}"
|
|
print(f"Y: |{y_bar}| {(normalized_y*100):.2f}%")
|
|
|
|
# Pen status
|
|
pen_status = f"{Fore.GREEN}Active{Style.RESET_ALL}" if pen_active else f"{Fore.RED}Inactive{Style.RESET_ALL}"
|
|
print(f"Pen: {pen_status}")
|
|
|
|
def visualize(self) -> None:
|
|
running = True
|
|
while running:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
running = False
|
|
|
|
self.screen.fill((0, 0, 0))
|
|
|
|
if self.idx < len(self.positions):
|
|
pos = self.positions[self.idx]
|
|
x, y, z = self._transform_coordinates(pos)
|
|
if self.prev_z < 0 and z < 0:
|
|
self.drawn_lines.append((self.prev_x, self.prev_y, x, y))
|
|
elif z > 0:
|
|
self.travel_moves.append((self.prev_x, self.prev_y, x, y))
|
|
self.prev_x, self.prev_y, self.prev_z = x, y, z
|
|
# Draw the current position
|
|
pygame.draw.circle(self.screen, (255, 0, 0), (int(x), int(y)), 5)
|
|
self.idx += 1
|
|
|
|
# Draw travel moves
|
|
for travel_move in self.travel_moves:
|
|
x1, y1, x2, y2 = travel_move
|
|
pygame.draw.line(self.screen, (0, 0, 255), (int(x1), int(y1)), (int(x2), int(y2)), 2)
|
|
|
|
# Draw drawn lines
|
|
for drawn_line in self.drawn_lines:
|
|
x1, y1, x2, y2 = drawn_line
|
|
pygame.draw.line(self.screen, (255, 255, 255), (int(x1), int(y1)), (int(x2), int(y2)), 2)
|
|
|
|
self._print_status()
|
|
|
|
pygame.display.flip()
|
|
self.clock.tick(10) |