class CanvasPolygon: def __init__(self, data): self.data = data # self.polygon # self.canvas if self.isValid(): shapes = json.loads(self.data['_shapes']) for shape in shapes['objects']: if shape['type'] == 'image': self.canvas = getCanvasSize(shape) if shape['type'] == 'rect': self.polygon = Polygon(getRectangleCoordinates(shape)) if shape['type'] == 'polygon': self.polygon = Polygon(getPolygonPoints(shape)) def scale(self, original_image): width, height = original_image.size exif = getExifDictionary(original_image) log.debug('exif data of the image is: %s',exif) orientation = exif['Orientation'] # get orientation from EXIF data of the image log.debug('orientation is: %s',orientation) log.debug('polygon canvas %s and points %s before:',self.canvas,self.polygon.points) # orientation: # 1 - top left (nothing), # 6 - top right (270), # 3 - bottom left (180) # 8 - bottom right (90) canvas_width = self.canvas['width'] canvas_height = self.canvas['height'] if orientation == 1: log.debug('orientation is 1') self.polygon.points = self.polygon.points self.polygon.scale(1.0*width/self.canvas['width'],1.0*height/self.canvas['height']) elif orientation == 6: log.debug('orientation is 6') self.polygon.points = [{'x':p['y'],'y':self.canvas['height']-p['x']} for p in self.polygon.points] self.canvas['height'] = canvas_width self.canvas['width'] = canvas_height self.polygon.scale(1.0*height/self.canvas['width'],1.0*width/self.canvas['height']) elif orientation == 3: log.debug('orientation is 3') self.polygon.points = [{'x':self.canvas['height']-p['x'],'y':self.canvas['weight']-p['y']} for p in self.polygon.points] self.polygon.scale(1.0*width/self.canvas['width'],1.0*height/self.canvas['height']) elif orientation == 8: log.debug('orientation is 8') self.polygon.points = [{'x':self.canvas['weight']-p['y'],'y':p['x']} for p in self.polygon.points] self.canvas['height'] = canvas_width self.canvas['width'] = canvas_height self.polygon.scale(1.0*height/self.canvas['width'],1.0*width/self.canvas['height']) else: log.debug('orientation is different') self.polygon.scale(1.0*width/self.canvas['width'],1.0*height/self.canvas['height']) log.debug('polygon canvas %s and points %s after:',self.canvas,self.polygon.points) def isValid(self): if '_shapes' in self.data: return True else: return False
def main(): sides = int(input("how many sides do you want? ")) side_length = int( input("what do you want the length of the sides to be? ")) poly = Polygon(sides, side_length) print(poly.get_area()) print("Your polygon's apothem is " + str(poly.apothem)) print("Your polygon's perimeter is " + str(poly.perimeter)) print("Your polygon's area is " + str(poly.area))
def __init__(self, data): self.data = data # self.polygon # self.canvas if self.isValid(): shapes = json.loads(self.data['_shapes']) for shape in shapes['objects']: if shape['type'] == 'image': self.canvas = getCanvasSize(shape) if shape['type'] == 'rect': self.polygon = Polygon(getRectangleCoordinates(shape)) if shape['type'] == 'polygon': self.polygon = Polygon(getPolygonPoints(shape))
def triangulate(poly: Polygon, hole: Polygon = None) -> List[Triangle]: """ Triangulates a polygon, potentially with a hole in it. Uses naive O(n^2) ear-clipping method. :param poly: polygon to be triangulated :param hole: hole in the polygon :return: list of triangles making up the polygon """ if hole: poly = _remove_hole(poly, hole) n = poly.n curr_n = n pts = np.array(poly.pts) ears = {ear: [(ear - 1) % n, ear, (ear + 1) % n] for ear in poly.ears()} # Adjacency dict of points in poly adj = {i: ((i - 1) % n, (i + 1) % n) for i in range(n)} tris = list() while len(tris) < n - 2: # Pick a random ear, turn into triangle, and append it to triangulation b, ear = ears.popitem() tris.append(Triangle(pts[ear].tolist())) # Update connection of vertices adjacent to ear vertex a, b, c = ear adj[a] = (adj[a][0], c) adj[c] = (a, adj[c][1]) # Update ear status of adjacent vertices ear_a = (adj[a][0], a, c) ear_c = (a, c, adj[c][1]) if poly.is_ear(ear_a): ears[a] = list(ear_a) else: ears.pop(a, None) if poly.is_ear(ear_c): ears[c] = list(ear_c) else: ears.pop(c, None) curr_n -= 1 return tris
def remove_point_triangulation(affected_triangles: List[Triangle], p: Point) -> Polygon: """ Removes a point from affected triangles, return the resulting polygon that fills the gap. :param affected_triangles: list of the triangles containing the point to be removed :param p: point to be removed :return: polygon created by merging the affected triangles """ # First we construct a dictionary that tells us adjacency of triangles boundaries = [set(tri.pts) for tri in affected_triangles] point2triangles = defaultdict(set) for i, bound in enumerate(boundaries): bound.remove(p) u, v = bound point2triangles[u].add(i) point2triangles[v].add(i) # Connect adjacent triangles, noting which point connects them graph = Graph() for u, (i, j) in point2triangles.items(): graph.add_edge(i, j, point=u) # Walk around the triangles to get the new outer boundary # TODO: Remember to make this work. DFS visits all nodes not all edges. I think find_cycle works. # new_boundary = [ graph.get_edge_data(i, j)["point"] for (i, j) in nx.find_cycle(graph) # for (i, j) in nx.dfs_edges(graph) ] return Polygon(new_boundary)
def _remove_hole(poly: Polygon, hole: Polygon) -> Polygon: """ Removes hole from polygon by turning it into a single degenerate polygon with a bridge edge connecting poly to interior hole :param poly: :param hole: :return: """ possible_bridges = list(product(poly.pts, hole.pts)) possible_bridges.sort(key=lambda b: utils.dist(*b)) bridge = None for bridge in possible_bridges: if _seg_intersect_poly(bridge, poly): continue if _seg_intersect_poly(bridge, hole): continue break poly_pt, hole_pt = bridge # Roll back the poly points to go around polygon first, away from bridge poly_ix = poly.pts.index(poly_pt) poly_pts = list(np.roll(poly.pts, -poly_ix)) # Reverse and roll the hole points because we must go around hole c.w. to # go around whole degenerate polygon ccw hole_pts = hole.pts[::-1] hole_ix = hole_pts.index(hole_pt) hole_pts = list(np.roll(hole_pts, -hole_ix)) degenerate_pts = poly_pts + [poly_pt] + hole_pts + [hole_pt] return Polygon(degenerate_pts)
def __init__(self, folder, name): """ Opens the json file of the country, and either collects the polygons online, or loads them from a file if it exists. :param folder: folder containing the country :param name: Name of the country (no need to specify ".json" """ self.folder = folder self.name = name # Now we load the variable self.polygons try: with open(self.folder + self.name + ".json", "r") as f: self.polygons = json.load(f) print('Loaded from file.') except FileNotFoundError: try: self.polygons = self.get_polygons() with open(folder + self.name + ".json", "w") as f: json.dump(self.polygons, f) print('Successfully collected the map online, {} polygons.'. format(len(self.polygons))) logger.info("{} has been found online.".format(self.name)) except ValueError: print('Something went wrong with {}.'.format(self.name)) logger.error("{} could not be found in OSM.".format(self.name)) self.polygons = [] self.polygons = [Polygon(p) for p in self.polygons] self.simplified = [a.array for a in self.polygons]
def _preprocess(self, subdivision: List[Polygon], plot_layers=False): """ If subdivision is not triangular, then triangulate each non-triangle region. Then place large triangle around region, and triangulate :param subdivision: """ logging.debug("Preprocessing planar subdivision") subdivision = triangle_graph(subdivision, self.digraph) logging.debug("Received triangulated subdivision") logging.debug("Constructing convex hull") all_pts = {p for tri in subdivision for p in tri.pts} hull = quickhull(list(all_pts)) hull = Polygon(hull) logging.debug("Wrapping polygon in bounding triangle") bounding_tri, gap_triangles = wrap_triangle(hull) for tri in gap_triangles: self.digraph.add_node(tri, original=False) layer = subdivision + gap_triangles if plot_layers: drawing.plot_polygons(layer, 'k-') plt.savefig("layer0.png") plt.clf() logging.debug("Iterating over layers") i = 0 while len(layer) > 1: logging.debug("Current layer size: %d" % len(layer)) layer = next_layer(layer, bounding_tri, self.digraph) i += 1 if plot_layers: drawing.plot_polygons(layer, 'k-') plt.savefig("layer%d.png" % i) plt.clf() logging.debug("Final layer size: %d" % len(layer)) self.top_layer = layer
""" logging.info("Running timing tests on point location") size = 100000 data = list() for i in range(min_pts, max_pts, inc): logging.info("Performing tests on %d points" % i) tiles = generate_triangle_tiling(num_pts=i, size=size) locator = Kirkpatrick(tiles) for j in range(n_iter): query = Point.sample_square(size) start = time.time() locator.locate(query) elapsed = time.time() - start data.append(Point(len(tiles), elapsed)) return data if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) tiles = [ Polygon([ Point(0, 0), Point(2, 0), Point(2, 2), Point(0, 2) ]) ] locator = Kirkpatrick(tiles) query_point = Point(1, 1) located_tile = locator.locate(query_point, plot_search=True) print(located_tile)
# Update ear status of adjacent vertices ear_a = (adj[a][0], a, c) ear_c = (a, c, adj[c][1]) if poly.is_ear(ear_a): ears[a] = list(ear_a) else: ears.pop(a, None) if poly.is_ear(ear_c): ears[c] = list(ear_c) else: ears.pop(c, None) curr_n -= 1 return tris if __name__ == '__main__': poly = Polygon([ Point(0.000000, 0.000000), Point(1.727261, 0.681506), Point(2.000000, 2.000000), Point(1.128893, 1.104487), Point(0.848083, 1.122645) ]) triangles = triangulate(poly) drawing.plot_polygons(triangles) plt.show()