示例#1
0
 def parse_a_line(self, parts):
     """ Parse an A (Arc) line """
     x, y, radius, start, end = [int(i) for i in parts[1:6]]
     # convert tenths of degrees to pi radians
     start = start / 1800.0
     end = end / 1800.0
     return Arc(x, y, end, start, radius)
 def test_create_new_arc(self):
     """ Test the creation of a new empty arc. """
     arc = Arc(0, 1, 2, 3, 4)
     assert arc.x == 0
     assert arc.y == 1
     assert arc.start_angle == 2
     assert arc.end_angle == 3
     assert arc.radius == 4
    def test_arc(self):
        """
        Arcs are output correctly.
        """

        writer = KiCAD()
        arc = Arc(0, 0, -0.5, 0.5, 1)
        line = writer.get_shape_line(arc)
        self.assertEqual(line, 'A 0 0 11 900 -900 %(unit)d %(convert)d 0 N\n')
示例#4
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
示例#5
0
    def parse_arc(self, args):
        """ Returns a parsed arc. """
        # ViewDraw saves arcs as three points along a circle. Start, mid, end
        # [not entirely sure that mid is a midpoint, but irrelevant here]. We
        # need to find the centre of that circle, and the angles of the start
        # and end points. Tracing from start to end, the arcs are always CCW.

        # To find the centre: construct two chords using the three points. Lines
        # drawn perpendicular to and bisecting these chords will intersect at
        # the circle's centre.
        x0, y0, x1, y1, x2, y2 = [float(pt) for pt in args.split()]
        # can't allow for infinite slopes (m_a and m_b), and can't allow m_a
        # to be a zero slope.
        while abs(x0 - x1) < 0.1 or abs(x1 - x2) < 0.1 or abs(y0 - y1) < 0.1:
            x0, y0, x1, y1, x2, y2 = x1, y1, x2, y2, x0, y0
        # slopes of the chords
        m_a, m_b = (y1 - y0) / (x1 - x0), (y2 - y1) / (x2 - x1)
        # find the centre
        xcenter = ((m_a * m_b * (y0 - y2) + m_b * (x0 + x1) - m_a *
                    (x1 + x2)) / (2 * (m_b - m_a)))
        ycenter = (-1 / m_a) * (xcenter - (x0 + x1) / 2) + (y0 + y1) / 2
        # radius is the distance from the centre to any of the three points
        rad = sqrt((xcenter - x0)**2 + (ycenter - y0)**2)

        # re-init xs,ys so that start and end points don't get confused.
        x0, y0, x1, y1, x2, y2 = [float(pt) for pt in args.split()]

        def angle(x, y):
            """ Calculate the angle from the center of the arc to (x, y). """
            # as parsed, the angle increases CCW. Here, we return an angle
            # increasing CW
            opp = y - ycenter
            adj = x - xcenter
            if abs(adj) < 0.01:
                # vertical line to x,y
                if opp > 0:
                    return 3 * pi / 2
                else:
                    return pi / 2

            ang = atan(opp / adj)
            # correct for ambiguity due to atan
            if adj < 0:
                ang += pi

            # restrict angle to (0, 2pi) range
            ang = ang % (2 * pi)
            # upverter uses CW angles, so...
            return 2 * pi - ang

        return ('shape',
                Arc(int(round(xcenter)), int(round(ycenter)),
                    angle(x2, y2) / pi,
                    angle(x0, y0) / pi, int(round(rad))))
