def parse_t(self, data, is_relative):
        """ Parse a T or t (quadratic shorthand bezier) segment. """

        points, data = self.parse_points(data)

        while points:
            start = self.cur_point

            end, points = points[0], points[1:]

            self.cur_point = end = self.get_path_point(end, is_relative)

            if self.prev_cmd not in 'qt' or not self.prev_ctl:
                ctl = start
            else:
                ctl = (start[0] - (self.prev_ctl[0] - start[0]),
                       start[1] - (self.prev_ctl[1] - start[1]))

            self.prev_ctl = ctl

            ctl1 = (start[0] + (2.0 / 3.0 * (ctl[0] - start[0])),
                    start[1] + (2.0 / 3.0 * (ctl[1] - start[1])))

            ctl2 = (end[0] + (2.0 / 3.0 * (ctl[0] - end[0])),
                    end[1] + (2.0 / 3.0 * (ctl[1] - end[1])))

            self.shapes.append(
                BezierCurve(make_point(ctl1, self.svg_mult),
                            make_point(ctl2, self.svg_mult),
                            make_point(start, self.svg_mult),
                            make_point(end, self.svg_mult)))

        return data
    def parse_s(self, data, is_relative):
        """ Parse an S or s (cubic shorthand bezier) segment. """

        points, data = self.parse_points(data)

        while points:
            start = self.cur_point

            (ctl2, end), points = points[:2], points[2:]

            self.cur_point = ctl2 = self.get_path_point(ctl2, is_relative)
            self.cur_point = end = self.get_path_point(end, is_relative)

            if self.prev_cmd not in 'cs' or not self.prev_ctl:
                ctl1 = start
            else:
                ctl1 = (start[0] - (self.prev_ctl[0] - start[0]),
                        start[1] - (self.prev_ctl[1] - start[1]))

            self.prev_ctl = ctl2

            self.shapes.append(
                BezierCurve(make_point(ctl1, self.svg_mult),
                            make_point(ctl2, self.svg_mult),
                            make_point(start, self.svg_mult),
                            make_point(end, self.svg_mult)))

        return data
    def parse_q(self, data, is_relative):
        """ Parse a Q or q (quadratic bezier) segment. """

        points, data = self.parse_points(data)

        while points:
            start = self.cur_point

            (ctl, end), points = points[:2], points[2:]

            self.cur_point = ctl = self.get_path_point(ctl, is_relative)
            self.cur_point = end = self.get_path_point(end, is_relative)

            self.prev_ctl = ctl

            ctl1 = (start[0] + (2.0 / 3.0 * (ctl[0] - start[0])),
                    start[1] + (2.0 / 3.0 * (ctl[1] - start[1])))

            ctl2 = (end[0] + (2.0 / 3.0 * (ctl[0] - end[0])),
                    end[1] + (2.0 / 3.0 * (ctl[1] - end[1])))

            self.shapes.append(
                BezierCurve(make_point(ctl1, self.svg_mult),
                            make_point(ctl2, self.svg_mult),
                            make_point(start, self.svg_mult),
                            make_point(end, self.svg_mult)))

        return data
Exemple #4
0
    def test_bezier_curve(self):
        """ Convert bezier to lines shape """

        bezier = BezierCurve((0, 0), (1, 1), (2, 2), (3, 3))
        writer = Specctra()
        writer.resolution = specctraobj.Resolution()
        writer.resolution.unit = 'mil'
        writer.resolution.resolution = 10
        obj = writer._convert_shape(bezier)
        self.assertEqual(
            to_string(writer, obj),
            '( (path signal 10.416667 20.833333 20.833333 20.833333 20.833333)'
            +
            ' (path signal 10.416667 20.833333 20.833333 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 10.416667 10.416667)'
            +
            ' (path signal 10.416667 10.416667 10.416667 20.833333 20.833333)'
            +
            ' (path signal 10.416667 20.833333 20.833333 20.833333 20.833333)'
            +
            ' (path signal 10.416667 20.833333 20.833333 20.833333 20.833333)'
            +
            ' (path signal 10.416667 20.833333 20.833333 31.250000 31.250000) )'
        )
    def test_bezier_curve(self):
        """
        BezierCurves are output correctly.
        """

        writer = KiCAD()
        bezier = BezierCurve((0, 0), (1, 1), (2, 2), (3, 3))
        line = writer.get_shape_line(bezier)
        self.assertEqual(line, 'P 2 %(unit)d %(convert)d 0 22 22 33 33 N\n')
