def test_two_segments():
    pt = PathCanvas()
    pt.move_to(100, 100)
    pt.line_to(150, 200)
    pt.move_to(17, 17)
    pt.rel_line_to(100, 200)
    pt.close_path()
    assert pt.paths == [
        Path([Point(100.0, 100.0), Point(150.0, 200.0)]),
        Path([Point(17.0, 17.0),
              Point(117.0, 217.0),
              Point(17.0, 17.0)]),
    ]
Beispiel #2
0
def combinable_paths_maybe_loops(draw):
    """Makes single-segment paths, with loops a possibility."""
    endpoints = draw(lists(ipoints, min_size=2, max_size=200, unique_by=tuple))
    rand = draw(randoms())
    paths = set()
    point_use = collections.defaultdict(int)

    target_number = len(endpoints) / 3
    if target_number < 1:
        target_number = 1

    while len(paths) < target_number:
        # Choose two points at random from the possible endpoints, and make a
        # segment.
        a, b = rand.sample(endpoints, k=2)
        if (a, b) in paths:
            continue
        paths.add((a, b))

        # Track how many times the points have been used.
        point_use[a] += 1
        point_use[b] += 1

        # Any point in two segments is no longer a candidate as an endpoint.
        if point_use[a] == 2:
            endpoints.remove(a)
        if point_use[b] == 2:
            endpoints.remove(b)

    return [Path(p) for p in paths]
def test_reflect_xy():
    pt = PathCanvas()
    pt.move_to(100, 100)
    pt.reflect_xy(1000, 2000)
    pt.line_to(200, 200)
    assert pt.paths == [
        Path([Point(100.0, 100.0), Point(1800, 3800)]),
    ]
def test_translation():
    pt = PathCanvas()
    pt.move_to(100, 100)
    pt.translate(1000, 2000)
    pt.line_to(10, 20)
    assert pt.paths == [
        Path([Point(100.0, 100.0), Point(1010.0, 2020.0)]),
    ]
def test_rel_line_to():
    pt = PathCanvas()
    pt.translate(1000, 2000)
    pt.move_to(0, 0)
    pt.rel_line_to(100, 200)
    assert pt.paths == [
        Path([Point(1000.0, 2000.0),
              Point(1100.0, 2200.0)]),
    ]
def test_save_restore():
    pt = PathCanvas()
    pt.move_to(100, 100)
    pt.translate(1000, 2000)
    pt.line_to(10, 20)
    pt.save()
    pt.translate(1, 2)
    pt.move_to(1, 2)
    pt.line_to(2, 4)
    pt.restore()
    pt.move_to(1, 2)
    pt.line_to(2, 4)
    assert pt.paths == [
        Path([Point(100.0, 100.0), Point(1010.0, 2020.0)]),
        Path([Point(1002.0, 2004.0),
              Point(1003.0, 2006.0)]),
        Path([Point(1001.0, 2002.0),
              Point(1002.0, 2004.0)]),
    ]
def test_reflect_line():
    pt = PathCanvas()
    pt.move_to(100, 100)
    pt.reflect_line(Point(50, -50), Point(150, 50))
    pt.line_to(100, 50)
    pt.line_to(100, 100)
    assert pt.paths == [
        Path([Point(100.0, 100.0),
              Point(150, 0), Point(200, 0)]),
    ]
Beispiel #8
0
def path_pieces(path, segs_to_points):
    """Produce a new series of paths, split at intersection points.

    Yields a series of pieces (paths).  The pieces trace the same line as the
    original path.  The endpoints of the pieces are all intersection points
    in `segs_to_points`, or the endpoints of the original path, if it isn't
    circular.  The pieces are in order along `path`, so consecutive pieces
    end and begin at the same point. If `path` is closed, then the first piece
    returned will begin at the first cut, not at the path's first point.

    """
    # If path is circular, then the first piece we collect has to be added to
    # the last piece, so save it for later.
    collecting_head = path.closed
    head = None

    piece = []
    for pt in path:
        if not piece:
            piece.append(pt)
        else:
            seg = Segment(piece[-1], pt)
            cuts = segs_to_points.get(seg)
            if cuts is not None:
                cuts = seg.sort_along(cuts)
                for cut in cuts:
                    ptcut = Point(*cut)
                    piece.append(ptcut)
                    if collecting_head:
                        head = piece
                        collecting_head = False
                    else:
                        yield Path(piece)
                    piece = [ptcut]
            piece.append(pt)

    piece = Path(piece)
    if head:
        piece = piece.join(Path(head))
    yield piece
Beispiel #9
0
def combinable_paths_no_loops(draw):
    """Makes varying-length paths, but no loops."""
    path_points = draw(
        lists(ipoints, min_size=2, max_size=200, unique_by=tuple))
    rand = draw(randoms())

    paths = [[]]
    length = rand.randint(2, 4)
    for pt in path_points:
        paths[-1].append(pt)
        length -= 1
        if length == 0:
            paths.append([])
            length = rand.randint(2, 4)
            joinable = (rand.random() > .5)
            if joinable:
                paths[-1].append(pt)

    if len(paths[-1]) < 2:
        paths.pop()

    rand.shuffle(paths)
    return [Path(p) for p in paths]
Beispiel #10
0
def test_clean_path(path, result):
    assert equal_path(Path(path).clean(), Path(result))
Beispiel #11
0
def test_join_paths(p1, p2, result):
    pth1, pth2 = Path(p1), Path(p2)
    pth1r, pth2r = Path(p1[::-1]), Path(p2[::-1])
    if result is not None:
        result = Path(result)

    def same(p1, p2):
        if p1 is None and p2 is None:
            return True
        elif p1 is None or p2 is None:
            return False
        else:
            return equal_path(p1, p2)

    assert same(pth1.join(pth2), result)
    assert same(pth1r.join(pth2), result)
    assert same(pth1.join(pth2r), result)
    assert same(pth1r.join(pth2r), result)
Beispiel #12
0
def test_equal_path(p1, p2, result):
    assert equal_path(Path(p1), Path(p2)) == result
Beispiel #13
0
def test_any_collinear(points, result):
    assert Path(points).any_collinear() == result