コード例 #1
0
    def test_equality(self):
        # This is to test the __eq__ and __ne__ methods, so we can't use
        # assertEqual and assertNotEqual
        path1 = Path(
            Line(start=600 + 350j, end=650 + 325j),
            Arc(start=650 + 325j, radius=25 + 25j, rotation=-30, arc=0, sweep=1, end=700 + 300j),
            CubicBezier(start=700 + 300j, control1=800 + 400j, control2=750 + 200j, end=600 + 100j),
            QuadraticBezier(start=600 + 100j, control=600, end=600 + 300j))
        path2 = Path(
            Line(start=600 + 350j, end=650 + 325j),
            Arc(start=650 + 325j, radius=25 + 25j, rotation=-30, arc=0, sweep=1, end=700 + 300j),
            CubicBezier(start=700 + 300j, control1=800 + 400j, control2=750 + 200j, end=600 + 100j),
            QuadraticBezier(start=600 + 100j, control=600, end=600 + 300j))

        self.assertTrue(path1 == path2)
        # Modify path2:
        path2[0].start = 601 + 350j
        self.assertTrue(path1 != path2)

        # Modify back:
        path2[0].start = 600 + 350j
        self.assertFalse(path1 != path2)

        # Get rid of the last segment:
        del path2[-1]
        self.assertFalse(path1 == path2)

        # It's not equal to a list of it's segments
        self.assertTrue(path1 != path1[:])
        self.assertFalse(path1 == path1[:])
コード例 #2
0
 def test_equality(self):
     # This is to test the __eq__ and __ne__ methods, so we can't use
     # assertEqual and assertNotEqual
     segment = QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j)
     self.assertTrue(segment == QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j))
     self.assertTrue(segment != QuadraticBezier(200 + 301j, 400 + 50j, 600 + 300j))
     self.assertFalse(segment == Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j))
     self.assertTrue(Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j) != segment)
コード例 #3
0
 def test_point_in_arc_rotated(self):
     arc = Arc(0 + 25j, 25 + 25j, 90.0, 0, 0, 0 - 25j)
     for i in range(100):
         x = sin(i * tau / 200) * 25
         y = cos(i * tau / 200) * 25
         p = i / 100.0
         point = arc.point(p)
         self.assertAlmostEqual(point.real, x, places=7)  # 7th place wrong.
         self.assertAlmostEqual(point.imag, y, places=7)
コード例 #4
0
 def test_circle(self):
     arc1 = Arc(0j, 100 + 100j, 0, 0, 0, 200 + 0j)
     arc2 = Arc(200 + 0j, 100 + 100j, 0, 0, 0, 0j)
     path = Path(arc1, arc2)
     self.assertAlmostEqual(path.point(0.0), (0j))
     self.assertAlmostEqual(path.point(0.25), (100 + 100j))
     self.assertAlmostEqual(path.point(0.5), (200 + 0j))
     self.assertAlmostEqual(path.point(0.75), (100 - 100j))
     self.assertAlmostEqual(path.point(1.0), (0j))
     self.assertAlmostEqual(path.length(), pi * 200)
コード例 #5
0
 def test_point_in_arc(self):
     from math import cos, sin, pi
     tau = 2 * pi
     arc = Arc(0 + 25j, 25 + 25j, 0.0, 0, 0, 0 - 25j)
     for i in range(100):
         x = sin(i * tau / 200) * 25
         y = cos(i * tau / 200) * 25
         p = i / 100.0
         point = arc.point(p)
         self.assertAlmostEqual(point.real, x, places=7)  # 7th place wrong.
         self.assertAlmostEqual(point.imag, y, places=7)
コード例 #6
0
 def test_point_in_arc_path(self):
     from math import cos, sin, pi
     tau = 2 * pi
     for angle in range(-180, 180, 60):
         arc = Arc(0 + 25j, 25 + 25j, angle, 0, 0, 0 - 25j)
         path = Path(arc)
         v = 5
         for i in range(v+1):
             x = sin(i * tau / (2.0 * float(v))) * 25
             y = cos(i * tau / (2.0 * float(v))) * 25
             p = i / float(v)
             point = path.point(p)
             self.assertAlmostEqual(point.real, x, places=6)
             self.assertAlmostEqual(point.imag, y, places=6)
             self.assertEqual(arc.point(p), point)