Exemple #6
0
    def parse_shape(self, shape):
        """ Extract a shape. """
        # pylint: disable=R0914
        # pylint: disable=R0911

        typ = shape.get('type')
        if 'rectangle' == typ:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            height = int(shape.get('height'))
            width = int(shape.get('width'))
            parsed_shape = Rectangle(x, y, width, height)
        elif 'rounded_rectangle' == typ:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            height = int(shape.get('height'))
            width = int(shape.get('width'))
            radius = int(shape.get('radius'))
            parsed_shape = RoundedRectangle(x, y, width, height, radius)
        elif 'arc' == typ:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            start_angle = float(shape.get('start_angle'))
            end_angle = float(shape.get('end_angle'))
            radius = int(shape.get('radius'))
            parsed_shape = Arc(x, y, start_angle, end_angle, radius)
        elif 'circle' == typ:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            radius = int(shape.get('radius'))
            parsed_shape = Circle(x, y, radius)
        elif 'label' == typ:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            rotation = float(shape.get('rotation'))
            text = shape.get('text')
            align = shape.get('align')
            parsed_shape = Label(x, y, text, align, rotation)
        elif 'line' == typ:
            p1 = self.parse_point(shape.get('p1'))
            p2 = self.parse_point(shape.get('p2'))
            parsed_shape = Line(p1, p2)
        elif 'polygon' == typ:
            parsed_shape = Polygon()
            for point in shape.get('points'):
                parsed_shape.add_point(self.parse_point(point))
        elif 'bezier' == typ:
            control1 = self.parse_point(shape.get('control1'))
            control2 = self.parse_point(shape.get('control2'))
            p1 = self.parse_point(shape.get('p1'))
            p2 = self.parse_point(shape.get('p2'))
            parsed_shape = BezierCurve(control1, control2, p1, p2)

        parsed_shape.styles = shape.get('styles') or {}
        parsed_shape.attributes = shape.get('attributes') or {}
        return parsed_shape
    def parse_c(self, data, is_relative):
        """ Parse a C or c (cubic bezier) segment. """

        points, data = self.parse_points(data)

        while points:
            start = self.cur_point

            (ctl1, ctl2, end), points = points[:3], points[3:]

            self.cur_point = ctl1 = self.get_path_point(ctl1, is_relative)
            self.cur_point = ctl2 = self.get_path_point(ctl2, is_relative)
            self.cur_point = end = self.get_path_point(end, is_relative)

            self.prev_ctl = ctl2

            self.shapes.append(
                BezierCurve(make_point(ctl1, self.svg_mult),
                            make_point(ctl2, self.svg_mult),
                            make_point(start, self.svg_mult),
                            make_point(end, self.svg_mult)))

        return data
    def parse_shape(self, shape):
        """ Extract a shape. """
        # pylint: disable=R0914
        # pylint: disable=R0911

        rotation = shape.get('rotation', 0.0)
        flip_horizontal = shape.get('flip_horizontal', False)

        shape_type = shape.get('type')
        if 'rectangle' == shape_type:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            height = int(shape.get('height'))
            width = int(shape.get('width'))
            parsed_shape = Rectangle(x, y, width, height)
        elif 'rounded_rectangle' == shape_type:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            height = int(shape.get('height'))
            width = int(shape.get('width'))
            radius = int(shape.get('radius'))
            parsed_shape = RoundedRectangle(x, y, width, height, radius)
        elif 'arc' == shape_type:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            start_angle = float(shape.get('start_angle'))
            end_angle = float(shape.get('end_angle'))
            radius = int(shape.get('radius'))
            parsed_shape = Arc(x, y, start_angle, end_angle, radius)
        elif 'circle' == shape_type:
            x = int(shape.get('x'))
            y = int(shape.get('y'))
            radius = int(shape.get('radius'))
            parsed_shape = Circle(x, y, radius)
        elif 'label' == shape_type:
            parsed_shape = self.parse_label(shape)
        elif 'line' == shape_type:
            p1 = self.parse_point(shape.get('p1'))
            p2 = self.parse_point(shape.get('p2'))
            parsed_shape = Line(p1, p2)
        elif 'polygon' == shape_type:
            parsed_shape = Polygon()
            for point in shape.get('points'):
                parsed_shape.add_point(self.parse_point(point))
        elif 'bezier' == shape_type:
            control1 = self.parse_point(shape.get('control1'))
            control2 = self.parse_point(shape.get('control2'))
            p1 = self.parse_point(shape.get('p1'))
            p2 = self.parse_point(shape.get('p2'))
            parsed_shape = BezierCurve(control1, control2, p1, p2)
        elif 'rounded_segment' == shape_type:
            p1 = self.parse_point(shape.get('p1'))
            p2 = self.parse_point(shape.get('p2'))
            width = int(shape.get('width'))
            parsed_shape = RoundedSegment(p1, p2, width)

        parsed_shape.rotation = rotation
        parsed_shape.flip_horizontal = flip_horizontal

        parsed_shape.styles = shape.get('styles') or {}
        parsed_shape.attributes = shape.get('attributes') or {}
        return parsed_shape
 def setUp(self):
     """ Setup the test case. """
     self.curve = BezierCurve((2, 9), (9, 8), (1, 1), (7, 2))
