def _get_tree(paths, closed): """ Add all paths to the tree and create mapping from ids of elements added to the tree to the elements data: Closed paths: [id of path, 1st point of segment, 2nd point of segment] Open paths [id of path, point of segment] """ # TODO: use models aabb? aabb = get_aabb(np.concatenate(paths)) tree = Quadtree([aabb.min[0], aabb.min[1], aabb.max[0], aabb.max[1]]) mapping = {} for path in paths: if closed: for i, j in zip(range(-1, len(path) - 1), range(len(path))): # add whole edge into the tree _add_edge(tree, mapping, path, i, j) else: _add_point(tree, mapping, path, 0) _add_point(tree, mapping, path, -1) tree.prune() return tree, mapping
def __init__(self, definition_file, points): # Open definition file and background image definition = ElementTree.parse(open(definition_file)).getroot() map_file = os.path.join( os.path.split(definition_file)[0], definition.attrib['bg']) self.background = Image.open(map_file) self.north = math.radians(float(definition.attrib['maxlat'])) self.south = math.radians(float(definition.attrib['minlat'])) self.west = math.radians(float(definition.attrib['minlon'])) self.east = math.radians(float(definition.attrib['maxlon'])) # Store ranges color and distance self.ranges = [(float(r.attrib['distance']), (int(r.attrib['red']), int(r.attrib['green']), int(r.attrib['blue']))) for r in definition.getiterator("range")] self.width, self.height = self.background.size self.points = points # Creating top quadtree element self.grid = Quadtree(self.north, self.south, self.west, self.east, 6) for point in points: self.grid.add(point) # Precompute latitude and longitude at each row and column self.pixel_lons = [ self.west + (self.east - self.west) * (float(i) / float(self.width)) for i in range(self.width) ] self.pixel_lats = [ self.north - (self.north - self.south) * (float(j) / float(self.height)) for j in range(self.height) ]
class TwoPhaseModel: def __init__(self, MI, NI, granulometry, matrixLabel): self.MI = MI self.NI = NI self.granulometry = granulometry self.matrixLabel = matrixLabel xv = np.linspace(0, self.MI - 1, self.MI, endpoint=True).astype(np.int32) yv = np.linspace(0, self.NI - 1, self.NI, endpoint=True).astype(np.int32) X, Y = np.int32(np.meshgrid(xv, yv)) self.coords = {(x, y) for x, y in zip(X.ravel(), Y.ravel())} depth = 4 self.qtree = Quadtree(int(depth), Rect(0, 0, int(self.MI), int(self.NI))) (self.XX, self.YY) = np.meshgrid(range(0, self.NI), range(0, self.MI)) def compute(self): Objs = [] Image = np.ones((self.MI, self.NI), np.int32) * self.matrixLabel Image = Image.astype(np.int32) start = time.time() for ix, value in enumerate( zip(self.granulometry.a_reversed, self.granulometry.c_reversed)): print(ix, value[0], value[1]) area_set = 0 while area_set < value[1]: cy, cx = self.coords.pop() #if Image[cy,cx] == self.matrixLabel: if True: b = self.granulometry.getB(value[0]) theta = random.uniform(0, np.pi) c = Ellipse(cy, cx, int(value[0]), int(b), theta) objs = self.qtree.query(c) if len(objs) == 0: self.qtree.insert(c) Objs.append(c) area_set += c.area() #ellipseMatrix(c.y(), c.x(), c.a(), c.b(), c.theta(), Image, int(self.granulometry.Label), self.XX, self.YY) #ellipseDiscard(c.y(), c.x(), c.a(), c.b(), c.theta(), self.XX, self.YY, self.coords, Image, self.granulometry.Label) else: self.coords.add((cy, cx)) print(time.time() - start) return Objs, int(self.granulometry.Label), self.XX, self.YY, Image
def test_quadtree_buildup(points: List[Point]) -> float: tracemalloc.start() starting_mem, _ = tracemalloc.get_traced_memory() tree = Quadtree(points) _, peak = tracemalloc.get_traced_memory() tracemalloc.stop() return peak - starting_mem
def __init__(self, definition_file, points): # Open definition file and background image definition = ElementTree.parse(open(definition_file)).getroot() map_file = os.path.join(os.path.split(definition_file)[0], definition.attrib['bg']) self.background = Image.open(map_file) self.north = math.radians(float(definition.attrib['maxlat'])) self.south = math.radians(float(definition.attrib['minlat'])) self.west = math.radians(float(definition.attrib['minlon'])) self.east = math.radians(float(definition.attrib['maxlon'])) # Store ranges color and distance self.ranges = [(float(r.attrib['distance']), (int(r.attrib['red']), int(r.attrib['green']), int(r.attrib['blue']))) for r in definition.getiterator("range")] self.width, self.height = self.background.size self.points = points # Creating top quadtree element self.grid = Quadtree(self.north, self.south, self.west, self.east, 6) for point in points: self.grid.add(point) # Precompute latitude and longitude at each row and column self.pixel_lons = [self.west + (self.east-self.west)*(float(i)/float(self.width)) for i in range(self.width)] self.pixel_lats = [self.north - (self.north-self.south)*(float(j)/float(self.height)) for j in range(self.height)]
def main(): pygame.init() screen = pygame.display.set_mode((width, height)) map = pygame.Surface((map_width, map_height)) pygame.display.set_caption("quadtree") font = pygame.font.SysFont('arial', 20) clock = pygame.time.Clock() particles = Group([ Particle( random.gauss(map_width / 2, 150) % map_width, random.gauss(map_height / 2, 150) % map_height, 4, map) for _ in range(1000) ]) qtree = Quadtree(map.get_rect(), 4, map) for p in particles: qtree.insert(p) while True: clock.tick(60) fps_text = font.render(f'fps:{int(clock.get_fps())}', True, THECOLORS['white']) fps_rect = fps_text.get_rect() for event in pygame.event.get(): if event.type == pygame.QUIT: exit() qtree = Quadtree(map.get_rect(), 4, map) for p in particles: qtree.insert(p) particles.update() for p in particles: p.highlight = False query_rect = Rect(p.rect.x, p.rect.y, p.radius * 2, p.radius * 2) if len(qtree.query(query_rect)) != 1: p.highlight = True map.fill(THECOLORS['black']) particles.draw(map) pygame.transform.scale(map, (width, height), screen) screen.blit(fps_text, fps_rect) pygame.display.update()
def capgrids_tree(): tree = Quadtree((-180, -90, 180, 90)) keys = {} i = 0 for mapid in range(1, 100): mapid = str(mapid) for letter in 'abcdefghijklmnop': for num in range(1, 10): try: b = box(mapid, letter + str(num)) except IndexError: continue v = "%s/%s" % (mapid, (letter + str(num)).capitalize()) if v not in keys: tree.add(i, b) keys[i] = v i += 1 return keys, tree
def __init__(self, canvas=None): self._matrix = Matrix() self._painter = DefaultPainter(self) self._bounding_box_painter = BoundingBoxPainter(self) # Handling selections. ### TODO: Move this to a context? self._selected_items = set() self._focused_item = None self._hovered_item = None self._dropzone_item = None ###/ self._qtree = Quadtree() self._bounds = Rectangle(0, 0, 0, 0) self._canvas = None if canvas: self._set_canvas(canvas)
def __init__(self, MI, NI, granulometry, matrixLabel): self.MI = MI self.NI = NI self.granulometry = granulometry self.matrixLabel = matrixLabel xv = np.linspace(0, self.MI - 1, self.MI, endpoint=True).astype(np.int32) yv = np.linspace(0, self.NI - 1, self.NI, endpoint=True).astype(np.int32) X, Y = np.int32(np.meshgrid(xv, yv)) self.coords = {(x, y) for x, y in zip(X.ravel(), Y.ravel())} depth = 4 self.qtree = Quadtree(int(depth), Rect(0, 0, int(self.MI), int(self.NI))) (self.XX, self.YY) = np.meshgrid(range(0, self.NI), range(0, self.MI))
def test_quadtree_search(points: List[Point], rectangles: List[Rectangle]) -> List[float]: tree = Quadtree(points) def time_individual(rectangle: Rectangle) -> float: start_time = default_timer() tree.find(rectangle) end_time = default_timer() return end_time - start_time return list(map(time_individual, rectangles))
def update_boids(): tree = Quadtree(b[0], 0, 0, WIDTH, HEIGHT) for i in range(1, len(b)): tree.insert(b[i]) for boid in b: accel = [0, 0] possible_close_boids = tree.findInCircle(boid.pos[0], boid.pos[1], NEIGHBORHOOD_THRESHOLD) if len(possible_close_boids) > 1: accel = boid.compute_acceleration(possible_close_boids, SEPARATION_THRESHOLD, C, A, S) if Quadtree.pointInCircle(tree, boid.pos[0], boid.pos[1], mouse[0], mouse[1], NEIGHBORHOOD_THRESHOLD): accel = list(map(sum, zip(accel, boid.avoid(mouse)))) boid.update(WIDTH, HEIGHT, accel)
def test(): pygame.init() screen = pygame.display.set_mode((W, H), 0) quadtree = Quadtree((0, 0, W, H)) triangles = [] p = (0, 0) while True: new_triangles = False new_point = False update = False events = pygame.event.get() for e in events: if e.type == pygame.QUIT: return elif e.type == pygame.KEYUP and e.key == pygame.K_ESCAPE: return elif e.type == pygame.KEYUP and e.key == pygame.K_SPACE: new_triangles = True elif e.type == pygame.KEYUP and e.key == pygame.K_RETURN: new_point = True elif e.type == pygame.MOUSEBUTTONUP: p = e.pos update = True print p if new_triangles: for i in range(N_triangles): quadtree.remove(i) print "foo" triangles = [] for i in range(N_triangles): triangles.append(get_random_triangle()) quadtree.add(i, triangles[-1]) print triangles[-1] if new_point: p = get_random_point() if new_point or new_triangles or update: screen.fill(BLACK) ids = quadtree.query(p) print ids for i in range(N_triangles): color = GREEN if i in ids else BLUE pygame.draw.lines(screen, color, True, triangles[i]) pygame.draw.line(screen, RED, (p[0]-2, p[1]-2), (p[0]+2, p[1]+2)) pygame.draw.line(screen, RED, (p[0]-2, p[1]+2), (p[0]+2, p[1]-2)) pygame.display.update()
class Map: def __init__(self, definition_file, points): # Open definition file and background image definition = ElementTree.parse(open(definition_file)).getroot() map_file = os.path.join(os.path.split(definition_file)[0], definition.attrib['bg']) self.background = Image.open(map_file) self.north = math.radians(float(definition.attrib['maxlat'])) self.south = math.radians(float(definition.attrib['minlat'])) self.west = math.radians(float(definition.attrib['minlon'])) self.east = math.radians(float(definition.attrib['maxlon'])) # Store ranges color and distance self.ranges = [(float(r.attrib['distance']), (int(r.attrib['red']), int(r.attrib['green']), int(r.attrib['blue']))) for r in definition.getiterator("range")] self.width, self.height = self.background.size self.points = points # Creating top quadtree element self.grid = Quadtree(self.north, self.south, self.west, self.east, 6) for point in points: self.grid.add(point) # Precompute latitude and longitude at each row and column self.pixel_lons = [self.west + (self.east-self.west)*(float(i)/float(self.width)) for i in range(self.width)] self.pixel_lats = [self.north - (self.north-self.south)*(float(j)/float(self.height)) for j in range(self.height)] def generate(self): "Generates the output image" ranges_image = Image.new('RGB', self.background.size) # Create a lists list with the distance from each pixel to its nearest point colors = [[self.color(self.distance(i,j)) for i in range(self.width)] for j in range(self.height)] # Flatten list colors = [item for sublist in colors for item in sublist] ranges_image.putdata(colors) return Image.blend(ranges_image, self.background.convert('RGB'), 0.5) def distance(self, i, j): lon = self.pixel_lons[i] lat = self.pixel_lats[j] point = Point(lat, lon) elements = PriorityQueue() elements.put_nowait((self.grid.distance(point), self.grid)) # We iterate over the priority queue until the nearest element is a point. While it isn't we add its children to the queue. while True: (distance, elem) = elements.get_nowait() #print "Iterating (%d, %d) distance: %f" % (i, j, distance) if isinstance(elem, Point): return distance else: for child in elem.children: elements.put_nowait((child.distance(point), child)) def color(self, distance): "Returns which color represents distance" return [c for (d,c) in self.ranges if d>distance][0]
pt.normal = -pt.position / np.sqrt(np.dot(pt.position, pt.position)) return pc def get_dist_func(pc): def dist(x, y): pt = Point(x, y, 0) neighbors = pc.nearest_neighbors(pt, 50) d = 0 for pt2 in neighbors: diff = pt.position - pt2.position d += np.dot(diff, pt2.normal) return d return dist if __name__ == '__main__': pc = get_circle() dist = get_dist_func(pc) quadtree = Quadtree(pc.points, 4) contour = quadtree.compute_contour(dist) print 'Found %d edges' % len(contour) # quadtree.display() for (pt1, pt2) in contour: x1, y1, _ = pt1.position x2, y2, _ = pt2.position plt.plot([x1, x2], [y1, y2]) # plt.show() quadtree.display()
class Map: def __init__(self, definition_file, points): # Open definition file and background image definition = ElementTree.parse(open(definition_file)).getroot() map_file = os.path.join( os.path.split(definition_file)[0], definition.attrib['bg']) self.background = Image.open(map_file) self.north = math.radians(float(definition.attrib['maxlat'])) self.south = math.radians(float(definition.attrib['minlat'])) self.west = math.radians(float(definition.attrib['minlon'])) self.east = math.radians(float(definition.attrib['maxlon'])) # Store ranges color and distance self.ranges = [(float(r.attrib['distance']), (int(r.attrib['red']), int(r.attrib['green']), int(r.attrib['blue']))) for r in definition.getiterator("range")] self.width, self.height = self.background.size self.points = points # Creating top quadtree element self.grid = Quadtree(self.north, self.south, self.west, self.east, 6) for point in points: self.grid.add(point) # Precompute latitude and longitude at each row and column self.pixel_lons = [ self.west + (self.east - self.west) * (float(i) / float(self.width)) for i in range(self.width) ] self.pixel_lats = [ self.north - (self.north - self.south) * (float(j) / float(self.height)) for j in range(self.height) ] def generate(self): "Generates the output image" ranges_image = Image.new('RGB', self.background.size) # Create a lists list with the distance from each pixel to its nearest point colors = [[self.color(self.distance(i, j)) for i in range(self.width)] for j in range(self.height)] # Flatten list colors = [item for sublist in colors for item in sublist] ranges_image.putdata(colors) return Image.blend(ranges_image, self.background.convert('RGB'), 0.5) def distance(self, i, j): lon = self.pixel_lons[i] lat = self.pixel_lats[j] point = Point(lat, lon) elements = PriorityQueue() elements.put_nowait((self.grid.distance(point), self.grid)) # We iterate over the priority queue until the nearest element is a point. While it isn't we add its children to the queue. while True: (distance, elem) = elements.get_nowait() #print "Iterating (%d, %d) distance: %f" % (i, j, distance) if isinstance(elem, Point): return distance else: for child in elem.children: elements.put_nowait((child.distance(point), child)) def color(self, distance): "Returns which color represents distance" return [c for (d, c) in self.ranges if d > distance][0]
# y = 2*(np.random.random()-0.5) # pc.add_point(x, y, 0) for pt in pc.points: pt.normal = -pt.position / np.sqrt(np.dot(pt.position, pt.position)) return pc def get_dist_func(pc): def dist(x, y): pt = Point(x, y, 0) neighbors = pc.nearest_neighbors(pt, 50) d = 0 for pt2 in neighbors: diff = pt.position - pt2.position d += np.dot(diff, pt2.normal) return d return dist if __name__ == '__main__': pc = get_circle() dist = get_dist_func(pc) quadtree = Quadtree(pc.points, 4) contour = quadtree.compute_contour(dist) print 'Found %d edges' % len(contour) # quadtree.display() for (pt1, pt2) in contour: x1, y1, _ = pt1.position x2, y2, _ = pt2.position plt.plot([x1, x2], [y1, y2]) # plt.show() quadtree.display()
class View(object): """ View class for gaphas.Canvas objects. """ def __init__(self, canvas=None): self._matrix = Matrix() self._painter = DefaultPainter(self) self._bounding_box_painter = BoundingBoxPainter(self) # Handling selections. ### TODO: Move this to a context? self._selected_items = set() self._focused_item = None self._hovered_item = None self._dropzone_item = None ###/ self._qtree = Quadtree() self._bounds = Rectangle(0, 0, 0, 0) self._canvas = None if canvas: self._set_canvas(canvas) matrix = property(lambda s: s._matrix, doc="Canvas to view transformation matrix") def _set_canvas(self, canvas): """ Use view.canvas = my_canvas to set the canvas to be rendered in the view. """ if self._canvas: self._qtree.clear() self._selected_items.clear() self._focused_item = None self._hovered_item = None self._dropzone_item = None self._canvas = canvas canvas = property(lambda s: s._canvas, _set_canvas) def emit(self, *args, **kwargs): """ Placeholder method for signal emission functionality. """ pass def queue_draw_item(self, *items): """ Placeholder for item redraw queueing. """ pass def select_item(self, item): """ Select an item. This adds @item to the set of selected items. """ self.queue_draw_item(item) if item not in self._selected_items: self._selected_items.add(item) self.emit('selection-changed', self._selected_items) def unselect_item(self, item): """ Unselect an item. """ self.queue_draw_item(item) if item in self._selected_items: self._selected_items.discard(item) self.emit('selection-changed', self._selected_items) def select_all(self): for item in self.canvas.get_all_items(): self.select_item(item) def unselect_all(self): """ Clearing the selected_item also clears the focused_item. """ self.queue_draw_item(*self._selected_items) self._selected_items.clear() self.focused_item = None self.emit('selection-changed', self._selected_items) selected_items = property(lambda s: s._selected_items, select_item, unselect_all, "Items selected by the view") def _set_focused_item(self, item): """ Set the focused item, this item is also added to the selected_items set. """ if not item is self._focused_item: self.queue_draw_item(self._focused_item, item) if item: self.select_item(item) if item is not self._focused_item: self._focused_item = item self.emit('focus-changed', item) def _del_focused_item(self): """ Items that loose focus remain selected. """ self._set_focused_item(None) focused_item = property(lambda s: s._focused_item, _set_focused_item, _del_focused_item, "The item with focus (receives key events a.o.)") def _set_hovered_item(self, item): """ Set the hovered item. """ if item is not self._hovered_item: self.queue_draw_item(self._hovered_item, item) self._hovered_item = item self.emit('hover-changed', item) def _del_hovered_item(self): """ Unset the hovered item. """ self._set_hovered_item(None) hovered_item = property(lambda s: s._hovered_item, _set_hovered_item, _del_hovered_item, "The item directly under the mouse pointer") def _set_dropzone_item(self, item): """ Set dropzone item. """ if item is not self._dropzone_item: self.queue_draw_item(self._dropzone_item, item) self._dropzone_item = item self.emit('dropzone-changed', item) def _del_dropzone_item(self): """ Unset dropzone item. """ self._set_dropzone_item(None) dropzone_item = property(lambda s: s._dropzone_item, _set_dropzone_item, _del_dropzone_item, 'The item which can group other items') def _set_painter(self, painter): """ Set the painter to use. Painters should implement painter.Painter. """ self._painter = painter painter.set_view(self) self.emit('painter-changed') painter = property(lambda s: s._painter, _set_painter) def _set_bounding_box_painter(self, painter): """ Set the painter to use for bounding box calculations. """ self._bounding_box_painter = painter painter.set_view(self) self.emit('painter-changed') bounding_box_painter = property(lambda s: s._bounding_box_painter, _set_bounding_box_painter) def get_item_at_point(self, pos, selected=True): """ Return the topmost item located at ``pos`` (x, y). Parameters: - selected: if False returns first non-selected item """ items = self._qtree.find_intersect((pos[0], pos[1], 1, 1)) for item in self._canvas.sort(items, reverse=True): if not selected and item in self.selected_items: continue # skip selected items v2i = self.get_matrix_v2i(item) ix, iy = v2i.transform_point(*pos) if item.point((ix, iy)) < 0.5: return item return None def get_handle_at_point(self, pos, distance=6): """ Look for a handle at ``pos`` and return the tuple (item, handle). """ def find(item): """ Find item's handle at pos """ v2i = self.get_matrix_v2i(item) d = v2i.transform_distance(distance, 0)[0] x, y = v2i.transform_point(*pos) for h in item.handles(): if not h.movable: continue hx, hy = h.pos if -d < (hx - x) < d and -d < (hy - y) < d: return h # The focused item is the prefered item for handle grabbing if self.focused_item: h = find(self.focused_item) if h: return self.focused_item, h # then try hovered item if self.hovered_item: h = find(self.hovered_item) if h: return self.hovered_item, h # Last try all items, checking the bounding box first x, y = pos items = self.get_items_in_rectangle((x - distance, y - distance, distance * 2, distance * 2), reverse=True) found_item, found_h = None, None for item in items: h = find(item) if h: return item, h return None, None def get_port_at_point(self, vpos, distance=10, exclude=None): """ Find item with port closest to specified position. List of items to be ignored can be specified with `exclude` parameter. Tuple is returned - found item - closest, connectable port - closest point on found port (in view coordinates) :Parameters: vpos Position specified in view coordinates. distance Max distance from point to a port (default 10) exclude Set of items to ignore. """ v2i = self.get_matrix_v2i vx, vy = vpos max_dist = distance port = None glue_pos = None item = None rect = (vx - distance, vy - distance, distance * 2, distance * 2) items = self.get_items_in_rectangle(rect, reverse=True) for i in items: if i in exclude: continue for p in i.ports(): if not p.connectable: continue ix, iy = v2i(i).transform_point(vx, vy) pg, d = p.glue((ix, iy)) if d >= max_dist: continue item = i port = p # transform coordinates from connectable item space to view # space i2v = self.get_matrix_i2v(i).transform_point glue_pos = i2v(*pg) return item, port, glue_pos def get_items_in_rectangle(self, rect, intersect=True, reverse=False): """ Return the items in the rectangle 'rect'. Items are automatically sorted in canvas' processing order. """ if intersect: items = self._qtree.find_intersect(rect) else: items = self._qtree.find_inside(rect) return self._canvas.sort(items, reverse=reverse) def select_in_rectangle(self, rect): """ Select all items who have their bounding box within the rectangle @rect. """ items = self._qtree.find_inside(rect) map(self.select_item, items) def zoom(self, factor): """ Zoom in/out by factor @factor. """ # TODO: should the scale factor be clipped? self._matrix.scale(factor, factor) # Make sure everything's updated #map(self.update_matrix, self._canvas.get_all_items()) self.request_update((), self._canvas.get_all_items()) def set_item_bounding_box(self, item, bounds): """ Update the bounding box of the item. ``bounds`` is in view coordinates. Coordinates are calculated back to item coordinates, so matrix-only updates can occur. """ v2i = self.get_matrix_v2i(item).transform_point ix0, iy0 = v2i(bounds.x, bounds.y) ix1, iy1 = v2i(bounds.x1, bounds.y1) self._qtree.add(item=item, bounds=bounds, data=Rectangle(ix0, iy0, x1=ix1, y1=iy1)) def get_item_bounding_box(self, item): """ Get the bounding box for the item, in view coordinates. """ return self._qtree.get_bounds(item) bounding_box = property(lambda s: s._bounds) def update_bounding_box(self, cr, items=None): """ Update the bounding boxes of the canvas items for this view, in canvas coordinates. """ painter = self._bounding_box_painter if items is None: items = self.canvas.get_all_items() # The painter calls set_item_bounding_box() for each rendered item. painter.paint(Context(cairo=cr, items=items, area=None)) # Update the view's bounding box with the rest of the items self._bounds = Rectangle(*self._qtree.soft_bounds) def paint(self, cr): self._painter.paint(Context(cairo=cr, items=self.canvas.get_all_items(), area=None)) def get_matrix_i2v(self, item): """ Get Item to View matrix for ``item``. """ if self not in item._matrix_i2v: self.update_matrix(item) return item._matrix_i2v[self] def get_matrix_v2i(self, item): """ Get View to Item matrix for ``item``. """ if self not in item._matrix_v2i: self.update_matrix(item) return item._matrix_v2i[self] def update_matrix(self, item): """ Update item matrices related to view. """ try: i2v = item._matrix_i2c.multiply(self._matrix) except AttributeError: # Fall back to old behaviour i2v = item._matrix_i2c * self._matrix item._matrix_i2v[self] = i2v v2i = Matrix(*i2v) v2i.invert() item._matrix_v2i[self] = v2i def _clear_matrices(self): """ Clear registered data in Item's _matrix{i2c|v2i} attributes. """ for item in self.canvas.get_all_items(): try: del item._matrix_i2v[self] del item._matrix_v2i[self] except KeyError: pass
from quadtree import Quadtree import numpy as np import time np.random.seed(5) p = Quadtree(0, 0, 100, 100, 5) N = 5000000 data = 100 * np.random.random(size=(N, 2)) data = data.astype(np.float32) start = time.time() p.insert(data) print(time.time() - start) start = time.time() r = .1 d = p.select_from(data, r) print(time.time() - start) print(d[0]) print()
def main(): parser = argparse.ArgumentParser() parser.add_argument('-d', type=int, action='store', dest='data_num', help='choose which data set to use') if len(sys.argv) != 3: print 'Command e.g.: python findNearPlace.py -d 0(1,2)' sys.exit(1) para = parser.parse_args() if para.data_num == 0: location_infile = settings["ROOT_PATH"] + settings["SRC_DATA_FILE1_1"] nearplace_outfile = settings["ROOT_PATH"] + settings["NEAR_PLACE_FILE1"] elif para.data_num == 1: location_infile = settings["ROOT_PATH"] + settings["SRC_DATA_FILE2_1"] nearplace_outfile = settings["ROOT_PATH"] + settings["NEAR_PLACE_FILE2"] elif para.data_num == 2: location_infile = settings["ROOT_PATH"] + settings["SRC_DATA_FILE3_3"] nearplace_outfile = settings["ROOT_PATH"] + settings["NEAR_PLACE_FILE3"] else: print 'Invalid choice of data set' sys.exit(1) loc_latlng = {} try: for entry in csv.reader(open(location_infile, 'rU')): pid, lat, lng = int(entry[0]), float(entry[2]), float(entry[3]) loc_latlng[pid] = (lat, lng) except: print entry sys.exit(1) # directly scanning all POIs to get answer, which is too slow '''writer = csv.writer(open(nearplace_outfile, "w"), lineterminator="\r\n") pids = loc_latlng.keys() for i in xrange(len(pids)): pid1 = pids[i] near_place = [] for j in xrange(len(pids)): pid2 = pids[j] dis = distance.distance(loc_latlng[pid1], loc_latlng[pid2]).miles if dis < settings["DISTANCE_THRESHOLD"]: near_place.append(pid2) writer.writerow([pid1] + near_place) print i''' # quad tree index_extent = (-90, -180, 90, 180) index = Quadtree(index_extent) for pid in loc_latlng: index.add(pid, loc_latlng[pid]) for pid in loc_latlng: start_time = time.clock() pid_set = findNearPlaceByQuadtree(loc_latlng, loc_latlng[pid], index.struct(), settings["DISTANCE_THRESHOLD"]) end_time = time.clock() print "Time Cost: %f(s)" % (end_time-start_time) raw_input() print len(pid_set) raw_input()
gmaxx = GALAXY_WIDTH gmaxy = GALAXY_HEIGHT testimage = Image.new('RGBA', (int(gmaxx), int(gmaxy))) nebulae = Image.new('RGB', (int(gmaxx), int(gmaxy))) draw = ImageDraw.Draw(testimage) draw2 = ImageDraw.Draw(nebulae) povfile = open("stars.pov", "w") squares = {} numstars = 0 totalstars = 0 sectors = {} planets = [] nplanets = [] tree = Quadtree((gminx, gminy, gmaxx, gmaxy), maxdepth=16) ntree = Quadtree((gminx, gminy, gmaxx, gmaxy), maxdepth=16) def is_nan2(num): return str(num) == "nan" def setsize(color): basesize = .05 sizemods = {'blue': 2.0, 'red': .7, 'yellow': 1.0, 'orange': 4, 'green': 4} size = basesize * sizemods[color] if color == 'red' and random.random() < .011: # red giant star size *= random.randint(4, 5)
class View(object): """ View class for gaphas.Canvas objects. """ def __init__(self, canvas=None): self._matrix = Matrix() self._painter = DefaultPainter(self) self._bounding_box_painter = BoundingBoxPainter(self) # Handling selections. ### TODO: Move this to a context? self._selected_items = set() self._focused_item = None self._hovered_item = None self._dropzone_item = None ###/ self._qtree = Quadtree() self._bounds = Rectangle(0, 0, 0, 0) self._canvas = None if canvas: self._set_canvas(canvas) matrix = property(lambda s: s._matrix, doc="Canvas to view transformation matrix") def _set_canvas(self, canvas): """ Use view.canvas = my_canvas to set the canvas to be rendered in the view. """ if self._canvas: self._qtree.clear() self._selected_items.clear() self._focused_item = None self._hovered_item = None self._dropzone_item = None self._canvas = canvas canvas = property(lambda s: s._canvas, _set_canvas) def emit(self, *args, **kwargs): """ Placeholder method for signal emission functionality. """ pass def queue_draw_item(self, *items): """ Placeholder for item redraw queueing. """ pass def select_item(self, item): """ Select an item. This adds @item to the set of selected items. """ self.queue_draw_item(item) if item not in self._selected_items: self._selected_items.add(item) self.emit('selection-changed', self._selected_items) def unselect_item(self, item): """ Unselect an item. """ self.queue_draw_item(item) if item in self._selected_items: self._selected_items.discard(item) self.emit('selection-changed', self._selected_items) def select_all(self): for item in self.canvas.get_all_items(): self.select_item(item) def unselect_all(self): """ Clearing the selected_item also clears the focused_item. """ self.queue_draw_item(*self._selected_items) self._selected_items.clear() self.focused_item = None self.emit('selection-changed', self._selected_items) selected_items = property(lambda s: s._selected_items, select_item, unselect_all, "Items selected by the view") def _set_focused_item(self, item): """ Set the focused item, this item is also added to the selected_items set. """ if not item is self._focused_item: self.queue_draw_item(self._focused_item, item) if item: self.select_item(item) if item is not self._focused_item: self._focused_item = item self.emit('focus-changed', item) def _del_focused_item(self): """ Items that loose focus remain selected. """ self._set_focused_item(None) focused_item = property(lambda s: s._focused_item, _set_focused_item, _del_focused_item, "The item with focus (receives key events a.o.)") def _set_hovered_item(self, item): """ Set the hovered item. """ if item is not self._hovered_item: self.queue_draw_item(self._hovered_item, item) self._hovered_item = item self.emit('hover-changed', item) def _del_hovered_item(self): """ Unset the hovered item. """ self._set_hovered_item(None) hovered_item = property(lambda s: s._hovered_item, _set_hovered_item, _del_hovered_item, "The item directly under the mouse pointer") def _set_dropzone_item(self, item): """ Set dropzone item. """ if item is not self._dropzone_item: self.queue_draw_item(self._dropzone_item, item) self._dropzone_item = item self.emit('dropzone-changed', item) def _del_dropzone_item(self): """ Unset dropzone item. """ self._set_dropzone_item(None) dropzone_item = property(lambda s: s._dropzone_item, _set_dropzone_item, _del_dropzone_item, 'The item which can group other items') def _set_painter(self, painter): """ Set the painter to use. Painters should implement painter.Painter. """ self._painter = painter painter.set_view(self) self.emit('painter-changed') painter = property(lambda s: s._painter, _set_painter) def _set_bounding_box_painter(self, painter): """ Set the painter to use for bounding box calculations. """ self._bounding_box_painter = painter painter.set_view(self) self.emit('painter-changed') bounding_box_painter = property(lambda s: s._bounding_box_painter, _set_bounding_box_painter) def get_item_at_point(self, pos, selected=True): """ Return the topmost item located at ``pos`` (x, y). Parameters: - selected: if False returns first non-selected item """ items = self._qtree.find_intersect((pos[0], pos[1], 1, 1)) for item in self._canvas.sort(items, reverse=True): if not selected and item in self.selected_items: continue # skip selected items v2i = self.get_matrix_v2i(item) ix, iy = v2i.transform_point(*pos) if item.point((ix, iy)) < 0.5: return item return None def get_handle_at_point(self, pos, distance=6): """ Look for a handle at ``pos`` and return the tuple (item, handle). """ def find(item): """ Find item's handle at pos """ v2i = self.get_matrix_v2i(item) d = v2i.transform_distance(distance, 0)[0] x, y = v2i.transform_point(*pos) for h in item.handles(): if not h.movable: continue hx, hy = h.pos if -d < (hx - x) < d and -d < (hy - y) < d: return h # The focused item is the prefered item for handle grabbing if self.focused_item: h = find(self.focused_item) if h: return self.focused_item, h # then try hovered item if self.hovered_item: h = find(self.hovered_item) if h: return self.hovered_item, h # Last try all items, checking the bounding box first x, y = pos items = self.get_items_in_rectangle( (x - distance, y - distance, distance * 2, distance * 2), reverse=True) found_item, found_h = None, None for item in items: h = find(item) if h: return item, h return None, None def get_port_at_point(self, vpos, distance=10, exclude=None): """ Find item with port closest to specified position. List of items to be ignored can be specified with `exclude` parameter. Tuple is returned - found item - closest, connectable port - closest point on found port (in view coordinates) :Parameters: vpos Position specified in view coordinates. distance Max distance from point to a port (default 10) exclude Set of items to ignore. """ v2i = self.get_matrix_v2i vx, vy = vpos max_dist = distance port = None glue_pos = None item = None rect = (vx - distance, vy - distance, distance * 2, distance * 2) items = self.get_items_in_rectangle(rect, reverse=True) for i in items: if i in exclude: continue for p in i.ports(): if not p.connectable: continue ix, iy = v2i(i).transform_point(vx, vy) pg, d = p.glue((ix, iy)) if d >= max_dist: continue item = i port = p # transform coordinates from connectable item space to view # space i2v = self.get_matrix_i2v(i).transform_point glue_pos = i2v(*pg) return item, port, glue_pos def get_items_in_rectangle(self, rect, intersect=True, reverse=False): """ Return the items in the rectangle 'rect'. Items are automatically sorted in canvas' processing order. """ if intersect: items = self._qtree.find_intersect(rect) else: items = self._qtree.find_inside(rect) return self._canvas.sort(items, reverse=reverse) def select_in_rectangle(self, rect): """ Select all items who have their bounding box within the rectangle @rect. """ items = self._qtree.find_inside(rect) map(self.select_item, items) def zoom(self, factor): """ Zoom in/out by factor @factor. """ # TODO: should the scale factor be clipped? self._matrix.scale(factor, factor) # Make sure everything's updated #map(self.update_matrix, self._canvas.get_all_items()) self.request_update((), self._canvas.get_all_items()) def set_item_bounding_box(self, item, bounds): """ Update the bounding box of the item. ``bounds`` is in view coordinates. Coordinates are calculated back to item coordinates, so matrix-only updates can occur. """ v2i = self.get_matrix_v2i(item).transform_point ix0, iy0 = v2i(bounds.x, bounds.y) ix1, iy1 = v2i(bounds.x1, bounds.y1) self._qtree.add(item=item, bounds=bounds, data=Rectangle(ix0, iy0, x1=ix1, y1=iy1)) def get_item_bounding_box(self, item): """ Get the bounding box for the item, in view coordinates. """ return self._qtree.get_bounds(item) bounding_box = property(lambda s: s._bounds) def update_bounding_box(self, cr, items=None): """ Update the bounding boxes of the canvas items for this view, in canvas coordinates. """ painter = self._bounding_box_painter if items is None: items = self.canvas.get_all_items() # The painter calls set_item_bounding_box() for each rendered item. painter.paint(Context(cairo=cr, items=items, area=None)) # Update the view's bounding box with the rest of the items self._bounds = Rectangle(*self._qtree.soft_bounds) def paint(self, cr): self._painter.paint( Context(cairo=cr, items=self.canvas.get_all_items(), area=None)) def get_matrix_i2v(self, item): """ Get Item to View matrix for ``item``. """ if self not in item._matrix_i2v: self.update_matrix(item) return item._matrix_i2v[self] def get_matrix_v2i(self, item): """ Get View to Item matrix for ``item``. """ if self not in item._matrix_v2i: self.update_matrix(item) return item._matrix_v2i[self] def update_matrix(self, item): """ Update item matrices related to view. """ try: i2v = item._matrix_i2c.multiply(self._matrix) except AttributeError: # Fall back to old behaviour i2v = item._matrix_i2c * self._matrix item._matrix_i2v[self] = i2v v2i = Matrix(*i2v) v2i.invert() item._matrix_v2i[self] = v2i def _clear_matrices(self): """ Clear registered data in Item's _matrix{i2c|v2i} attributes. """ for item in self.canvas.get_all_items(): try: del item._matrix_i2v[self] del item._matrix_v2i[self] except KeyError: pass
dimensions = {'xmin': 0.0, 'xmax': 8.0, 'ymin': 0.0, 'ymax': 8.0} resolution = 1.0/32.0 data = sample_data(doubletorus_f, resolution, dimensions) print "done" print "dual contouring..." [dc_verts, dc_edges] = dual_contour(data, resolution, dimensions) print "done." #non_manifold_verts = detectManifolds2d(dc_edges) print "transforming into objects..." vertex_set, edge_set = transform_into_object_sets(dc_verts, dc_edges) print "done." print "building quadtree..." qt = Quadtree(8.0, np.array([0,0])) qt.add_dataset(vertex_set) print "quadtree of depth "+str(qt.get_depth())+" constructed." print "done." print "plotting..." import matplotlib.pyplot as plt #fig = plt.figure() #plot_qt(qt) #plot_vertices(vertex_set) #plot_edges(edge_set) #plot_non_manifold_vertices(dc_verts, non_manifold_verts) plot_qt(qt, 'b--')
from quadtree import Quadtree, RGB from PIL import Image def is_valid_read_file(parser, arg): if not os.path.exists(arg): parser.error("The file %s does not exist!" % arg) else: return arg parser = argparse.ArgumentParser() parser.add_argument('image', help='image file', type=lambda x: is_valid_read_file(parser, x)) parser.add_argument('operation', help='operation to do on image', type=str) args = parser.parse_args() img_raw = Image.open(args.image) img_rgb = img_raw.convert('RGB') width, height = img_rgb.size shape = (height, width) colors = np.empty(shape, dtype=RGB) pixels = img_rgb.load() for h in range(height): for w in range(width): colors[h][w] = RGB(pixels[w, h]) qtree = Quadtree(colors) modified = qtree.outline()
def test_quadtree_buildup(points: List[Point]) -> float: start_time = default_timer() _ = Quadtree(points) end_time = default_timer() return end_time - start_time
nargs='?', default=10) p.add_argument("-p", "--maxpoints", help="the maximum number of points in each area (required)", type=int, required=True) p.add_argument("-u", "--upper", help="upper left point (required)", type=float, nargs=2, metavar=('X', 'Y'), required=True) p.add_argument("-l", "--lower", help="loewr right point (required)", type=float, nargs=2, metavar=('X', 'Y'), required=True) args = p.parse_args() X = read_data(args.infile) qtree = Quadtree(args.upper[0], args.upper[1], args.lower[0], args.lower[1], args.maxpoints, args.maxdepth) qtree.fit(X) pickle.dump(qtree, args.outfile)
import numpy as np import matplotlib.pyplot as plt from quadtree import Point, Rectangle, Quadtree DPI = 72 np.random.seed(60) width, height = 600, 400 N = 500 coords = np.random.randn(N, 2) * height / 3 + (width / 2, height / 2) points = [Point(*coord) for coord in coords] print(len(points)) center = Point(width / 2, height / 2) domain = Rectangle(center, height, width) qtree = Quadtree(domain, 3) for point in points: qtree.insert(point) print('Number of points in the domain =', len(qtree)) # it might not be adding all the points for some reason fig = plt.figure(figsize=(700 / DPI, 500 / DPI), dpi=DPI) ax = plt.subplot() ax.set_xlim(0, width) ax.set_ylim(0, height) qtree.draw(ax) ax.scatter([p.x for p in points], [p.y for p in points], s=4) ax.set_xticks([]) ax.set_yticks([])
import numpy as np from quadtree import Quadtree def read_data(f): data = [] for line in f: entries = line.rstrip().split(' ') lat = float(entries[0]) lng = float(entries[1]) data.append((lat,lng)) return np.array(data) p = argparse.ArgumentParser() p.add_argument("-i", "--infile", help="input file (default=STDIN)", type=argparse.FileType('r'), nargs='?', default=sys.stdin) p.add_argument("-o", "--outfile", help="output file (default=STDOUT)", type=argparse.FileType('w'), nargs='?', default=sys.stdout) p.add_argument("-d", "--maxdepth", help="the maximum number of quadtree depth (default=10)", type=int, nargs='?', default=10) p.add_argument("-p", "--maxpoints", help="the maximum number of points in each area (required)", type=int, required=True) p.add_argument("-u", "--upper", help="upper left point (required)", type=float, nargs=2, metavar=('X','Y'), required=True) p.add_argument("-l", "--lower", help="loewr right point (required)", type=float, nargs=2, metavar=('X', 'Y'), required=True) args = p.parse_args() X = read_data(args.infile) qtree = Quadtree(args.upper[0],args.upper[1],args.lower[0],args.lower[1],args.maxpoints,args.maxdepth) X_trans = qtree.fit_transform(X) print '"area ID","upper left x","upper left y","lower right x","lower right y"' for i in range(len(X_trans)): a = qtree.leaves_[X_trans[i]] print >>args.outfile, "%s,%s,%s,%s,%s" % (a.aid,a.x1,a.y1,a.x2,a.y2)