Example #1
0
def stroke_path(path, pen):
    """Create a QPainterPath stroke from the `path` drawn with `pen`.
    """
    stroker = QPainterPathStroker()
    stroker.setCapStyle(pen.capStyle())
    stroker.setJoinStyle(pen.joinStyle())
    stroker.setMiterLimit(pen.miterLimit())
    stroker.setWidth(max(pen.widthF(), 1e-9))

    return stroker.createStroke(path)
    def buildPath(self):
        srcPos, tarPos = self.getNodePos()
        if self.pathPnt and (self.pathPnt[0] - srcPos).manhattanLength(
        ) < 0.05 and (self.pathPnt[1] - tarPos).manhattanLength() < 0.05:
            return self.path
        self.pathPnt = (srcPos, tarPos)
        path = QtGui.QPainterPath()
        path.moveTo(srcPos)
        dx = tarPos.x() - srcPos.x()
        p1 = srcPos + QtCore.QPointF(dx * 0.3, 0)
        p2 = tarPos + QtCore.QPointF(-dx * 0.7, 0)
        path.cubicTo(p1, p2, tarPos)
        self.curve = QtGui.QPainterPath(path)
        self.path = path

        from PyQt4.QtGui import QPainterPathStroker
        stroker = QPainterPathStroker()
        stroker.setWidth(10.0)
        self.pathShape = stroker.createStroke(self.path)
        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
    def setAnchorPath(self, path):
        """
        Set the anchor's curve path as a :class:`QPainterPath`.
        """
        self.__anchorPath = path
        # Create a stroke of the path.
        stroke_path = QPainterPathStroker()
        stroke_path.setCapStyle(Qt.RoundCap)

        # Shape is wider (bigger mouse hit area - should be settable)
        stroke_path.setWidth(9)
        self.__shape = stroke_path.createStroke(path)

        # The full stroke
        stroke_path.setWidth(3)
        self.__fullStroke = stroke_path.createStroke(path)

        # The dotted stroke (when not connected to anything)
        stroke_path.setDashPattern(Qt.DotLine)
        self.__dottedStroke = stroke_path.createStroke(path)

        if self.anchored:
            self.setPath(self.__fullStroke)
            self.setBrush(self.connectedBrush)
        else:
            self.setPath(self.__dottedStroke)
            self.setBrush(self.normalBrush)
Example #6
0
    def setAnchorPath(self, path):
        """
        Set the anchor's curve path as a :class:`QPainterPath`.
        """
        self.__anchorPath = path
        # Create a stroke of the path.
        stroke_path = QPainterPathStroker()
        stroke_path.setCapStyle(Qt.RoundCap)

        # Shape is wider (bigger mouse hit area - should be settable)
        stroke_path.setWidth(12)
        self.__shape = stroke_path.createStroke(path)

        # The full stroke
        stroke_path.setWidth(3)
        self.__fullStroke = stroke_path.createStroke(path)

        # The dotted stroke (when not connected to anything)
        stroke_path.setDashPattern(Qt.DotLine)
        self.__dottedStroke = stroke_path.createStroke(path)

        if self.anchored:
            self.setPath(self.__fullStroke)
            self.setBrush(self.connectedBrush)
        else:
            self.setPath(self.__dottedStroke)
            self.setBrush(self.normalBrush)
Example #7
0
def path_stroke(path, width=1, join_style=Qt.MiterJoin):
    stroke = QPainterPathStroker()
    stroke.setWidth(width)
    stroke.setJoinStyle(join_style)
    return stroke.createStroke(path)
def path_stroke(path, width=1, join_style=Qt.MiterJoin):
    stroke = QPainterPathStroker()
    stroke.setWidth(width)
    stroke.setJoinStyle(join_style)
    return stroke.createStroke(path)
Example #9
0
def shapeFromPath(path, pen):
    """Create a QPainterPath shape from the `path` drawn with `pen`.
    """
    stroker = QPainterPathStroker()
    stroker.setCapStyle(pen.capStyle())
    stroker.setJoinStyle(pen.joinStyle())
    stroker.setMiterLimit(pen.miterLimit())
    stroker.setWidth(max(pen.widthF(), 1e-9))

    shape = stroker.createStroke(path)
    shape.addPath(path)

    return shape