コード例 #7
0
 def test_repr(self):
     from path import Point
     path = Path(
         Line(start=600 + 350j, end=650 + 325j),
         Arc(start=650 + 325j, radius=25 + 25j, rotation=-30, arc=0, sweep=1, end=700 + 300j),
         CubicBezier(start=700 + 300j, control1=800 + 400j, control2=750 + 200j, end=600 + 100j),
         QuadraticBezier(start=600 + 100j, control=600, end=600 + 300j))
     self.assertEqual(eval(repr(path)), path)
コード例 #8
0
 def test_length(self):
     # I'll test the length calculations by making a circle, in two parts.
     arc1 = Arc(0j, 100 + 100j, 0, 0, 0, 200 + 0j)
     arc1_length = arc1.length(1e-5, 4)
     arc2 = Arc(200 + 0j, 100 + 100j, 0, 0, 0, 0j)
     self.assertAlmostEqual(arc1.length(), pi * 100)
     self.assertAlmostEqual(arc2.length(), pi * 100)
コード例 #9
0
 def test_svg_specs_little_pie(self):
     # Little pie: M275,175 v-150 a150,150 0 0,0 -150,150 z
     path = Path(Line(275 + 175j, 275 + 25j),
                 Arc(275 + 25j, 150 + 150j, 0, 0, 0, 125 + 175j),
                 Line(125 + 175j, 275 + 175j))
     # The points and length for this path are calculated and not regression tests.
     self.assertAlmostEqual(path.point(0.0), (275 + 175j))
     self.assertAlmostEqual(path.point(0.2800495767557787), (275 + 25j))
     self.assertAlmostEqual(path.point(0.5), (168.93398282201787 + 68.93398282201787j))
     self.assertAlmostEqual(path.point(1 - 0.2800495767557787), (125 + 175j))
     self.assertAlmostEqual(path.point(1.0), (275 + 175j))
     # The errors seem to accumulate. Still 6 decimal places is more than good enough.
     self.assertAlmostEqual(path.length(), pi * 75 + 300, places=6)
コード例 #10
0
    def test_svg_specs_big_pie(self):
        """The paths that are in the SVG specs"""

        # Big pie: M300,200 h-150 a150,150 0 1,0 150,-150 z
        path = Path(Line(300 + 200j, 150 + 200j),
                    Arc(150 + 200j, 150 + 150j, 0, 1, 0, 300 + 50j),
                    Line(300 + 50j, 300 + 200j))
        # The points and length for this path are calculated and not regression tests.
        self.assertAlmostEqual(path.point(0.0), (300 + 200j))
        self.assertAlmostEqual(path.point(0.14897825542), (150 + 200j))
        self.assertAlmostEqual(path.point(0.5), (406.066017177 + 306.066017177j))
        self.assertAlmostEqual(path.point(1 - 0.14897825542), (300 + 50j))
        self.assertAlmostEqual(path.point(1.0), (300 + 200j))
        # The errors seem to accumulate. Still 6 decimal places is more than good enough.
        self.assertAlmostEqual(path.length(), pi * 225 + 300, places=6)
