def __init__(self, base_path, symmetry_tiles=True): self.base_path = base_path tiles_dir = os.path.join(base_path, 'tiles') assert os.path.isdir(base_path) assert os.path.isdir(tiles_dir) self.tiles_name = glob.glob( os.path.join(os.path.join(tiles_dir), "*.txt")) self.proto_tiles = [ Tile(Polygon(getSVGShapeAsNp(tile_name)), id=i) for i, tile_name in enumerate(self.tiles_name) ] if symmetry_tiles: symm_tiles = [] for tile in self.proto_tiles: symm_tile_poly = shapely.affinity.affine_transform( tile.tile_poly, (-1, 0, 0, 1, 0, 0)) # notice: the shape become Counter-CLOCKWISE now symm_tile_poly = shapely.geometry.polygon.orient( symm_tile_poly, sign=-1.0) symm_tiles.append( Tile(symm_tile_poly, id=tile.id + len(self.tiles_name))) self.proto_tiles.extend(symm_tiles) self.complete_graph = None assert len(self.proto_tiles) > 0 # tile count and graph can be got accordingly self.tile_count = len(self.proto_tiles)
def is_partial_edge_connected(tile_1: Tile, tile_2: Tile): # always clockwise orientation assert not tile_1.tile_poly.exterior.is_ccw assert not tile_2.tile_poly.exterior.is_ccw ########################## # checking the whether two triangle align trinagle_1_points = list(tile_1.tile_poly.exterior.coords) trinagle_2_points = list(tile_2.tile_poly.exterior.coords) for i in range(tile_1.get_edge_num()): for j in range(tile_2.get_edge_num()): # 4 points for checking a_1 = np.array([trinagle_1_points[i][0], trinagle_1_points[i][1]]) a_2 = np.array( [trinagle_1_points[i + 1][0], trinagle_1_points[i + 1][1]]) line_a = a_2 - a_1 b_1 = np.array([trinagle_2_points[j][0], trinagle_2_points[j][1]]) b_2 = np.array( [trinagle_2_points[j + 1][0], trinagle_2_points[j + 1][1]]) line_b = b_2 - b_1 # check whether the slope is the same if abs(abs(normalize(line_a).dot(normalize(line_b))) - 1.0) < EPS \ and (abs(abs(normalize(line_a).dot(normalize(b_1 - a_2))) - 1.0) < EPS or abs(abs(normalize(line_a).dot(normalize(b_2 - a_2))) - 1.0) < EPS): base_vec = normalize(line_a) unit_a_1 = 0 unit_a_2 = line_a.dot(base_vec) unit_b_1 = (b_1 - a_1).dot(base_vec) unit_b_2 = (b_2 - a_1).dot(base_vec) current_overlap = max( 0.0, min(unit_a_2, max(unit_b_1, unit_b_2)) - max(unit_a_1, min(unit_b_1, unit_b_2))) if current_overlap > EPS: tile_1_edge_length = tile_1.get_edge_length(i) tile_2_edge_length = tile_2.get_edge_length(j) if abs(tile_1_edge_length - tile_2_edge_length) > EPS: return True return False
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 get_tile_instance(base_tile: Tile, base_edge_idx, align_tile: Tile, align_edge_idx, align_mode): base_edge_p0, base_edge_p1 = base_tile.get_edge(base_edge_idx) tile_instance = tiling_util.align_tile(base_edge_p1, base_edge_p0, align_tile.tile_poly, align_edge_idx, align_mode) return Tile(tile_instance, id = align_tile.id)
def polygon_align_type(tile_1: Tile, tile_2: Tile): i, point_a, j, point_b = get_first_touch_point(tile_1, tile_2) return tile_1.get_align_point(i, point_a), tile_2.get_align_point(j, point_b)
def getTile(self, p, z): tile = Tile(-1, -1, z) metres_in_tile = tile.getMetresInTile() tile.x = math.floor((Tile.HALF_EARTH + p[0]) / metres_in_tile) tile.y = math.floor((Tile.HALF_EARTH - p[1]) / metres_in_tile) return tile
def __init__(self, url, z=13): self.tile = Tile(-1, -1, z) self.url = url self.sphMerc = GoogleProjection() self.indexedTiles = {}