import tkinter as tk from positions import * TEXT_SIZE = 14 PADDING = 40 OVERLAP_OUTLINE_WIDTH = 4 SCREEN_WIDTH=1200 SCREEN_HEIGHT=160 VSCALE=2 def rgb_to_hex(rgb): r, g, b = rgb return f"#{r:02x}{g:02x}{b:02x}" def rect_bounds(box): return box.get_left(), box.get_top(), box.get_right(), box.get_bottom() def intersection(a, b): ax1, ay1, ax2, ay2 = rect_bounds(a) bx1, by1, bx2, by2 = rect_bounds(b) x1 = max(ax1, bx1) y1 = max(ay1, by1) x2 = min(ax2, bx2) y2 = min(ay2, by2) if x1 < x2 and y1 < y2: return x1, y1, x2, y2 return None def visualize_packing(items): root = tk.Tk() root.title("Rectangle Packing Visualizer") canvas_width = SCREEN_WIDTH + PADDING * 2 canvas_height = SCREEN_HEIGHT*VSCALE + PADDING * 2 canvas = tk.Canvas( root, width=canvas_width, height=canvas_height, bg="black", highlightthickness=0 ) canvas.pack() ox = PADDING oy = PADDING # Outer perimeter canvas.create_rectangle( ox, oy, ox + SCREEN_WIDTH, oy + SCREEN_HEIGHT*VSCALE, fill="white", outline="white" ) boxes = [box for item in items for box in item.boxes] # Draw boxes for box in boxes: x1 = ox + box.get_left() y1 = oy + box.get_top() * VSCALE x2 = ox + box.get_right() y2 = oy + box.get_bottom() * VSCALE canvas.create_rectangle( x1, y1, x2, y2, fill=rgb_to_hex(box.item.color), outline="black" ) # Icon containers draw only vertical separators for simulated icon/dot slots. if box.item.is_icon_item and box is box.item.boxes[0]: cursor = box.get_left() for kind, width in box.item.render_segments()[:-1]: cursor += width x = ox + cursor canvas.create_line( x, y1, x, y2, fill="black", width=2, ) # Draw overlap regions for i in range(len(boxes)): for j in range(i + 1, len(boxes)): if boxes[i].item is boxes[j].item: continue overlap = intersection(boxes[i], boxes[j]) if overlap: x1, y1, x2, y2 = overlap y1 *= VSCALE y2 *= VSCALE x1 += ox y1 += oy x2 += ox y2 += oy # Red overlap area canvas.create_rectangle( x1, y1, x2, y2, fill="red", outline="red" ) # Thick red circle around overlap cx = (x1 + x2) / 2 cy = (y1 + y2) / 2 radius = max(x2 - x1, y2 - y1) / 2 + 12 canvas.create_oval( cx - radius, cy - radius, cx + radius, cy + radius, outline="red", width=OVERLAP_OUTLINE_WIDTH ) # Draw item texts for item in items: x1 = ox + item.get_left() y1 = oy + item.get_top() * VSCALE x2 = ox + item.get_right() y2 = oy + item.get_bottom() * VSCALE canvas.create_text( (x1 + x2) / 2, (y1 + y2) / 2, text=item.rendername(), font=("Arial", TEXT_SIZE), fill="black" ) root.mainloop() if __name__ == "__main__": containers = position_containers() visualize_packing(containers)