コード例 #11
0
ファイル: test_paths.py プロジェクト: ysire/md2reveal
    def test_svg_specs(self):
        """The paths that are in the SVG specs"""

        # Big pie: M300,200 h-150 a150,150 0 1,0 150,-150 z
        path = Path(Line(300 + 200j, 150 + 200j),
                    Arc(150 + 200j, 150 + 150j, 0, 1, 0, 300 + 50j),
                    Line(300 + 50j, 300 + 200j))
        # The points and length for this path are calculated and not regression tests.
        self.assertAlmostEqual(path.point(0.0), (300 + 200j))
        self.assertAlmostEqual(path.point(0.14897825542), (150 + 200j))
        self.assertAlmostEqual(path.point(0.5),
                               (406.066017177 + 306.066017177j))
        self.assertAlmostEqual(path.point(1 - 0.14897825542), (300 + 50j))
        self.assertAlmostEqual(path.point(1.0), (300 + 200j))
        # The errors seem to accumulate. Still 6 decimal places is more than good enough.
        self.assertAlmostEqual(path.length(), pi * 225 + 300, places=6)

        # Little pie: M275,175 v-150 a150,150 0 0,0 -150,150 z
        path = Path(Line(275 + 175j, 275 + 25j),
                    Arc(275 + 25j, 150 + 150j, 0, 0, 0, 125 + 175j),
                    Line(125 + 175j, 275 + 175j))
        # The points and length for this path are calculated and not regression tests.
        self.assertAlmostEqual(path.point(0.0), (275 + 175j))
        self.assertAlmostEqual(path.point(0.2800495767557787), (275 + 25j))
        self.assertAlmostEqual(path.point(0.5),
                               (168.93398282201787 + 68.93398282201787j))
        self.assertAlmostEqual(path.point(1 - 0.2800495767557787),
                               (125 + 175j))
        self.assertAlmostEqual(path.point(1.0), (275 + 175j))
        # The errors seem to accumulate. Still 6 decimal places is more than good enough.
        self.assertAlmostEqual(path.length(), pi * 75 + 300, places=6)

        # Bumpy path: M600,350 l 50,-25
        #             a25,25 -30 0,1 50,-25 l 50,-25
        #             a25,50 -30 0,1 50,-25 l 50,-25
        #             a25,75 -30 0,1 50,-25 l 50,-25
        #             a25,100 -30 0,1 50,-25 l 50,-25
        path = Path(
            Line(600 + 350j, 650 + 325j),
            Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j),
            Line(700 + 300j, 750 + 275j),
            Arc(750 + 275j, 25 + 50j, -30, 0, 1, 800 + 250j),
            Line(800 + 250j, 850 + 225j),
            Arc(850 + 225j, 25 + 75j, -30, 0, 1, 900 + 200j),
            Line(900 + 200j, 950 + 175j),
            Arc(950 + 175j, 25 + 100j, -30, 0, 1, 1000 + 150j),
            Line(1000 + 150j, 1050 + 125j),
        )
        # These are *not* calculated, but just regression tests. Be skeptical.
        self.assertAlmostEqual(path.point(0.0), (600 + 350j))
        self.assertAlmostEqual(path.point(0.3), (755.31526434 + 217.51578768j))
        self.assertAlmostEqual(path.point(0.5), (832.23324151 + 156.33454892j))
        self.assertAlmostEqual(path.point(0.9), (974.00559321 + 115.26473532j))
        self.assertAlmostEqual(path.point(1.0), (1050 + 125j))
        # The errors seem to accumulate. Still 6 decimal places is more than good enough.
        self.assertAlmostEqual(path.length(), 860.6756221710)
コード例 #12
0
 def test_non_arc(self):
     # And arc with the same start and end is a noop.
     segment = Arc(0 + 70j, 35 + 35j, 0, 1, 0, 0 + 70j)
     self.assertEqual(segment.length(), 0)
     self.assertEqual(segment.point(0.5), segment.start)