Example #10
0
    def setGeometry(self):
        """
        Read the parameters that define the geometry of the point
        """
        params = parameters.instance
        self.setEditable(params.is_cell_editable)
        points = self.points
        polygon_id = self.polygon_id
        polygon = [
            points[pt].pos() if pt in points else None for pt in polygon_id
        ]
        non_none_cnt = len([p for p in polygon if p is not None])
        if non_none_cnt == 0:
            self.rect = QRectF()
            self.bounding_rect = QRectF()
            self.setVisible(False)
            return
        self.setVisible(True)
        # First, check if this is a "simple" cell
        walls = self.walls
        real_polygon = [pid for pid in polygon_id if pid in points]
        #sides = [ walls[real_polygon[i], real_polygon[(i+1)%len(real_polygon)]] for i in range(len(real_polygon)) ]
        sides = [None] * len(polygon)
        self.sides = sides
        real_scale_x = self.scale[0] / self.glob_scale
        real_scale_y = self.scale[1] / self.glob_scale
        for i in range(len(polygon)):
            if polygon[i] is not None:  # Find the next
                j = (i + 1) % len(polygon)
                while polygon[j] is None:
                    j = (j + 1) % len(polygon)
                w = [
                    QPointF(p.x() * real_scale_x,
                            p.y() * real_scale_y)
                    for p in walls[polygon_id[i], polygon_id[j]]
                ]
                sides[i] = [polygon[i]] + w + [polygon[j]]
        prev = real_polygon[-1]
        polygon_shape = []
        for i in range(len(polygon)):
            if polygon[i]:
                polygon_shape.append(polygon[i])
                polygon_shape.extend(sides[i])
# Now add the dummy points .. starts at the first non-None point
        if non_none_cnt > 2:
            start = None
            for i in range(len(polygon)):
                if polygon[i] is not None:
                    start = i
                    break
            prev = start
            cur = start + 1 if start + 1 < len(polygon) else 0
            log_debug("Polygon before: [%s]" %
                      ",".join("(%f,%f)" %
                               (p.x(), p.y()) if p is not None else "None"
                               for p in polygon))
            while cur != start:
                if polygon[cur] is None:
                    cnt = 1
                    next = cur + 1 if cur + 1 < len(polygon) else 0
                    while True:
                        if polygon[next] is None:
                            cnt += 1
                        else:
                            break
                        next += 1
                        if next == len(polygon):
                            next = 0
                    #print "%d points missing" % cnt
                    # First, find total length of wall
                    length = 0.0
                    side = sides[prev]
                    for i in range(len(side) - 1):
                        length += dist(side[i], side[i + 1])
                    diff = length / (cnt + 1)  # Distance between two points
                    i = cur
                    p = side[0]
                    for j in range(cnt):
                        l = 0.0
                        found = False
                        for k in range(len(side) - 1):
                            dl = dist(side[k], side[k + 1])
                            l += dl
                            if l > diff * (
                                    1 + 1e-5
                            ):  # Account for accumulation of small errors
                                c = (i + j) % len(polygon)
                                delta = diff - l + dl
                                p = side[k] + (side[k + 1] -
                                               side[k]) * delta / dl
                                s1 = side[:k + 1] + [p]
                                s2 = [p] + side[k + 1:]
                                sides[c - 1] = s1
                                sides[c] = s2
                                side = s2
                                polygon[c] = p
                                found = True
                                break
                        assert found, "Could not find point in polygon for position %d" % (
                            j + i, )
                        #p = p + diff
                        #c = (i+j)%len(polygon)
                        #polygon[c] = QPointF(p)
                    cur = next
                else:
                    prev = cur
                    cur += 1
                if cur >= len(polygon):
                    cur = 0
            assert None not in polygon, "Error, some dummy points were not added"
        else:
            polygon = [p for p in polygon if p is not None]
        center = sum(polygon, QPointF(0, 0)) / float(len(polygon))
        self.center = center
        if len(polygon) > 2:
            polygon = QPolygonF(polygon + [polygon[0]])
            polygon.translate(-center)
            polygon_shape = QPolygonF(polygon_shape + [polygon_shape[0]])
            self.polygon_shape = polygon_shape
            polygon_shape.translate(-center)
            # Translate the sides too
            sides = [[p - center for p in s] for s in sides]
            self.sides = sides
            assert len(sides) == len(polygon) - 1
        elif len(polygon) == 2:
            polygon = QLineF(polygon[0], polygon[1])
            polygon.translate(-center)
        else:
            polygon = None
        self.polygon = polygon
        self.setPos(center)
        params = parameters.instance
        self.prepareGeometryChange()
        size = params.cell_size
        scale = self.scale
        height = size * cos(pi / 6) * scale[1]
        width = size * scale[0]
        pos_x = size * cos(pi / 3) * scale[0]
        self.sel_rect = QRectF(-width, -height, 2 * width, 2 * height)
        if isinstance(polygon, QPolygonF):
            self.rect = self.polygon_shape.boundingRect() | self.sel_rect
        elif isinstance(polygon, QLineF):
            self.rect = QRectF(polygon.p1(),
                               polygon.p2()).normalized() | self.sel_rect
        else:
            self.rect = self.sel_rect
        self.bounding_rect = QRectF(self.rect)
        if self.p1 in points and self.p2 in points:
            self.division_line = QLineF(points[self.p1].pos() - center,
                                        points[self.p2].pos() - center)
        else:
            self.division_line = None
        self.hexagon = QPolygonF([
            QPointF(-width, 0),
            QPointF(-pos_x, height),
            QPointF(pos_x, height),
            QPointF(width, 0),
            QPointF(pos_x, -height),
            QPointF(-pos_x, -height)
        ])
        self.hexagon_path = QPainterPath()
        self.hexagon_path.addPolygon(self.hexagon)
        s1 = QPainterPath()
        if isinstance(self.polygon, QPolygonF):
            s1.addPolygon(polygon_shape)
        elif isinstance(self.polygon, QLineF):
            s1.moveTo(self.polygon.p1())
            s1.lineTo(self.polygon.p2())
        stroke = QPainterPathStroker()
        sel_thick = 3 * params.cell_thickness
        if sel_thick == 0:
            sel_thick = 3
        stroke.setWidth(sel_thick)
        self.stroke = stroke.createStroke(s1)
