def setup(self): boundary = RectangleRange(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2, WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2) self.qt = QuadTree(boundary) for i in range(2000): px = random.randint(5, WINDOW_WIDTH - 5) py = random.randint(50, WINDOW_HEIGHT - 5) v = Vehicle(Vector2(px, py), Vector2(0, 0)) p = QuadTreePoint(px, py, v) self.qt.insert(p) self.r1 = RectangleRange(WINDOW_WIDTH // 2 - 100, WINDOW_HEIGHT // 2 + 100, 200, 100) self.r2 = CircleRange(WINDOW_WIDTH // 2 + 220, WINDOW_HEIGHT // 2 - 100, 90) self.r1dx = 1 self.r1dy = 2 self.r2dx = 2 self.r2dy = 1 print(self.qt)
class Driver(object): def __init__(self,width,height): self.width = width self.height = height self.rockSpeeds = np.arange(1,15,1) self.numRocks = 5 self.q = QuadTree(BoundingBox(Point(0,0),Point(self.width,self.height)),1) self.rockSize = 5 self.win = GraphWin("Testing", self.width, self.height, autoflush=False) self.rocks = [] self.boxes = [] xWalls = [0,self.width] yWalls = [0,self.height] self.win.addItem(Rectangle(Point(5,5),Point(self.width,self.height))) self.win.redraw() for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0+self.rockSize,int(self.width)-self.rockSize) startY = random.randint(0+self.rockSize,int(self.height)-self.rockSize) speed = random.choice(self.rockSpeeds) #r = Rock(Point(click.getX(),click.getY()),self.rockSize) r = Rock(Point(startX,startY),self.rockSize) #r.movementVector.Destination(random.randint(self.width/2,self.width),random.randint(0,360)) self.rocks.append(r) r.drawRock(self.win) self.q.insert(r) # self.drawBoxes() while True: #self.win.delAll() self.moveRocks() self.drawRocks() time.sleep(.5) print "hello" #self.win.getMouse() # Pause to view result self.win.close() # Close window when done def drawBoxes(self): boxes = self.q.getBBoxes() for box in boxes: box = Rectangle(box.ul,box.lr) box.draw(self.win) def drawRocks(self): for r in self.rocks: r.drawRock(self.win) def moveRocks(self): for r in self.rocks: r.moveRock(self.win,self.width,self.height)
def subdivide(self): #print "self:",self.bbox l = self.bbox.ul.x r = self.bbox.lr.x t = self.bbox.ul.y b = self.bbox.lr.y mX = (l+r) / 2 mY = (t+b) / 2 self.northEast = QuadTree(BoundingBox(Point(mX,t),Point(r,mY)),self.maxPoints) self.southEast = QuadTree(BoundingBox(Point(mX,mY),Point(r,b)),self.maxPoints) self.southWest = QuadTree(BoundingBox(Point(l,mY),Point(mX,b)),self.maxPoints) self.northWest = QuadTree(BoundingBox(Point(l,t),Point(mX,mY)),self.maxPoints)
def __init__(self, width, height): self.width = width self.height = height self.rockSpeeds = np.arange(1, 15, 1) self.numRocks = 5 self.q = QuadTree( BoundingBox(Point(0, 0), Point(self.width, self.height)), 1) self.rockSize = 5 self.win = GraphWin("Testing", self.width, self.height, autoflush=False) self.rocks = [] self.boxes = [] xWalls = [0, self.width] yWalls = [0, self.height] self.win.addItem(Rectangle(Point(5, 5), Point(self.width, self.height))) self.win.redraw() for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0 + self.rockSize, int(self.width) - self.rockSize) startY = random.randint(0 + self.rockSize, int(self.height) - self.rockSize) speed = random.choice(self.rockSpeeds) #r = Rock(Point(click.getX(),click.getY()),self.rockSize) r = Rock(Point(startX, startY), self.rockSize) #r.movementVector.Destination(random.randint(self.width/2,self.width),random.randint(0,360)) self.rocks.append(r) r.drawRock(self.win) self.q.insert(r) # self.drawBoxes() while True: #self.win.delAll() self.moveRocks() self.drawRocks() time.sleep(.5) print "hello" #self.win.getMouse() # Pause to view result self.win.close() # Close window when done
def __init__(self, positionComponents, velocityComponents, accelerationComponents, geometryComponents, collsionComponents, viewSize, dt): Observer.__init__(self) Publisher.__init__(self) self.positionComponents = positionComponents self.velocityComponents = velocityComponents self.accelerationComponents = accelerationComponents self.geometryComponents = geometryComponents self.collsionComponents = collsionComponents self.dt = dt self.interestingCollisions = ["Box", "Box"] self.__qTree = QuadTree(Rect(0, 0, viewSize[0], viewSize[1]))
def __init__(self,width,height): self.width = width self.height = height self.rockSpeeds = np.arange(1,15,1) self.numRocks = 25 self.q = QuadTree(BoundingBox(Point(0,0),Point(self.width,self.height)),1) self.rockSize = 5 self.win = GraphWin("MoveRocks", self.width, self.height) self.boxes = [] self.rocks = [] xWalls = [0,self.width] yWalls = [0,self.height] for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0+self.rockSize,int(self.width)-self.rockSize) startY = random.randint(0+self.rockSize,int(self.height)-self.rockSize) speed = random.choice(self.rockSpeeds) self.rocks.append(Rock(Point(startX,startY),self.rockSize)) self.win.flush() self.drawRocks() for i in range(1000): #time.sleep(.01) self.moveRocks() self.win.promptClose(self.win.getWidth()/2, 20)
def main(X): #------------------------------------------------------------ # Create a set of structured random points in two dimensions np.random.seed(0) # X is a 2 * 30 array. # X = np.random.random((30, 2)) * 2 - 1 print("X: ", X) X[:, 1] *= 0.1 X[:, 1] += X[:, 0] ** 2 #------------------------------------------------------------ # Use our Quad Tree class to recursively divide the space mins = (-1.1, -0.1) maxs = (1.1, 1.1) #mins = (0,0) #maxs = (570,240) QT = QuadTree(X, mins, maxs, depth=3) #------------------------------------------------------------ # Plot four different levels of the quad tree fig = plt.figure(figsize=(5, 5)) fig.subplots_adjust(wspace=0.1, hspace=0.15, left=0.1, right=0.9, bottom=0.05, top=0.9) for level in range(1, 5): ax = fig.add_subplot(2, 2, level, xticks=[], yticks=[]) ax.scatter(X[:, 0], X[:, 1]) QT.draw_rectangle(ax, depth=level - 1) Nlines = 1 + 2 ** (level - 1) draw_grid(ax, (mins[0], maxs[0]), (mins[1], maxs[1]), Nlines, Nlines, linewidth=1, color='#CCCCCC', zorder=0) ax.set_xlim(-1.2, 1.2) ax.set_ylim(-0.15, 1.15) ax.set_title('level %i' % level) # suptitle() adds a title to the entire figure fig.suptitle('Quad-tree Example') plt.show()
def __init__(self): config_parser = ConfigParser() config_parser.read('config.cfg') data_set = config_parser.get('system-config', 'data_set') data_set_abs_path = join(abspath(dirname(__file__)), data_set) lars_path = config_parser.get('system-config', 'lars') self.db = database.connect() from QuadTree import QuadTree self.quad_tree = QuadTree.import_tree(join(data_set_abs_path, abspath(lars_path)))
def __init__(self, dimensions, obstacles=[], precision=4, tilesize=[64, 64]): self.precision = precision self.tilesize = tilesize self.split_tilesize = [tilesize[0] / precision, tilesize[1] / precision] self.width = dimensions[0] self.height = dimensions[1] self.grid = [[1 for x in range(self.width * precision)] for y in range(self.height * precision)] self.quadtree = QuadTree(Rect(0, 0, tilesize[0] * self.width, tilesize[1] * self.height), 0, 5, 10, obstacles) self.obstacles = obstacles
def __init__(self, dimensions, obstacles=[], precision=4, tilesize=[64, 64]): self.precision = precision self.tilesize = tilesize self.split_tilesize = [ tilesize[0] / precision, tilesize[1] / precision ] self.width = dimensions[0] self.height = dimensions[1] self.grid = [[1 for x in range(self.width * precision)] for y in range(self.height * precision)] self.quadtree = QuadTree( Rect(0, 0, tilesize[0] * self.width, tilesize[1] * self.height), 0, 5, 10, obstacles) self.obstacles = obstacles
class Driver(object): def __init__(self, width, height): self.width = width self.height = height self.rockSpeeds = np.arange(1, 15, 1) self.numRocks = 25 self.q = QuadTree( BoundingBox(Point(0, 0), Point(self.width, self.height)), 1) self.rockSize = 5 self.win = GraphWin("MoveRocks", self.width, self.height) self.boxes = [] self.rocks = [] xWalls = [0, self.width] yWalls = [0, self.height] for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0 + self.rockSize, int(self.width) - self.rockSize) startY = random.randint(0 + self.rockSize, int(self.height) - self.rockSize) speed = random.choice(self.rockSpeeds) self.rocks.append(Rock(Point(startX, startY), self.rockSize)) self.win.flush() self.drawRocks() for i in range(1000): #time.sleep(.01) self.moveRocks() self.win.promptClose(self.win.getWidth() / 2, 20) def drawRocks(self): for r in self.rocks: r.draw(self.win) def moveRocks(self): for r in self.rocks: r.move(r.dx(), r.dy()) self.win.flush() def drawBoxes(self): boxes = self.q.getBBoxes() for box in boxes: box = Rectangle(box.ul, box.lr) box.draw(self.win)
def __init__(self): super().__init__() self.infoObject = pygame.display.Info() self.CAM_HEIGHT = self.infoObject.current_h - 80 self.CAM_WIDTH = int(self.infoObject.current_w-100) self.num_of_creatures = 180 self.num_of_food = 100 self.game_bounds = (-5000, 5000) self.running = True # self.camera = Camera(self.CAM_WIDTH, self.CAM_HEIGHT, x=-(self.CAM_WIDTH / 2), y=-(self.CAM_HEIGHT / 2)) self.camera = Camera(self.CAM_WIDTH, self.CAM_HEIGHT, x=0, y=0, zoom=1.0) self.screen = pygame.display.set_mode((self.CAM_WIDTH, self.CAM_HEIGHT)) self.fullscreen = False # QuadTree for collision detection self.quadtree = QuadTree( bounds=( -self.WORLD_WIDTH/2, -self.WORLD_HEIGHT/2, self.WORLD_WIDTH, self.WORLD_HEIGHT), depth=9) self.ui = UserInterface(self.screen) self.dt = 0 # Will draw the quadtree overlay if true self.draw_quadtree = False self.paused = False # When the user clicks on the screen it's position will be stored here self.mouse_screen_position = None self.mouse_real_position = None # How fast everything moves self.game_speed = 1.0 self.selected_creature = None self.follow_creature = False self.breeder = Breeder() self.population_stats = StatsTracker() self.spinner = Background()
def subdivide(self): #print "self:",self.bbox l = self.bbox.ul.x r = self.bbox.lr.x t = self.bbox.ul.y b = self.bbox.lr.y mX = (l + r) / 2 mY = (t + b) / 2 self.northEast = QuadTree(BoundingBox(Point(mX, t), Point(r, mY)), self.maxPoints) self.southEast = QuadTree(BoundingBox(Point(mX, mY), Point(r, b)), self.maxPoints) self.southWest = QuadTree(BoundingBox(Point(l, mY), Point(mX, b)), self.maxPoints) self.northWest = QuadTree(BoundingBox(Point(l, t), Point(mX, mY)), self.maxPoints)
class Driver(object): def __init__(self,width,height): self.width = width self.height = height self.rockSpeeds = np.arange(1,15,1) self.numRocks = 25 self.q = QuadTree(BoundingBox(Point(0,0),Point(self.width,self.height)),1) self.rockSize = 5 self.win = GraphWin("MoveRocks", self.width, self.height) self.boxes = [] self.rocks = [] xWalls = [0,self.width] yWalls = [0,self.height] for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0+self.rockSize,int(self.width)-self.rockSize) startY = random.randint(0+self.rockSize,int(self.height)-self.rockSize) speed = random.choice(self.rockSpeeds) self.rocks.append(Rock(Point(startX,startY),self.rockSize)) self.win.flush() self.drawRocks() for i in range(1000): #time.sleep(.01) self.moveRocks() self.win.promptClose(self.win.getWidth()/2, 20) def drawRocks(self): for r in self.rocks: r.draw(self.win) def moveRocks(self): for r in self.rocks: r.move(r.dx(),r.dy()) self.win.flush() def drawBoxes(self): boxes = self.q.getBBoxes() for box in boxes: box = Rectangle(box.ul,box.lr) box.draw(self.win)
def __init__(self, width, height): self.width = width self.height = height self.rockSpeeds = np.arange(1, 15, 1) self.numRocks = 25 self.q = QuadTree( BoundingBox(Point(0, 0), Point(self.width, self.height)), 1) self.rockSize = 5 self.win = GraphWin("MoveRocks", self.width, self.height) self.boxes = [] self.rocks = [] xWalls = [0, self.width] yWalls = [0, self.height] for i in range(self.numRocks): #click = self.win.getMouse() # Pause to view result startX = random.randint(0 + self.rockSize, int(self.width) - self.rockSize) startY = random.randint(0 + self.rockSize, int(self.height) - self.rockSize) speed = random.choice(self.rockSpeeds) self.rocks.append(Rock(Point(startX, startY), self.rockSize)) self.win.flush() self.drawRocks() for i in range(1000): #time.sleep(.01) self.moveRocks() self.win.promptClose(self.win.getWidth() / 2, 20)
def main(): screen = None sim_world = World() quadtree = QuadTree(bounds=(-WORLD_WIDTH / 2, -WORLD_HEIGHT / 2, WORLD_WIDTH, WORLD_HEIGHT), depth=9) sim_world.add_system(NeuralNetworkSystem()) sim_world.add_system(MovingSystem()) sim_world.add_system(CollisionSystem(quadtree)) sim_world.add_system(ShapeRenderer(screen)) Creature(sim_world, Position(4, 5), Orientation(50.0), Color(255, 255, 255)) sim_world.process()
def _reload_init(self): self.quadtree = QuadTree( bounds=( -self.WORLD_WIDTH/2, -self.WORLD_HEIGHT/2, self.WORLD_WIDTH, self.WORLD_HEIGHT), depth=9) self.ui = UserInterface(self.screen) self.dt = 0 # When the user clicks on the screen it's position will be stored here self.mouse_screen_position = None self.mouse_real_position = None # How fast everything moves self.game_speed = 1.0 self.selected_creature = None self.follow_creature = False self.population_stats = StatsTracker()
plt.plot(yline, y, 'r-') # division line plt.plot(node.x, node.y, 'bo') plt.show() if __name__ == "__main__": from QuadTree import QuadTree as QT nodeNum = 300 # Generate random numbers from discrete uniform distribution. # x = np.random.random_integers(-100, 100, nodeNum) # y = np.random.random_integers(-100, 100, nodeNum) # Generate random numbers from discrete standard normal distribution. x = np.random.randint(-100, 100, nodeNum) y = np.random.randint(-100, 100, nodeNum) # Generate random numbers from normal distribution # x = np.random.normal(0, 20, nodeNum) # y = np.random.normal(0, 20, nodeNum) lst = [(x[i], y[i]) for i in range(nodeNum)] qt = QT() qt.makeOptQT(lst) area = Rect((max(x), max(y)), (min(x), min(y))) QTdivision(qt,area)
class Grid2D(): def __init__(self, dimensions, obstacles=[], precision=4, tilesize=[64, 64]): self.precision = precision self.tilesize = tilesize self.split_tilesize = [tilesize[0] / precision, tilesize[1] / precision] self.width = dimensions[0] self.height = dimensions[1] self.grid = [[1 for x in range(self.width * precision)] for y in range(self.height * precision)] self.quadtree = QuadTree(Rect(0, 0, tilesize[0] * self.width, tilesize[1] * self.height), 0, 5, 10, obstacles) self.obstacles = obstacles def refresh(self, rect=None): self.quadtree.clear() self.quadtree.particles = self.obstacles self.quadtree.update() self.calculate_clearance(rect) def find_path(self, start, target, clearance=1, method="diagonal"): orig_target = target if not self.quadtree.collideline(((start[0] * WIDTH, start[1] * HEIGHT), (target[0] * WIDTH, target[1] * HEIGHT))): return [target] start = (round(start[0] * self.precision), round(start[1] * self.precision)) target = (round(target[0] * self.precision), round(target[1] * self.precision)) if (start[0] >= 0 and start[1] >= 0 and target[0] >= 0 and target[1] >= 0 and start[0] <= self.width * self.precision - 1 and target[0] <= self.width * self.precision - 1 and start[1] <= self.height * self.precision - 1 and target[1] <= self.height * self.precision - 1 and self.grid[target[1]][target[0]] >= clearance): parents = {} g_score = {start:0} h_score = {start:heuristic(start, target, method)} f_score = {start:h_score[start]} closed_list = [] open_heap = [] heappush(open_heap, (f_score[start], start)) counter = 0 while open_heap: counter += 1 current = heappop(open_heap)[1] closed_list.append(current) if current == target: path = [] while current in parents: path.append(current) current = parents[current] path.reverse() path = [[x[0] / self.precision, x[1] / self.precision] for x in path] if path: path[-1] = orig_target return path for neighbor in get_neighbors(current, self.width * self.precision - 1, self.height * self.precision - 1): if self.grid[neighbor[1]][neighbor[0]] < clearance or neighbor in closed_list: continue elif neighbor not in set([x[1] for x in open_heap]): g_score[neighbor] = g_score[current] + compute_g_score(current, neighbor) h_score[neighbor] = heuristic(neighbor, target, method) f_score[neighbor] = g_score[neighbor] + h_score[neighbor] heappush(open_heap, (f_score[neighbor], neighbor)) parents[neighbor] = current else: potential_g = g_score[current] + compute_g_score(current, neighbor) potential_f = h_score[neighbor] + potential_g if potential_f < f_score[neighbor]: f_score[neighbor] = potential_f g_score[neighbor] = potential_g parents[neighbor] = current heappush(open_heap, (f_score[neighbor], neighbor)) #Just to prevent huge lags - it won't find the path, but at least it will still be playable if counter >= 1000: return None return None def calculate_clearance(self, rect=None): if rect: startx = int(rect.x // self.split_tilesize[0]) starty = int(rect.y // self.split_tilesize[1]) #Add one because list[a:b] does not include b #Use math.ceil just to make sure we don't leave anything out endx = int(math.ceil((rect.x + rect.width) / self.split_tilesize[0]) + 1) endy = int(math.ceil((rect.y + rect.height) / self.split_tilesize[1]) + 1) #Check if endx or endy are too big in case the previous "safety precautions" brought them past the edges of the grid if endx >= len(self.grid[0]): endx -= 1 elif endy >= len(self.grid): endy -= 1 for i, y in enumerate(self.grid[starty:endy]): for j, x in enumerate(y[startx:endx]): if self.quadtree.colliderect(Rect(((j + startx) * self.split_tilesize[0], (i + starty) * self.split_tilesize[1]), self.split_tilesize)): self.grid[i + starty][j + startx] = 0 else: self.grid[i + starty][j + startx] = 1 else: for i, y in enumerate(self.grid): for j, x in enumerate(y): if self.quadtree.colliderect(Rect((j * self.split_tilesize[0], i * self.split_tilesize[1]), self.split_tilesize)): self.grid[i][j] = 0 """
class CollisionSystem(Observer, Publisher): def __init__(self, positionComponents, velocityComponents, accelerationComponents, geometryComponents, collsionComponents, viewSize, dt): Observer.__init__(self) Publisher.__init__(self) self.positionComponents = positionComponents self.velocityComponents = velocityComponents self.accelerationComponents = accelerationComponents self.geometryComponents = geometryComponents self.collsionComponents = collsionComponents self.dt = dt self.interestingCollisions = ["Box", "Box"] self.__qTree = QuadTree(Rect(0, 0, viewSize[0], viewSize[1])) def resolve(self): self.__qTree.empty() self.__qTree.addEntities(self) collisions = self.__qTree.findCollisions(self) for collision in collisions: self.publishEvent(collision) def findCollisions(self, entityIDs): """Returns a bool indicating if the two entities collided and a collision class which records the two entities and the lambda at which they collide""" collisions = [] for e1id, e2id in combinations(entityIDs, 2): if ((self.collsionComponents[e1id].category, self.collsionComponents[e2id].category) in self.interestingCollisions or (self.collsionComponents[e2id].category, self.collsionComponents[e1id].category) in self.interestingCollisions): continue da_x = 0 da_y = 0 dv_x = 0 dv_y = 0 if e1id in self.accelerationComponents.keys(): da_x += self.accelerationComponents[e1id].ax da_y += self.accelerationComponents[e1id].ay dv_x += self.velocityComponents[e1id].vx dv_y += self.velocityComponents[e1id].vy elif e1id in self.velocityComponents.keys(): dv_x += self.velocityComponents[e1id].vx dv_y += self.velocityComponents[e1id].vy if e2id in self.accelerationComponents.keys(): da_x -= self.accelerationComponents[e2id].ax da_y -= self.accelerationComponents[e2id].ay dv_x -= self.velocityComponents[e2id].vx dv_y -= self.velocityComponents[e2id].vy elif eid in self.velocityComponents.keys(): dv_x -= self.velocityComponents[e2id].vx dv_y -= self.velocityComponents[e2id].vy loc1 = self.positionComponents[e1id] loc2 = self.positionComponents[e2id] geom1 = self.geometryComponents[e1id] geom2 = self.geometryComponents[e2id] dx0_rl = (loc1.x + geom1.width) - loc2.x dx0_lr = loc1.x - (loc2.x + geom2.width) dy0_tb = loc1.y - (loc2.y + geom1.height) dy0_bt = (loc1.y + geom1.height) - loc2.y if da_x != 0: test, lx = self.__findLForAccel(da_x, dv_x, dx0_lr, dx0_rl) elif dv_x != 0: test, lx = self.__findLForVel(dv_x, dx0_lr, dx0_rl) else: test, lx = self.__findLForPos(dx0_lr, dx0_rl) if test == False: continue if da_y != 0: test, ly = self.__findLForAccel(da_y, dv_y, dy0_tb, dy0_bt) elif dv_y != 0: test, ly = self.__findLForVel(dv_y, dy0_tb, dy0_bt) else: test, ly = self.__findLForPos(dy0_tb, dy0_bt) if test == False: continue L = 10 # L > 1 impies no collision for l1 in lx: if l1[0] > 1 or l1[1] < 0: continue for l2 in ly: if l2[0] > 1 or l2[1] < 0: continue if l1[0] <= l2[0] <= l1[1]: L = min(L, l2[0]) axis = "y" if l2[0] <= l1[0] <= l2[1]: L = min(L, l1[0]) axis = "x" if L < 0 or L > 1: continue else: print "collision found!!!" collisions.append(Collision(e1id, e2id, L, axis)) return collisions def __findLForAccel(self, da, dv, dx0_lr, dx0_rl): dis_lr = (dv)**2 - 2 * da * dx0_lr if dis_lr >= 0: lx_1lr = (-dv + sqrt(dis_lr)) / (da * self.dt) lx_2lr = (-dv - sqrt(dis_lr)) / (da * self.dt) lx_1lr, lx_2lr = min(lx_1lr, lx_2lr), max(lx_1lr, lx_2lr) dis_rl = (dv)**2 - 2 * da * dx0_rl if dis_rl >= 0: lx_1rl = (-dv + sqrt(dis_rl)) / (da * self.dt) lx_2rl = (-dv - sqrt(dis_rl)) / (da * self.dt) lx_1rl, lx_2rl = min(lx_1rl, lx_2rl), max(lx_1rl, lx_2rl) if dis_lr < 0 and dis_rl < 0: return False, None lx = [] if dis_rl > 0 and dis_lr > 0: temp = (max(0, min(lx_1rl, lx_1lr)), min(1, max(lx_1rl, lx_1lr))) if temp[0] <= temp[1]: lx.append(temp) temp = (max(0, min(lx_2lr, lx_2rl)), min(1, max(lx_2rl, lx_2lr))) if temp[0] <= temp[1]: lx.append(temp) elif dis_rl > 0: temp = (max(0, min(lx_1rl, lx_2rl)), min(1, max(lx_1rl, lx_2rl))) if temp[0] < temp[1]: lx.append(temp) else: temp = (max(0, min(lx_1lr, lx_2lr)), min(1, max(lx_1lr, lx_2lr))) if temp[0] < temp[1]: lx.append(temp) #find the intersection of dl and [0,1] if len(lx) != 0: return True, lx else: return False, None def __findLForVel(self, dv, dx0_l, dx0_r): # x1 = x10 + vx1*dt*lx # x2 = x20 + vx2*dt*lx # x1 = x2 => 0 = dx0 + dvx*dt*lx # => lx = -dx0 / (dvx*dt) l_1 = -dx0_r / (dv * self.dt) l_2 = -dx0_l / (dv * self.dt) L = sorted((min(l_1, l_2), max(l_1, l_2))) if L[0] <= 1 and L[1] >= 0: L = [L] return True, L else: return False, None def __findLForPos(self, dx0_less, dx0_great): if dx0_less < 0 and dx0_great > 0: return True, [(0, 1)] else: return False, None def inBoundary(self, r1): """ returns a bool indicating if the entitiy is in the rect over the timestep dt """ eInBoundary = [] for e1id in self.collsionComponents.keys(): da_x = 0 da_y = 0 dv_x = 0 dv_y = 0 if e1id in self.accelerationComponents.keys(): da_x += self.accelerationComponents[e1id].ax da_y += self.accelerationComponents[e1id].ay dv_x += self.velocityComponents[e1id].vx dv_y += self.velocityComponents[e1id].vy elif e1id in self.velocityComponents.keys(): dv_x += self.velocityComponents[e1id].vx dv_y += self.velocityComponents[e1id].vy loc1 = self.positionComponents[e1id] geom1 = self.geometryComponents[e1id] dx0_rl = (loc1.x + geom1.width) - r1.x dx0_lr = loc1.x - (r1.x + r1.width) dy0_tb = loc1.y - (r1.y + r1.height) dy0_bt = (loc1.y + geom1.height) - r1.y if da_x != 0: test, lx = self.__findLForAccel(da_x, dv_x, dx0_lr, dx0_rl) elif dv_x != 0: test, lx = self.__findLForVel(dv_x, dx0_lr, dx0_rl) else: test, lx = self.__findLForPos(dx0_lr, dx0_rl) if test == False: continue if da_y != 0: test, ly = self.__findLForAccel(da_y, dv_y, dy0_tb, dy0_bt) elif dv_y != 0: test, ly = self.__findLForVel(dv_y, dy0_tb, dy0_bt) else: test, ly = self.__findLForPos(dy0_tb, dy0_bt) if test == False: continue L = 10 # L > 1 impies no collision for l1 in lx: if l1[0] > 1 or l1[1] < 0: continue for l2 in ly: if l2[0] > 1 or l2[1] < 0: continue if l1[0] <= l2[0] <= l1[1]: L = min(L, l2[0]) if l2[0] <= l1[0] <= l2[1]: L = min(L, l1[0]) if L < 0 or L > 1: continue else: eInBoundary.append(e1id) return eInBoundary
def generate_qt(points): qt = QuadTree() for p in points: qt.insert(p) return qt
class QuadTree(object): def __init__(self, bbox, maxPoints): self.northEast = None self.southEast = None self.southWest = None self.northWest = None self.points = [] self.bbox = bbox self.maxPoints = maxPoints self.smallestContainer = None def __str__(self): return "\nnorthwest: %s,\nnorthEast: %s,\nsouthWest: %s,\nsouthEast: %s,\npoints: %s,\nbbox: %s,\nmaxPoints: %s\n" % ( self.northWest, self.northEast, self.southWest, self.southEast, self.points, self.bbox, self.maxPoints) """ Insert a new point into this QuadTree node """ def insert(self, point): if not self.bbox.containsPoint(point): #print "Point %s is not inside bounding box %s" % (point,self.bbox) return False if len(self.points) < self.maxPoints: # If we still have spaces in the bucket array for this QuadTree node, # then the point simply goes here and we're finished self.points.append(point) return True elif self.northEast == None: # Otherwise we split this node into NW/NE/SE/SW quadrants self.subdivide() # Insert the point into the appropriate quadrant, and finish if ((self.northEast.insert(point)) or (self.southEast.insert(point)) or (self.southWest.insert(point)) or (self.northWest.insert(point))): return True # If we couldn't insert the new point, then we have an exception situation raise ValueError("Point %s is outside bounding box %s" % (point, self.bbox)) """ Split this QuadTree node into four quadrants for NW/NE/SE/SW """ def subdivide(self): #print "self:",self.bbox l = self.bbox.ul.x r = self.bbox.lr.x t = self.bbox.ul.y b = self.bbox.lr.y mX = (l + r) / 2 mY = (t + b) / 2 self.northEast = QuadTree(BoundingBox(Point(mX, t), Point(r, mY)), self.maxPoints) self.southEast = QuadTree(BoundingBox(Point(mX, mY), Point(r, b)), self.maxPoints) self.southWest = QuadTree(BoundingBox(Point(l, mY), Point(mX, b)), self.maxPoints) self.northWest = QuadTree(BoundingBox(Point(l, t), Point(mX, mY)), self.maxPoints) #print self.northEast,self.southEast,self.southWest,self.northWest """ Return an array of all points within this QuadTree and its child nodes that fall within the specified bounding box """ def searchBox(self, bbox): results = [] if self.bbox.overlaps(bbox) or self.bbox.containsBox(bbox): # Test each point that falls within the current QuadTree node for p in self.points: # Test each point stored in this QuadTree node in turn, adding to the results array # if it falls within the bounding box if self.bbox.containsPoint(p): results.append(p) # If we have child QuadTree nodes.... if (not self.northWest == None): # ... search each child node in turn, merging with any existing results results = results + self.northWest.searchBox(self.bbox) results = results + self.northEast.searchBox(self.bbox) results = results + self.southWest.searchBox(self.bbox) results = results + self.southEast.searchBox(self.bbox) return results """ Returns the containers points that are in the same container as another point. """ def searchNeighbors(self, point): #If its not a point (its a bounding rectangle) if not hasattr(point, 'x'): return [] results = [] if self.bbox.containsPoint(point): print point, " in ", self.bbox # Test each point that falls within the current QuadTree node for p in self.points: print p # Test each point stored in this QuadTree node in turn, adding to the results array # if it falls within the bounding box if self.bbox.containsPoint(p): print p, " in bbox" results.append(p) # If we have child QuadTree nodes.... if (not self.northWest == None): # ... search each child node in turn, merging with any existing results results = results + self.northWest.searchNeighbors(point) results = results + self.northEast.searchNeighbors(point) results = results + self.southWest.searchNeighbors(point) results = results + self.southEast.searchNeighbors(point) return results """ Print helper to draw tree """ def getBBoxes(self): bboxes = [] bboxes.append(self.bbox) if (not self.northWest == None): # ... search each child node in turn, merging with any existing results bboxes = bboxes + self.northWest.getBBoxes() bboxes = bboxes + self.northEast.getBBoxes() bboxes = bboxes + self.southWest.getBBoxes() bboxes = bboxes + self.southEast.getBBoxes() return bboxes
length = 800 rad = 50 v_scale = 1.5 a_scale = 2.5 p_scale = 4 center = Point(width / 2, length / 2) main_rect = Rect(center, width, length) pygame.init() gameDisplay = pygame.display.set_mode((width, length)) gameDisplay.fill((255, 255, 255)) clock = pygame.time.Clock() players = [Point(rx=width, ry=length, rvx=10, rvy=10) for i in range(200)] running = True qTree = QuadTree(main_rect, 4) for player in players: qTree.insert(player) while running: pygame.display.update() gameDisplay.fill((255, 255, 255)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False keys = pygame.key.get_pressed() if (keys[pygame.K_k]): running = False if (keys[pygame.K_q]): rad += 1 print('rad:', rad)
from matplotlib import cm MAX_OBJECTS = 5 for d in range(2,10): ax = plt.subplot(1,2,1) ax2 = plt.subplot(1,2,2) print 'Depth = %d' % d st = time.time() # build quadtree print 'Building QuadTree...', quadtree = QuadTree(d,[ mins[0], maxs[0], mins[1], maxs[1]], MAX_OBJECTS) quadtree.clear_gobjects(); colors = [] for i in range(d): colors.append(cm.Blues(1.*i/d) ) level = quadtree.get_minlevel() plt.title('Level '+str(level)) plotted_bounds = [] for t in triobjects: quadtree.insert_gobject(t) bounds = [] quadtree.getBounds(bounds)
background = (34, 34, 34) # Screen size scale_factor = 5 width = 360 * scale_factor height = 180 * scale_factor pygame.init() # Create screen, set title and icon screen = pygame.display.set_mode((width, height)) pygame.display.set_caption("Quadtree") q = QuadTree(width, height) search_rect = pygame.Rect(0, 0, 80, 80) search_color = (81, 243, 157) text_color = (0, 255, 0) text_background = (0, 0, 255) modes = ['n of points: ', 'total population: ', 'REMOVING!'] mode = 0 font = pygame.font.Font('freesansbold.ttf', 32) text = font.render('n of points: ', True, text_color, text_background) textRect = text.get_rect() textRect.left = 2 textRect.top = height - textRect.height - 2
class CreatureSim(PyGameBase): """Runs the creature sim game""" CAMERA_MOVE_SPEED = .5 GAME_SPEED_INCREMENT = .1 MAX_GAME_SPEED = 2.0 MIN_GAME_SPEED = .1 WORLD_WIDTH = 100000 WORLD_HEIGHT = 100000 SELECTED_COLOR = GREEN def __init__(self): super().__init__() self.infoObject = pygame.display.Info() self.CAM_HEIGHT = self.infoObject.current_h - 80 self.CAM_WIDTH = int(self.infoObject.current_w-100) self.num_of_creatures = 180 self.num_of_food = 100 self.game_bounds = (-5000, 5000) self.running = True # self.camera = Camera(self.CAM_WIDTH, self.CAM_HEIGHT, x=-(self.CAM_WIDTH / 2), y=-(self.CAM_HEIGHT / 2)) self.camera = Camera(self.CAM_WIDTH, self.CAM_HEIGHT, x=0, y=0, zoom=1.0) self.screen = pygame.display.set_mode((self.CAM_WIDTH, self.CAM_HEIGHT)) self.fullscreen = False # QuadTree for collision detection self.quadtree = QuadTree( bounds=( -self.WORLD_WIDTH/2, -self.WORLD_HEIGHT/2, self.WORLD_WIDTH, self.WORLD_HEIGHT), depth=9) self.ui = UserInterface(self.screen) self.dt = 0 # Will draw the quadtree overlay if true self.draw_quadtree = False self.paused = False # When the user clicks on the screen it's position will be stored here self.mouse_screen_position = None self.mouse_real_position = None # How fast everything moves self.game_speed = 1.0 self.selected_creature = None self.follow_creature = False self.breeder = Breeder() self.population_stats = StatsTracker() self.spinner = Background() def run(self): self.load() self.setup_keys() self.game_loop() def game_loop(self): while self.running: self.dt = self.clock.tick() self.screen.fill(BLACK) self.handle_events() self.handle_key_presses() self.update_creature_positions() self.scene_graph.update() self.center_camera() self.quadtree.update_objects(self.entities) self.handle_collisions() self.do_obj_events() self.render_frame() def render_frame(self): pygame.display.set_caption(str(self.clock.get_fps())) # Find all objects in nodes intersecting the screen objects_to_draw = self.quadtree.get_objects_at_bounds(self.camera.get_bounds()) for scene_object in objects_to_draw: scene_object.draw(self.screen, self.camera) if self.draw_quadtree: self.quadtree.draw_tree(self.screen, self.camera) self.draw_ui() pygame.display.flip() def center_camera(self): if self.selected_creature and self.follow_creature: self.camera.position[0] = self.selected_creature.position[0] self.camera.position[1] = self.selected_creature.position[1] def do_obj_events(self): if not self.paused: self.check_healths() def remove_creature(self, creature): if creature.selected: self.unfollow_creature() self.quadtree.remove(creature) self.entities.remove(creature) self.entities.remove(creature.vision_cone) self.scene_graph.remove(creature) def check_healths(self): for creature in self.get_creatures(): if creature.health <= 0: self.remove_creature(creature) self._breed_creature() for food in self.get_foods(): if food.eaten == True: self.quadtree.remove(food) self.entities.remove(food) self._insert_new_food() def _insert_new_creature(self): new_creature = Creature( x=randrange(*self.game_bounds), y=randrange(*self.game_bounds), color=WHITE ) new_creature.vision_cone = VisionCone(parent=new_creature, x=265, color=RED) self.entities.append(new_creature.vision_cone) self._insert_creature(new_creature) return new_creature def _insert_creature(self, creature): self.entities.append(creature) creature.calc_absolute_position() self.scene_graph.add(creature) self.scene_graph.add_to_parent(creature.vision_cone, creature, transformer=OldStyleTransformer) self.quadtree.insert(creature) def _insert_new_food(self): new_food = Food( x=randrange(*self.game_bounds), y=randrange(*self.game_bounds), color=DARKGREEN ) self._insert_food(new_food) return new_food def _insert_food(self, food): self.entities.append(food) food.calc_absolute_position() self.quadtree.insert(food) def _breed_creature(self): new_weights = self.breeder.breed(list(self.get_creatures())) new_creature = Creature( x=randrange(*self.game_bounds), y=randrange(*self.game_bounds), nn_weights=new_weights ) new_creature.vision_cone = VisionCone(parent=new_creature, x=265, color=RED) self.entities.append(new_creature.vision_cone) self._insert_creature(new_creature) return new_creature def handle_collisions(self): # Handle collisions for each creature's vision cone for creature in self.get_creatures(): # Get rough idea of what things could be colliding first_pass = self.quadtree.get_objects_at_bounds(creature.get_bounds()) if first_pass: for entity in first_pass: creature.vision_cone.check_collision(entity) creature.check_collision(entity) for entity in self.entities: entity.finish_collisions() def handle_key_presses(self): # Camera Zoom if self.key_presses["zoom-in"]: self.camera.zoom_in(self.dt) if self.key_presses["zoom-out"]: self.camera.zoom_out(self.dt) # Camera movement if not self.follow_creature: if self.key_presses["cam-up"]: self.camera.move(y_change=-self.dt * self.CAMERA_MOVE_SPEED) if self.key_presses["cam-down"]: self.camera.move(y_change=self.dt * self.CAMERA_MOVE_SPEED) if self.key_presses["cam-left"]: self.camera.move(x_change=-self.dt * self.CAMERA_MOVE_SPEED) if self.key_presses["cam-right"]: self.camera.move(x_change=self.dt * self.CAMERA_MOVE_SPEED) def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() self.register_key_presses(event) def register_key_presses(self, event): # Key Down ######################## if event.type == KEYDOWN: if event.key == K_ESCAPE: raise SystemExit() try: self.key_presses[self.key_map[event.key]] = True except KeyError: pass if event.key == K_t: self.draw_quadtree = not self.draw_quadtree if event.key == K_b: self.select_best() if event.key == K_F5: self.save_state() if event.key == K_F9: self.load_state() if event.key == K_p: self.paused = not self.paused if event.key == K_F11: self.toggle_fullscreen() if event.key == K_f: self.toggle_follow_creature() if event.key == K_RIGHTBRACKET: self.speedup_game() if event.key == K_LEFTBRACKET: self.slowdown_game() # Key Up ######################## if event.type == KEYUP: try: self.key_presses[self.key_map[event.key]] = False except KeyError: pass # Mouse Down ######################## if event.type == pygame.MOUSEBUTTONDOWN: self.handle_click() def toggle_fullscreen(self): self.fullscreen = not self.fullscreen if self.fullscreen: pygame.display.set_mode((self.CAM_WIDTH, self.CAM_HEIGHT), pygame.FULLSCREEN) else: pygame.display.set_mode((self.CAM_WIDTH, self.CAM_HEIGHT)) def save_state(self): def export_items(items): with open('weight_data.pickle', 'wb+') as f: pickle.dump(items, f) # dump the creatures and food stuffs # let's get all the creatures first x = list(self.get_creatures()) y = list(self.get_foods()) export_items([x, y]) self.ui.toast("Saved Simulation") def load_state(self): def retrieve_items(): with open('weight_data.pickle', 'rb+') as f: return pickle.load(f) try: creatures, foods = retrieve_items() except: return self.reload(creatures, foods) self.ui.toast("Loaded Simulation") def toggle_follow_creature(self): if self.selected_creature: self.follow_creature = not self.follow_creature def unfollow_creature(self): self.follow_creature = False def select_best(self): self.unselect_creature() self.unfollow_creature() best = self._find_best() self.select_creature(best) self.toggle_follow_creature() def _find_best(self): return max(self.get_creatures(), key=lambda c: c.total_food_eaten) def select_creature(self, creature): self.selected_creature = creature creature.selected = True def unselect_creature(self): if self.selected_creature: self.selected_creature.selected = False self.selected_creature = None self.unfollow_creature() def handle_click(self): self.mouse_screen_position = pygame.mouse.get_pos() self.mouse_real_position = self.camera.real_position(self.mouse_screen_position) hit = self.quadtree.ray_cast(self.mouse_real_position) if hit: # If our hit is a Creature if issubclass(type(hit), Creature): self.unselect_creature() self.select_creature(hit) def _reload_init(self): self.quadtree = QuadTree( bounds=( -self.WORLD_WIDTH/2, -self.WORLD_HEIGHT/2, self.WORLD_WIDTH, self.WORLD_HEIGHT), depth=9) self.ui = UserInterface(self.screen) self.dt = 0 # When the user clicks on the screen it's position will be stored here self.mouse_screen_position = None self.mouse_real_position = None # How fast everything moves self.game_speed = 1.0 self.selected_creature = None self.follow_creature = False self.population_stats = StatsTracker() def reload(self, creatures, foods): self._reload_init() self.load(creatures, foods) def load(self, creatures=None, foods=None): """Sets up various game world objects""" self.entities = [] self.scene_graph = SceneGraph() self.scene_graph.add(self.spinner) if creatures and foods: for creature in creatures: self._insert_creature(creature) for food in foods: self._insert_food(food) else: # Create creatures for x in range(self.num_of_creatures): self._insert_new_creature() # Create foods for x in range(self.num_of_food): self._insert_new_food() # Setup text boxes self.speed_textbox = TextBox("", (10, self.CAM_HEIGHT - 40)) self.creature_stats_textbox = MultilineTextBox([""], (10, 10)) self.population_stats_textbox = MultilineTextBox([""], (self.CAM_WIDTH-300, 10)) num_creatures_text = "{} Creatures, {} Food".format(self.num_of_creatures, self.num_of_food) self.num_creatures_textbox = TextBox(num_creatures_text, (10, self.CAM_HEIGHT - 70)) self.ui.add(self.speed_textbox) self.ui.add(self.creature_stats_textbox) self.ui.add(self.num_creatures_textbox) self.ui.add(self.population_stats_textbox) def update_creature_positions(self): if not self.paused: for creature in self.get_creatures(): network = creature.nn network.compute_network() creature.rotate((self.dt * creature.rotation_speed) * self.game_speed) creature.move_forward((self.dt * creature.speed) * self.game_speed) creature.do_everyframe_action(self.dt, self.game_speed) creature.update_position() def speedup_game(self): self.game_speed = min(self.MAX_GAME_SPEED, self.game_speed + self.GAME_SPEED_INCREMENT) def slowdown_game(self): self.game_speed = max(self.MIN_GAME_SPEED, self.game_speed - self.GAME_SPEED_INCREMENT) def setup_keys(self): """Sets up key presses""" key_map = { K_w: "cam-up", K_s: "cam-down", K_a: "cam-left", K_d: "cam-right", K_e: "zoom-out", K_q: "zoom-in", } self.register_keys(key_map) def draw_ui(self): ui = self.ui if self.paused: speed_text = "Speed: Paused" else: speed_text = "Speed: {:.2}x".format(self.game_speed) self.speed_textbox.set(speed_text) if self.selected_creature: self.creature_stats_textbox.set(self.selected_creature.get_stats()) else: self.creature_stats_textbox.clear() stats = self.population_stats.update(list(self.get_creatures())) self.population_stats_textbox.set(stats) ui.draw() def get_creatures(self): return (entity for entity in self.entities if issubclass(type(entity), Creature)) def get_foods(self): return (entity for entity in self.entities if issubclass(type(entity), Food))
def main(size=10, max_nodes=800): """ if squares are not fully forming increase plane size :param size: :param max_nodes: :return: """ print "size: " + str(size) print "max_nodes: " + str(max_nodes) globals.init() X = Util.getPlane(size) mins = (0.0, 0.0) maxs = (size - 1.0, size - 1.0) QT = QuadTree(X, mins, maxs, 0, 0) QT.add_square() print "Generating road network..." # for high density choose ones counter depth with highest number of squares randomly while (True): node = randrange(max(globals.node_index)) if len(globals.node_index ) > max_nodes: # limit network generation by number of nodes break Util.add_square_at(QT, node) #Util.printStats(globals.node_index) #Util.bfs_print(QT) fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111) ax.set_xlim(0, size - 1.0) ax.set_ylim(0, size - 1.0) # for each depth generate squares print "generating squares..." for d in range(0, len(globals.node_index)): QT.draw_rectangle(ax, depth=d) print "writing data to files..." fn = open('../node-list', 'w') fe = open('../edge-list', 'w') edgeCount = 0 #directed edge count for point in globals.edges: if point in globals.coord_id: fn.write( str(globals.coord_id[point]) + "," + str(point.x) + "," + str(point.y) + "\n") for edge in globals.edges[point]: fe.write( str(globals.coord_id[point]) + "," + str(globals.coord_id[edge]) + "\n") edgeCount = edgeCount + 1 fn.close() fe.close() print "# of edges: " + str(edgeCount) plt.savefig('../rand-quad-road-network.png') dir_path = os.path.dirname(os.path.realpath(".")) print "generate road network image at: " + dir_path + "/rand-quad-road-network.png" print "node list at: " + dir_path + "/node-list" print "edge list at: " + dir_path + "/edge-list" print "Done"
from Point import Point from QuadTree import QuadTree p1 = Point(5., 5.) p2 = Point(10., 10.) p3 = Point(8., 8.) p4 = Point(2., 2.) p5 = Point(3., 3.) p6 = Point(7., 3.) qt = QuadTree(p1) qt.insert(p2) qt.insert(p3) qt.insert(p4) qt.insert(p5) qt.insert(p6) print(qt)
class Test4(Graphics): def __init__(self): super().__init__("PyGame Test 4", WINDOW_WIDTH, WINDOW_HEIGHT) self.setClearColor(Graphics.BLACK) self.setTargetFps(60) def setup(self): boundary = RectangleRange(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2, WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2) self.qt = QuadTree(boundary) for i in range(2000): px = random.randint(5, WINDOW_WIDTH - 5) py = random.randint(50, WINDOW_HEIGHT - 5) v = Vehicle(Vector2(px, py), Vector2(0, 0)) p = QuadTreePoint(px, py, v) self.qt.insert(p) self.r1 = RectangleRange(WINDOW_WIDTH // 2 - 100, WINDOW_HEIGHT // 2 + 100, 200, 100) self.r2 = CircleRange(WINDOW_WIDTH // 2 + 220, WINDOW_HEIGHT // 2 - 100, 90) self.r1dx = 1 self.r1dy = 2 self.r2dx = 2 self.r2dy = 1 print(self.qt) def cleanup(self): pass def draw(self): for p in self.qt.all(): self.filled_circle(p.userdata.pos.x, p.userdata.pos.y, 3, Graphics.WHITE) self.rectangle(self.r1.cx - self.r1.w, self.r1.cy - self.r1.h, self.r1.cx + self.r1.w, self.r1.cy + self.r1.h, Graphics.RED) self.circle(self.r2.x, self.r2.y, self.r2.r, Graphics.GREEN) for p in self.qt.queryRectangle(self.r1): self.filled_circle(p.userdata.pos.x, p.userdata.pos.y, 3, Graphics.RED) for p in self.qt.queryCircle(self.r2): self.filled_circle(p.userdata.pos.x, p.userdata.pos.y, 3, Graphics.GREEN) def update(self, timeDelta): self.r1.cx += self.r1dx self.r1.cy += self.r1dy if self.r1.cx + self.r1.w >= WINDOW_WIDTH: self.r1dx *= -1 if self.r1.cx - self.r1.w <= 0: self.r1dx *= -1 if self.r1.cy + self.r1.h >= WINDOW_HEIGHT: self.r1dy *= -1 if self.r1.cy - self.r1.h <= 0: self.r1dy *= -1 self.r2.x += self.r2dx self.r2.y += self.r2dy if self.r2.x + self.r2.r >= WINDOW_WIDTH: self.r2dx *= -1 if self.r2.x - self.r2.r <= 0: self.r2dx *= -1 if self.r2.y + self.r2.r >= WINDOW_HEIGHT: self.r2dy *= -1 if self.r2.y - self.r2.r <= 0: self.r2dy *= -1 # for p in self.points: # p.update() def mouseEvent(self, x, y): print(f"mouseCallback: {x} {y}") def keyEvent(self, key): print(f"keyCallback: {key}")
def __init__(self, x, y, w, h, *args): self.tree = QuadTree(x, y, w, h, 1, args[0]) self.objects = [] self.surface = args[0]
class Grid2D(): def __init__(self, dimensions, obstacles=[], precision=4, tilesize=[64, 64]): self.precision = precision self.tilesize = tilesize self.split_tilesize = [ tilesize[0] / precision, tilesize[1] / precision ] self.width = dimensions[0] self.height = dimensions[1] self.grid = [[1 for x in range(self.width * precision)] for y in range(self.height * precision)] self.quadtree = QuadTree( Rect(0, 0, tilesize[0] * self.width, tilesize[1] * self.height), 0, 5, 10, obstacles) self.obstacles = obstacles def refresh(self, rect=None): self.quadtree.clear() self.quadtree.particles = self.obstacles self.quadtree.update() self.calculate_clearance(rect) def find_path(self, start, target, clearance=1, method="diagonal"): orig_target = target if not self.quadtree.collideline( ((start[0] * WIDTH, start[1] * HEIGHT), (target[0] * WIDTH, target[1] * HEIGHT))): return [target] start = (round(start[0] * self.precision), round(start[1] * self.precision)) target = (round(target[0] * self.precision), round(target[1] * self.precision)) if (start[0] >= 0 and start[1] >= 0 and target[0] >= 0 and target[1] >= 0 and start[0] <= self.width * self.precision - 1 and target[0] <= self.width * self.precision - 1 and start[1] <= self.height * self.precision - 1 and target[1] <= self.height * self.precision - 1 and self.grid[target[1]][target[0]] >= clearance): parents = {} g_score = {start: 0} h_score = {start: heuristic(start, target, method)} f_score = {start: h_score[start]} closed_list = [] open_heap = [] heappush(open_heap, (f_score[start], start)) counter = 0 while open_heap: counter += 1 current = heappop(open_heap)[1] closed_list.append(current) if current == target: path = [] while current in parents: path.append(current) current = parents[current] path.reverse() path = [[x[0] / self.precision, x[1] / self.precision] for x in path] if path: path[-1] = orig_target return path for neighbor in get_neighbors( current, self.width * self.precision - 1, self.height * self.precision - 1): if self.grid[neighbor[1]][neighbor[ 0]] < clearance or neighbor in closed_list: continue elif neighbor not in set([x[1] for x in open_heap]): g_score[neighbor] = g_score[current] + compute_g_score( current, neighbor) h_score[neighbor] = heuristic(neighbor, target, method) f_score[ neighbor] = g_score[neighbor] + h_score[neighbor] heappush(open_heap, (f_score[neighbor], neighbor)) parents[neighbor] = current else: potential_g = g_score[current] + compute_g_score( current, neighbor) potential_f = h_score[neighbor] + potential_g if potential_f < f_score[neighbor]: f_score[neighbor] = potential_f g_score[neighbor] = potential_g parents[neighbor] = current heappush(open_heap, (f_score[neighbor], neighbor)) #Just to prevent huge lags - it won't find the path, but at least it will still be playable if counter >= 1000: return None return None def calculate_clearance(self, rect=None): if rect: startx = int(rect.x // self.split_tilesize[0]) starty = int(rect.y // self.split_tilesize[1]) #Add one because list[a:b] does not include b #Use math.ceil just to make sure we don't leave anything out endx = int( math.ceil((rect.x + rect.width) / self.split_tilesize[0]) + 1) endy = int( math.ceil((rect.y + rect.height) / self.split_tilesize[1]) + 1) #Check if endx or endy are too big in case the previous "safety precautions" brought them past the edges of the grid if endx >= len(self.grid[0]): endx -= 1 elif endy >= len(self.grid): endy -= 1 for i, y in enumerate(self.grid[starty:endy]): for j, x in enumerate(y[startx:endx]): if self.quadtree.colliderect( Rect(((j + startx) * self.split_tilesize[0], (i + starty) * self.split_tilesize[1]), self.split_tilesize)): self.grid[i + starty][j + startx] = 0 else: self.grid[i + starty][j + startx] = 1 else: for i, y in enumerate(self.grid): for j, x in enumerate(y): if self.quadtree.colliderect( Rect((j * self.split_tilesize[0], i * self.split_tilesize[1]), self.split_tilesize)): self.grid[i][j] = 0 """
from QuadTree import QuadTree import Util import globals import numpy as np from random import randrange globals.init() # 2 D plane size = 1000 # if aquares are not fully forming increase plane size X = Util.getPlane(size) mins = (0.0, 0.0) maxs = (size - 1.0, size - 1.0) QT = QuadTree(X, mins, maxs, 0, 0) QT.add_square() # Util.add_square_at(QT,3) print "running ... " # for high density choose ones counter depth with highest number of squares randomly while (True): # node=Util.getBetaInt(5,1,1000,max(globals.nodeIndex)) node = randrange(max(globals.nodeIndex)) if len(globals.nodeIndex ) > 800: # limit network generation by number of nodes break Util.add_square_at(QT, node)
class CollisionDetection(object): def __init__(self, x, y, w, h, *args): self.tree = QuadTree(x, y, w, h, 1, args[0]) self.objects = [] self.surface = args[0] def addBody(self, b): if not hasattr(b, "appearance"): raise AttributeError("Specify an appearance for each collision body.") self.objects.append(b) def getNumBodies(self): return self.objects.__len__() def updateStep(self, delta): self.tree.clear() # Add the bodies to the tree idx = 0 size = self.objects.__len__() while idx < size: self.tree.insert(self.objects[idx]) idx += 1 self.broadphase1(self.objects) self.tree.updateAppearance() # def broadphase2(self, obj, objects): # '''Sweep and prune collision detection''' # sweepAndPrune = SweepAndPrune() # return sweepAndPrune.getNearest(obj, objects) def broadphase1(self, objects): '''QuadTree collision detection''' detectedCollisions = [] for x in objects: if x.getType() == 'static': continue possible = self.tree.retrieve(x) print(possible.__len__()) bodyX = self.getBody(x) bodyX.x += bodyX.force.x bodyX.y += bodyX.force.y bodyX.appearance.x += bodyX.force.x bodyX.appearance.y += bodyX.force.y self.applyGravity(bodyX) self.applyHorizontalFriction(bodyX) for y in possible: # Run collision detection algorithm bodyY = self.getBody(y) if bodyY is bodyX: # Skip itself continue if self.isColliding(bodyX, bodyY): detectedCollisions.append(Pair(bodyX, bodyY)) return detectedCollisions def applyGravity(self, body): body.force += Vec2(0, .2) def bounce(self, body): if body.x + body.w > self.tree.w: body.force.x = -abs(body.force.x) elif body.x < 0: body.force.x = abs(body.force.x) if body.y + body.h > self.tree.h: body.force.y = -abs(body.force.y) elif body.y < 0: body.force.y = abs(body.force.y) def capSpeed(self, body): # Cap speed maxspeed = 10 if body.force.x > maxspeed: body.force.x = maxspeed if body.force.x < -maxspeed: body.force.x = -maxspeed if body.force.y > maxspeed: body.force.y = maxspeed if body.force.y < -maxspeed: body.force.y = -maxspeed def applyHorizontalFriction(self, body): body.force.x -= body.force.x * .1 def isColliding(self, bX, bY): return VecMath.refresh(bX, bY, self.surface) # myx1 = bX.x #left # myy1 = bX.y #top # myx2 = bX.x + bX.w #right # myy2 = bX.y + bX.h #bottom # otherx1 = bY.x #left # othery1 = bY.y #top # otherx2 = bY.x + bY.w #right # othery2 = bY.y + bY.h #bottom # return myy1 < othery2 and myy2 > othery1 and myx1 < otherx2 and myx2 > otherx1 def correctCollision(self, bx, by): diffX = 0 if bx.x < by.x: # ok so x is left of y ... diffX = by.x + by.w - bx.x bx.force.x = -diffX/2 by.force.x = diffX/2 else: diffX = by.x + by.w - bx.x bx.force.x = diffX/2 by.force.x = -diffX/2 diffY = 0 if bx.y < by.y: # ok so x is left of y ... diffY = bx.y + bx.h - by.y bx.force.y = -diffY/2 by.force.y = diffY/2 else: diffY = by.y + by.h - bx.y bx.force.y = -diffY/2 by.force.y = diffY/2 def correctStaticCollision(self, bx, static): diffX = 0 # if bx.x < static.x: # ok so x is left of y ... # diffX = static.x + static.w - bx.x # bx.force.x = -diffX/2 # else: # diffX = static.x + static.w - bx.x # bx.force.x = diffX/2 diffY = 0 if bx.y < static.y: diffY = bx.y + bx.h - static.y bx.force.y = -diffY/2 else: diffY = static.y + static.h - bx.y bx.force.y = -diffY/2 def getBody(self, obj): if not isinstance(obj, Body): if hasattr(obj, "body"): return obj.body else: raise ValueError("This object does not have a body attached to it.") return obj
class QuadTree(object): def __init__(self,bbox,maxPoints): self.northEast = None self.southEast = None self.southWest = None self.northWest = None self.points = [] self.bbox = bbox self.maxPoints = maxPoints self.smallestContainer = None def __str__(self): return "\nnorthwest: %s,\nnorthEast: %s,\nsouthWest: %s,\nsouthEast: %s,\npoints: %s,\nbbox: %s,\nmaxPoints: %s\n" % (self.northWest, self.northEast,self.southWest, self.southEast,self.points,self.bbox,self.maxPoints) """ Insert a new point into this QuadTree node """ def insert(self,point): if not self.bbox.containsPoint(point): print "Point %s is not inside bounding box %s" % (point,self.bbox) return False if len(self.points) < self.maxPoints: # If we still have spaces in the bucket array for this QuadTree node, # then the point simply goes here and we're finished self.points.append(point) return True elif self.northEast == None: # Otherwise we split this node into NW/NE/SE/SW quadrants self.subdivide() # Insert the point into the appropriate quadrant, and finish if ((self.northEast.insert(point)) or (self.southEast.insert(point)) or (self.southWest.insert(point)) or (self.northWest.insert(point))): return True # If we couldn't insert the new point, then we have an exception situation raise ValueError("Point %s is outside bounding box %s" % (point,self.bbox)) """ Split this QuadTree node into four quadrants for NW/NE/SE/SW """ def subdivide(self): #print "self:",self.bbox l = self.bbox.ul.x r = self.bbox.lr.x t = self.bbox.ul.y b = self.bbox.lr.y mX = (l+r) / 2 mY = (t+b) / 2 self.northEast = QuadTree(BoundingBox(Point(mX,t),Point(r,mY)),self.maxPoints) self.southEast = QuadTree(BoundingBox(Point(mX,mY),Point(r,b)),self.maxPoints) self.southWest = QuadTree(BoundingBox(Point(l,mY),Point(mX,b)),self.maxPoints) self.northWest = QuadTree(BoundingBox(Point(l,t),Point(mX,mY)),self.maxPoints) #print self.northEast,self.southEast,self.southWest,self.northWest """ Return an array of all points within this QuadTree and its child nodes that fall within the specified bounding box """ def searchBox(self,bbox): results = [] if self.bbox.overlaps(bbox) or self.bbox.containsBox(bbox): # Test each point that falls within the current QuadTree node for p in self.points: # Test each point stored in this QuadTree node in turn, adding to the results array # if it falls within the bounding box if self.bbox.containsPoint(p): results.append(p) # If we have child QuadTree nodes.... if (not self.northWest == None): # ... search each child node in turn, merging with any existing results results = results + self.northWest.searchBox(self.bbox) results = results + self.northEast.searchBox(self.bbox) results = results + self.southWest.searchBox(self.bbox) results = results + self.southEast.searchBox(self.bbox) return results """ Returns the containers points that are in the same container as another point. """ def searchNeighbors(self,point): #If its not a point (its a bounding rectangle) if not hasattr(point, 'x'): return [] results = [] if self.bbox.containsPoint(point): print point," in ",self.bbox # Test each point that falls within the current QuadTree node for p in self.points: print p # Test each point stored in this QuadTree node in turn, adding to the results array # if it falls within the bounding box if self.bbox.containsPoint(p): print p," in bbox" results.append(p) # If we have child QuadTree nodes.... if (not self.northWest == None): # ... search each child node in turn, merging with any existing results results = results + self.northWest.searchNeighbors(point) results = results + self.northEast.searchNeighbors(point) results = results + self.southWest.searchNeighbors(point) results = results + self.southEast.searchNeighbors(point) return results """ Print helper to draw tree """ def getBBoxes(self): bboxes = [] bboxes.append(self.bbox) if (not self.northWest == None): # ... search each child node in turn, merging with any existing results bboxes = bboxes + self.northWest.getBBoxes() bboxes = bboxes + self.northEast.getBBoxes() bboxes = bboxes + self.southWest.getBBoxes() bboxes = bboxes + self.southEast.getBBoxes() return bboxes
#print(variables.time) variables.time += variables.time_delta all_entities = variables.all_entities player = variables.player entities_to_remove = set() events = pygame.event.get() for event in events: if event.type == pygame.QUIT: variables.running = False break if variables.is_playing: for x in variables.entities_to_add: all_entities.add(x) variables.entities_to_add = set() quad_tree = QuadTree(None, 0, variables.HEIGHT, 0, variables.WIDTH) ticks = pygame.time.get_ticks() if variables.time - last_spawn > 0.8 and variables.time - variables.start_time < 50 or variables.time - last_spawn > 0.4 and variables.time - variables.start_time >= 50: spawn_enemy() last_spawn = variables.time keys = pygame.key.get_pressed() #Input if keys[K_a]: player.acc_right = player.turning_speed if player.vel_right < 0: player.vel_right = 0 player.acc_forwards = player.turning_speed elif keys[K_d]: player.acc_right = -player.turning_speed if player.vel_right > 0:
numpy.where( zip_to_coord['zipcode'] == int(ele[4].split("-")[0]))) except ValueError as e: c = None, None lat, lon = c if lat is None or lon is None: cleaned_record.extend( ["<system-reserve-None>", "<system-reserve-None>"]) else: cleaned_record.extend([str(lat), str(lon)]) original_r.append(cleaned_record) with open(join(data_set_abs_path, "users.dat"), "w") as user_file: for ele in original_r: user_file.write("::".join(ele) + "\n") db = database(data_set_abs_path) db.create() db.close() db = database.connect() r_sys = RecommendationSystem() user_zip_list = [(user_id, (lat, lon)) for user_id, lat, lon in r_sys.db.fetch( "SELECT user_id, lat, lon FROM users WHERE lat IS NOT NULL AND lon IS NOT NULL" )] tree = QuadTree(r_sys) tree.to_quad_tree(user_zip_list) lars_path = configParser.get('system-config', 'lars') tree.export_tree(join(data_set_abs_path, abspath(lars_path)))
#main.py """ Created on Tue Jun 26 17:29:33 2018 @author: JadyWu """ #%% from QuadTree import QuadTree print("Implementation of FCM into") print("start generating the tree") tree = QuadTree(0.0, 0.0, 4.0, 4.0, None, 0, "0") tree.generateQuadtree(5) tree.writeTreeToConsole() print("generating the tree finished\n") print("start writing") tree.writeTreeToVtk("quadTree.vtk") print("writing finished\n")
from matplotlib import cm MAX_OBJECTS = 5 for d in range(2, 10): ax = plt.subplot(1, 2, 1) ax2 = plt.subplot(1, 2, 2) print 'Depth = %d' % d st = time.time() # build quadtree print 'Building QuadTree...', quadtree = QuadTree(d, [mins[0], maxs[0], mins[1], maxs[1]], MAX_OBJECTS) quadtree.clear_gobjects() colors = [] for i in range(d): colors.append(cm.Blues(1. * i / d)) level = quadtree.get_minlevel() plt.title('Level ' + str(level)) plotted_bounds = [] for t in triobjects: quadtree.insert_gobject(t) bounds = [] quadtree.getBounds(bounds)