示例#6
0
 def _draw_arc(self, end_pts, center_offset):
     """ Convert arc path into shape. """
     start, end = end_pts
     offset = {'i': center_offset[0], 'j': center_offset[1]}
     for k in offset:
         if offset[k] is None:
             offset[k] = 0
     center, radius = self._get_ctr_and_radius(end_pts, offset)
     start_angle = self._get_angle(center, start)
     end_angle = self._get_angle(center, end)
     clockwise = 'ANTI' not in self.status['interpolation']
     self._check_mq(start_angle, end_angle, clockwise)
     return Arc(center.x, center.y, start_angle if clockwise else end_angle,
                end_angle if clockwise else start_angle, radius)
    def make_shape_for_wire(self, wire):
        """ Generate an openjson shape for an eaglexml wire. """

        if wire.curve is None:
            return Line((self.make_length(wire.x1), self.make_length(wire.y1)),
                        (self.make_length(wire.x2), self.make_length(wire.y2)))

        curve, x1, y1, x2, y2 = map(
            float, (wire.curve, wire.x1, wire.y1, wire.x2, wire.y2))

        if curve < 0:
            curve = -curve
            negative = True
            mult = -1.0
        else:
            negative = False
            mult = 1.0

        if curve > 180.0:
            major_arc = True
            curve = 360.0 - curve
            mult *= -1.0
        else:
            major_arc = False

        chordlen = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))

        radius = chordlen / (2.0 * sin(radians(curve) / 2))

        mx, my = (x1 + x2) / 2, (y1 + y2) / 2  # midpoint between arc points

        h = sqrt(pow(radius, 2) - pow(chordlen / 2, 2))  # height of isoceles

        # calculate center point
        cx = mx + mult * h * (y1 - y2) / chordlen
        cy = my + mult * h * (x2 - x1) / chordlen

        if negative:
            start_angle = atan2(y2 - cy, x2 - cx)
            end_angle = start_angle + radians(curve) - (pi
                                                        if major_arc else 0.0)
        else:
            start_angle = atan2(y1 - cy, x1 - cx)
            end_angle = start_angle + radians(curve) + (pi
                                                        if major_arc else 0.0)

        return Arc(self.make_length(cx), self.make_length(cy),
                   round(start_angle / pi, 3) % 2.0,
                   round(end_angle / pi, 3) % 2.0, self.make_length(radius))
示例#8
0
    def test_arc(self):
        """ Convert arc to lines shape """

        arc = Arc(0, 0, -0.5, 0.5, 1)
        writer = Specctra()
        obj = writer._convert_shape(arc)
        self.assertEqual(
            to_string(writer, obj),
            '( (path signal 10.416667 -0.000000 -10.416667 -6.122763 -8.427260)'
            +
            ' (path signal 10.416667 -6.122763 -8.427260 -9.906839 -3.218927)'
            +
            ' (path signal 10.416667 -9.906839 -3.218927 -9.906839 3.218927)' +
            ' (path signal 10.416667 -9.906839 3.218927 -6.122763 8.427260)' +
            ' (path signal 10.416667 -6.122763 8.427260 -0.000000 10.416667) )'
        )
示例#9
0
    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 make_arc(p1, p2, p0):
     start_angle = math.atan2(p1.y - p0.y, p1.x - p0.x) / math.pi
     end_angle = math.atan2(p2.y - p0.y, p2.x - p0.x) / math.pi
     return Arc(p0.x, p0.y, start_angle, end_angle, aperture)
示例#11
0
 def test_max_point_arc_wraparound(self):
     """max_point() of an arc that traces through 0 degrees"""
     arc = Arc(2, 3, 1.75, 0.25, 5)
     self.assertEqual(arc.max_point().x, 5 + 2)
     self.assertEqual(arc.max_point().y, int(round(sin(0.25 * pi) * 5 + 3)))
示例#12
0
 def test_max_point_arc(self):
     """max_point() of an arc tracing bottom-right quarter"""
     arc = Arc(2, 3, 0, 0.5, 5)
     self.assertEqual(arc.max_point().x, 7)
     self.assertEqual(arc.max_point().y, 8)
示例#13
0
 def test_min_point_arc(self):
     """min_point() of an arc tracing top-left quarter"""
     arc = Arc(2, 3, 1, 1.5, 5)
     self.assertEqual(arc.min_point().x, -3)
     self.assertEqual(arc.min_point().y, -2)
示例#14
0
 def test_max_point_arc_is_circle(self):
     '''max_point() when an arc actually traces out a full circle'''
     arc = Arc(2, 3, 0, 2, 5)
     self.assertEqual(arc.max_point().x, 7)
     self.assertEqual(arc.max_point().y, 8)
 def test_min_point_arc_is_circle(self):
     """min_point() when an arc actually traces out a full circle"""
     arc = Arc(2, 3, 0, 2, 5)
     self.assertEqual(arc.min_point().x, -3)
     self.assertEqual(arc.min_point().y, -2)