Example #11
0
    def setGeometry(self):
        """
        Read the parameters that define the geometry of the point
        """
        params = parameters.instance
        self.setEditable(params.is_cell_editable)
        points = self.points
        polygon_id = self.polygon_id
        polygon = [points[pt].pos() if pt in points else None for pt in polygon_id]
        non_none_cnt = len([p for p in polygon if p is not None])
        if non_none_cnt == 0:
            self.rect = QRectF()
            self.bounding_rect = QRectF()
            self.setVisible(False)
            return
        self.setVisible(True)
# First, check if this is a "simple" cell
        walls = self.walls
        real_polygon = [pid for pid in polygon_id if pid in points]
        #sides = [ walls[real_polygon[i], real_polygon[(i+1)%len(real_polygon)]] for i in range(len(real_polygon)) ]
        sides = [None] * len(polygon)
        self.sides = sides
        real_scale_x = self.scale[0]/self.glob_scale
        real_scale_y = self.scale[1]/self.glob_scale
        for i in range(len(polygon)):
            if polygon[i] is not None:  # Find the next
                j = (i+1) % len(polygon)
                while polygon[j] is None:
                    j = (j+1) % len(polygon)
                w = [QPointF(p.x()*real_scale_x, p.y()*real_scale_y) for p in walls[polygon_id[i], polygon_id[j]]]
                sides[i] = [polygon[i]] + w + [polygon[j]]
        prev = real_polygon[-1]
        polygon_shape = []
        for i in range(len(polygon)):
            if polygon[i]:
                polygon_shape.append(polygon[i])
                polygon_shape.extend(sides[i])
