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 points_to_segment(points: List[sg.Point2]) -> List[sg.Segment2]: """ A List of points to a list of segments :param points: A list of points :return: A list of Segments """ segments = [] for idx in range(len(points) - 1): segments.append(sg.Segment2(points[idx], points[idx + 1])) segments.append(sg.Segment2(points[0], points[-1])) return segments
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 index_to_segment(points: List[sg.Point2], indexes: List[int]) -> List[sg.Segment2]: """ Converts a list of point indexes to a list of segments representing the Polygon :param points: :param indexes: :return: A list of line segments """ segments = [] for idx in range(len(indexes) - 1): segments.append( sg.Segment2(points[indexes[idx]], points[indexes[idx + 1]])) segments.append(sg.Segment2(points[indexes[0]], points[indexes[-1]])) return segments
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 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 are_portals_coplanar(new_portal: Portal, portal_frustum: PortalFrustum): (old_portal, _, _, _, _) = portal_frustum (old_pt1, old_pt2, _) = old_portal (new_pt1, new_pt2, _) = new_portal old_seg = skgeom.Segment2(old_pt1, old_pt2) old_line = old_seg.supporting_line() return old_line.has_on(new_pt1) and old_line.has_on(new_pt2)
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 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 _FindHull(s: List[sg.Point2], p: sg.Point2, q: sg.Point2, hull_points: List[sg.Point2]): """ A helper function for the QuickHull, uses recursion :param s: :param p: :param q: :param hull_points: :return: """ if len(s) == 0: return seg = sg.Segment2(p, q) c = max(s, key=lambda point: sg.squared_distance(seg, point)) hull_points.insert(hull_points.index(p) + 1, c) s.remove(c) s1, s2 = split_points_triangle(s, (p, q, c)) _FindHull(s1, p, c, hull_points) _FindHull(s2, c, q, hull_points)
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 split_points_triangle( points: List[sg.Point2], trig: Tuple[sg.Point2, sg.Point2, sg.Point2] ) -> Tuple[List[sg.Point2], List[sg.Point2]]: """ Splits a list of points depending on which side of a line the points lie on ignoring the points in a triangle :param points: :param trig: :return: """ a = [] b = [] proj = sg.Line2(trig[0], trig[1]).projection(trig[2]) proj_seg = sg.Segment2(proj, trig[2]) for point in points: if not triangle_isInside(trig, point): value = seg_side(proj_seg, point) if value > 0: a.append(point) elif value < 0: b.append(point) return (a, b)
def _draw(): if len(points) != 0 and len(points) != 1 and len(points) != 2: des = algo_impl.get() t0 = time.time() segments = None if des == 'python': segments = qh_py(points) elif des == 'scipy': segments = qh_scipy(points) elif des == 'compiled': segments = qh_wrapper(points) t1 = time.time() print(f'{(t1 - t0) * 1000} ms') redraw_plot(subplot, canvas, points, segments=segments) elif len(points) == 2: redraw_plot(subplot, canvas, points, segments=[sg.Segment2(points[0], points[1])]) else: redraw_plot(subplot, canvas, points)
def QHull(points: List[sg.Point2]) -> List[sg.Segment2]: """ Finds the convex hull via QuickHull :param points: A list of points to find the convex hull for :return: A list of line segments """ point_list = copy.copy(points) hull_points = [] points.sort(key=lambda point: point.x()) mn = points[0] mx = points[-1] hull_points.append(mn) hull_points.append(mx) point_list.remove(mn) point_list.remove(mx) seg = sg.Segment2(mn, mx) # a line between the left most and right most point s1, s2 = split_points(point_list, seg) _FindHull(s1, mn, mx, hull_points) _FindHull(s2, mx, mn, hull_points) return points_to_segment(hull_points)
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()