def test_iteration_more(self):
        self.qt = QuadTree(Region(0, 0, 1024, 1024))
        points = []
        for _ in range(100):
            x = random.randint(0, 1021)
            y = random.randint(0, 1021)
            points.append((x, y))
            self.qt.add((x, y))

        for pt in self.qt:
            self.assertTrue(pt in points)
Beispiel #2
0
    def __init__(self, master, factor):
        """App for creating point-based quadtree dynamically."""
        
        master.title("Click to add/remove points: [0,0] - (" + str(512//factor) + "," + str(512//factor) + ")") 
        self.master = master 
        self.factor = factor
        
        # QuadTree holds the events
        self.tree = QuadTree(Region(0,0, 512//factor,512//factor))
        
        self.canvas = Canvas(master, width=512, height=512)        
        self.canvas.bind("<Button-1>", self.click)
        self.canvas.bind("<Button-2>", self.reset)      # Needed for Mac
        self.canvas.bind("<Button-3>", self.reset)      # This is PC
        master.bind("<Key>", self.zoom)
        self.canvas.pack()

        # no visualization just yet
        self.viz = None
    def test_cleanup(self):
        self.qt = QuadTree(Region(0, 0, 128, 128))
        actual = []
        for i in range(128):
            for j in range(128):
                actual.append((i, j))

        # For five times, add all randomly and remove randomly until
        # tree is entirely empty
        for i in range(5):
            random.shuffle(actual)

            for pt in actual:
                self.assertTrue(self.qt.add(pt))

            random.shuffle(actual)

            for pt in actual:
                self.assertTrue(self.qt.remove(pt))

            self.assertTrue(self.qt.root == None)
Beispiel #4
0
 def zoom(self, key):
     """
     Zoom in (+) and Zoom out (-) with key events. In rebuilding tree, 
     some points may get lost when zooming in.
     """
     factor = self.factor
     if key.char == '+':
         factor = min(factor*2, 256)
     elif key.char == '-':
         factor = max(factor//2, 1)
         
     if factor != self.factor:
         self.factor = factor
         self.canvas.delete(ALL)
         oldTree = self.tree
         self.tree = QuadTree(Region(0,0, 512//factor,512//factor))
         self.master.title("Click to add/remove points: [0,0] - (" + str(512//factor) + "," + str(512//self.factor) + ")") 
            
         for pt in oldTree:
             self.tree.add(pt) 
             
         self.visit(self.tree.root)
         self.viz.plot(self.tree.root)
 def setUp(self):
     self.qt = QuadTree(Region(0, 0, 8, 8))
class TestQuadRegionMethods(unittest.TestCase):
    def setUp(self):
        self.qt = QuadTree(Region(0, 0, 8, 8))

    def tearDown(self):
        self.qt = None

    def test_basic(self):
        self.qt.add((0, 0))

        self.assertTrue((0, 0) in self.qt)
        self.assertFalse((0, 1) in self.qt)

    def test_convertFull(self):
        self.qt.add((0, 0))
        self.qt.add((1, 1))
        self.qt.add((1, 0))

        self.assertTrue((0, 0) in self.qt)
        self.assertFalse((0, 1) in self.qt)
        self.assertTrue((1, 1) in self.qt)
        self.assertTrue((1, 0) in self.qt)

        # now make full
        self.qt.add((0, 1))

        self.assertTrue((0, 0) in self.qt)
        self.assertTrue((0, 1) in self.qt)
        self.assertTrue((1, 1) in self.qt)
        self.assertTrue((1, 0) in self.qt)

    def test_degradeFull(self):
        self.qt.add((0, 0))
        self.qt.add((1, 1))
        self.qt.add((1, 0))

        self.assertTrue((0, 0) in self.qt)
        self.assertFalse((0, 1) in self.qt)
        self.assertTrue((1, 1) in self.qt)
        self.assertTrue((1, 0) in self.qt)

        # now make full
        self.qt.add((0, 1))

        self.assertTrue((0, 0) in self.qt)
        self.assertTrue((0, 1) in self.qt)
        self.assertTrue((1, 1) in self.qt)
        self.assertTrue((1, 0) in self.qt)

        # now remove from full
        self.assertTrue(self.qt.remove((0, 1)))

        # validate others are there
        self.assertTrue((0, 0) in self.qt)
        self.assertFalse((0, 1) in self.qt)
        self.assertTrue((1, 1) in self.qt)
        self.assertTrue((1, 0) in self.qt)

    def test_prune(self):
        self.qt.add((0, 0))
        self.assertTrue((0, 0) in self.qt)

        # now clear
        self.qt.remove((0, 0))

        self.assertFalse((0, 0) in self.qt)
        self.assertTrue(self.qt.root is None)

    def test_presentation(self):
        self.qt.add((7, 4))
        self.qt.add((3, 4))
        self.qt.add((4, 6))
        self.qt.add((6, 6))
        self.qt.add((5, 1))
        self.qt.add((4, 3))
        self.qt.add((7, 7))
        self.qt.add((2, 5))
        self.qt.add((5, 3))
        self.qt.add((4, 5))
        self.qt.add((7, 6))
        self.qt.add((5, 2))
        self.qt.add((7, 5))
        self.qt.add((4, 4))
        self.qt.add((5, 4))
        self.qt.add((4, 7))
        self.qt.add((5, 7))
        self.qt.add((5, 6))
        self.qt.add((6, 5))
        self.qt.add((2, 4))
        self.qt.add((3, 5))
        self.qt.add((6, 7))
        self.qt.add((6, 4))
        self.qt.add((5, 5))
        self.qt.add((4, 2))

        # Top-level
        self.assertTrue(self.qt.root.children[SW] == None)
        self.assertTrue(self.qt.root.children[NE].full)

        # second level
        self.assertTrue(self.qt.root.children[NW].children[SE].full)
        self.assertTrue(self.qt.root.children[SE].children[NW].full)

        # third level
        self.assertTrue(
            self.qt.root.children[SE].children[SW].children[NE].isPoint())
        self.assertTrue(
            self.qt.root.children[SE].children[SW].children[NE].full)

    def test_presentation_odd(self):
        self.qt.add((3, 4))
        self.qt.add((4, 3))

        # Top-level
        self.assertTrue(self.qt.root.children[NE] == None)
        self.assertTrue(self.qt.root.children[SW] == None)

        # last level
        self.assertTrue(
            self.qt.root.children[NW].children[SE].children[SE].isPoint())
        self.assertTrue(
            self.qt.root.children[NW].children[SE].children[SE].full)

        self.assertTrue(
            self.qt.root.children[SE].children[NW].children[NW].isPoint())
        self.assertTrue(
            self.qt.root.children[SE].children[NW].children[NW].full)

    def test_checkerboard(self):
        for i in range(8):
            for j in range(8):
                if (i + j) % 2 == 0:
                    self.assertTrue(self.qt.add((i, j)))

        for i in range(8):
            for j in range(8):
                if (i + j) % 2 == 0:
                    self.assertTrue((i, j) in self.qt)

        # now fill in others.
        for i in range(8):
            for j in range(8):
                if (i + j) % 2 == 1:
                    self.assertTrue(self.qt.add((i, j)))

        self.assertTrue(self.qt.root.full)
        for i in range(8):
            for j in range(8):
                self.assertTrue((i, j) in self.qt)

    def test_createFull(self):
        """
        Randomly add all points and validate root node is full. Then remove one
        and validate not full.
        """
        toAdd = []
        for i in range(8):
            for j in range(8):
                toAdd.append((i, j))

        random.shuffle(toAdd)
        for pt in toAdd:
            self.assertTrue(self.qt.add(pt))

        self.assertTrue(self.qt.root.full)

        random.shuffle(toAdd)
        for pt in toAdd:
            self.assertTrue(self.qt.remove(pt))

        self.assertTrue(self.qt.root == None)

    def test_iteration(self):

        self.qt.add((0, 0))

        grab = list(self.qt)

        self.assertEqual([(0, 0)], grab)

    def test_iteration_with_full(self):

        self.qt.add((0, 0))
        self.qt.add((1, 1))
        self.qt.add((1, 0))
        self.qt.add((0, 1))

        grab = list(self.qt)

        self.assertEqual([(0, 0), (0, 1), (1, 0), (1, 1)], grab)

    def test_checkerboard_iterator(self):
        actual = []
        for i in range(8):
            for j in range(8):
                if (i + j) % 2 == 0:
                    actual.append((i, j))
                    self.assertTrue(self.qt.add((i, j)))

        grab = list(self.qt)

        # validate all points are there.
        for pt in actual:
            self.assertTrue(pt in grab)
        for pt in grab:
            self.assertTrue(pt in actual)

    def test_iteration_more(self):
        self.qt = QuadTree(Region(0, 0, 1024, 1024))
        points = []
        for _ in range(100):
            x = random.randint(0, 1021)
            y = random.randint(0, 1021)
            points.append((x, y))
            self.qt.add((x, y))

        for pt in self.qt:
            self.assertTrue(pt in points)

    def test_cleanup(self):
        self.qt = QuadTree(Region(0, 0, 128, 128))
        actual = []
        for i in range(128):
            for j in range(128):
                actual.append((i, j))

        # For five times, add all randomly and remove randomly until
        # tree is entirely empty
        for i in range(5):
            random.shuffle(actual)

            for pt in actual:
                self.assertTrue(self.qt.add(pt))

            random.shuffle(actual)

            for pt in actual:
                self.assertTrue(self.qt.remove(pt))

            self.assertTrue(self.qt.root == None)
Beispiel #7
0
 def reset(self, event):
     """Reset to start state."""
     self.tree = QuadTree(Region(0,0, 512//self.factor,512//self.factor))
     self.canvas.delete(ALL)
     self.visit(self.tree.root)
     self.viz.clear()
Beispiel #8
0
class QuadTreeRegionApp:
    
    def __init__(self, master, factor):
        """App for creating point-based quadtree dynamically."""
        
        master.title("Click to add/remove points: [0,0] - (" + str(512//factor) + "," + str(512//factor) + ")") 
        self.master = master 
        self.factor = factor
        
        # QuadTree holds the events
        self.tree = QuadTree(Region(0,0, 512//factor,512//factor))
        
        self.canvas = Canvas(master, width=512, height=512)        
        self.canvas.bind("<Button-1>", self.click)
        self.canvas.bind("<Button-2>", self.reset)      # Needed for Mac
        self.canvas.bind("<Button-3>", self.reset)      # This is PC
        master.bind("<Key>", self.zoom)
        self.canvas.pack()

        # no visualization just yet
        self.viz = None

    def zoom(self, key):
        """
        Zoom in (+) and Zoom out (-) with key events. In rebuilding tree, 
        some points may get lost when zooming in.
        """
        factor = self.factor
        if key.char == '+':
            factor = min(factor*2, 256)
        elif key.char == '-':
            factor = max(factor//2, 1)
            
        if factor != self.factor:
            self.factor = factor
            self.canvas.delete(ALL)
            oldTree = self.tree
            self.tree = QuadTree(Region(0,0, 512//factor,512//factor))
            self.master.title("Click to add/remove points: [0,0] - (" + str(512//factor) + "," + str(512//self.factor) + ")") 
               
            for pt in oldTree:
                self.tree.add(pt) 
                
            self.visit(self.tree.root)
            self.viz.plot(self.tree.root)

    def toCartesian(self, y):
        """Convert tkinter point into Cartesian."""
        return self.canvas.winfo_height() - y

    def toTk(self,y):
        """Convert Cartesian into tkinter point."""
        if y == maxValue: return 0
        tk_y = self.canvas.winfo_height()
        if y != minValue:
            tk_y -= y
        return tk_y
         
    def click(self, event):
        """Add point to quadtree, based on factor."""
        pt = [event.x // self.factor, self.toCartesian(event.y) // self.factor]
        if pt in self.tree:
            self.tree.remove(pt)
        else:
            self.tree.add(pt)

        self.canvas.delete(ALL)
        self.visit(self.tree.root)
        self.viz.plot(self.tree.root)
            
    def reset(self, event):
        """Reset to start state."""
        self.tree = QuadTree(Region(0,0, 512//self.factor,512//self.factor))
        self.canvas.delete(ALL)
        self.visit(self.tree.root)
        self.viz.clear()
        
    def visit(self, node):
        """Visit nodes recursively."""
        if node == None: 
            return

        # draw rectangular region with criss-crossed hashed lines 
        r = node.region
        self.canvas.create_rectangle(self.factor * r.x_min,
                                     self.factor * self.toTk(r.y_min),
                                     self.factor * r.x_max, 
                                     self.factor * self.toTk(r.y_max))
         
        self.canvas.create_line(self.factor * r.x_min,
                                self.toTk(self.factor * node.origin[Y]),
                                self.factor * r.x_max,
                                self.toTk(self.factor * node.origin[Y]),
                                dash=(2, 4)) 
        self.canvas.create_line(self.factor * node.origin[X],
                                self.toTk(self.factor * r.y_min),
                                self.factor * node.origin[X],
                                self.toTk(self.factor * r.y_max),
                                dash=(2, 4))
         
        if node.isPoint() or node.full:
            pt = [node.region.x_min, node.region.y_min]
            width = node.region.x_max - node.region.x_min
            self.canvas.create_rectangle(self.factor * pt[X],
                                         self.toTk(self.factor * pt[Y]),
                                         self.factor * (pt[X]+width),
                                         self.toTk(self.factor * (pt[Y]+width)),
                                         fill='black')
        for n in node.children:
            self.visit(n)