예제 #1
0
    def test_toolpath(self):
        passes = feed.pocket(config, self.pocket()).passes
        def fy(yl, line):
            fx = line[-1]
            # Account for the feed-up line segment.
            return [*y(yl, line), (Point(fx, yl), Point(fx, yl + 0.25))]

        paths = [[(l.p1, l.p2) for l in p.segments()] for p in passes]
        self.assertEqual(paths, [
            [
                *fy(0.25, (0.25, 2.75)),
                *fy(0.50, (2.75, 0.25)),
                *fy(0.75, (0.25, 0.75)),
                *fy(1.00, (0.75, 0.25)),
                *fy(1.25, (0.25, 0.75)),
                *fy(1.50, (0.75, 0.25)),
                *fy(1.75, (0.25, 0.75)),
                *fy(2.00, (0.75, 0.25)),
                *fy(2.25, (0.25, 0.75)),
                # need to move over after feeding up halfway into a line
                (Point(0.75, 2.50), Point(0.25, 2.50)),
                *fy(2.50, (0.25, 2.75)),
                *y(2.75, (2.75, 0.25)),
            ],
            [
                *fy(0.75, (2.25, 2.75)),
                *fy(1.00, (2.75, 2.25)),
                *fy(1.25, (2.25, 2.75)),
                *fy(1.50, (2.75, 2.25)),
                *fy(1.75, (2.25, 2.75)),
                *fy(2.00, (2.75, 2.25)),
                *y(2.25, (2.25, 2.75)),
            ]
        ])
예제 #2
0
    def test_offset_merge(self):
        notch = Polygon([Point(0, 0), Point(7, 0), Point(4, 4), Point(3, 4)])

        parts = notch.offset(-(1.0 + 0.1))

        self.assertEqual(len(parts.polygons), 1)
        self.assertEqual(len(parts.polygons[0].points), 3)
예제 #3
0
    def test_offset_square(self):
        square = Polygon([Point(0, 0), Point(3, 0), Point(3, 3), Point(0, 3)])

        parts = square.offset(-0.25)
        self.assertEqual(
            set(c for poly in parts.polygons for p in poly.points
                for c in (p.x, p.y)), set([0.25, 2.75]))
예제 #4
0
 def test_double_diamond(self):
     diamond = Polygon([
         Point(1, 0),
         Point(2, 1),
         Point(1, 2),
         Point(0, 1),
     ])
     double = [diamond, diamond + Point(3, 0.1)]
     polygons = decompose.trapezoidal(double)
예제 #5
0
    def test_offset_split_notch(self):
        notch = Polygon(
            [Point(0, 0),
             Point(6, 0),
             Point(6, 5),
             Point(3, 1),
             Point(0, 5)])

        parts = notch.offset(-(0.375 + 0.1))

        self.assertEqual(len(parts.polygons), 2)
예제 #6
0
    def test_part(self):
        r = 10
        n = 6
        angles = [tau * i / n for i in range(n)]
        circle = Polygon([
            Point(math.cos(theta) * r, math.sin(theta) * r)
            for theta in angles
        ])

        part = Part(circle, [Tab(Line(Point(0, 0), Vector(0, 1)), 2)], 1.0)
        passes = feed.part(config, part).passes
        self.assertEqual(len(passes), 2)
예제 #7
0
    def test_contain_through_lines(self):
        shape = Polygon([Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0)])

        self.assertFalse(shape.contains(Point(-1, 0)))
        self.assertFalse(shape.contains(Point(0, -1)))
        self.assertFalse(shape.contains(Point(2, 0)))
        self.assertFalse(shape.contains(Point(0, 2)))
예제 #8
0
    def test_point_on_shape(self):
        shape = Polygon([Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0)])

        self.assertTrue(shape.contains(Point(0.5, 0)))
        self.assertTrue(shape.contains(Point(0, 0.5)))
        self.assertTrue(shape.contains(Point(1, 0.5)))
        self.assertTrue(shape.contains(Point(0.5, 1)))
예제 #9
0
    def test_outset(self):
        square = Polygon([Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0)])

        self.assertEqual(list(square.offset(0.1).points), [
            Point(-0.1, -0.1),
            Point(-0.1, 1.1),
            Point(1.1, 1.1),
            Point(1.1, -0.1)
        ])
예제 #10
0
    def test_engrave(self):
        polygon = ComplexPolygon([
            Polygon([Point(0, 0), Point(0, 100), Point(100, 100), Point(100, 0)]),
            Polygon([Point(1, 1), Point(1, 1.25), Point(1.25, 1.25), Point(1.25, 1)])
        ])

        engrave = Engrave(polygon, 0.5)
        passes = feed.engrave(config, engrave).passes
        self.assertEqual(len(passes[0].path), 5)
예제 #11
0
    def test_unworkable_part_removal(self):
        polygon = ComplexPolygon([
            Polygon([Point(0, 0), Point(0, 100), Point(100, 100), Point(100, 0)]),
            Polygon([Point(1, 1), Point(1, 1.25), Point(1.25, 1.25), Point(1.25, 1)])
        ])
        pocket = Part(polygon, [], 1.0)

        passes = feed.part(config, pocket).passes
        self.assertEqual(len(passes), 1)
