diff --git a/flake.nix b/flake.nix index 5754027..2be1c7d 100644 --- a/flake.nix +++ b/flake.nix @@ -4,13 +4,14 @@ { devShells.x86_64-linux = let - python = pkgs.python312; + python = pkgs.python312Full; pythonEnv = python.withPackages ( - ps: with pkgs.python312Packages; [ + ps: with ps; [ pip ipython - tkinter + matplotlib + numpy ruff jedi-language-server diff --git a/main.py b/main.py new file mode 100644 index 0000000..c71b076 --- /dev/null +++ b/main.py @@ -0,0 +1,4 @@ +from src.quadtree import TkQuadTree + +if __name__ == "__main__": + TkQuadTree.fromFile("files/quadtree.txt").paint() diff --git a/src/quadtree.py b/src/quadtree.py index 5a0b87c..ef4c94f 100644 --- a/src/quadtree.py +++ b/src/quadtree.py @@ -1,5 +1,6 @@ from __future__ import annotations from tkinter import ttk, Tk, Canvas +from typing import Self class QuadTree: @@ -17,19 +18,26 @@ class QuadTree: self.bd = bd self.bg = bg + @property + def corners(self) -> list[bool | QuadTree]: + """ + utility function returning all the corners of the quad as a tuple + """ + return (self.hg, self.hd, self.bd, self.bg) + @property def depth(self) -> int: """Recursion depth of the quadtree""" depths = [] - for i in ["hg", "hd", "bd", "bg"]: + for corner in self.corners: try: - depths.append(self.__dict__[i].depth + 1) + depths.append(corner.depth + 1) except AttributeError: depths.append(1) return max(depths) - @staticmethod - def fromFile(filename: str) -> QuadTree: + @classmethod + def fromFile(cls, filename: str) -> Self: """Open a given file, containing a textual representation of a list""" def parse(file) -> QuadTree: @@ -37,11 +45,11 @@ class QuadTree: while char := file.read(1): match char: case "0" | "1": - nodes.append(char) + nodes.append(char == "1") case "[": nodes.append(parse(file)) case "]": - return QuadTree(*nodes) + return cls(*nodes) case _: pass if len(nodes) == 1: @@ -59,24 +67,37 @@ class QuadTree: class TkQuadTree(QuadTree): - def paint(self): + def paint(self, size_x=1000, size_y=1000): """TK representation of a Quadtree""" root = Tk() - canvas = Canvas(root, width=1000, height=1000) + canvas = Canvas(root, width=size_y, height=size_x) canvas.pack() - self.draw_tree((0,0),(1000,1000)) - canvas.create_rectangle(0, 0, 500, 500, fill = "white") + self.draw_tree((0, 0, size_x, size_y), canvas) root.mainloop() - def draw_tree(boundaries: tuple[tuple[int]]): - pass - - @staticmethod - def fromFile(filename): - tree = QuadTree.fromFile(filename) - return TkQuadTree( - hg = tree.hg, - hd = tree.hd, - bd = tree.bd, - bg = tree.bg + def draw_tree(self, boundaries: tuple[int], canvas): + """ + draw the quadtree where each quad will be half of the specified boundarie. + boundaries: a tuple of 4 items describing the start / end corner of the canvas boundarie. + ex: (start_x, start_y, end_x, end_y) + """ + center = ( + # compute the center of the current boundary + boundaries[0] + abs((boundaries[2] - boundaries[0]) // 2), + boundaries[1] + abs((boundaries[3] - boundaries[1]) // 2), ) + rectangles = [ + # compute boundaries of each future quad + (*boundaries[:2], *center), + (center[0], *boundaries[1:3], center[1]), + (*center, *boundaries[2:]), + (boundaries[0], center[1], center[0], boundaries[3]), + ] + for rectangle, corner in zip(rectangles, self.corners): + try: + corner.draw_tree(rectangle, canvas) + except AttributeError: + canvas.create_rectangle( + *rectangle, + fill="white" if corner else "black", + )