class BezierCurveTests(unittest.TestCase):
    """ The tests of the core module bezier shape """

    def setUp(self):
        """ Setup the test case. """
        self.curve = BezierCurve((2, 9), (9, 8), (1, 1), (7, 2))

    def tearDown(self):
        """ Teardown the test case. """
        del self.curve

    def test_create_new_bezier_curve(self):
        """ Test the creation of a new empty bezier. """
        control1 = Point(2, 9)
        control2 = Point(9, 8)
        p1 = Point(1, 1)
        p2 = Point(7, 2)
        assert self.curve.control1.x == control1.x
        assert self.curve.control1.y == control1.y
        assert self.curve.control2.x == control2.x
        assert self.curve.control2.y == control2.y
        assert self.curve.p1.x == p1.x
        assert self.curve.p1.y == p1.y
        assert self.curve.p2.x == p2.x
        assert self.curve.p2.y == p2.y


    def interp_bezier(self, points, typ):
        return tuple([int(round(((1 - typ) ** 3) * pts[0]
                                + 3 * ((1 - typ) ** 2) * typ * pts[1]
                                + 3 * (1 - typ) * (typ ** 2) * pts[2]
                                + (typ ** 3) * pts[3]))
                      for pts in ([pt.x for pt in points],
                                  [pt.y for pt in points])])
    

    def bez_recurse(self, pts, lo, hi):
        """Helper method to draw a bezier curve"""
        # kind of important that we don't just copy how it's done in the method
        # to be tested, so do it by recusively bisecting the curve until we hit
        # the necessary resolution
        [plo, phi] = [self.interp_bezier(pts, typ) for typ in (lo, hi)]
        if abs(plo[0] - phi[0]) <= 1 and abs(plo[1] - phi[1]) <= 1:
            return [plo, phi]
        mid = (lo + hi) / 2.
        bot_half = self.bez_recurse(pts, lo, mid)
        top_half = self.bez_recurse(pts, mid, hi)
        if bot_half[-1] == top_half[0]:
            bot_half = bot_half[:-1]
        return bot_half + top_half


    def test_bezier_min_point(self):
        points = self.bez_recurse([self.curve.p1, self.curve.control1,
                                   self.curve.control2, self.curve.p2], 0., 1.)
        x = min([pt[0] for pt in points])
        y = min([pt[1] for pt in points])
        min_pt = self.curve.min_point()
        self.assertEqual(min_pt.x, x)
        self.assertEqual(min_pt.y, y)


    def test_bezier_max_point(self):
        points = self.bez_recurse([self.curve.p1, self.curve.control1,
                                   self.curve.control2, self.curve.p2], 0., 1.)
        x = max([pt[0] for pt in points])
        y = max([pt[1] for pt in points])
        max_pt = self.curve.max_point()
        self.assertEqual(max_pt.x, x)
        self.assertEqual(max_pt.y, y)