def _split_node(self, new_x, new_y): # create new child facets self.left = FacetTreeElem(self.pos_x, self.pos_y) self.right = FacetTreeElem(new_x, new_y) # calculate middle line l_point = self.left.position r_point = self.right.position con_dir_vec = r_point - l_point m_point = l_point + 0.5 * con_dir_vec m_dir_vec = con_dir_vec.cross() bisector = euclid.Line2(m_point, m_point + m_dir_vec) # calculate intersections and update polygon coordinates #print("Splitting %s into %s with new coords %s" % (self, self.right, self.coords)) for cur_x, cur_y, prev_x, prev_y in zip( self.coords[::2], self.coords[1::2], self.coords[-2:-1] + self.coords[:-2:2], self.coords[-1:] + self.coords[1:-1:2], ): #print("cur_x: %s, cur_y: %s, prev_x: %s, prev_y: %s" % (cur_x, cur_y, prev_x, prev_y)) current_edge = euclid.LineSegment2( euclid.Point2(prev_x, prev_y), euclid.Point2(cur_x, cur_y), ) intersection = bisector.intersect(current_edge) if intersection: # intersection -> add intersection point to both facet polygons if not self.left.has_coord(*list(intersection)): #print("left: adding %s to %s" % (intersection, self.left.coords)) self.left.coords.extend(list(intersection)) if not self.right.has_coord(*list(intersection)): #print("right: adding %s to %s" % (intersection, self.right.coords)) self.right.coords.extend(list(intersection)) # put current point in facet which is nearer nearest_facet = self.get_nearest(cur_x, cur_y) if not nearest_facet.has_coord(cur_x, cur_y): #print("(%s, %s) not in %s" % (cur_x, cur_y, nearest_facet.coords)) nearest_facet.coords.extend([cur_x, cur_y]) #else: #print("(%s, %s) in %s" % (cur_x, cur_y, nearest_facet.coords)) self.left.occupation = self.occupation self.occupation = None # check new facets #if self.left._is_good_facet() and self.right._is_good_facet(): #self.left.occupation = self.occupation #self.occupation = None #else: ## undo the new facets #self.left = None #self.right = None # return the facet generated from new point or None when no good facets return self.right
def activate(self): mode.Mode.activate(self) self.application.state.hotspots.append( rules.Hotspot(point=euclid.Point2( self.state.window_width / 2 + self.START_HOTSPOT_OFFSET, self.state.window_height / 2), radius=self.HOTSPOT_RADIUS, colour=(0.0, 1.0, 0.0, 1.0), callback=self.start)) self.application.state.hotspots.append( rules.Hotspot(point=euclid.Point2( self.state.window_width / 2 + self.RESET_HOTSPOT_OFFSET, self.state.window_height / 2), radius=self.HOTSPOT_RADIUS, colour=(1.0, 0.0, 0.0, 1.0), callback=self.reset))
def facet_map(self): if not hasattr(self, '_facet_map'): border_width = self.border_ratio * self.window_width _facet_map = {} _facet_grid = [] grid_coords = self._facet_grid_coords for index, coords in enumerate( zip(grid_coords[::2], grid_coords[1::2])): pos = euclid.Point2(coords[0], coords[1]) #closest_facet = min(self.facets, key=lambda f: f.position.distance(pos)) facets_by_distance = sorted( self.facets, key=lambda f: f.position.distance(pos)) if len(facets_by_distance) > 1: closest_facet = facets_by_distance[0] closest_facet_2 = facets_by_distance[1] if abs( pos.distance(closest_facet.position) - pos.distance(closest_facet_2.position) ) < border_width: closest_facet.border_indices.add(index) closest_facet_2.border_indices.add(index) else: closest_facet = facets_by_distance[0] _facet_map.setdefault(closest_facet, []).append((index, pos)) _facet_grid.append(closest_facet) self._facet_map = _facet_map self._facet_grid = _facet_grid return self._facet_map
def bounding_box(self): """ the axis parallel bounding box of the facet """ minX = float("infinity") maxX = float("-infinity") for x in self.coords[::2]: if (x < minX): minX = x if (x > maxX): maxX = x minY = float("infinity") maxY = float("-infinity") for y in self.coords[1::2]: if (y < minY): minY = y if (y > maxY): maxY = y return (euclid.Point2(minX, minY), euclid.Point2(maxX, maxY))
def get_nearest(self, x, y): if self.left == None and self.right == None: return self else: pos = euclid.Point2(x, y) dist_left = pos.distance(self.left.position) dist_right = pos.distance(self.right.position) if dist_left < dist_right: return self.left.get_nearest(x, y) else: return self.right.get_nearest(x, y)
def get_touched_blob(self, x, y): """Return the blob at position (x, y), if the touch is unambiguous, None otherwise.""" if self.state: touch_point = euclid.Point2(x, y) blobs = [] for player in self.state.players: for blob in player.blobs: if blob.position == touch_point or blob.position.distance( touch_point) < blob.radius: blobs.append(blob) if len(blobs) == 1: return blobs[0] return None
def generate_facets_2(self, facet_count): sites = [ euclid.Point2(random.randint(0, self.window_width), random.randint(0, self.window_height)) for i in range(facet_count) ] self.log.debug(u"Using sites %s to generate board...", str(sites)) context = voronoi.MultiblobContext() voronoi.voronoi(voronoi.SiteList(sites), context) self.log.debug(u"Voronoi vertices: %s", str(context.vertices)) #self.log.debug(u"Voronoi lines: %s", str(lines)) self.log.debug(u"Voronoi edges: %s", str(context.edges))
def update(self, dt, state): if random.random() > 0.5: if len(state.powerups) < self.MAX_POWERUPS: if state.facets: powerup_positions = [(p.position.x, p.position.y) for p in state.powerups] facets = [ f for f in state.facets if (f.gen_x, f.gen_y) not in powerup_positions ] min_occupation = min( [sum(f.occupation.values()) for f in facets]) facet = random.choice([ f for f in facets if sum(f.occupation.values()) == min_occupation ]) powerup = random.choice(self.powerups)(euclid.Point2( facet.gen_x, facet.gen_y)) self.log.debug(u"Placing powerup %s...", powerup) state.powerups.append(powerup) self._powerup_gen_player.queue(self._powerup_gen_source) self._powerup_gen_player.play()
def position(self): return euclid.Point2(self.pos_x, self.pos_y)
def position(self): return euclid.Point2(float(self.pos_x), float(self.pos_y))
def get_touched_hotspot(self, x, y): p = euclid.Point2(x, y) for hotspot in self.hotspots: if hotspot.c.distance(p) <= hotspot.r: return hotspot return None