コード例 #13
0
def parse_path(pathdef, current_pos=0j):
    # In the SVG specs, initial movetos are absolute, even if
    # specified as 'm'. This is the default behavior here as well.
    # But if you pass in a current_pos variable, the initial moveto
    # will be relative to that current_pos. This is useful.
    elements = list(_tokenize_path(pathdef))
    # Reverse for easy use of .pop()
    elements.reverse()

    segments = Path()
    start_pos = None
    command = None

    while elements:

        if elements[-1] in COMMANDS:
            # New command.
            last_command = command  # Used by S and T
            command = elements.pop()
            absolute = command in UPPERCASE
            command = command.upper()
        else:
            # If this element starts with numbers, it is an implicit command
            # and we don't change the command. Check that it's allowed:
            if command is None:
                raise ValueError("Unallowed implicit command in %s, position %s" % (
                    pathdef, len(pathdef.split()) - len(elements)))

        if command == 'M':
            # Moveto command.
            x = elements.pop()
            y = elements.pop()
            pos = float(x) + float(y) * 1j
            if absolute:
                current_pos = pos
            else:
                current_pos += pos

            # when M is called, reset start_pos
            # This behavior of Z is defined in svg spec:
            # http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand
            start_pos = current_pos

            # Implicit moveto commands are treated as lineto commands.
            # So we set command to lineto here, in case there are
            # further implicit commands after this moveto.
            command = 'L'

        elif command == 'Z':
            # Close path
            if not (current_pos == start_pos):
                segments.append(Line(current_pos, start_pos))
            segments.closed = True
            current_pos = start_pos
            start_pos = None
            command = None  # You can't have implicit commands after closing.

        elif command == 'L':
            x = elements.pop()
            y = elements.pop()
            pos = float(x) + float(y) * 1j
            if not absolute:
                pos += current_pos
            segments.append(Line(current_pos, pos))
            current_pos = pos

        elif command == 'H':
            x = elements.pop()
            pos = float(x) + current_pos.imag * 1j
            if not absolute:
                pos += current_pos.real
            segments.append(Line(current_pos, pos))
            current_pos = pos

        elif command == 'V':
            y = elements.pop()
            pos = current_pos.real + float(y) * 1j
            if not absolute:
                pos += current_pos.imag * 1j
            segments.append(Line(current_pos, pos))
            current_pos = pos

        elif command == 'C':
            control1 = float(elements.pop()) + float(elements.pop()) * 1j
            control2 = float(elements.pop()) + float(elements.pop()) * 1j
            end = float(elements.pop()) + float(elements.pop()) * 1j

            if not absolute:
                control1 += current_pos
                control2 += current_pos
                end += current_pos

            segments.append(CubicBezier(current_pos, control1, control2, end))
            current_pos = end

        elif command == 'S':
            # Smooth curve. First control point is the "reflection" of
            # the second control point in the previous path.

            if last_command not in 'CS':
                # If there is no previous command or if the previous command
                # was not an C, c, S or s, assume the first control point is
                # coincident with the current point.
                control1 = current_pos
            else:
                # The first control point is assumed to be the reflection of
                # the second control point on the previous command relative
                # to the current point.
                control1 = current_pos + current_pos - segments[-1].control2

            control2 = float(elements.pop()) + float(elements.pop()) * 1j
            end = float(elements.pop()) + float(elements.pop()) * 1j

            if not absolute:
                control2 += current_pos
                end += current_pos

            segments.append(CubicBezier(current_pos, control1, control2, end))
            current_pos = end

        elif command == 'Q':
            control = float(elements.pop()) + float(elements.pop()) * 1j
            end = float(elements.pop()) + float(elements.pop()) * 1j

            if not absolute:
                control += current_pos
                end += current_pos

            segments.append(QuadraticBezier(current_pos, control, end))
            current_pos = end

        elif command == 'T':
            # Smooth curve. Control point is the "reflection" of
            # the second control point in the previous path.

            if last_command not in 'QT':
                # If there is no previous command or if the previous command
                # was not an Q, q, T or t, assume the first control point is
                # coincident with the current point.
                control = current_pos
            else:
                # The control point is assumed to be the reflection of
                # the control point on the previous command relative
                # to the current point.
                control = current_pos + current_pos - segments[-1].control

            end = float(elements.pop()) + float(elements.pop()) * 1j

            if not absolute:
                end += current_pos

            segments.append(QuadraticBezier(current_pos, control, end))
            current_pos = end

        elif command == 'A':
            radius = float(elements.pop()) + float(elements.pop()) * 1j
            rotation = float(elements.pop())
            arc = float(elements.pop())
            sweep = float(elements.pop())
            end = float(elements.pop()) + float(elements.pop()) * 1j

            if not absolute:
                end += current_pos

            segments.append(Arc(current_pos, radius, rotation, arc, sweep, end))
            current_pos = end

    return segments
