Exemple #1
0
def getIntersectionPathFromBox(infLine, left, right, top, bottom):
    # Intersect the line with all the sides of the box and
    #  take the two points inside the box.
    # This will always be on the top and bottom
    # or on the left and right sides.
    p1 = complex(left, infLine.y_for_x(left))
    p2 = complex(right, infLine.y_for_x(right))
    l1 = Line(start=p1, end=p2)

    p3 = complex(infLine.x_for_y(top), top)
    p4 = complex(infLine.x_for_y(bottom), bottom)
    l2 = Line(start=p3, end=p4)

    if l1.length() < l2.length():
        return l2
    else:
        return l1
Exemple #2
0
sp_10A_11 = pathtosvg(pf_10A_11)
seg_10A_11 = parse_path(sp_10A_11)
t = seg_10A_11.ilength(4.0 * cm)
pt10B = pt("10B", pt10A[0] - abs(pt10A[0] - np.real(seg_10A_11.point(t)) / cm),
           (np.imag(seg_10A_11.point(t)) / cm))
#t = seg_10A_11.ilength(1.0*cm)
#pt10C = pt("10C", np.real(seg.point(t))/cm, np.imag(seg.point(t))/cm)

path1 = svgwrite.path.Path('%s' % sp_10A_11, fill="none",
                           stroke=col_sew)  # (pt2ph(pt10B),

# only curve 0.25, not 0.5
hipline_curve = 0.2  # not 0.5
seg_11_8 = Line(complex(pt11[0] * cm, pt11[1] * cm),
                complex(pt8[0] * cm, pt8[1] * cm))
seg_length = seg_11_8.length()
t_mid = seg_11_8.ilength(seg_length / 2)
geo_mid = seg_11_8.point(t_mid)
n = seg_11_8.normal(t_mid)
normal_line = Line(seg_11_8.point(t_mid),
                   seg_11_8.point(t_mid) + hipline_curve * cm * n)
ctrl_pt = (np.real(normal_line.point(1)), np.imag(normal_line.point(1)))
ctrl_pt_str = str(np.real(normal_line.point(1))) + ", " + str(
    np.imag(normal_line.point(1)))

p_11_8 = (pt2cm(pt11), ctrl_pt, pt2cm(pt8))
pf_11_8 = fitpath(p_11_8, 10e-1)
sp_11_8 = pathtosvg(pf_11_8).replace('M', 'L')[17:]

