Ejemplo n.º 1
0
    def calculateForces(self):
        if not self.scene() or self.scene().mouseGrabberItem() is self:
            self.newPos = self.pos()
            return

        # Sum up all forces pushing this item away.
        xvel = 0.0
        yvel = 0.0
        for item in self.scene().items():
            if not isinstance(item, Node):
                continue

            line = QLineF(self.mapFromItem(item, 0, 0), QPointF(0, 0))
            dx = line.dx()
            dy = line.dy()
            l = 2.0 * (dx * dx + dy * dy)
            if l > 0:
                xvel += (dx * 150.0) / l
                yvel += (dy * 150.0) / l

        # Now subtract all forces pulling items together.
        #weight = (len(self.edgeList) + 1) * 100.0
        for edge in self.edgeList:
            if edge.sourceNode() is self:
                pos = self.mapFromItem(edge.destNode(), 0, 0)
            else:
                weight = edge.weight * 6
                pos = self.mapFromItem(edge.sourceNode(), 0, 0)
                xvel += pos.x() / weight
                yvel += pos.y() / weight

        if qAbs(xvel) < 0.1 and qAbs(yvel) < 0.1:
            xvel = yvel = 0.0

        sceneRect = self.scene().sceneRect()
        self.newPos = self.pos() + QPointF(xvel, yvel)
        self.newPos.setX(
            min(max(self.newPos.x(),
                    sceneRect.left() + 10),
                sceneRect.right() - 10))
        self.newPos.setY(
            min(max(self.newPos.y(),
                    sceneRect.top() + 10),
                sceneRect.bottom() - 10))
Ejemplo n.º 2
0
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(self.mapFromItem(self.source, 0, 0),
                      self.mapFromItem(self.dest, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        if length > 20.0:
            edgeOffset = QPointF((line.dx() * 10) / length,
                                 (line.dy() * 10) / length)

            self.sourcePoint = line.p1() + edgeOffset
            self.destPoint = line.p2() - edgeOffset
        else:
            self.sourcePoint = line.p1()
            self.destPoint = line.p1()
Ejemplo n.º 3
0
 def crop_line(self, line, line_point):
     global_rect = self.globalBoundingRect()
     
     # Go to local coordinate system - ellipse equations assume ellipse is centered on (0,0)        
     local_trans = global_rect.center()
     local_line = QLineF(line.p1() - local_trans, line.p2() - local_trans)
     
     if(local_line.dx() == 0):
         return line
     
     # Solve line equation        
     e_a = ((local_line.p2().y() - local_line.p1().y()) / 
               (local_line.p2().x() - local_line.p1().x()))
     
     e_b = local_line.p1().y() - e_a * local_line.p1().x()
     
     # ellipse params 
     e_c = global_rect.width()/2
     e_d = global_rect.height()/2
     
     # check condition
     if(e_c * e_d == 0):
         return line
     
     # precalculate things that are used more than once
     # a^2, b^2 ...
     ak = math.pow(e_a, 2)
     bk = math.pow(e_b, 2)
     ck = math.pow(e_c, 2)
     dk = math.pow(e_d, 2)
     
     # check another condition
     if((ak * ck + dk) == 0):
         return line
     
     # a^2*c^2, c^2*d^2
     akck = ak * ck
     ckdk = ck * dk
     
     # a*b*c^2
     abck = e_a*e_b*ck
     
     # parts of denomiator and numerator of x
     denom = (akck + dk)
     numer =  math.sqrt(ck*dk*(akck-bk+dk))
     
     # Decide which points to take
     xrel = (line.p1().x() > line.p2().x())
     yrel = (line.p1().y() > line.p2().y())
     
     if(line_point != 0):
         xrel = not xrel
         yrel = not yrel
     
     if((xrel and yrel) or (xrel and not yrel)):
         x1 = (-numer - abck) / denom
         y1 = (e_b*dk - e_a*math.sqrt(-ckdk*(-akck+bk-dk))) / denom
         
         intersectionPoint = QPointF(x1, y1)
     elif((not xrel and yrel) or (not xrel and not yrel)):
         x2 = (numer - abck) / denom         
         y2 = -(e_b*dk - e_a*math.sqrt(-ckdk*(-akck+bk-dk))) / denom  
     
         intersectionPoint = QPointF(x2, y2)
 
     # Go back to global coordinate system
     intersectionPoint = intersectionPoint + local_trans
 
     if(line_point == 0):
         return QLineF(intersectionPoint, line.p2())
     else:
         return QLineF(line.p1(), intersectionPoint)  
     
     return line
Ejemplo n.º 4
0
    def paint(self, painter, option, widget):
        if not self.source or not self.dest:
            return

        # Draw the line itself.
        line = QLineF(self.sourcePoint, self.destPoint)

        if line.length() == 0.0:
            return

        palette = QPalette()

        self.setZValue(self.state)

        if self.state == 3:
            pen = QPen(Qt.red, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        if self.state == 2:
            pen = QPen(Qt.red, 2, Qt.DashLine, Qt.RoundCap, Qt.RoundJoin)
        elif self.state == 1:
            pen = QPen(palette.color(QPalette.Disabled, QPalette.WindowText),
                       0, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        elif self.state == 0:
            pen = QPen()
            pen.setBrush(QBrush(Qt.NoBrush))

        painter.setPen(pen)

        painter.drawLine(line)

        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        # draw arrowheads
        if self.state == 2 or self.state == 3:

            # Draw the arrows if there's enough room.
            sourceArrowP1 = self.sourcePoint + QPointF(
                math.sin(angle + Edge.Pi / 3) * self.arrowSize,
                math.cos(angle + Edge.Pi / 3) * self.arrowSize)
            sourceArrowP2 = self.sourcePoint + QPointF(
                math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize,
                math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize)
            destArrowP1 = self.destPoint + QPointF(
                math.sin(angle - Edge.Pi / 3) * self.arrowSize,
                math.cos(angle - Edge.Pi / 3) * self.arrowSize)
            destArrowP2 = self.destPoint + QPointF(
                math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize,
                math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize)

            painter.setPen(
                QPen(Qt.red, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
            painter.drawPolygon(
                QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
            #painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))

        if self.state > 0 and self.source > self.dest:
            point = QPointF((self.sourcePoint.x() + self.destPoint.x()) / 2,
                            (self.sourcePoint.y() + self.destPoint.y()) / 2)
            point = QPointF(point.x() + math.sin(angle) * 16,
                            point.y() + math.cos(angle) * 16)
            painter.drawText(point, self.text)