def display_matplotlib(self): fig = plt.figure(1, figsize=SIZE, dpi=90) ax = fig.add_subplot(111) for polygon in self.scene: plot_coords(ax, polygon.exterior) patch = patches.Polygon(polygon.exterior.xy, facecolor=color_isvalid(self.scene), edgecolor=color_isvalid(self.scene, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) plt.show()
def plotTest(sheet, agents, fname): fig = plt.figure(figsize=SIZE, dpi=90) # 3: invalid polygon, ring touch along a line ax = fig.add_subplot(121) plot_coords(ax, sheet.exterior) for _a in agents: patch = PolygonPatch(_a, facecolor=color_isvalid(_a), edgecolor=color_isvalid(_a, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) plt.savefig(fname)
from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid fig = pyplot.figure(1, figsize=SIZE, dpi=90) # 3: invalid polygon, ring touch along a line ax = fig.add_subplot(121) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int = [(0.5, 0), (1.5, 0), (1.5, 1), (0.5, 1), (0.5, 0)] polygon = Polygon(ext, [int]) plot_coords(ax, polygon.interiors[0]) plot_coords(ax, polygon.exterior) patch = PolygonPatch(polygon, facecolor=color_isvalid(polygon), edgecolor=color_isvalid(polygon, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) ax.set_title('c) 无效', fontproperties=font_song) set_limits(ax, -1, 3, -1, 3) # 4: invalid self-touching ring ax = fig.add_subplot(122) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int_1 = [(0.5, 0.25), (1.5, 0.25), (1.5, 1.25), (0.5, 1.25), (0.5, 0.25)] int_2 = [(0.5, 1.25), (1, 1.25), (1, 1.75), (0.5, 1.75)] # int_2 = [
from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid fig = pyplot.figure(1, figsize=SIZE, dpi=90) # 1: valid multi-polygon ax = fig.add_subplot(121) a = [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)] b = [(1, 1), (1, 2), (2, 2), (2, 1), (1, 1)] multi1 = MultiPolygon([[a, []], [b, []]]) for polygon in multi1: plot_coords(ax, polygon.exterior) patch = PolygonPatch(polygon, facecolor=color_isvalid(multi1), edgecolor=color_isvalid(multi1, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) ax.set_title('a) valid') set_limits(ax, -1, 3, -1, 3) #2: invalid self-touching ring ax = fig.add_subplot(122) c = [(0, 0), (0, 1.5), (1, 1.5), (1, 0), (0, 0)] d = [(1, 0.5), (1, 2), (2, 2), (2, 0.5), (1, 0.5)] multi2 = MultiPolygon([[c, []], [d, []]]) for polygon in multi2:
from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid fig = pyplot.figure(1, figsize=SIZE, dpi=90) # 3: invalid polygon, ring touch along a line ax = fig.add_subplot(121) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int = [(0.5, 0), (1.5, 0), (1.5, 1), (0.5, 1), (0.5, 0)] polygon = Polygon(ext, [int]) plot_coords(ax, polygon.interiors[0]) plot_coords(ax, polygon.exterior) patch = PolygonPatch(polygon, facecolor=color_isvalid(polygon), edgecolor=color_isvalid(polygon, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) ax.set_title('c) invalid') set_limits(ax, -1, 3, -1, 3) #4: invalid self-touching ring ax = fig.add_subplot(122) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int_1 = [(0.5, 0.25), (1.5, 0.25), (1.5, 1.25), (0.5, 1.25), (0.5, 0.25)] int_2 = [(0.5, 1.25), (1, 1.25), (1, 1.75), (0.5, 1.75)] # int_2 = [ polygon = Polygon(ext, [int_1, int_2]) plot_coords(ax, polygon.interiors[0])
from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid fig = pyplot.figure(1, figsize=SIZE, dpi=90) # 1: valid multi-polygon ax = fig.add_subplot(121) a = [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)] b = [(1, 1), (1, 2), (2, 2), (2, 1), (1, 1)] multi1 = MultiPolygon([[a, []], [b, []]]) for polygon in multi1: plot_coords(ax, polygon.exterior) patch = PolygonPatch(polygon, facecolor=color_isvalid(multi1), edgecolor=color_isvalid(multi1, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) ax.set_title('a) 有效', fontproperties=font_song) set_limits(ax, -1, 3, -1, 3) # 2: invalid self-touching ring ax = fig.add_subplot(122) c = [(0, 0), (0, 1.5), (1, 1.5), (1, 0), (0, 0)] d = [(1, 0.5), (1, 2), (2, 2), (2, 0.5), (1, 0.5)]
def plot_line_isvalid(ax, ob, **kwargs): kwargs["color"] = color_isvalid(ob) plot_line(ax, ob, **kwargs)
def gen_macros_for_fence_region(macro_pos_x, macro_pos_y, macro_size_x, macro_size_y, regions, xl, xh, yl, yh, merge=False, plot=False): # tt = time.time() macros = MultiPolygon([ box( macro_pos_x[i], macro_pos_y[i], macro_pos_x[i] + macro_size_x[i], macro_pos_y[i] + macro_size_y[i], ) for i in range(macro_size_x.size(0)) ]) # print("macro:", time.time()-tt) # tt = time.time() num_boxes = regions.size(0) regions = regions.view(num_boxes, 2, 2) fence_regions = MultiPolygon([ box(regions[i, 0, 0], regions[i, 0, 1], regions[i, 1, 0], regions[i, 1, 1]) for i in range(num_boxes) ]) site = box(xl, yl, xh, yh) reverse = site.difference(fence_regions).union(macros) # print("fence region:", time.time()-tt) # tt = time.time() slices = [] xs = torch.cat( [regions[:, :, 0].view(-1), macro_pos_x, macro_pos_x + macro_size_x], dim=0).sort()[0] for i in range(xs.size(0) + 1): x_l = xl if i == 0 else xs[i - 1] x_h = xh if i == xs.size(0) else xs[i] cvx_hull = box(x_l, yl, x_h, yh) intersect = reverse.intersection(cvx_hull) if isinstance(intersect, Polygon): slices.append(intersect.bounds) elif isinstance(intersect, (GeometryCollection, MultiPolygon)): slices.extend( [j.bounds for j in intersect if (isinstance(j, Polygon))]) # print("slicing:", time.time()-tt) # tt = time.time() if merge: raw_bbox_list = sorted(slices, key=lambda x: (x[1], x[0])) cur_bbox = None bbox_list = [] for i, p in enumerate(raw_bbox_list): minx, miny, maxx, maxy = p if cur_bbox is None: cur_bbox = [minx, miny, maxx, maxy] elif cur_bbox[1] == miny and cur_bbox[3] == maxy: cur_bbox[2:] = p[2:] else: bbox_list.append(cur_bbox) cur_bbox = [minx, miny, maxx, maxy] else: bbox_list.append(cur_bbox) else: bbox_list = slices # print("merge:", time.time()-tt) bbox_list = torch.tensor(bbox_list).float() pos_x = bbox_list[:, 0] pos_y = bbox_list[:, 1] node_size_x = bbox_list[:, 2] - bbox_list[:, 0] node_size_y = bbox_list[:, 3] - bbox_list[:, 1] if plot: from descartes.patch import PolygonPatch from matplotlib import pyplot as plt from figures import BLUE, SIZE, color_isvalid, plot_coords, set_limits res = [] for bbox in bbox_list: res.append(box(*bbox)) res = MultiPolygon(res) fig = plt.figure(1, figsize=SIZE, dpi=90) ax = fig.add_subplot(121) for polygon in res: # plot_coords(ax, polygon.exterior) patch = PolygonPatch( polygon, facecolor=color_isvalid(fence_regions), edgecolor=color_isvalid(fence_regions, valid=BLUE), alpha=0.5, zorder=2, ) ax.add_patch(patch) set_limits(ax, -1, 20, -1, 20) ax = fig.add_subplot(122) patch = PolygonPatch( reverse, facecolor=color_isvalid(reverse), edgecolor=color_isvalid(reverse, valid=BLUE), alpha=0.5, zorder=2, ) ax.add_patch(patch) set_limits(ax, -1, 20, -1, 20) plt.savefig("polygon.png") return pos_x, pos_y, node_size_x, node_size_y
def slice_non_fence_region( regions, xl, yl, xh, yh, macro_pos_x=None, macro_pos_y=None, macro_size_x=None, macro_size_y=None, merge=False, plot=False, figname="non_fence_region.png", device=torch.device("cuda:0"), ): if type(regions) == list: if isinstance(regions[0], np.ndarray): regions = torch.from_numpy(np.concatenate(regions, 0)).to(device) elif isinstance(regions[0], torch.Tensor): regions = torch.cat(regions, dim=0).to(device) # [n_box, 4] elif isinstance(regions, np.ndarray): regions = torch.from_numpy(regions).to(device) if macro_pos_x is not None: if isinstance(macro_pos_x, np.ndarray): macro_pos_x = torch.from_numpy(macro_pos_x).to(device).float() macro_pos_y = torch.from_numpy(macro_pos_y).to(device).float() macro_size_x = torch.from_numpy(macro_size_x).to(device).float() macro_size_y = torch.from_numpy(macro_size_y).to(device).float() regions = torch.cat( [ regions, torch.stack([ macro_pos_x, macro_pos_y, macro_pos_x + macro_size_x, macro_pos_y + macro_size_y ], 0).t(), ], 0, ) num_boxes = regions.size(0) regions = regions.view(num_boxes, 2, 2) fence_regions = MultiPolygon([ box(regions[i, 0, 0], regions[i, 0, 1], regions[i, 1, 0], regions[i, 1, 1]) for i in range(num_boxes) ]) fence_regions = unary_union(fence_regions) site = box(xl, yl, xh, yh) non_fence_region = unary_union(site.difference(fence_regions)) slices = [] xs = regions[:, :, 0].view(-1).sort()[0] for i in range(xs.size(0) + 1): x_l = xl if i == 0 else xs[i - 1] x_h = xh if i == xs.size(0) else xs[i] cvx_hull = box(x_l, yl, x_h, yh) if x_l >= x_h or not cvx_hull.is_valid: continue intersect = non_fence_region.intersection(cvx_hull) if isinstance(intersect, Polygon) and len(intersect.bounds) == 4: slices.append(intersect.bounds) elif isinstance(intersect, (GeometryCollection, MultiPolygon)): slices.extend([ j.bounds for j in intersect if (isinstance(j, Polygon) and len(j.bounds) == 4) ]) if merge: raw_bbox_list = sorted(slices, key=lambda x: (x[1], x[0])) cur_bbox = None bbox_list = [] for i, p in enumerate(raw_bbox_list): minx, miny, maxx, maxy = p if cur_bbox is None: cur_bbox = [minx, miny, maxx, maxy] elif cur_bbox[1] == miny and cur_bbox[3] == maxy and cur_bbox[ 2] == minx: cur_bbox[2:] = p[2:] else: bbox_list.append(cur_bbox) cur_bbox = [minx, miny, maxx, maxy] else: bbox_list.append(cur_bbox) else: bbox_list = slices if plot: from descartes.patch import PolygonPatch from matplotlib import pyplot as plt # from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid res = [] bbox_list_np = np.array(bbox_list) bbox_list_np *= 1000 / np.max(bbox_list_np) for bbox in bbox_list_np: res.append(box(*bbox.tolist())) res = MultiPolygon(res) fig = plt.figure(1, figsize=SIZE, dpi=90) ax = fig.add_subplot(121) for polygon in res: # plot_coords(ax, polygon.exterior) patch = PolygonPatch( polygon, facecolor=color_isvalid(non_fence_region), edgecolor=color_isvalid(non_fence_region, valid=BLUE), alpha=0.5, zorder=2, ) ax.add_patch(patch) set_limits(ax, -1, 1000, -1, 1000, dx=100, dy=100) # ax = fig.add_subplot(122) # patch = PolygonPatch(non_fence_region, facecolor=color_isvalid( # non_fence_region), edgecolor=color_isvalid(non_fence_region, valid=BLUE), alpha=0.5, zorder=2) # ax.add_patch(patch) # set_limits(ax, -1, 1000, -1, 1000, dx=100, dy=100) plt.savefig(figname) plt.close() bbox_list = torch.tensor(bbox_list, device=device) # print("non fence region area after slicing:", ((bbox_list[:,2]-bbox_list[:,0])*(bbox_list[:,3]-bbox_list[:,1])).sum().item()) return bbox_list
from figures import BLUE, SIZE, set_limits, plot_coords, color_isvalid fig = pyplot.figure(1, figsize=SIZE, dpi=90) # 1: valid polygon ax = fig.add_subplot(121) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int = [(1, 0), (0.5, 0.5), (1, 1), (1.5, 0.5), (1, 0)][::-1] polygon = Polygon(ext, [int]) plot_coords(ax, polygon.interiors[0]) plot_coords(ax, polygon.exterior) patch = PolygonPatch(polygon, facecolor=color_isvalid(polygon), edgecolor=color_isvalid(polygon, valid=BLUE), alpha=0.5, zorder=2) ax.add_patch(patch) ax.set_title('a) valid') set_limits(ax, -1, 3, -1, 3) #2: invalid self-touching ring ax = fig.add_subplot(122) ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)] int = [(1, 0), (0, 1), (0.5, 1.5), (1.5, 0.5), (1, 0)][::-1] polygon = Polygon(ext, [int]) plot_coords(ax, polygon.interiors[0]) plot_coords(ax, polygon.exterior)