path1.push('%s' % sp_11_8)  # curve
# path1.push('L %s' % (pt2ph(pt8))) # curve
Exemple #3
0
def scan_lines(paths, current_y=None):
    bbox = overall_bbox(paths)
    lines = []
    fudge_factor = 0.01
    orientation = abs(bbox[3]-bbox[2]) > abs(bbox[1]-bbox[0])
    if not current_y:
        current_y = bbox[2] if orientation else bbox[0]
    max_pos = bbox[3] if orientation else bbox[1]
    debug_shapes = [[paths, "none", "gray"]]

    while current_y < max_pos:
        current_y += MINIMUM_STITCH_DISTANCE

        if orientation:
            left = min(bbox[0], bbox[1])
            right = max(bbox[0], bbox[1])

            if left < 0:
                left *= 1.0 + fudge_factor
            else:
                left *= 1.0 - fudge_factor
            if right < 0:
                right *= 1.0 - fudge_factor
            else:
                right *= 1.0 + fudge_factor
            test_line = Line(start=current_y*1j+left, end=current_y*1j+right)
        else:
            up = min(bbox[2], bbox[3])
            down = max(bbox[2], bbox[3])
            if up < 0:
                up *= 1.0 + fudge_factor
            else:
                up *= 1.0 - fudge_factor
            if down < 0:
                down *= 1.0 - fudge_factor
            else:
                down *= 1.0 + fudge_factor
            test_line = Line(start=current_y  + up*1j,
                             end=current_y + down *1j)
        squash_intersections = []
        for path in paths:
            if path.start == path.end:
                continue
            intersections = path.intersect(test_line)
            if len(intersections) > 0:
                squash_intersections += [test_line.point(p[1]) for p in intersections]
        if len(squash_intersections) == 0:
            continue

        intersections = sorted(squash_intersections, key=lambda x: abs(x-test_line.start))
        if len(squash_intersections) < 2:
            continue
        debug_shapes.append([test_line, "none", "black"])
        for i in range(0, 2*int(len(intersections)/2), 2):
            def format_center(ind):
                return (intersections[ind].real, intersections[ind].imag)
            debug_shapes.append([Circle(center=format_center(i), r=1, fill="red")])
            debug_shapes.append([Circle(center=format_center(i+1), r=1, fill="blue")])
            line = Line(start=intersections[i], end=intersections[i+1])
            debug_shapes.append([line, "none", "green"])
            if line.length() > MAXIMUM_STITCH:
                num_segments = ceil(line.length() / MAXIMUM_STITCH)
                for seg_i in range(int(num_segments)):
                    lines.append(Line(start=line.point(seg_i/num_segments),
                                      end=line.point((seg_i+1)/num_segments)))
            else:
                lines.append(line)
        write_debug("fillscan", debug_shapes)
    return lines
    def fill_polygon(self, paths):
        rotated = 0
        fudge_factor = 0.03
        while len(paths) > 2:
            if len(paths) < 4:
                self.fill_triangle(paths, color="red")
                return
            shapes = [[Path(*paths), "none", "blue"],
                      [Path(*paths), "none", "green"]]
            write_debug("close", shapes)
            paths = remove_close_paths(paths)

            if len(paths) <= 2:
                return
            # check whether the next triangle is concave
            test_line1 = Line(start=paths[0].start, end=paths[1].end)
            test_line1 = Line(start=test_line1.point(fudge_factor),
                              end=test_line1.point(1 - fudge_factor))
            comparison_path = Path(*paths)
            if test_line1.length() == 0:
                has_intersection = True
            else:
                has_intersection = len([
                    1 for line in paths if len(line.intersect(test_line1)) > 0
                ]) > 0

            if not path1_is_contained_in_path2(
                    test_line1, comparison_path) or has_intersection:
                shapes = [[comparison_path, "none", "blue"],
                          [test_line1, "none", "black"]]
                write_debug("anim", shapes)
                # rotate the paths
                paths = paths[1:] + [paths[0]]
                rotated += 1
                if rotated >= len(paths):
                    print("failed to rotate into a concave path -> ",
                          (test_line1.start.real, test_line1.start.imag),
                          (test_line1.end.real, test_line1.end.imag),
                          [(p.start.real, p.start.imag) for p in paths])
                    return
                continue
            side = shorter_side(paths)

            test_line2 = Line(start=paths[1].start, end=paths[2].end)
            test_line2 = Line(start=test_line2.point(fudge_factor),
                              end=test_line2.point(1 - fudge_factor))
            test_line3 = Line(start=paths[-1 + side].end,
                              end=paths[(3 + side) % len(paths)].start)
            test_line3 = Line(start=test_line3.point(fudge_factor),
                              end=test_line3.point(1 - fudge_factor))

            num_intersections = []
            for path in comparison_path:
                if test_line3.length() == 0:
                    print("test line 3 is degenerate!")
                num_intersections += test_line3.intersect(path)
                num_intersections += test_line2.intersect(path)

            rect_not_concave = not path1_is_contained_in_path2(
                test_line2, comparison_path)

            # test for concavity. If concave, fill as triangle
            if is_concave(
                    paths) or len(num_intersections) > 0 or rect_not_concave:
                self.fill_triangle(paths, color="blue")
                shapes = [[Path(*paths), "none", "black"]]
                to_remove = []
                to_remove.append(paths.pop(0))
                to_remove.append(paths.pop(0))
                for shape in to_remove:
                    shapes.append([shape, "none", "blue"])
                closing_line = Line(start=paths[-1].end, end=paths[0].start)
                shapes.append([closing_line, "none", "green"])
                shapes.append([test_line1, "none", "red"])
                write_debug("rem", shapes)

            else:
                # check whether the next triangle is concave
                side, side2 = self.fill_trap(paths)
                if side:
                    paths = paths[1:] + [paths[0]]
                shapes = [[Path(*paths), "none", "black"]]
                to_remove = []
                to_remove.append(paths.pop(0))
                to_remove.append(paths.pop(0))
                to_remove.append(paths.pop(0))
                # if the trap was stitched in the vertical (perpendicular to the
                # stitches), don't remove that segment
                linecolors = ["blue", "purple", "pink"]
                for i, shape in enumerate(to_remove):
                    shapes.append([shape, "none", linecolors[i]])
                closing_line = Line(start=paths[-1].end, end=paths[0].start)
                shapes.append([closing_line, "none", "green"])
                shapes.append([test_line2, "none", "purple"])
                write_debug("rem", shapes)
                delta = closing_line.length() - (test_line3.length() /
                                                 (1.0 - 2.0 * fudge_factor))
                if abs(delta) > 1e-14:
                    print("closing line different than test!", side,
                          test_line3, closing_line)
            rotated = 0
            if paths[-1].end != paths[0].start:
                # check for intersections
                closing_line = Line(start=paths[-1].end, end=paths[0].start)
                paths.insert(0, closing_line)
            else:
                print("removed paths but they connected anyway")