コード例 #14
0
    def test_points(self):
        arc1 = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
        self.assertAlmostEqual(arc1.center, 100 + 0j)
        self.assertAlmostEqual(arc1.theta, 180.0)
        self.assertAlmostEqual(arc1.delta, -90.0)

        self.assertAlmostEqual(arc1.point(0.0), (0j))
        self.assertAlmostEqual(arc1.point(0.1), (1.23116594049 + 7.82172325201j))
        self.assertAlmostEqual(arc1.point(0.2), (4.89434837048 + 15.4508497187j))
        self.assertAlmostEqual(arc1.point(0.3), (10.8993475812 + 22.699524987j))
        self.assertAlmostEqual(arc1.point(0.4), (19.0983005625 + 29.3892626146j))
        self.assertAlmostEqual(arc1.point(0.5), (29.2893218813 + 35.3553390593j))
        self.assertAlmostEqual(arc1.point(0.6), (41.2214747708 + 40.4508497187j))
        self.assertAlmostEqual(arc1.point(0.7), (54.6009500260 + 44.5503262094j))
        self.assertAlmostEqual(arc1.point(0.8), (69.0983005625 + 47.5528258148j))
        self.assertAlmostEqual(arc1.point(0.9), (84.3565534960 + 49.3844170298j))
        self.assertAlmostEqual(arc1.point(1.0), (100 + 50j))

        arc2 = Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j)
        self.assertAlmostEqual(arc2.center, 50j)
        self.assertAlmostEqual(arc2.theta, 270.0)
        self.assertAlmostEqual(arc2.delta, -270.0)

        self.assertAlmostEqual(arc2.point(0.0), (0j))
        self.assertAlmostEqual(arc2.point(0.1), (-45.399049974 + 5.44967379058j))
        self.assertAlmostEqual(arc2.point(0.2), (-80.9016994375 + 20.6107373854j))
        self.assertAlmostEqual(arc2.point(0.3), (-98.7688340595 + 42.178276748j))
        self.assertAlmostEqual(arc2.point(0.4), (-95.1056516295 + 65.4508497187j))
        self.assertAlmostEqual(arc2.point(0.5), (-70.7106781187 + 85.3553390593j))
        self.assertAlmostEqual(arc2.point(0.6), (-30.9016994375 + 97.5528258148j))
        self.assertAlmostEqual(arc2.point(0.7), (15.643446504 + 99.3844170298j))
        self.assertAlmostEqual(arc2.point(0.8), (58.7785252292 + 90.4508497187j))
        self.assertAlmostEqual(arc2.point(0.9), (89.1006524188 + 72.699524987j))
        self.assertAlmostEqual(arc2.point(1.0), (100 + 50j))

        arc3 = Arc(0j, 100 + 50j, 0, 0, 1, 100 + 50j)
        self.assertAlmostEqual(arc3.center, 50j)
        self.assertAlmostEqual(arc3.theta, 270.0)
        self.assertAlmostEqual(arc3.delta, 90.0)

        self.assertAlmostEqual(arc3.point(0.0), (0j))
        self.assertAlmostEqual(arc3.point(0.1), (15.643446504 + 0.615582970243j))
        self.assertAlmostEqual(arc3.point(0.2), (30.9016994375 + 2.44717418524j))
        self.assertAlmostEqual(arc3.point(0.3), (45.399049974 + 5.44967379058j))
        self.assertAlmostEqual(arc3.point(0.4), (58.7785252292 + 9.54915028125j))
        self.assertAlmostEqual(arc3.point(0.5), (70.7106781187 + 14.6446609407j))
        self.assertAlmostEqual(arc3.point(0.6), (80.9016994375 + 20.6107373854j))
        self.assertAlmostEqual(arc3.point(0.7), (89.1006524188 + 27.300475013j))
        self.assertAlmostEqual(arc3.point(0.8), (95.1056516295 + 34.5491502813j))
        self.assertAlmostEqual(arc3.point(0.9), (98.7688340595 + 42.178276748j))
        self.assertAlmostEqual(arc3.point(1.0), (100 + 50j))

        arc4 = Arc(0j, 100 + 50j, 0, 1, 1, 100 + 50j)
        self.assertAlmostEqual(arc4.center, 100 + 0j)
        self.assertAlmostEqual(arc4.theta, 180.0)
        self.assertAlmostEqual(arc4.delta, 270.0)

        self.assertAlmostEqual(arc4.point(0.0), (0j))
        self.assertAlmostEqual(arc4.point(0.1), (10.8993475812 - 22.699524987j))
        self.assertAlmostEqual(arc4.point(0.2), (41.2214747708 - 40.4508497187j))
        self.assertAlmostEqual(arc4.point(0.3), (84.3565534960 - 49.3844170298j))
        self.assertAlmostEqual(arc4.point(0.4), (130.901699437 - 47.5528258148j))
        self.assertAlmostEqual(arc4.point(0.5), (170.710678119 - 35.3553390593j))
        self.assertAlmostEqual(arc4.point(0.6), (195.105651630 - 15.4508497187j))
        self.assertAlmostEqual(arc4.point(0.7), (198.768834060 + 7.82172325201j))
        self.assertAlmostEqual(arc4.point(0.8), (180.901699437 + 29.3892626146j))
        self.assertAlmostEqual(arc4.point(0.9), (145.399049974 + 44.5503262094j))
        self.assertAlmostEqual(arc4.point(1.0), (100 + 50j))
コード例 #15
0
 def test_equality(self):
     # This is to test the __eq__ and __ne__ methods, so we can't use
     # assertEqual and assertNotEqual
     segment = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
     self.assertTrue(segment == Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j))
     self.assertTrue(segment != Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j))
コード例 #16
0
 def test_issue25(self):
     # This raised a math domain error
     Arc((725.307482225571 - 915.5548199281527j),
         (202.79421639137703 + 148.77294617167183j),
         225.6910319606926, 1, 1,
         (-624.6375539637027 + 896.5483089399895j))