# Now add the dummy points .. starts at the first non-None point
        if non_none_cnt > 2:
            start = None
            for i in range(len(polygon)):
                if polygon[i] is not None:
                    start = i
                    break
            prev = start
            cur = start+1 if start+1 < len(polygon) else 0
            log_debug("Polygon before: [%s]" % ",".join("(%f,%f)" % (p.x(), p.y()) if p is not None else "None"
                                                        for p in polygon))
            while cur != start:
                if polygon[cur] is None:
                    cnt = 1
                    next = cur+1 if cur+1 < len(polygon) else 0
                    while True:
                        if polygon[next] is None:
                            cnt += 1
                        else:
                            break
                        next += 1
                        if next == len(polygon):
                            next = 0
                    #print "%d points missing" % cnt
                    # First, find total length of wall
                    length = 0.0
                    side = sides[prev]
                    for i in range(len(side)-1):
                        length += dist(side[i], side[i+1])
                    diff = length/(cnt+1)  # Distance between two points
                    i = cur
                    p = side[0]
                    for j in range(cnt):
                        l = 0.0
                        found = False
                        for k in range(len(side)-1):
                            dl = dist(side[k], side[k+1])
                            l += dl
                            if l > diff*(1+1e-5):  # Account for accumulation of small errors
                                c = (i + j) % len(polygon)
                                delta = diff-l+dl
                                p = side[k] + (side[k+1]-side[k])*delta/dl
                                s1 = side[:k+1] + [p]
                                s2 = [p] + side[k+1:]
                                sides[c-1] = s1
                                sides[c] = s2
                                side = s2
                                polygon[c] = p
                                found = True
                                break
                        assert found, "Could not find point in polygon for position %d" % (j+i,)
                        #p = p + diff
                        #c = (i+j)%len(polygon)
                        #polygon[c] = QPointF(p)
                    cur = next
                else:
                    prev = cur
                    cur += 1
                if cur >= len(polygon):
                    cur = 0
            assert None not in polygon, "Error, some dummy points were not added"
        else:
            polygon = [p for p in polygon if p is not None]
        center = sum(polygon, QPointF(0, 0)) / float(len(polygon))
        self.center = center
        if len(polygon) > 2:
            polygon = QPolygonF(polygon+[polygon[0]])
            polygon.translate(-center)
            polygon_shape = QPolygonF(polygon_shape + [polygon_shape[0]])
            self.polygon_shape = polygon_shape
            polygon_shape.translate(-center)
            # Translate the sides too
            sides = [[p-center for p in s] for s in sides]
            self.sides = sides
            assert len(sides) == len(polygon)-1
        elif len(polygon) == 2:
            polygon = QLineF(polygon[0], polygon[1])
            polygon.translate(-center)
        else:
            polygon = None
        self.polygon = polygon
        self.setPos(center)
        params = parameters.instance
        self.prepareGeometryChange()
        size = params.cell_size
        scale = self.scale
        height = size*cos(pi/6)*scale[1]
        width = size*scale[0]
        pos_x = size*cos(pi/3)*scale[0]
        self.sel_rect = QRectF(-width, -height, 2*width, 2*height)
        if isinstance(polygon, QPolygonF):
            self.rect = self.polygon_shape.boundingRect() | self.sel_rect
        elif isinstance(polygon, QLineF):
            self.rect = QRectF(polygon.p1(), polygon.p2()).normalized() | self.sel_rect
        else:
            self.rect = self.sel_rect
        self.bounding_rect = QRectF(self.rect)
        if self.p1 in points and self.p2 in points:
            self.division_line = QLineF(points[self.p1].pos()-center, points[self.p2].pos()-center)
        else:
            self.division_line = None
        self.hexagon = QPolygonF([QPointF(-width, 0), QPointF(-pos_x, height), QPointF(pos_x, height),
                                  QPointF(width, 0), QPointF(pos_x, -height), QPointF(-pos_x, -height)])
        self.hexagon_path = QPainterPath()
        self.hexagon_path.addPolygon(self.hexagon)
        s1 = QPainterPath()
        if isinstance(self.polygon, QPolygonF):
            s1.addPolygon(polygon_shape)
        elif isinstance(self.polygon, QLineF):
            s1.moveTo(self.polygon.p1())
            s1.lineTo(self.polygon.p2())
        stroke = QPainterPathStroker()
        sel_thick = 3*params.cell_thickness
        if sel_thick == 0:
            sel_thick = 3
        stroke.setWidth(sel_thick)
        self.stroke = stroke.createStroke(s1)