예제 #12
0
 def test_square(self):
     square = Polygon([
         Point(0, 0),
         Point(0, 1),
         Point(1, 1),
         Point(1, 0),
     ])
     polygons = decompose.trapezoidal([square])
     self.assertEqual([p.points for p in polygons], [
         [Point(0, 0), Point(0, 1),
          Point(1, 1), Point(1, 0)],
     ])
예제 #13
0
    def test_simple(self):
        polygons = [
            rect(Point(0, 0), Point(1, 1)),
            rect(Point(1, 0), Point(2, 2))
        ]

        segments = [l for p in polygons for l in p.segments()]
        fragments = [
            LineSegment(l.p1, l.p2) for l in decompose.fragment(segments)
        ]
        self.assertEqual(
            set(fragments) - set(segments),
            set([
                LineSegment(Point(1, 0), Point(1, 1)),
                LineSegment(Point(1, 1), Point(1, 2))
            ]))

        self.assertEqual(
            set(segments) - set(fragments),
            set([LineSegment(Point(1, 0), Point(1, 2))]))
예제 #14
0
    def test_complex_offset_cleanup(self):
        polygon = ComplexPolygon([
            Polygon(
                [Point(0, 0),
                 Point(0, 100),
                 Point(100, 100),
                 Point(100, 0)]),
            Polygon([Point(1, -1),
                     Point(1, -2),
                     Point(2, -2),
                     Point(2, -1)])
        ])

        self.assertEqual(len(polygon.offset(-2).exterior), 1)
예제 #15
0
 def test_offset_foot_double_merge(self):
     foot = Polygon([
         Point(0, 0),
         Point(10, 0),
         Point(10, 1),
         Point(10, 10),
         Point(1, 10),
         Point(1, 2),
         Point(0, 1)
     ])
     rect = foot.offset(-2)
     self.assertEqual(len(rect.polygons[0].points), 4)
예제 #16
0
    def test_inset_local_merge(self):
        # the magic of 3-4-5 triangles...
        trapezoid = Polygon(
            [Point(0, 0),
             Point(9, 12),
             Point(9 + 5, 12),
             Point(9 + 5 + 9, 0)])

        self.assertEqual(
            [p.round(4) for p in trapezoid.offset(-5).points],
            [Point(10 + 3, 5),
             Point(10, 5),
             Point(10 + (3 / 2), 5 + (4 / 2))])
예제 #17
0
    def test_star_contain(self):
        # taken from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
        # we use the evenodd fill-rule so we don't have to calculate crossing
        # orientation.
        star = Polygon([
            Point(50, 0),
            Point(21, 90),
            Point(98, 35),
            Point(2, 35),
            Point(79, 90)
        ])

        self.assertFalse(star.contains(Point(50, 50)))
예제 #18
0
 def test_embedded(self):
     square = Polygon([
         Point(0, 0),
         Point(0, 10),
         Point(10, 10),
         Point(10, 0),
     ])
     inner = Polygon([Point(4, 4), Point(4, 6), Point(6, 6), Point(6, 4)])
     polygons = decompose.trapezoidal([square, inner])
     self.assertEqual([p.points for p in polygons], [[
         Point(0.0, 0.0),
         Point(0.0, 4.0),
         Point(10.0, 4.0),
         Point(10.0, 0.0)
     ], [
         Point(0.0, 4.0),
         Point(0.0, 6.0),
         Point(4.0, 6.0),
         Point(4.0, 4.0)
     ],
                                                     [
                                                         Point(6.0, 4.0),
                                                         Point(6.0, 6.0),
                                                         Point(10.0, 6.0),
                                                         Point(10.0, 4.0)
                                                     ],
                                                     [
                                                         Point(0.0, 6.0),
                                                         Point(0.0, 10.0),
                                                         Point(10.0, 10.0),
                                                         Point(10.0, 6.0)
                                                     ]])
예제 #19
0
    def test_contain_through_point(self):
        # when we cross through a vertex, it still only should count as one
        # boundary crossing for evenodd purposes.
        shape = Polygon([Point(-1, 0), Point(0, 1), Point(1, 0), Point(0, -1)])

        self.assertTrue(shape.contains(Point(0, 0)))
        self.assertTrue(shape.contains(Point(-0.5, 0)))
        self.assertTrue(shape.contains(Point(0, -0.5)))
        self.assertTrue(shape.contains(Point(0, 0.5)))
        self.assertTrue(shape.contains(Point(0.5, 0)))

        self.assertFalse(shape.contains(Point(2, 0)))
        self.assertFalse(shape.contains(Point(0, 2)))
        self.assertFalse(shape.contains(Point(0, -2)))
        self.assertFalse(shape.contains(Point(-2, 0)))
예제 #20
0
 def test_generic_instance(self):
     self.assertTrue(isinstance(Point(1, 1), generic.Point))
