def has_isolated_areas(area_map, obstacle=-1): """ Flood fills the area to check if there are isolated areas. """ v_map = (area_map == obstacle).copy() f_point = get_random_coords(area_map, 1, obstacle)[0] to_visit = [f_point] while len(to_visit) > 0: l = len(to_visit) for point in to_visit: v_map[point] = True for i in range(l): for adj_point in get_adj(*to_visit.pop(0)): if is_valid(adj_point, area_map, obstacle) \ and not v_map[adj_point] \ and adj_point not in to_visit: to_visit.append(adj_point) if v_map.sum() == v_map.size: return False return True
def wavefront_caller(area_map, start_point, center_point, obstacle=-1): """ The main wavefront algorithm. start_point, center_point : form (x,y) return : coverage_path : path followed on for coverage backtrack_paths : paths followed to get to uncovered point, subsets of coverage_path. backtrack_starts : starting indices of the backtrack paths """ assert is_valid(start_point, area_map, obstacle), "invalid start" assert is_valid(center_point, area_map, obstacle), "invalid center" dist_map = dist_fill(area_map, [center_point]) return wavefront_follow(dist_map, start_point, obstacle)
def get_step(path_map, next_point, obstacle=-1): min_d_val = path_map[next_point] possible_point = None for adj_point in get_adj(*next_point): if is_valid(adj_point, path_map, obstacle): d_val = path_map[adj_point] if d_val < min_d_val: min_d_val = d_val possible_point = adj_point return possible_point, min_d_val
def loop(): d_val = 1 while len(to_visit) > 0: l = len(to_visit) for point in to_visit: d_map[point] = d_val v_map[point] = True if point == start_point: return # check if point is the start or something d_val += 1 for i in range(l): for adj_point in get_adj(*to_visit.pop(0)): if is_valid(adj_point, area_map, obstacle) \ and not v_map[adj_point] \ and adj_point not in to_visit: to_visit.append(adj_point)
def get_next_valid(c_point, keeper, obstacle): """ Checks points (RDLU) for one with max dist and not yet visited. """ rdlu = lambda p:np.array([(p[0],p[1]+1),(p[0]+1,p[1]),\ (p[0],p[1]-1),(p[0]-1,p[1])]) max_ = -1 next_point = None for possible_point in rdlu(c_point): possible_point = tuple(possible_point) """ is_valid = True if the point is within bounds and hasn't been visited previously. """ if is_valid(possible_point, keeper["is_visited"], obstacle=True): d_val = keeper["dist_map"][possible_point] if d_val > max_: max_ = d_val next_point = possible_point return next_point
def dist_fill_single(area_map, fill_point): v_map = area_map == OB dist_map = area_map.copy().astype(np.int32) assert is_valid(fill_point, area_map), \ "invalid fill point" fval = 0 dist_map[fill_point] = fval v_map[fill_point] = True to_visit = np.array([fill_point]) while len(to_visit) > 0: x, y = np.array(to_visit).T dist_map[x, y] = fval v_map[x, y] = True udlr = np.unique(get_udlr(to_visit), axis=0) mask = is_valid_vectorized(udlr, v_map) to_visit = udlr[mask] fval += 1 return dist_map