def findEdge(tuple, binary): path = [ (tuple), ] binary = binary # Keep finding edge until exit expression is satified while True: # If a closed path is form, exit the function if len(path) > 1 and path[0] == path[-1]: print("") return path else: print("Tracing at {} \r".format((path[-1])), end="") # Finds the pixels with normal diagonal setting (Adds extra black pixel) try: possible_points, binary = getNextCorner(path[-1], binary) next_point = detectDeadend(possible_points, path)[0] # Finds the pixels with invert setting if normal setting fails (Adds white pixel instead) except IndexError: try: possible_points, binary = getNextCorner(path[-1], binary, invert=True) next_point = detectDeadend(possible_points, path)[0] # If both methods fail, output the last 10 pixels for debugging and raise error except IndexError: print("") print("Last 10 points of the path: {}".format(path[-10:])) raise IndexError( "This error should only occur when processing diagonal pixels, refer to readme.md for more info." ) # Append next point to path path.append(next_point)
def bugBase(startpoint, endpoint, path, obstacleslist, step_size): # INPUT: startpoint is a tuple (x_start,y_start) in W_free # INPUT: endpoint is a tuple (x_end, y_end) in W_free # INPUT: obstaclelist contains lists of polygons, # Where each list in obstaclelist contains the vertices of the polygons # INPUT: step_size the maximum line-segment length between each points # That is going to become the path of the robot # OUTPUT: A sequence/list of points from start to the first collision with a polygon # that is if there is no polygons on the line between start-goal the list will be points # going from start to goal # OUTPUT: Also returns the message "FAIL" or "SUCCESS" strings to say if you reached goal or not ## Q? Is it assumed that the obstacles are all in the way of the robot? startGoalDist = hw1.computeDistanceBetweenTwoPoints(startpoint, endpoint) directionalVector = ( step_size * (endpoint[0] - startpoint[0]) / startGoalDist, step_size * (endpoint[1] - startpoint[1]) / startGoalDist, ) current_position = startpoint while hw1.computeDistanceBetweenTwoPoints(current_position, endpoint) > step_size: polygonClosest, distanceToPolygon = closestPolygon( current_position, obstacleslist) if distanceToPolygon < step_size: return "Failure, There is an obstacle between the start and goal", path, polygonClosest current_position = ( path[-1][0] + directionalVector[0], path[-1][1] + directionalVector[1], ) path.append(current_position) path.append(endpoint) return "Success", path, None
def calc_edges_for_path(trace, node_index): edges = [] path = [node_index[trace[0]['descriptor']]] for i in range(0,len(trace)-1): left = node_index[trace[i]['descriptor']] right = node_index[trace[i+1]['descriptor']] if left > right: edges.append((right,left)) else: edges.append((left,right)) path.append(right) return edges, path
def create_path(start, end, speedmean, speedvar, thetavar): """Simulate a ship moving from start to end.""" path = [] p = start[:] while np.linalg.norm(p - end) > 0.1: direction = end - p speed = max(0.001, np.random.normal(speedmean, speedvar)) theta = np.random.normal(np.arctan2(direction[1], direction[0]), thetavar) delta = speed*np.array([np.cos(theta), np.sin(theta)]) path.append([p[0], p[1], delta[0], delta[1]]) p += delta return path
def create_path(start, end, speedmean, speedvar, thetavar): """Simulate a ship moving from start to end.""" path = [] p = start[:] while np.linalg.norm(p - end) > 0.1: direction = end - p speed = max(0.001, np.random.normal(speedmean, speedvar)) theta = np.random.normal(np.arctan2(direction[1], direction[0]), thetavar) delta = speed * np.array([np.cos(theta), np.sin(theta)]) path.append([p[0], p[1], delta[0], delta[1]]) p += delta return path
def calc_edges_for_path(trace, node_index): edges = [] path = [node_index[trace[0]['descriptor']]] for i in range(0,len(trace)-1): left = node_index[trace[i]['descriptor']] right = node_index[trace[i+1]['descriptor']] if left > right: edges.append((right,left)) else: edges.append((left,right)) path.append(right) # still a bug. The path from D to S2 lacks S2, so for the demo we just draw it! if path[0] == node_index['D'] and path[-1] != node_index['S1']: path.append(node_index['S2']) return edges, path
def construct_paths(segs): """constructed paths from segs""" n = len(segs) assert(n > 0) paths = [] path = [] used = [0] * n for _ in range(n): if not path: # path is empty for i, seg in enumerate(segs): if used[i]: continue else: used[i] = 1 P1, P2 = seg path.append(P1) path.append(P2) break else: P0 = path[-1] for i, seg in enumerate(segs): if used[i]: continue else: P1, P2 = seg if is_point_close(P0, P1): used[i] = 1 path.append(P2) break elif is_point_close(P0, P2): used[i] = 1 path.append(P1) break else: print("Polygon construction failed") if is_point_close(path[0], path[-1]): path = np.array(path) path = path[:-1] area = 0 xs, ys = path[:, 0], path[:, 1] m = path.shape[0] for i in range(m): j = (i + 1) % m area += xs[i] * ys[j] - xs[j] * ys[i] if area < 0: path = np.flipud(path) paths.append(path) path = [] return paths
def resample_to_shape(source_file, region, sp_res, grid, prefix=None, nan_value=None, dest_nan_value=None, variables=None, shapefile=None): """ Resamples images and clips country boundaries Parameters ---------- source_file : str Path to source file. region : str Identifier of the region in the shapefile. If the default shapefile is used, this would be the FIPS country code. sp_res : int or float Spatial resolution of the shape-grid. grid : poets.grid.RegularGrid or poets.grid.ShapeGrid Grid to resample data to. prefix : str, optional Prefix for the variable in the NetCDF file, should be name of source nan_value : int, float, optional Not a number value of the original data as given by the data provider dest_nan_value : int or float, optional NaN value used in the final NetCDF file. variables : list of str, optional Variables to resample from original file. shapefile : str, optional Path to shape file, uses "world country admin boundary shapefile" by default. Returns ------- res_data : dict of numpy.arrays resampled image dest_lon : numpy.array longitudes of the points in the resampled image dest_lat : numpy.array latitudes of the points in the resampled image gpis : numpy.array grid point indices timestamp : datetime.date date of the image metadata : dict Metadata derived from input file. """ if prefix is not None: prefix += '_' fileExtension = os.path.splitext(source_file)[1].lower() if region == 'global': lon_min = -180 lon_max = 180 lat_min = -90 lat_max = 90 else: shp = Shape(region, shapefile) lon_min = shp.bbox[0] lon_max = shp.bbox[2] lat_min = shp.bbox[1] lat_max = shp.bbox[3] if fileExtension in ['.nc', '.nc3', '.nc4']: data_src, lon, lat, timestamp, metadata = nc.read_image( source_file, variables) if (lon_min >= lon.max() or lon_max <= lon.min() or lat_max <= lat.min() or lat_min >= lat.max()): return "No data" data, src_lon, src_lat = nc.clip_bbox(data_src, lon, lat, lon_min, lat_min, lon_max, lat_max) elif fileExtension in ['.h5']: data_src, lon, lat, timestamp, metadata = h5.read_image( source_file, variables) if (lon_min >= lon.max() or lon_max <= lon.min() or lat_max <= lat.min() or lat_min >= lat.max()): return "No data" data, src_lon, src_lat = nc.clip_bbox(data_src, lon, lat, lon_min, lat_min, lon_max, lat_max) elif fileExtension in imgfiletypes: data, src_lon, src_lat, timestamp, metadata = bbox_img( source_file, region, fileExtension, shapefile) if nan_value is not None: for key in data.keys(): data[key] = np.ma.array(data[key], mask=(data[key] == nan_value)) src_lon, src_lat = np.meshgrid(src_lon, src_lat) lons = grid.arrlon[0:grid.shape[0]] dest_lon, dest_lat = np.meshgrid(lons, np.unique(grid.arrlat)[::-1]) gpis = grid.get_bbox_grid_points(grid.arrlat.min(), grid.arrlat.max(), grid.arrlon.min(), grid.arrlon.max()) search_rad = 180000 * sp_res data = resample.resample_to_grid(data, src_lon, src_lat, dest_lon, dest_lat, search_rad=search_rad) res_data = {} path = [] if region != 'global': _, _, multipoly = shp._get_shape() for ring in multipoly: poly_verts = list(ring.exterior.coords) path.append(matplotlib.path.Path(poly_verts)) coords = [grid.arrlon, grid.arrlat[::-1]] coords2 = np.zeros((len(coords[0]), 2)) for idx in range(0, len(coords[0])): coords2[idx] = [coords[0][idx], coords[1][idx]] mask_old = path[0].contains_points(coords2) for key in data.keys(): if variables is not None: if key not in variables: del metadata[key] continue if region != 'global': for ring in path: mask_new = (ring.contains_points(coords2)) mask_rev = scipy.logical_or(mask_old, mask_new) mask_old = mask_rev mask_rev = mask_rev.reshape(dest_lon.shape) mask = np.invert(mask_rev) mask[data[key].mask == True] = True else: mask = data[key].mask if prefix is None: var = key else: var = prefix + key if metadata is not None: metadata[var] = metadata[key] if var != key: del metadata[key] res_data[var] = np.ma.masked_array(data[key], mask=np.copy(mask), fill_value=dest_nan_value) dat = np.copy(res_data[var].data) dat[mask == True] = dest_nan_value res_data[var] = np.ma.masked_array(dat, mask=np.copy(mask), fill_value=dest_nan_value) return res_data, dest_lon, dest_lat, gpis, timestamp, metadata
def resample_to_shape(source_file, region, sp_res, grid, prefix=None, nan_value=None, dest_nan_value=None, variables=None, shapefile=None): """ Resamples images and clips country boundaries Parameters ---------- source_file : str Path to source file. region : str Identifier of the region in the shapefile. If the default shapefile is used, this would be the FIPS country code. sp_res : int or float Spatial resolution of the shape-grid. grid : poets.grid.RegularGrid or poets.grid.ShapeGrid Grid to resample data to. prefix : str, optional Prefix for the variable in the NetCDF file, should be name of source nan_value : int, float, optional Not a number value of the original data as given by the data provider dest_nan_value : int or float, optional NaN value used in the final NetCDF file. variables : list of str, optional Variables to resample from original file. shapefile : str, optional Path to shape file, uses "world country admin boundary shapefile" by default. Returns ------- res_data : dict of numpy.arrays resampled image dest_lon : numpy.array longitudes of the points in the resampled image dest_lat : numpy.array latitudes of the points in the resampled image gpis : numpy.array grid point indices timestamp : datetime.date date of the image metadata : dict Metadata derived from input file. """ if prefix is not None: prefix += '_' fileExtension = os.path.splitext(source_file)[1].lower() if region == 'global': lon_min = -180 lon_max = 180 lat_min = -90 lat_max = 90 else: shp = Shape(region, shapefile) lon_min = shp.bbox[0] lon_max = shp.bbox[2] lat_min = shp.bbox[1] lat_max = shp.bbox[3] if fileExtension in ['.nc', '.nc3', '.nc4']: data_src, lon, lat, timestamp, metadata = nc.read_image(source_file, variables) if (lon_min >= lon.max() or lon_max <= lon.min() or lat_max <= lat.min() or lat_min >= lat.max()): return "No data" data, src_lon, src_lat = nc.clip_bbox(data_src, lon, lat, lon_min, lat_min, lon_max, lat_max) elif fileExtension in ['.h5']: data_src, lon, lat, timestamp, metadata = h5.read_image(source_file, variables) if (lon_min >= lon.max() or lon_max <= lon.min() or lat_max <= lat.min() or lat_min >= lat.max()): return "No data" data, src_lon, src_lat = nc.clip_bbox(data_src, lon, lat, lon_min, lat_min, lon_max, lat_max) elif fileExtension in imgfiletypes: data, src_lon, src_lat, timestamp, metadata = bbox_img(source_file, region, fileExtension, shapefile) if nan_value is not None: for key in data.keys(): data[key] = np.ma.array(data[key], mask=(data[key] == nan_value)) src_lon, src_lat = np.meshgrid(src_lon, src_lat) lons = grid.arrlon[0:grid.shape[0]] dest_lon, dest_lat = np.meshgrid(lons, np.unique(grid.arrlat)[::-1]) gpis = grid.get_bbox_grid_points(grid.arrlat.min(), grid.arrlat.max(), grid.arrlon.min(), grid.arrlon.max()) search_rad = 180000 * sp_res data = resample.resample_to_grid(data, src_lon, src_lat, dest_lon, dest_lat, search_rad=search_rad) res_data = {} path = [] if region != 'global': _, _, multipoly = shp._get_shape() for ring in multipoly: poly_verts = list(ring.exterior.coords) path.append(matplotlib.path.Path(poly_verts)) coords = [grid.arrlon, grid.arrlat[::-1]] coords2 = np.zeros((len(coords[0]), 2)) for idx in range(0, len(coords[0])): coords2[idx] = [coords[0][idx], coords[1][idx]] mask_old = path[0].contains_points(coords2) for key in data.keys(): if variables is not None: if key not in variables: del metadata[key] continue if region != 'global': for ring in path: mask_new = (ring.contains_points(coords2)) mask_rev = scipy.logical_or(mask_old, mask_new) mask_old = mask_rev mask_rev = mask_rev.reshape(dest_lon.shape) mask = np.invert(mask_rev) mask[data[key].mask == True] = True else: mask = data[key].mask if prefix is None: var = key else: var = prefix + key if metadata is not None: metadata[var] = metadata[key] if var != key: del metadata[key] res_data[var] = np.ma.masked_array(data[key], mask=np.copy(mask), fill_value=dest_nan_value) dat = np.copy(res_data[var].data) dat[mask == True] = dest_nan_value res_data[var] = np.ma.masked_array(dat, mask=np.copy(mask), fill_value=dest_nan_value) return res_data, dest_lon, dest_lat, gpis, timestamp, metadata
def onclick(self, event): """ Draw contours on the data for a click in the thematic map :param event: mouse click on thematic map preview """ if event.inaxes == self.previewax: y, x = int(event.xdata), int(event.ydata) label = self.selection_array[x, y] contiguous_regions = scipy.ndimage.label( self.selection_array == label)[0] this_region = contiguous_regions == (contiguous_regions[x, y]) # remove the boundaries so any region touching the edge isn't drawn odd this_region[0, :] = 0 this_region[:, 0] = 0 this_region[this_region.shape[0] - 1, :] = 0 this_region[:, this_region.shape[1] - 1] = 0 # convert the region mask into just a true/false array of its boundary pixels edges = binary_erosion(this_region) ^ this_region # convert the boundary pixels into a path, moving around instead of just where x, y = np.where(edges) coords = np.dstack([x, y])[0] path = [coords[0]] coords = coords[1:] while len(coords): # and steps < 5: dist = np.sum(np.abs(path[-1] - coords), axis=1) # neighbor_index = np.where(dist == 1)[0][0] neighbor_index = np.argmin(dist) if dist[neighbor_index] < 5: path.append(coords[neighbor_index].copy()) coords[neighbor_index:-1] = coords[neighbor_index + 1:] coords = coords[:-1] # not_finished = len(coords) != 0 else: break # path.append(path[0].copy()) path = np.array(path) clips = [] while len(coords) > 5: dist = np.sum(np.abs(path[-1] - coords), axis=1) neighbor_index = np.argmin(dist) clip = [coords[neighbor_index].copy()] coords[neighbor_index:-1] = coords[neighbor_index + 1:] coords = coords[:-1] while len(coords): dist = np.sum(np.abs(clip[-1] - coords), axis=1) # neighbor_index = np.where(dist == 1)[0][0] neighbor_index = np.argmin(dist) if dist[neighbor_index] < 5: # print(coords[neighbor_index], dist[neighbor_index]) clip.append(coords[neighbor_index].copy()) coords[neighbor_index:-1] = coords[neighbor_index + 1:] coords = coords[:-1] # not_finished = len(coords) != 0 else: break clips.append(np.array(clip)) self.region_patches.append( PatchCollection([ Polygon(np.dstack([path[:, 1], path[:, 0]])[0], False, fill=False, facecolor=None, edgecolor="black", alpha=1, lw=2.5) ] + [ Polygon(np.dstack([clip[:, 1], clip[:, 0]])[0], False, fill=False, facecolor=None, edgecolor="black", alpha=1, lw=2.0) for clip in clips ], match_original=True)) #self.imageax.add_patch(self.region_patches[-1]) self.imageax.add_collection(self.region_patches[-1]) self.fig.canvas.draw_idle()
def circumnavigateObstacle(p_hit, goal_point, path, obstacle, step_size): # logic to go around obstacle and finding p_leave # Remember where we started leftStart = False start_point = p_hit start_line_point = computeNextMove(p_hit, obstacle, step_size) current_point = start_point # Optimal point of leave p_leave = p_hit shortest_distance_to_goal = hw1.computeDistanceBetweenTwoPoints( p_hit, goal_point) while True: # Once the robot reenters the line segment between start_point and start_line_point # The robot has completed one round around the obstacle if not leftStart and hw1.computeDistancePointToSegment( current_point, start_point, start_line_point)[0] > step_size: # Once it leaves the line segment at start, set leftStart to True leftStart = True current_point = computeNextMove(current_point, obstacle, step_size) path.append(current_point) distance_to_goal = hw1.computeDistanceBetweenTwoPoints( current_point, goal_point) if distance_to_goal < shortest_distance_to_goal: # Find point of leave p_leave = current_point shortest_distance_to_goal = distance_to_goal if (hw1.computeDistancePointToSegment(path[-1], start_point, start_line_point)[0] < 2 * step_size) and leftStart: # Get out of this while loop break # Now the robot have to move to the point of leave while True: p_leave_line_point = computeNextMove(p_leave, obstacle, step_size) if hw1.computeDistancePointToSegment( path[-1], p_leave, p_leave_line_point)[0] < step_size: # The point of leave is necessarily at the exact point it has been at before break # move until at point of leave current_point = computeNextMove(current_point, obstacle, step_size) path.append(current_point) # Move one step away from polygon directionalVector = ( (goal_point[0] - current_point[0]) / hw1.computeDistanceBetweenTwoPoints(current_point, goal_point), (goal_point[1] - current_point[1]) / hw1.computeDistanceBetweenTwoPoints(current_point, goal_point), ) if hw1.computeDistanceBetweenTwoPoints(current_point, goal_point) > step_size: current_point = ( current_point[0] + directionalVector[0] * step_size, current_point[1] + directionalVector[1] * step_size, ) path.append(current_point) else: current_point = goal_point path.append(current_point) return path
def astar(maze, start, end): """Returns a list of tuples as a path from the given start to the given end in the given maze""" # Create start and end node start_node = Node(None, start) start_node.g = start_node.h = start_node.f = 0 end_node = Node(None, end) end_node.g = end_node.h = end_node.f = 0 # Initialize both open and closed list open_list = [] closed_list = [] # Add the start node open_list.append(start_node) # Loop until you find the end while len(open_list) > 0: # Get the current node current_node = open_list[0] current_index = 0 for index, item in enumerate(open_list): if item.f < current_node.f: current_node = item current_index = index # Pop current off open list, add to closed list open_list.pop(current_index) closed_list.append(current_node) # Found the goal if current_node == end_node: path = [] current = current_node while current is not None: path.append(current.position) current = current.parent return path[::-1] # Return reversed path # Generate children children = [] for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares # Get node position node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1]) # Make sure within range if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0: continue # Make sure walkable terrain if maze[node_position[0]][node_position[1]] != 0: continue # Create new node new_node = Node(current_node, node_position) # Append children.append(new_node) # Loop through children for child in children: # Child is on the closed list for closed_child in closed_list: if child == closed_child: continue # Create the f, g, and h values child.g = current_node.g + 1 child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2) child.f = child.g + child.h # Child is already in the open list for open_node in open_list: if child == open_node and child.g > open_node.g: continue # Add the child to the open list open_list.append(child)