コード例 #17
0
ファイル: test_parsing.py プロジェクト: ysire/md2reveal
    def test_svg_examples(self):
        """Examples from the SVG spec"""
        path1 = parse_path('M 100 100 L 300 100 L 200 300 z')
        self.assertEqual(
            path1,
            Path(Line(100 + 100j, 300 + 100j), Line(300 + 100j, 200 + 300j),
                 Line(200 + 300j, 100 + 100j)))

        path1 = parse_path('M 100 100 L 200 200')
        path2 = parse_path('M100 100L200 200')
        self.assertEqual(path1, path2)

        path1 = parse_path('M 100 200 L 200 100 L -100 -200')
        path2 = parse_path('M 100 200 L 200 100 -100 -200')
        self.assertEqual(path1, path2)

        path1 = parse_path("""M100,200 C100,100 250,100 250,200
                              S400,300 400,200""")
        self.assertEqual(
            path1,
            Path(CubicBezier(100 + 200j, 100 + 100j, 250 + 100j, 250 + 200j),
                 CubicBezier(250 + 200j, 250 + 300j, 400 + 300j, 400 + 200j)))

        path1 = parse_path('M100,200 C100,100 400,100 400,200')
        self.assertEqual(
            path1,
            Path(CubicBezier(100 + 200j, 100 + 100j, 400 + 100j, 400 + 200j)))

        path1 = parse_path('M100,500 C25,400 475,400 400,500')
        self.assertEqual(
            path1,
            Path(CubicBezier(100 + 500j, 25 + 400j, 475 + 400j, 400 + 500j)))

        path1 = parse_path('M100,800 C175,700 325,700 400,800')
        self.assertEqual(
            path1,
            Path(CubicBezier(100 + 800j, 175 + 700j, 325 + 700j, 400 + 800j)))

        path1 = parse_path('M600,200 C675,100 975,100 900,200')
        self.assertEqual(
            path1,
            Path(CubicBezier(600 + 200j, 675 + 100j, 975 + 100j, 900 + 200j)))

        path1 = parse_path('M600,500 C600,350 900,650 900,500')
        self.assertEqual(
            path1,
            Path(CubicBezier(600 + 500j, 600 + 350j, 900 + 650j, 900 + 500j)))

        path1 = parse_path("""M600,800 C625,700 725,700 750,800
                              S875,900 900,800""")
        self.assertEqual(
            path1,
            Path(CubicBezier(600 + 800j, 625 + 700j, 725 + 700j, 750 + 800j),
                 CubicBezier(750 + 800j, 775 + 900j, 875 + 900j, 900 + 800j)))

        path1 = parse_path('M200,300 Q400,50 600,300 T1000,300')
        self.assertEqual(
            path1,
            Path(QuadraticBezier(200 + 300j, 400 + 50j, 600 + 300j),
                 QuadraticBezier(600 + 300j, 800 + 550j, 1000 + 300j)))

        path1 = parse_path('M300,200 h-150 a150,150 0 1,0 150,-150 z')
        self.assertEqual(
            path1,
            Path(Line(300 + 200j, 150 + 200j),
                 Arc(150 + 200j, 150 + 150j, 0, 1, 0, 300 + 50j),
                 Line(300 + 50j, 300 + 200j)))

        path1 = parse_path('M275,175 v-150 a150,150 0 0,0 -150,150 z')
        self.assertEqual(
            path1,
            Path(Line(275 + 175j, 275 + 25j),
                 Arc(275 + 25j, 150 + 150j, 0, 0, 0, 125 + 175j),
                 Line(125 + 175j, 275 + 175j)))

        path1 = parse_path("""M600,350 l 50,-25 
                              a25,25 -30 0,1 50,-25 l 50,-25 
                              a25,50 -30 0,1 50,-25 l 50,-25 
                              a25,75 -30 0,1 50,-25 l 50,-25 
                              a25,100 -30 0,1 50,-25 l 50,-25""")
        self.assertEqual(
            path1,
            Path(Line(600 + 350j, 650 + 325j),
                 Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j),
                 Line(700 + 300j, 750 + 275j),
                 Arc(750 + 275j, 25 + 50j, -30, 0, 1, 800 + 250j),
                 Line(800 + 250j, 850 + 225j),
                 Arc(850 + 225j, 25 + 75j, -30, 0, 1, 900 + 200j),
                 Line(900 + 200j, 950 + 175j),
                 Arc(950 + 175j, 25 + 100j, -30, 0, 1, 1000 + 150j),
                 Line(1000 + 150j, 1050 + 125j)))