Пример #1
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()
Пример #2
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, 1024, 1024))

        self.qt.add((22, 40))
        self.qt.add((13, 59))
        self.qt.add((57, 37))
        self.qt.add((43, 21))
        self.qt.add((33, 11))
    def test_iteration(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)
Пример #5
0
 def __init__(self, master):
     """App for creating Quad tree dynamically with fixed circles that ALMOST ALWAYS detect collisions."""
     
     master.title("Click to add fixed circles for ALMOST detecting collisions.") 
     self.master = master 
     
     # QuadTree holds the events
     self.tree = QuadTree(Region(0,0,512,512))
     
     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
     self.canvas.pack()
class TestQuadPointMethods(unittest.TestCase):
    def setUp(self):
        self.qt = QuadTree(Region(0, 0, 1024, 1024))

        self.qt.add((22, 40))
        self.qt.add((13, 59))
        self.qt.add((57, 37))
        self.qt.add((43, 21))
        self.qt.add((33, 11))

    def tearDown(self):
        self.qt = None

    def test_basic(self):
        self.assertTrue((43, 21) in self.qt)
        self.assertFalse((21, 43) in self.qt)

    def test_adding(self):
        for _ in range(1000):
            # make sure these are even (within 0..1023, even incremented ones)
            x = random.randint(0, 1021)
            if x % 2 == 1:
                x += 1
            y = random.randint(0, 1021)
            if y % 2 == 1:
                y += 1

            pt = (x, y)
            badpt = (x + 1, y + 1)
            self.qt.add(pt)
            self.assertTrue(pt in self.qt)  # (x,y) is there
            self.assertFalse(badpt in self.qt)  # different indices not present

    def test_iteration(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)
Пример #7
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
Пример #8
0
class QuadTreePointApp:
    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.points:
            for pt in node.points:
                self.canvas.create_rectangle(self.factor * pt[X],
                                             self.toTk(self.factor * pt[Y]),
                                             self.factor * (pt[X] + 1),
                                             self.toTk(self.factor *
                                                       (pt[Y] + 1)),
                                             fill='black')
        for n in node.children:
            self.visit(n)
Пример #9
0
 def reset(self, event):
     """Reset to start state."""
     self.tree = QuadTree(Region(0,0,512,512))
     self.canvas.delete(ALL)
     self.visit(self.tree.root)
Пример #10
0
class QuadTreeInvalidApp:
    
    def __init__(self, master):
        """App for creating Quad tree dynamically with fixed circles that ALMOST ALWAYS detect collisions."""
        
        master.title("Click to add fixed circles for ALMOST detecting collisions.") 
        self.master = master 
        
        # QuadTree holds the events
        self.tree = QuadTree(Region(0,0,512,512))
        
        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
        self.canvas.pack()

    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 circle to QuadTree with random radius."""
        circle = [event.x, self.toCartesian(event.y), Radius, False, False]
        
        # To find all collisions, take advantage of the fact that circles
        # can neither be modified nor deleted, so any new collisions are 
        # solely between the new circle and existing circles in the QuadTree.
        for circ in collide(self.tree.root, circle):
            circ[HIT] = 1
            circle[HIT] = 1
                
        self.tree.add(circle)
        self.canvas.delete(ALL)
        self.visit(self.tree.root)

    def reset(self, event):
        """Reset to start state."""
        self.tree = QuadTree(Region(0,0,512,512))
        self.canvas.delete(ALL)
        self.visit(self.tree.root)

    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(r.x_min, self.toTk(r.y_min), 
                                     r.x_max, self.toTk(r.y_max))
         
        self.canvas.create_line(r.x_min, self.toTk(node.origin[Y]), 
                                r.x_max, self.toTk(node.origin[Y]),
                                dash=(2, 4)) 
        self.canvas.create_line(node.origin[X], self.toTk(r.y_min), 
                                node.origin[X], self.toTk(r.y_max),
                                dash=(2, 4))
        
        if node.points: 
            for circle in node.points:
                markColor = 'black'
                if circle[HIT]: markColor = 'red'
                self.canvas.create_oval(circle[X] - circle[RADIUS], self.toTk(circle[Y]) - circle[RADIUS], 
                                        circle[X] + circle[RADIUS], self.toTk(circle[Y]) + circle[RADIUS], 
                                        fill=markColor)
        
        for n in node.children:
            self.visit(n)