def split_by_plane(self, node): plane = node.get_plane_line() inter = skgeom.intersection(plane, skgeom.Segment2(skgeom.Point2(self.x1, self.y1), skgeom.Point2(self.x2, self.y2))) #print(inter) px1 = node.partition_x_coord px2 = px1 + node.dx py1 = node.partition_y_coord py2 = py1 + node.dy (ix, iy) = intersect_portal_by_plane(self.x1, self.y1, self.x2, self.y2, px1, py1, px2, py2) #plane.x1, plane.y1, plane.x2, plane.y2) p1 = Point(self.x1, self.y1) p2 = Point(self.x2, self.y2) p1_class = p1.classify_against_plane(node) p2_class = p2.classify_against_plane(node) p1_to_intersection = Line(self.x1, self.y1, ix, iy) intersection_to_p2 = Line(ix, iy, self.x2, self.y2) if p1_class == IN_FRONT and p2_class == BEHIND: return (p1_to_intersection, intersection_to_p2) elif p1_class == BEHIND and p2_class == IN_FRONT: return (intersection_to_p2, p1_to_intersection) else: raise Exception("This shouldnt happen")
def draw_rv(): segments = [] for i in range(10): segments.append(sg.Segment2(sg.Point2(r(), r()), sg.Point2(r(), r()))) intersections = [] for s1, s2 in itertools.permutations(segments, 2): isect = sg.intersection(s1, s2) if isect: intersections.append(isect) for s in segments: draw(s) for i in intersections: draw(i) HEIGHT = 10 THETA_H = 45 THETA_V = 60 pt_h_r = sg.Point2(HEIGHT * math.tan(THETA_H * math.pi / 180), 0) pt_v_r = sg.Point2(HEIGHT * math.tan(THETA_V * math.pi / 180), 0) print(dir(sg.Transformation2)) pt_v_r = pt_v_r.transform(sg.Transformation2.Rotation(3, math.pi/2)) pt_r = sg.Segment2(pt_h_r, pt_v_r) draw(pt_h_r) draw(pt_v_r) draw(pt_r) plt.show()
def pts2Edges(self, pts): edges = [] for i in range(1, len(pts)): e = sg.Segment2(sg.Point2(pts[i - 1][0], pts[i - 1][1]), sg.Point2(pts[i][0], pts[i][1])) edges.append(e) e = sg.Segment2(sg.Point2(pts[len(pts) - 1][0], pts[len(pts) - 1][1]), sg.Point2(pts[0][0], pts[0][1])) edges.append(e) return edges
def intersect_portal_by_plane(portal_x1, portal_y1, portal_x2, portal_y2, plane_x1, plane_y1, plane_x2, plane_y2): """ returns a (x, y) tuple or None if there is no intersection """ portal_seg = skgeom.Segment2(skgeom.Point2(portal_x1, portal_y1), skgeom.Point2(portal_x2, portal_y2)) plane_line = skgeom.Segment2(skgeom.Point2(plane_x1, plane_y1), skgeom.Point2(plane_x2, plane_y2)).supporting_line() inter = skgeom.intersection(plane_line, portal_seg) #print(inter) if inter: return (inter.x(), inter.y()) """
def compute_graph_margins(G): # (1) pick the graph M component that contains the corner nodes. # (2) in M, compute an arrangement to find unbounded faces. # (3) from these faces' edges, computer an outer graph. # (4) on this outer graph, compute margins by shortest paths. assert not nx.is_directed(G) components = list(nx.connected_components(G)) assert len(components) == 1 node00 = sorted(list(G.nodes), key=lambda node: (node[0], node[1]))[0] node10 = sorted(list(G.nodes), key=lambda node: (-node[0], node[1]))[0] node11 = sorted(list(G.nodes), key=lambda node: (-node[0], -node[1]))[0] node01 = sorted(list(G.nodes), key=lambda node: (node[0], -node[1]))[0] corners = (node00, node10, node11, node01) main_graph = G.subgraph([nodes for nodes in components if node00 in nodes][0]) if not all(c in main_graph for c in corners): #print("corners", corners) #print("G", list(G.edges)) raise ValueError() arr = sg.arrangement.Arrangement() for a, b in main_graph.edges: arr.insert(sg.Segment2(sg.Point2(*a), sg.Point2(*b))) boundary = set() for h in arr.halfedges: if h.face().is_unbounded(): c = h.curve() boundary.add(_tuple(c.source())) boundary.add(_tuple(c.target())) outer_graph = main_graph.subgraph(boundary) assert all(c in outer_graph for c in corners) set_euclidean_weights(outer_graph) return dict( ((Margin.LEFT, nx.shortest_path(outer_graph, node00, node01, "euclidean")), (Margin.RIGHT, nx.shortest_path(outer_graph, node10, node11, "euclidean")), (Margin.TOP, nx.shortest_path(outer_graph, node00, node10, "euclidean")), (Margin.BOTTOM, nx.shortest_path(outer_graph, node01, node11, "euclidean"))))
def qh_wrapper(points): array = points_to_np(points) np_vert = qh.calc(array) #print(np_vert) segments = [] for vert_idx in range(np_vert.shape[0] - 1): segments.append( sg.Segment2( sg.Point2(np_vert[vert_idx, 0], np_vert[vert_idx, 1]), sg.Point2(np_vert[vert_idx + 1, 0], np_vert[vert_idx + 1, 1]))) segments.append( sg.Segment2(sg.Point2(np_vert[-1, 0], np_vert[-1, 1]), sg.Point2(np_vert[0, 0], np_vert[0, 1]))) return segments
def test_voronoi(self): npoints = np.random.rand(100, 2) * 20 - 10 points = [] for r in npoints: print(r) points.append(skgeom.Point2(*r)) vdiag = voronoi.VoronoiDiagram() for p in points: vdiag.insert(p) xx = vdiag.finite_edges for el in xx: print(el) for he in vdiag.edges: source, target = he.source(), he.target() if source and target: plt.plot([source.point().x(), target.point().x()], [source.point().y(), target.point().y()]) plt.scatter(npoints[:, 0], npoints[:, 1]) plt.axis('equal') plt.gca().set_adjustable("box") plt.gca().set_xlim([-10, 10]) plt.gca().set_ylim([-10, 10]) plt.show()
def on_button_press(event): if 65 <= event.x <= 450 and 350 >= event.y >= 42: click_point = sg.Point2((float(event.x - 65) / (450 - 65)) * 2 - 1, (float(event.y - 42) / (350 - 42)) * 2 - 1) points.append(click_point) _draw() button_press_handler(event, canvas)
def classify_against_plane(self, node): plane_line = node.get_plane_line() self_seg = skgeom.Segment2(skgeom.Point2(self.x1, self.y1), skgeom.Point2(self.x2, self.y2)) inter = skgeom.intersection(plane_line, self_seg) if inter: if isinstance(inter, skgeom.Segment2): return COINCIDENT else: return SPANNING else: num_positive = 0 num_negative = 0 #print("-- classifying point --") for point in [Point(self.x1,self.y1), Point(self.x2, self.y2)]: #proj = plane_line.projection(skgeom.Point2(point.x, point.y)) #print("projection: {}".format(proj)) val = point.classify_against_plane(node) if val == IN_FRONT: #print("one point in front") num_positive += 1 elif val == BEHIND: #print("one point behind") num_negative += 1 #print("-- done --\n") if num_positive == 0 and num_negative > 0: return BEHIND if num_positive > 0 and num_negative > 0: return SPANNING #print(self) #print(node) #raise Exception("This should not happen") # return SPANNING if num_positive == 2: return IN_FRONT elif num_negative == 2: return BEHIND return COINCIDENT
def getVisibilityPolygon(self, fromPt): vs = sg.RotationalSweepVisibility(self.boundary_obs) q = sg.Point2(fromPt[0], fromPt[1]) face = self.boundary_obs.find(q) vx = vs.compute_visibility(q, face) visibilityPolygon = self.getSgPolyFromArr(vx) self.visbilityPolygon = visibilityPolygon return visibilityPolygon
def isPtinPoly(self, pt, polygon): # pt as a list position = polygon.oriented_side(sg.Point2(pt[0], pt[1])) if position == sg.Sign.POSITIVE: return 1 elif position == sg.Sign.NEGATIVE: return -1 elif position == sg.Sign.ZERO: return 0
def _extract_simple_polygons_skgeom(coords, orientation=None): coords = _without_closing_point(coords) assert coords[0] != coords[-1] arr = sg.arrangement.Arrangement() for a, b in zip(coords, coords[1:] + [coords[0]]): arr.insert(sg.Segment2(sg.Point2(*a), sg.Point2(*b))) polygons = [] for _, boundary in geometry.face_boundaries(arr): polygons.append( sg.Polygon(list(reversed(_without_closing_point(boundary))))) if len(polygons) > 1 and orientation is not None: polygons = sorted(polygons, key=lambda p: np.dot(p.coords[0], orientation)) return polygons
def assign_region_mask(img, poly, pixel): for i0 in range(0, pixel): for j0 in range(0, pixel): d_list = [] for e0 in poly.edges: d = distance(e0.point(0), e0.point(1), sg.Point2(i0, j0)) d_list.append(d) # on one of the edges if abs(min(d_list)) < 0.5 * np.sqrt(2): img[j0, i0, :] = 999 # not on the edges else: if poly.oriented_side(sg.Point2(i0, j0)) == sg.Sign.NEGATIVE: img[j0, i0, :] = -1.0 else: img[j0, i0, :] = 1.0 # assign value to the inner and outer region of the domain img_c = img[:, :, 0:1] img_h = img[:, :, 1:3] img_c = np.where(img_c != 1, img_c, -2) img_h = np.where(img_h != 1, img_h, 0) img = np.concatenate((img_c, img_h), axis=2) return img
def create_polygon(points, pixel, shape_id=0, use_convex_hull=True): sgPoints = [] for p0 in points: sgPoints.append(sg.Point2(p0[0], p0[1])) if use_convex_hull: # the following make sure the inside has +1, and outside has -1 # but not work for L-shape, I guess. chull_points = sg.convex_hull.graham_andrew(sgPoints) poly = sg.Polygon(chull_points) else: # for L-shape, please define points counter-clock-wise print( "Please define the points counter-clock-wise to make sure inner has flag of +1 and outer has -1" ) poly = sg.Polygon(sgPoints) draw(sgPoints) return poly
def apply_bcs_one_edge(img, list_of_edges, pixel, e0, _val, one_bc_value, bc_order_type): """ apply bcs on one edge """ if _val == 'c': channel = 0 elif _val == 'h': channel = 1 else: print("bc val type = ", _val, ". Not sure what it is! In apply_bcs_one_edge()") exit(0) for i0 in range(0, pixel): for j0 in range(0, pixel): # only distance of pixels on the boundary will be calculated to save computational time if img[j0, i0, channel] == 999: d = distance(e0.point(0), e0.point(1), sg.Point2(i0, j0)) if abs(d) < 0.5 * np.sqrt(2): # if d < 0.5 and d >= 0.0: # inside the domain # if d > -0.5 and d <= 0.0: # outside the domain # print(d) if channel == 0: img[j0, i0, channel] = compute_bc_value(one_bc_value, bc_order_type, e0, i0, j0, bc_type=_val) if channel == 1: # bc_x = compute_bc_value(one_bc_value, bc_order_type, e0, i0, j0, bc_type=_val) [bc_x, bc_y] = compute_bc_value(one_bc_value, bc_order_type, e0, i0, j0, bc_type=_val) img[j0, i0, channel] = bc_x img[j0, i0, channel + 1] = bc_y
def _generate(): n_points = int(v.get()) for i in range(n_points): points.append(sg.Point2(2 * r() - 1, 2 * r() - 1)) _draw()
def compute_margins_from_boundary(boundary_pts, phi=-math.pi / 2, cache=None): k_gon = sg.maximum_area_inscribed_k_gon( [sg.Point2(*p) for p in boundary_pts], 4) corners = [(float(v.x()), float(v.y())) for v in k_gon.vertices] def _sort_by(a, axis): return sorted(a, key=lambda p: p[axis]) by_y = _sort_by(corners, 1) top_left, top_right = _sort_by(by_y[:2], 0) bottom_left, bottom_right = _sort_by(by_y[2:], 0) top_left, top_right, bottom_right, bottom_left = _maximize_margins_area( boundary_pts, [top_left, top_right, bottom_right, bottom_left]) pts = [tuple(x) for x in boundary_pts] G = nx.Graph() G.add_nodes_from(pts) G.add_edges_from(list(closed_boundary(pts))) set_euclidean_weights(G) m = dict() m[Margin.TOP] = nx.shortest_path(G, top_left, top_right, weight='euclidean') m[Margin.RIGHT] = nx.shortest_path(G, top_right, bottom_right, weight='euclidean') m[Margin.BOTTOM] = nx.shortest_path(G, bottom_right, bottom_left, weight='euclidean') m[Margin.LEFT] = nx.shortest_path(G, bottom_left, top_left, weight='euclidean') return m if False: annotated = [[] for _ in range(len(boundary_pts))] pts = np.array(boundary_pts) xmin = np.min(pts[:, 0]) xmax = np.max(pts[:, 0]) ymin = np.min(pts[:, 1]) ymax = np.max(pts[:, 1]) largest = sg.LargestEmptyIsoRectangle(sg.Point2(xmin, ymin), sg.Point2(xmax, ymax)) largest.insert([sg.Point2(*p) for p in convex_boundary_pts]) rectangle = largest.largest_empty_iso_rectangle r_xmin = rectangle.xmin() r_xmax = rectangle.xmax() r_ymin = rectangle.ymin() r_ymax = rectangle.ymax() eps = 0.5 for m, p in zip(annotated, boundary_pts): if p[0] >= r_xmax - eps: m.append(Margin.RIGHT) if p[0] <= r_xmin + eps: m.append(Margin.LEFT) if p[1] >= r_ymax - eps: m.append(Margin.BOTTOM) if p[1] <= r_ymin + eps: m.append(Margin.TOP) return _extract_margins(boundary_pts, annotated)
def get_plane_line(self): px = self.partition_x_coord py = self.partition_y_coord return skgeom.Segment2(skgeom.Point2(px, px + self.dx), skgeom.Point2(py, py + self.dy)).supporting_line()