def get_all_tiles(base_tile: Tile, align_tile: Tile, integer_align): result_tiles = [] align_tags = [] # a tag tuple to indicate the alignment types for base_edge_idx in range(base_tile.get_edge_num()): for align_neighbor_idx in range(align_tile.get_edge_num()): for align_mode in [0, 1]: align_tag = (base_tile.id, align_tile.id, base_edge_idx, align_neighbor_idx, align_mode) if integer_align: base_edge_length = base_tile.get_edge_length(base_edge_idx) tile_edge_length = align_tile.get_edge_length(align_neighbor_idx) if abs(math.floor(base_edge_length / tile_edge_length + EPS) - base_edge_length / tile_edge_length) > EPS and \ abs(math.floor(tile_edge_length / base_edge_length + EPS) - tile_edge_length / base_edge_length) > EPS: continue new_tile = get_tile_instance(base_tile, base_edge_idx, align_tile, align_neighbor_idx, align_mode=align_mode) if tiling_util.intersection_area(new_tile, base_tile) < EPS: result_tiles.append(new_tile) align_tags.append(align_tag) return result_tiles, align_tags
def _form__graph(self): print("start computing adjacency brick_layouts...") for i, j in itertools.combinations(range(len(self.tiles)), 2): colli_area = tiling_util.intersection_area(self.tiles[i], self.tiles[j]) align_length = tiling_util.polygon_align_length(self.tiles[i], self.tiles[j]) self.max_align_length = max(align_length, self.max_align_length) edge_feature_back = self.to_edge_feature(colli_area, align_length) if align_length > 1e-6 and colli_area < 1e-6: tile_i_align, tile_j_align = tiling_util.polygon_align_type(self.tiles[i], self.tiles[j]) else: tile_i_align, tile_j_align = 0, 0 # reflected feature edge_feature = self.to_edge_feature_new(colli_area, align_length, tile_i_align, tile_j_align, self.tiles[i].id, self.tiles[j].id) reflected_feature = self.to_edge_feature_new(colli_area, align_length, tile_j_align, tile_i_align, self.tiles[j].id, self.tiles[i].id) ## assertion of correctness assert edge_feature_back is None or \ edge_feature is None or \ (edge_feature[0] == edge_feature_back[0] and \ edge_feature[1] == edge_feature_back[1] and \ edge_feature[2] == tile_i_align and edge_feature[3] == tile_j_align) if edge_feature is not None: if colli_area < 1e-6: tile_i_align, tile_j_align = tiling_util.polygon_align_type(self.tiles[i], self.tiles[j]) self._addEdge(i, j, edge_feature) self._addEdge(j, i, reflected_feature) print("Computing adjacency brick_layouts complete.") print(f"Node count: {len(self.tiles)}") print(f"Edge count: {len(self.adj_edges + self.colli_edges)}") print("Tiles:") for idx, tile in enumerate(self.tiles): print(f":{idx}->{tile.id}")
def edge_features_mapping(self, proto_tiles): unique_features = [] # for each center tiles and align tiles: cnt_i = 0 for center_tile in proto_tiles: cnt_i += 1 cnt_j = 0 for align_tile in proto_tiles: cnt_j += 1 # get one ring neigbhour one_ring_tiles, _ = get_all_tiles(center_tile, align_tile, integer_align = True) one_ring_tiles = self._remove_reductant(one_ring_tiles) # calculating unique features for neigbor_tile in one_ring_tiles: colli_area = tiling_util.intersection_area(center_tile, neigbor_tile) align_length = tiling_util.polygon_align_length(center_tile, neigbor_tile) edge_feature_back = self.to_edge_feature(colli_area, align_length) if align_length > 1e-6 and colli_area < 1e-6: tile_i_align, tile_j_align = tiling_util.polygon_align_type(center_tile, neigbor_tile) else: tile_i_align, tile_j_align = 0, 0 edge_feature = self.to_edge_feature_new(colli_area, align_length, tile_i_align, tile_j_align, center_tile.id, neigbor_tile.id) reflected_feature = self.to_edge_feature_new(colli_area, align_length, tile_j_align, tile_i_align, neigbor_tile.id, center_tile.id) ## assertion of correctness assert edge_feature_back is None or \ edge_feature is None or \ (edge_feature[0] == edge_feature_back[0] and \ edge_feature[1] == edge_feature_back[1] and \ edge_feature[2] == tile_i_align and edge_feature[3] == tile_j_align) if edge_feature is not None: # get direct (i -> j) or reflected features(j -> i) current_edge_feature = edge_feature[self.align_start_index:] current_reflected_feature = reflected_feature[self.align_start_index:] # not in existing list: for u in unique_features: assert len(u) == len(current_edge_feature) ## ensure both of alignment and reflection do not exist in the list if not any( np.allclose(np.array(unique_feature),np.array(current_edge_feature), atol = ONE_HOT_EPS) for unique_feature in unique_features) \ and not any( np.allclose(np.array(unique_feature),np.array(current_reflected_feature), atol = ONE_HOT_EPS) for unique_feature in unique_features) \ and edge_feature[0] < EPS: unique_features.append(current_edge_feature) assert edge_feature[1] > 0 # assertion for correctness for i, j in itertools.combinations(range(len(unique_features)), 2): assert ( ( not (unique_features[i][2] == unique_features[j][2] and unique_features[i][3] == unique_features[j][3]) or abs(unique_features[i][0] - unique_features[j][0]) + abs( unique_features[i][1] - unique_features[j][1]) > EPS ) or not (unique_features[i][2] == unique_features[j][3] and unique_features[i][3] == unique_features[j][2]) or abs(unique_features[i][0] - unique_features[j][1]) + abs( unique_features[i][1] - unique_features[j][0]) > EPS ) print("one_hot_cnt: ", len(unique_features)) return unique_features