Example #1
0
def arrow_path_concave(line, width):
    """
    Return a :class:`QPainterPath` of a pretty looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))

    start, end = baseline.p1(), baseline.p2()
    mid = (start + end) / 2.0
    normal = QLineF.fromPolar(1.0, baseline.angle() + 90).p2()

    path.moveTo(start)
    path.lineTo(start + (normal * width / 4.0))

    path.quadTo(mid + (normal * width / 4.0),
                end + (normal * width / 1.5))

    path.lineTo(end - (normal * width / 1.5))
    path.quadTo(mid - (normal * width / 4.0),
                start - (normal * width / 4.0))
    path.closeSubpath()

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [p2,
              p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
              baseline.p2(),
              p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(),
              p2]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Example #2
0
def arrow_path_concave(line, width):
    """
    Return a :class:`QPainterPath` of a pretty looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))

    start, end = baseline.p1(), baseline.p2()
    mid = (start + end) / 2.0
    normal = QLineF.fromPolar(1.0, baseline.angle() + 90).p2()

    path.moveTo(start)
    path.lineTo(start + (normal * width / 4.0))

    path.quadTo(mid + (normal * width / 4.0), end + (normal * width / 1.5))

    path.lineTo(end - (normal * width / 1.5))
    path.quadTo(mid - (normal * width / 4.0), start - (normal * width / 4.0))
    path.closeSubpath()

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        baseline.p2(), p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Example #3
0
def arrow_path_plain(line, width):
    """
    Return an :class:`QPainterPath` of a plain looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))
    path.moveTo(baseline.p1())
    path.lineTo(baseline.p2())

    stroker = QPainterPathStroker()
    stroker.setWidth(width)
    path = stroker.createStroke(path)

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2,
        p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(),
        p2,
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Example #4
0
def arrow_path_plain(line, width):
    """
    Return an :class:`QPainterPath` of a plain looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))
    path.moveTo(baseline.p1())
    path.lineTo(baseline.p2())

    stroker = QPainterPathStroker()
    stroker.setWidth(width)
    path = stroker.createStroke(path)

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Example #5
0
 def _write(self, shapes, svg_file, width, height, stroke_colour = None, stroke_width = None, background_colour = None):
 
     svg_file.write('<?xml version="1.0" standalone="no"?>\n'
                         '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n'
                         '  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
     
     svg_file.write('<svg width="%.6fcm" height="%.6fcm" ' % (width, height))
     svg_file.write('viewBox="%.6f %.6f %.6f %.6f" '
                         'xmlns="http://www.w3.org/2000/svg" '
                         'version="1.1">\n' % (0.0, 0.0, width, height))
     
     if stroke_width is None:
         stroke_width = "0.1%"
     
     if background_colour is not None:
     
         svg_file.write('<polygon fill="%s" ' % background_colour)
         svg_file.write('points="%.6f,%.6f %.6f,%.6f %.6f,%.6f %.6f,%.6f" />\n' % (
             0.0, 0.0, width, 0.0, width, height, 0.0, height))
     
     path = QPainterPath()
     shapes.reverse()
     
     new_shapes = {}
     
     for points, polygon in shapes:
     
         rgb = self.parts.colours.get(polygon.colour, "#ffffff")
         
         new_points = []
         for x, y in points:
             new_points.append(QPointF(x + width/2.0, height/2.0 - y))
         
         new_polygon = QPolygonF(new_points)
         new_path = QPainterPath()
         new_path.addPolygon(new_polygon)
         
         if path.contains(new_path):
             continue
         
         inter = path.intersected(new_path)
         remaining = new_path.subtracted(inter)
         
         # Combine the new path with the accumulated path and simplify
         # the result.
         path = path.united(new_path)
         path = path.simplified()
         
         piece_dict = new_shapes.setdefault(polygon.piece, {})
         colour_path = piece_dict.get(polygon.colour, QPainterPath())
         piece_dict[polygon.colour] = colour_path.united(remaining)
     
     for piece, piece_dict in new_shapes.items():
     
         svg_file.write('<g>\n')
         
         for colour, colour_path in piece_dict.items():
         
             if colour_path.isEmpty():
                 continue
             
             rgb = self.parts.colours.get(colour, "#ffffff")
             
             shape = '<path style="fill:%s; opacity:%f" d="' % (
                 rgb, self._opacity_from_colour(colour))
             
             i = 0
             in_path = False
             while i < colour_path.elementCount():
                 p = colour_path.elementAt(i)
                 if p.type == QPainterPath.MoveToElement:
                     if in_path:
                         shape += 'Z '
                     shape += 'M %.6f %.6f ' % (p.x, p.y)
                     in_path = True
                 elif p.type == QPainterPath.LineToElement:
                     shape += 'L %.6f %.6f ' % (p.x, p.y)
                 i += 1
             
             if in_path:
                 shape += 'Z'
             shape += '" />\n'
             
             svg_file.write(shape)
         
         svg_file.write('</g>\n')
     
     svg_file.write("</svg>\n")
     svg_file.close()