예제 #21
0
    def test_complex_multiply(self):
        polygon = ComplexPolygon([
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]),
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)])
        ])

        moved = polygon * Vector(20, 10)

        self.assertEqual(moved.interior, [
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)]) * Vector(20, 10)
        ])

        self.assertEqual(moved.exterior, [
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]) * Vector(20, 10)
        ])

        moved = polygon * 2

        self.assertEqual(moved.interior, [
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)]) * 2
        ])

        self.assertEqual(moved.exterior, [
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]) * 2
        ])

        moved = polygon / 2

        self.assertEqual(moved.interior, [
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)]) / 2
        ])

        self.assertEqual(moved.exterior, [
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]) / 2
        ])
예제 #22
0
def y(y, pairs):
    pairs = [pairs] if isinstance(pairs, tuple) else pairs
    return [(Point(x1, y), Point(x2, y)) for x1, x2 in pairs]
예제 #23
0
    def test_inset_split(self):
        dumbbell = Polygon([
            Point(0, 0),
            Point(0, 3),
            Point(1, 3),
            Point(1, 4),
            Point(0, 4),
            Point(0, 7),
            Point(3, 7),
            Point(3, 4),
            Point(2, 4),
            Point(2, 3),
            Point(3, 3),
            Point(3, 0)
        ])

        self.assertEqual(dumbbell.inset(2), [
            Polygon([Point(1, 5),
                     Point(1, 6),
                     Point(2, 6),
                     Point(2, 5)]),
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)])
        ])
예제 #24
0
 def pocket(self):
     polygon = ComplexPolygon([
         Polygon([Point(0, 0), Point(0, 3), Point(3, 3), Point(3, 0)]),
         Polygon([Point(1, 1), Point(1, 2), Point(2, 2), Point(2, 1)])
     ])
     return Pocket(polygon, 1.0)
예제 #25
0
 def test_batching_from_bottom_overlap(self):
     polygon = Circle(Point(0, 0), 2.0)
     pocket = Pocket(polygon, 1.0)
     batches = batch_scanlines(feed.scanlines(config, pocket))
     self.assertEqual(len(batches), 1)
예제 #26
0
 def fy(yl, line):
     fx = line[-1]
     # Account for the feed-up line segment.
     return [*y(yl, line), (Point(fx, yl), Point(fx, yl + 0.25))]
예제 #27
0
    def test_complex(self):
        f = Polygon([
            Point(0, 0),
            Point(0, 7),
            Point(4, 7),
            Point(4, 5),
            Point(2, 5),
            Point(2, 4),
            Point(4, 4),
            Point(4, 2),
            Point(2, 2),
            Point(2, 0)
        ])

        polygons = decompose.trapezoidal([f])
        self.assertEqual(
            [p.points for p in polygons],
            [[Point(0, 0), Point(0, 2),
              Point(2, 2), Point(2, 0)],
             [Point(0, 2), Point(0, 4),
              Point(4, 4), Point(4, 2)],
             [Point(0, 4), Point(0, 5),
              Point(2, 5), Point(2, 4)],
             [Point(0, 5), Point(0, 7),
              Point(4, 7), Point(4, 5)]])

        inverted = Polygon([Point(p.y, p.x) for p in f.points])
        polygons = decompose.trapezoidal([inverted])
        self.assertEqual([p.points for p in polygons], [[
            Point(7.0, 0.0),
            Point(7.0, 2.0),
            Point(0.0, 2.0),
            Point(0.0, 0.0)
        ], [
            Point(2.0, 2.0),
            Point(2.0, 4.0),
            Point(4.0, 4.0),
            Point(4.0, 2.0)
        ], [
            Point(5.0, 2.0),
            Point(5.0, 4.0),
            Point(7.0, 4.0),
            Point(7.0, 2.0)
        ]])
예제 #28
0
    def test_complex_add(self):
        polygon = ComplexPolygon([
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]),
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)])
        ])

        moved = polygon + Vector(20, 10)

        self.assertEqual(moved.interior, [
            Polygon([Point(1, 1),
                     Point(1, 2),
                     Point(2, 2),
                     Point(2, 1)]) + Vector(20, 10)
        ])

        self.assertEqual(moved.exterior, [
            Polygon([Point(0, 0),
                     Point(0, 3),
                     Point(3, 3),
                     Point(3, 0)]) + Vector(20, 10)
        ])
예제 #29
0
    def test_inwards(self):
        w = Polygon([
            Point(0, 0),
            Point(0, 2),
            Point(1, 2),
            Point(1, 1),
            Point(2, 1),
            Point(2, 2),
            Point(3, 2),
            Point(3, 1),
            Point(4, 1),
            Point(4, 2),
            Point(5, 2),
            Point(5, 0),
        ])

        down = Vector(0, -1)
        up = Vector(0, 1)
        left = Vector(-1, 0)
        right = Vector(1, 0)

        directions = [
            right, down, left, down, right, down, left, down, right, down,
            left, up
        ]

        for s, d in zip(w.segments(), directions):
            self.assertEqual(w.inwards(s), d)
예제 #30
0
 def test_circle_inset(self):
     c = Circle(Point(0, 0), 53.975, segments=100).to_clockwise()
     self.assertEqual(len(list(c.offset(-1.5875).points)), 100)