예제 #1
0
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()
예제 #2
0
 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
예제 #3
0
파일: utils.py 프로젝트: anhydrous99/QHull
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
예제 #4
0
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())

    """
예제 #5
0
파일: utils.py 프로젝트: anhydrous99/QHull
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
예제 #6
0
파일: run.py 프로젝트: anhydrous99/QHull
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
예제 #7
0
    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")
예제 #8
0
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)
예제 #9
0
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"))))
예제 #10
0
    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
예제 #11
0
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)
예제 #12
0
파일: skgeom.py 프로젝트: sepastian/origami
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
예제 #13
0
파일: utils.py 프로젝트: anhydrous99/QHull
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)
예제 #14
0
파일: run.py 프로젝트: anhydrous99/QHull
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)
예제 #15
0
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)
예제 #16
0
 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()