1

I am trying to build a point region quadtree which stores points on a 2D map with Python.

Each point consists of its coordinates (x, z) and a pointer which leads to data of this point in another file.

In the quadtree, each stores only one point, so

  1. when inserting a point to a region which has no children and no point, the point just goes into this region;
  2. When a region has children, we try to insert the point into one of its children.
  3. When inserting a point to region with no children, but is already occupied by a point, this region is subdivided into four equal sub-regions, and the old point is taken out from this region and put into one of the subregions. Then, we try to insert the new point into the children. After we can detete this point from map 2D and display it.

I try to realize an insert function, remove and print but I have not succeeded. Can someone help me with this please? I am a newbee in programming and have been stuck on this for two days. Many thanks in advance!

Alok Mysore
  • 606
  • 3
  • 16
rafael
  • 11
  • 2
  • Could you show us the code you tried so far? – Cristik Apr 19 '15 at 14:36
  • i work with the same code for insertion but it does not work and if insertion not working i can't implement deletion and display [link](http://stackoverflow.com/questions/26660296/maximum-recursion-depth-exceeded-when-inserting-points-into-a-quadtree-using-pyt) – rafael Apr 19 '15 at 14:44
  • The only thing I see in the code you link to is the possibility that the same point can be inserted into more that one child because of the overlapping test for Gordon's "contains" method. But it would be good if you provide your own code. – xxyzzy Apr 19 '15 at 15:37

1 Answers1

0

I also tried to develop this approach, but such things do not work well because I need the leaves prendrend the value (x, y) that determines the position, here the class QuadTree(object):

def __init__(self, items=[], depth=6, boundingRect=None):
    # The sub-quadrants are empty to start with.
    self.nw = self.ne = self.se = self.sw = None

    # If we've reached the maximum depth then insert all items into this
    # quadrant.
    self.depth = depth
    if self.depth == 0:
        self.items = items
        return

    # Find this quadrant's centre.
    if boundingRect:
        l, t, r, b = self.l, self.t, self.r, self.b = boundingRect
    else:
        # If there isn't a bounding rect, then calculate it from the items.
        l = self.l = min(item.rect.left for item in items)
        t = self.t = min(item.rect.top for item in items)
        r = self.r = max(item.rect.right for item in items)
        b = self.b = max(item.rect.bottom for item in items)
    cx = self.cx = (l + r) * 0.5
    cy = self.cy = (t + b) * 0.5

    self.items = []
    if not items:
        return
    nw_items = []
    ne_items = []
    se_items = []
    sw_items = []

    for item in items:
        # Which of the sub-quadrants does the item overlap?
        in_nw = item.rect.left <= cx and item.rect.top <= cy
        in_sw = item.rect.left <= cx and item.rect.bottom >= cy
        in_ne = item.rect.right >= cx and item.rect.top <= cy
        in_se = item.rect.right >= cx and item.rect.bottom >= cy

        # If it overlaps all 4 quadrants then insert it at the current
        # depth, otherwise append it to a list to be inserted under every
        # quadrant that it overlaps.
        if in_nw and in_ne and in_se and in_sw:
            self.items.append(item)
        else:
            if in_nw: nw_items.append(item)
            if in_ne: ne_items.append(item)
            if in_se: se_items.append(item)
            if in_sw: sw_items.append(item)

    # Create the sub-quadrants, recursively.
    if nw_items:
        self.nw = QuadTree(nw_items, self.depth-1, (l, t, cx, cy))
    if ne_items:
        self.ne = QuadTree(ne_items, self.depth-1, (cx, t, r, cy))
    if se_items:
        self.se = QuadTree(se_items, self.depth-1, (cx, cy, r, b))
    if sw_items:
        self.sw = QuadTree(sw_items, self.depth-1, (l, cy, cx, b))

def insert(self, item):
    # If we've reached the maximum depth then insert item in this quadrant.
    if self.depth == 0:
        self.items.append(item)
        return

    in_nw = item.rect.left <= self.cx and item.rect.top <= self.cy
    in_sw = item.rect.left <= self.cx and item.rect.bottom >= self.cy
    in_ne = item.rect.right >= self.cx and item.rect.top <= self.cy
    in_se = item.rect.right >= self.cx and item.rect.bottom >= self.cy

    # If it overlaps all 4 quadrants then insert it at the current
    # depth, otherwise append it to the item list of every quadrant
    # that it overlaps.
    if in_nw and in_ne and in_se and in_sw:
        self.items.append(item)
    else:
        if in_nw:
            if self.nw:
                self.nw.insert(item)
            else:
                self.nw = QuadTree([item], self.depth-1,
                                   (self.l, self.t, self.cx, self.cy))
        if in_ne:
            if self.ne:
                self.ne.insert(item)
            else:
                self.ne = QuadTree([item], self.depth-1,
                                   (self.cx, self.t, self.r, self.cy))
        if in_se:
            if self.se:
                self.se.insert(item)
            else:
                self.se = QuadTree([item], self.depth-1,
                                   (self.cx, self.cy, self.r, self.b))
        if in_sw:
            if self.sw:
                self.sw.insert(item)
            else:
                self.sw = QuadTree([item], self.depth-1,
                                   (self.l, self.cy, self.cx, self.b))

def remove(self, item):
    # If we've reached the maximum depth remove the itam from this quadrant.
    if self.depth == 0:
        self.items.remove(item)
        return

    in_nw = item.rect.left <= self.cx and item.rect.top <= self.cy
    in_sw = item.rect.left <= self.cx and item.rect.bottom >= self.cy
    in_ne = item.rect.right >= self.cx and item.rect.top <= self.cy
    in_se = item.rect.right >= self.cx and item.rect.bottom >= self.cy

    # If it overlaps all 4 quadrants remove it, otherwise
    # search the lower quadrants for it
    if in_nw and in_ne and in_se and in_sw:
        self.items.remove(item)
    else:
        if in_nw and self.nw:
                self.nw.remove(item)
        if in_ne and self.ne:
                self.ne.remove(item)
        if in_se and self.se:
                self.se.remove(item)
        if in_sw and self.sw:
                self.sw.remove(item)

class class Item(object):

    def __init__(self, left, top, right, bottom):
        self.left = left
        self.top = top
        self.right = right
        self.bottom = bottom
rafael
  • 11
  • 2