Exemplo n.º 1
0
 def paint(self,
           painter: QPainter,
           option: QStyleOptionGraphicsItem,
           widget=None):
     if not self.source or not self.dest:
         return
     line = QLineF(self.source_point, self.dest_point)
     if line.length() == 0.0:
         return
     color = self.get_color()
     width = SupremeSettings()['edge_width']
     if option.state & QStyle.State_Sunken:
         color, width = Qt.red, 2
         painter.setPen(QPen(Qt.black, 2, Qt.DashLine))
         painter.drawPolygon(self.getSelectionPolygon())
     elif option.state & QStyle.State_MouseOver:
         color, width = Qt.blue, 2
     painter.setPen(
         QPen(color, width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
     painter.drawLine(line)
     angle = math.acos(line.dx() / line.length())
     if line.dy() >= 0:
         angle = math.pi * 2 - angle
     if self.arrow_size > 0:
         dest_arrow_p1 = self.dest_point + QPointF(
             math.sin(angle - math.pi / 3) * self.arrow_size,
             math.cos(angle - math.pi / 3) * self.arrow_size)
         dest_arrow_p2 = self.dest_point + QPointF(
             math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
             math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)
         painter.setBrush(color)
         painter.drawPolygon(
             QPolygonF([line.p2(), dest_arrow_p1, dest_arrow_p2]))
     self.draw_animated_objects()
Exemplo n.º 2
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

        painter.setPen(QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap,
                Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        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.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
Exemplo n.º 3
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

        painter.setPen(QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap,
                Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        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.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
Exemplo n.º 4
0
    def paint(self, painter, option, widget):
        assert self.fromSquare is not None
        assert self.toSquare is not None
        line = QLineF(self.sourcePoint, self.destPoint)

        assert(line.length() != 0.0)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi*2.0) - angle

        destArrowP1 = self.destPoint + QPointF(
                math.sin(angle - math.pi / 3) * self.arrowSize,
                math.cos(angle - math.pi / 3) * self.arrowSize
        )
        destArrowP2 = self.destPoint + QPointF(
                math.sin(angle - math.pi + math.pi / 3) * self.arrowSize,
                math.cos(angle - math.pi + math.pi / 3) * self.arrowSize
        )

        painter.setPen(self.pen)
        painter.setBrush(self.brush)
        # arrowhead1 = QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])
        arrowhead2 = QPolygonF([line.p2(), destArrowP1, destArrowP2])
        painter.drawPolygon(arrowhead2)

        painter.setPen(self.pen)
        painter.drawLine(line)
Exemplo n.º 5
0
    def paint(self, painter, option, widget):
        color = Qt.red if self.isSelected() else Qt.black
        painter.setPen(QPen(color, 2, Qt.SolidLine))
        path = QPainterPath(self.startPoint) # start path
        # iterating over all points of line
        for i in range(len(self.points) - 1):
            x1, y1 = self.points[i].x(), self.points[i].y()
            x2, y2 = self.points[i + 1].x(), self.points[i + 1].y()
            for point in sorted(self.commonPathsCenters, key=lambda x: x.x() + x.y(), reverse=x2 < x1 or y2 < y1):
                x, y = point.x(), point.y()
                if x == x1 == x2:
                    # vertical
                    if min(y1, y2) + 8 <= y < max(y1, y2) - 8:
                        if y2 > y1:
                            path.lineTo(point - QPointF(0, 8))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 90, -180)
                            path.moveTo(point + QPointF(0, 8))
                        else:
                            path.lineTo(point + QPointF(0, 8))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), -90, 180)
                            path.moveTo(point - QPointF(0, 8))
                elif y == y1 == y2:
                    # horizontal
                    if min(x1, x2) + 8 <= x < max(x1, x2) - 8:
                        if x2 > x1:
                            path.lineTo(point - QPointF(8, 0))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 180, 180)
                            path.moveTo(point + QPointF(8, 0))
                        else:
                            path.lineTo(point + QPointF(8, 0))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 0, -180)
                            path.lineTo(point - QPointF(8, 0))
            path.lineTo(self.points[i + 1])
            # draw arrow in last segment
            if i == len(self.points) - 2:
                arrow_size = 20.0
                line = QLineF(self.points[i], self.points[i + 1])
                if line.length() < 20:
                    continue
                angle = math.acos(line.dx() / line.length())

                if line.dy() >= 0:
                    angle = (math.pi * 2) - angle

                arrow_p1 = line.p2() - QPointF(math.sin(angle + math.pi / 2.5) * arrow_size,
                                               math.cos(angle + math.pi / 2.5) * arrow_size)

                arrow_p2 = line.p2() - QPointF(math.sin(angle + math.pi - math.pi / 2.5) * arrow_size,
                                               math.cos(angle + math.pi - math.pi / 2.5) * arrow_size)

                arrowHead = QPolygonF()
                arrowHead.append(line.p2())
                arrowHead.append(arrow_p1)
                arrowHead.append(arrow_p2)
                painter.save()
                painter.setBrush(Qt.black)
                painter.drawPolygon(arrowHead)
                painter.restore()

        painter.drawPath(path) # draw final path
Exemplo n.º 6
0
    def gen_endpoints(origin_sides: dict, destination_sides: dict) -> QLineF:
        """
        This method finds the shortest path between two rectangles.

        Parameters
        ----------
        origin_sides : dict
            The dictionary {side_label: side_size} of the starting rect.
        destination_sides : dict
            The dictionary {side_label: side_size} of the ending rect.

        Returns
        ----------
        QLineF
            The shortest line.

        """

        # Init the line with the maximum possible value
        shortest_line = QLineF(-sys.maxsize / 2, -sys.maxsize / 2,
                               sys.maxsize / 2, sys.maxsize / 2)
        for o_side, origin_side in origin_sides.items():
            o_mid_x, o_mid_y = u.get_midpoint(o_side, origin_side)

            for d_side, destination_side in destination_sides.items():
                d_mid_x, d_mid_y = u.get_midpoint(d_side, destination_side)

                # Update line
                line = QLineF(o_mid_x, o_mid_y, d_mid_x, d_mid_y)
                if line.length() < shortest_line.length():
                    shortest_line = line

        return shortest_line
Exemplo n.º 7
0
 def area(self) -> float:
     d1 = QLineF(self.points[0], self.points[2])
     d2 = QLineF(self.points[1], self.points[3])
     angle = d1.angleTo(d2)
     angle = math.radians(angle)
     d1 = d1.length()
     d2 = d2.length()
     return abs(d1 * d2 * math.sin(angle))
Exemplo n.º 8
0
    def timerEvent(self):
        # Don't move too far away.
        lineToCenter = QLineF(QPointF(0, 0), self.mapFromScene(0, 0))
        if lineToCenter.length() > 150:
            angleToCenter = math.acos(lineToCenter.dx() / lineToCenter.length())
            if lineToCenter.dy() < 0:
                angleToCenter = Mouse.TwoPi - angleToCenter;
            angleToCenter = Mouse.normalizeAngle((Mouse.Pi - angleToCenter) + Mouse.Pi / 2)

            if angleToCenter < Mouse.Pi and angleToCenter > Mouse.Pi / 4:
                # Rotate left.
                self.angle += [-0.25, 0.25][self.angle < -Mouse.Pi / 2]
            elif angleToCenter >= Mouse.Pi and angleToCenter < (Mouse.Pi + Mouse.Pi / 2 + Mouse.Pi / 4):
                # Rotate right.
                self.angle += [-0.25, 0.25][self.angle < Mouse.Pi / 2]
        elif math.sin(self.angle) < 0:
            self.angle += 0.25
        elif math.sin(self.angle) > 0:
            self.angle -= 0.25

        # Try not to crash with any other mice.
        dangerMice = self.scene().items(QPolygonF([self.mapToScene(0, 0),
                                                         self.mapToScene(-30, -50),
                                                         self.mapToScene(30, -50)]))

        for item in dangerMice:
            if item is self:
                continue
        
            lineToMouse = QLineF(QPointF(0, 0), self.mapFromItem(item, 0, 0))
            angleToMouse = math.acos(lineToMouse.dx() / lineToMouse.length())
            if lineToMouse.dy() < 0:
                angleToMouse = Mouse.TwoPi - angleToMouse
            angleToMouse = Mouse.normalizeAngle((Mouse.Pi - angleToMouse) + Mouse.Pi / 2)

            if angleToMouse >= 0 and angleToMouse < Mouse.Pi / 2:
                # Rotate right.
                self.angle += 0.5
            elif angleToMouse <= Mouse.TwoPi and angleToMouse > (Mouse.TwoPi - Mouse.Pi / 2):
                # Rotate left.
                self.angle -= 0.5

        # Add some random movement.
        if len(dangerMice) > 1 and (qrand() % 10) == 0:
            if qrand() % 1:
                self.angle += (qrand() % 100) / 500.0
            else:
                self.angle -= (qrand() % 100) / 500.0

        self.speed += (-50 + qrand() % 100) / 100.0

        dx = math.sin(self.angle) * 10
        self.mouseEyeDirection = 0.0 if qAbs(dx / 5) < 1 else dx / 5

        self.setRotation(self.rotation() + dx)
        self.setPos(self.mapToParent(0, -(3 + math.sin(self.speed) * 3)))
Exemplo n.º 9
0
    def paint(self, painter, index):
        widget = self.parent()
        if index != widget.activeIndex():
            return
        scale = widget.inverseScale()
        # metrics
        if self._rulerObject is not None:
            line, a = self._rulerObject
            origin = line.p1()
            cursor = line.p2()
            size = 8 * scale
            halfSize = 4 * scale
            color = QColor(255, 85, 127, 170)

            # line
            painter.save()
            painter.setPen(color)
            drawing.drawLine(painter, origin.x(), origin.y(), cursor.x(),
                             cursor.y(), scale)
            # ellipses
            ellipses = [
                (origin.x(), origin.y()),
                (cursor.x(), cursor.y()),
            ]
            path = QPainterPath()
            path.setFillRule(Qt.WindingFill)
            for x, y in itertools.chain(self._rulerPts.values(), ellipses):
                x -= halfSize
                y -= halfSize
                path.addEllipse(x, y, size, size)
            painter.fillPath(path, color)
            painter.restore()
            # text
            line = QLineF(line)
            xAlign = yAlign = "center"
            ellipses.pop(0)
            rp = self._rulerPts
            # XXX: sort shouldn't be performed in paintEvent
            for pt in itertools.chain((rp[k] for k in sorted(rp)), ellipses):
                p = QPointF(*pt)
                line.setP2(p)
                if line.length():
                    d = str(round(line.length(), 1))
                    pos = (line.p1() + line.p2()) / 2
                    drawing.drawTextAtPoint(painter, d, pos.x(), pos.y(),
                                            scale, xAlign, yAlign)
                line.setP1(p)
            xAlign, yAlign = "left", "top"
            dx = cursor.x() - origin.x()
            px = size
            if dx < 0:
                xAlign = "right"
                px = -px
            drawing.drawTextAtPoint(painter, a,
                                    cursor.x() + px,
                                    cursor.y() + size, scale, xAlign, yAlign)
Exemplo n.º 10
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(
                onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
Exemplo n.º 11
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(onCurve.x, onCurve.y, otherPoint.x,
                               otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
Exemplo n.º 12
0
    def paint(self, painter, option, widget):
        """
        Customize line adding an arrow head

        :param QPainter painter: Painter instance of the item
        :param option:  Painter option of the item
        :param widget:  Widget instance
        """
        if not self.source or not self.destination:
            return
        line = QLineF(self.source_point, self.destination_point)
        if qFuzzyCompare(line.length(), 0):
            return

        # Draw the line itself
        color = QColor()
        color.setHsv(120 - 60 / self.steps_max * self.steps,
                     180 + 50 / self.steps_max * self.steps,
                     150 + 80 / self.steps_max * self.steps)
        if self.highlighted:
            color.setHsv(0, 0, 0)

        style = self.line_style

        painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

        # Draw the arrows
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (2.0 * math.pi) - angle

        #  arrow in the middle of the arc
        hpx = line.p1().x() + (line.dx() / 2.0)
        hpy = line.p1().y() + (line.dy() / 2.0)
        head_point = QPointF(hpx, hpy)

        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        destination_arrow_p1 = head_point + QPointF(
            math.sin(angle - math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi / 3) * self.arrow_size)
        destination_arrow_p2 = head_point + QPointF(
            math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)

        painter.setBrush(color)
        painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2]))

        if self.metadata["confirmation_text"]:
            painter.drawText(head_point, self.metadata["confirmation_text"])
Exemplo n.º 13
0
def rotateUIPointAroundRefLine(x1, y1, x2, y2, pt):
    """
    Given three points p1, p2, pt this rotates pt around p2 such that p1,p2 and
    p1,pt are collinear.
    """
    line = QLineF(pt.x, pt.y, x2, y2)
    p2p_l = line.length()
    line.setP1(QPointF(x1, y1))
    p1p2_l = line.length()
    if not p1p2_l:
        return
    line.setLength(p1p2_l + p2p_l)
    pt.x = line.x2()
    pt.y = line.y2()
Exemplo n.º 14
0
def rotateUIPointAroundRefLine(x1, y1, x2, y2, pt):
    """
    Given three points p1, p2, pt this rotates pt around p2 such that p1,p2 and
    p1,pt are collinear.
    """
    line = QLineF(pt.x, pt.y, x2, y2)
    p2p_l = line.length()
    line.setP1(QPointF(x1, y1))
    p1p2_l = line.length()
    if not p1p2_l:
        return
    line.setLength(p1p2_l + p2p_l)
    pt.x = line.x2()
    pt.y = line.y2()
Exemplo n.º 15
0
    def paint(self, painter, option, widget):
        """
        Customize line adding an arrow head

        :param QPainter painter: Painter instance of the item
        :param option:  Painter option of the item
        :param widget:  Widget instance
        """
        if not self.source or not self.destination:
            return
        line = QLineF(self.source_point, self.destination_point)
        if qFuzzyCompare(line.length(), 0):
            return

        # Draw the line itself
        color = QColor()
        style = Qt.SolidLine
        if self.status == ARC_STATUS_STRONG:
            color.setNamedColor('blue')
        if self.status == ARC_STATUS_WEAK:
            color.setNamedColor('salmon')
            style = Qt.DashLine

        painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

        # Draw the arrows
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (2.0 * math.pi) - angle

        #  arrow in the middle of the arc
        hpx = line.p1().x() + (line.dx() / 2.0)
        hpy = line.p1().y() + (line.dy() / 2.0)
        head_point = QPointF(hpx, hpy)

        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        destination_arrow_p1 = head_point + QPointF(
            math.sin(angle - math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi / 3) * self.arrow_size)
        destination_arrow_p2 = head_point + QPointF(
            math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)

        painter.setBrush(color)
        painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2]))

        if self.metadata["confirmation_text"]:
            painter.drawText(head_point, self.metadata["confirmation_text"])
Exemplo n.º 16
0
    def paint(self, painter, option, widget):
        """
        Customize line adding an arrow head

        :param QPainter painter: Painter instance of the item
        :param option:  Painter option of the item
        :param widget:  Widget instance
        """
        if not self.source or not self.destination:
            return
        line = QLineF(self.source_point, self.destination_point)
        if qFuzzyCompare(line.length(), 0):
            return

        # Draw the line itself
        color = QColor()
        style = Qt.SolidLine
        if self.status == ARC_STATUS_STRONG:
            color.setNamedColor('blue')
        if self.status == ARC_STATUS_WEAK:
            color.setNamedColor('salmon')
            style = Qt.DashLine

        painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))

        # Draw the arrows
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (2.0 * math.pi) - angle

        #  arrow in the middle of the arc
        hpx = line.p1().x() + (line.dx() / 2.0)
        hpy = line.p1().y() + (line.dy() / 2.0)
        head_point = QPointF(hpx, hpy)

        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        destination_arrow_p1 = head_point + QPointF(
            math.sin(angle - math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi / 3) * self.arrow_size)
        destination_arrow_p2 = head_point + QPointF(
            math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
            math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)

        painter.setBrush(color)
        painter.drawPolygon(
            QPolygonF([head_point, destination_arrow_p1,
                       destination_arrow_p2]))
Exemplo n.º 17
0
    def move(self, item, dest, moveSpeed):
        walkLine = QLineF(item.getGuidedPos(), dest)
        if moveSpeed >= 0 and walkLine.length() > moveSpeed:
            # The item is too far away from it's destination point so we move
            # it towards it instead.
            dx = walkLine.dx()
            dy = walkLine.dy()

            if abs(dx) > abs(dy):
                # Walk along x-axis.
                if dx != 0:
                    d = moveSpeed * dy / abs(dx)

                    if dx > 0:
                        s = moveSpeed
                    else:
                        s = -moveSpeed

                    dest.setX(item.getGuidedPos().x() + s)
                    dest.setY(item.getGuidedPos().y() + d)
            else:
                # Walk along y-axis.
                if dy != 0:
                    d = moveSpeed * dx / abs(dy)

                    if dy > 0:
                        s = moveSpeed
                    else:
                        s = -moveSpeed

                    dest.setX(item.getGuidedPos().x() + d)
                    dest.setY(item.getGuidedPos().y() + s)

        item.setGuidedPos(dest)
Exemplo n.º 18
0
    def setWedgeGizmo(self, neighbor_virtual_helix: int,
                      neighbor_virtual_helix_item: SliceVirtualHelixItemT):
        """Adds a :class:`WedgeGizmo` to oriented toward the specified neighbor vhi.

        Called by :meth:`SliceNucleicAcidPartItem._refreshVirtualHelixItemGizmos`,
        before :meth:`setWedgeGizmo` and :meth:`endAddWedgeGizmos`.

        Args:
            neighbor_virtual_helix: the id_num of neighboring virtual helix
            neighbor_virtual_helix_item: the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item
        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS * 1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
Exemplo n.º 19
0
    def move(self, item, dest, moveSpeed):
        walkLine = QLineF(item.getGuidedPos(), dest)
        if moveSpeed >= 0 and walkLine.length() > moveSpeed:
            # The item is too far away from it's destination point so we move
            # it towards it instead.
            dx = walkLine.dx()
            dy = walkLine.dy()

            if abs(dx) > abs(dy):
                # Walk along x-axis.
                if dx != 0:
                    d = moveSpeed * dy / abs(dx)

                    if dx > 0:
                        s = moveSpeed
                    else:
                        s = -moveSpeed

                    dest.setX(item.getGuidedPos().x() + s)
                    dest.setY(item.getGuidedPos().y() + d)
            else:
                # Walk along y-axis.
                if dy != 0:
                    d = moveSpeed * dx / abs(dy)

                    if dy > 0:
                        s = moveSpeed
                    else:
                        s = -moveSpeed

                    dest.setX(item.getGuidedPos().x() + d)
                    dest.setY(item.getGuidedPos().y() + s)

        item.setGuidedPos(dest)
Exemplo n.º 20
0
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(
            self.mapFromItem(self.source,
                             self.source.getDrawSize() * -0.5,
                             self.source.getDrawSize() * -0.5),
            self.mapFromItem(self.dest,
                             self.dest.getDrawSize() * -0.5,
                             self.dest.getDrawSize() * -0.5))
        length = line.length()

        self.prepareGeometryChange()

        if length > self.source.getDrawSize():
            edgeOffset = QPointF(
                (line.dx() * self.source.getDrawSize() / 2) / length,
                (line.dy() * self.source.getDrawSize() / 2) / length)

            self.sourcePoint = line.p1() + edgeOffset
            self.destPoint = line.p2() - edgeOffset
        else:
            self.sourcePoint = line.p1()
            self.destPoint = line.p1()
Exemplo n.º 21
0
    def setWedgeGizmo(self, neighbor_virtual_helix,
                      neighbor_virtual_helix_item):
        """Adds a WedgeGizmo to oriented toward the specified neighbor vhi.

        Called by NucleicAcidPartItem _refreshVirtualHelixItemGizmos, in between
        with beginAddWedgeGizmos and endAddWedgeGizmos.

        Args:
            neighbor_virtual_helix (int): the id_num of neighboring virtual helix
            neighbor_virtual_helix_item (cadnano.views.sliceview.virtualhelixitem.VirtualHelixItem):
            the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item

        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS * 1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
Exemplo n.º 22
0
    def findNearestPoint(self, part_item, target_scenepos):
        """
        Args:
            part_item (TYPE): Description
            target_scenepos (TYPE): Description
        """
        li = self._line_item
        pos = li.mapFromScene(target_scenepos)

        line = li.line()
        mouse_point_vec = QLineF(self._CENTER_OF_HELIX, pos)

        # Check if the click happened on the origin VH
        if mouse_point_vec.length() < self._RADIUS:
            # return part_item.mapFromScene(target_scenepos)
            return None

        angle_min = 9999
        direction_min = None
        for vector in self.vectors:
            angle_new = mouse_point_vec.angleTo(vector)
            if angle_new < angle_min:
                direction_min = vector
                angle_min = angle_new
        if direction_min is not None:
            li.setLine(direction_min)
            return part_item.mapFromItem(li, direction_min.p2())
        else:
            print("default point")
            line.setP2(pos)
            li.setLine(line)
            return part_item.mapFromItem(li, pos)
Exemplo n.º 23
0
class GuideLine(Guide):
    def __init__(self, line_or_point, follows=None):
        super(GuideLine, self).__init__(follows)

        if isinstance(line_or_point, QLineF):
            self.line = line_or_point
        elif follows is not None:
            self.line = QLineF(self.prevGuide.endPos(), line_or_point)
        else:
            self.line = QLineF(QPointF(0, 0), line_or_point)

    def length(self):
        return self.line.length()

    def startPos(self):
        return QPointF(self.line.p1().x() * self.scaleX,
                       self.line.p1().y() * self.scaleY)

    def endPos(self):
        return QPointF(self.line.p2().x() * self.scaleX,
                       self.line.p2().y() * self.scaleY)

    def guide(self, item, moveSpeed):
        frame = item.guideFrame - self.startLength
        endX = (self.line.p1().x() +
                (frame * self.line.dx() / self.length())) * self.scaleX
        endY = (self.line.p1().y() +
                (frame * self.line.dy() / self.length())) * self.scaleY
        pos = QPointF(endX, endY)
        self.move(item, pos, moveSpeed)
Exemplo n.º 24
0
    def findNearestPoint(self, part_item, target_scenepos):
        """
        Args:
            part_item (TYPE): Description
            target_scenepos (TYPE): Description
        """
        li = self._line_item
        pos = li.mapFromScene(target_scenepos)

        line = li.line()
        mouse_point_vec = QLineF(self._CENTER_OF_HELIX, pos)

        # Check if the click happened on the origin VH
        if mouse_point_vec.length() < self._RADIUS:
            # return part_item.mapFromScene(target_scenepos)
            return None

        angle_min = 9999
        direction_min = None
        for vector in self.vectors:
            angle_new = mouse_point_vec.angleTo(vector)
            if angle_new < angle_min:
                direction_min = vector
                angle_min = angle_new
        if direction_min is not None:
            li.setLine(direction_min)
            return part_item.mapFromItem(li, direction_min.p2())
        else:
            print("default point")
            line.setP2(pos)
            li.setLine(line)
            return part_item.mapFromItem(li, pos)
Exemplo n.º 25
0
class GuideLine(Guide):
    def __init__(self, line_or_point, follows=None):
        super(GuideLine, self).__init__(follows)

        if isinstance(line_or_point, QLineF):
            self.line = line_or_point
        elif follows is not None:
            self.line = QLineF(self.prevGuide.endPos(), line_or_point)
        else:
            self.line = QLineF(QPointF(0, 0), line_or_point)

    def length(self):
        return self.line.length()

    def startPos(self):
        return QPointF(self.line.p1().x() * self.scaleX,
                self.line.p1().y() * self.scaleY)

    def endPos(self):
        return QPointF(self.line.p2().x() * self.scaleX,
                self.line.p2().y() * self.scaleY)

    def guide(self, item, moveSpeed):
        frame = item.guideFrame - self.startLength
        endX = (self.line.p1().x() + (frame * self.line.dx() / self.length())) * self.scaleX
        endY = (self.line.p1().y() + (frame * self.line.dy() / self.length())) * self.scaleY
        pos = QPointF(endX, endY)
        self.move(item, pos, moveSpeed)
Exemplo n.º 26
0
    def setWedgeGizmo(self, neighbor_virtual_helix: int,
                            neighbor_virtual_helix_item: GridVirtualHelixItemT):
        """Adds a WedgeGizmo to oriented toward the specified neighbor vhi.

        Called by NucleicAcidPartItem _refreshVirtualHelixItemGizmos, in between
        with beginAddWedgeGizmos and endAddWedgeGizmos.

        Args:
            neighbor_virtual_helix: the id_num of neighboring virtual helix
            neighbor_virtual_helix_item:
            the neighboring virtual helix item
        """
        wg_dict = self.wedge_gizmos
        nvhi = neighbor_virtual_helix_item

        nvhi_name = nvhi.getProperty('name')
        pos = self.scenePos()
        line = QLineF(pos, nvhi.scenePos())
        line.translate(_RADIUS, _RADIUS)
        if line.length() > (_RADIUS*1.99):
            color = '#5a8bff'
        else:
            color = '#cc0000'
            nvhi_name = nvhi_name + '*'  # mark as invalid
        line.setLength(_RADIUS)
        if neighbor_virtual_helix in wg_dict:
            wedge_item = wg_dict[neighbor_virtual_helix]
        else:
            wedge_item = WedgeGizmo(_RADIUS, WEDGE_RECT, self)
            wg_dict[neighbor_virtual_helix] = wedge_item
        wedge_item.showWedge(line.angle(), color, outline_only=False)
        self._added_wedge_gizmos.add(neighbor_virtual_helix)
Exemplo n.º 27
0
    def joystick_direction(self):
        if not self.grab_center:
            return 0
        norm_vector = QLineF(self._center(), self.moving_offset)
        current_distance = norm_vector.length()
        angle = norm_vector.angle()

        distance = min(current_distance / self.__max_distance, 1.0)
        if current_distance > 30:
            if 22.5 <= angle < 67.5:
                self.calc_pwm(1, 1)
                return (Direction.RightUp, distance)
            elif 67.5 <= angle < 112.5:
                self.calc_pwm(0, 1)
                return (Direction.Up, distance)
            elif 112.5 <= angle < 157.5:
                self.calc_pwm(-1, 1)
                return (Direction.LeftUp, distance)
            elif 157.5 <= angle < 202.5:
                self.calc_pwm(-1, 0)
                return (Direction.Left, distance)
            elif 202.5 <= angle < 247.5:
                self.calc_pwm(-1, -1)
                return (Direction.LeftDown, distance)
            elif 247.5 <= angle < 292.5:
                self.calc_pwm(0, -1)
                return (Direction.Down, distance)
            elif 292.5 <= angle < 337.5:
                self.calc_pwm(1, -1)
                return (Direction.RightDown, distance)
            else:
                self.calc_pwm(1, 0)
                return (Direction.Right, distance)
        else:
            return (Direction.Neutral, 0)
Exemplo n.º 28
0
    def paint(self, painter, option, widget):
        if self._source is None or self._dest is None:
            return

        # Get level of detail
        lod = option.levelOfDetailFromTransform(painter.worldTransform())

        if lod < 0.1:
            return

        scene = self.scene()
        if scene is None:
            return

        line = QLineF(self.source_point, self.dest_point)
        if self._source != self._dest and qFuzzyCompare(line.length(), 0.):
            return

        # If selected, change color to red
        if option.state & QStyle.State_Selected:
            pen = scene.networkStyle().edgePen(selected=True)
            pen.setWidthF(self.pen().widthF())
            painter.setPen(pen)
        else:
            painter.setPen(self.pen())

        painter.drawPath(self.path())
Exemplo n.º 29
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        siblings = _getOffCurveSiblingPoints(contour, point)
        # if an onCurve is selected, the offCurve will move along with it
        if not siblings:
            return
        point.move(delta)
        for onCurve, otherPoint in siblings:
            if not onCurve.smooth:
                continue
            # if the onCurve is smooth, we need to either...
            if otherPoint.segmentType is None and not otherPoint.selected:
                # keep the other offCurve inline
                line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
                otherLine = QLineF(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
                line.setLength(line.length() + otherLine.length())
                otherPoint.x = line.x2()
                otherPoint.y = line.y2()
            else:
                # keep point in tangency with onCurve -> otherPoint segment,
                # i.e. do an orthogonal projection
                point.x, point.y, _ = bezierMath.lineProjection(
                    onCurve.x, onCurve.y, otherPoint.x, otherPoint.y,
                    point.x, point.y, False)
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                # avoid double move for qCurve with single offCurve
                if d > 0:
                    otherPt = contour.getPoint(index + 2 * d)
                    if otherPt.segmentType is not None and \
                            otherPt.segmentType != "move" and otherPt.selected:
                        continue
                pt.move(delta)
                maybeProjectUISmoothPointOffcurve(contour, point)
    contour.dirty = True
Exemplo n.º 30
0
    def ulti(self):
        scene_items = self.scene().items()

        for i in scene_items:
            if (isinstance(i, Minion) or isinstance(i, BigMinion)) and i.team != self.team:
                this_line = QLineF(self.pos(), i.pos())
                if this_line.length() <= 150:
                    this_line.setLength(150)
                    i.setPos(i.x() + this_line.dx(), i.y() + this_line.dy())
            elif (i.__class__.__name__ == 'Tower' or i.__class__.__name__ == 'Nexus' or
                    i.__class__.__name__ == 'Inhibitor') and i.team != self.team:
                this_line = QLineF(self.pos(), i.pos())
                if this_line.length() <= 150:
                    i.decrease_health(100)

        self.ulti_available = False
        self.ulti_cooldown_timer.start(self.cooldown)
Exemplo n.º 31
0
    def should_be_moving(self):
        ln = QLineF(self.pos(), self.destination)
        CLOSE_DIST = 30

        if ln.length() > CLOSE_DIST:
            return True
        else:
            return False
Exemplo n.º 32
0
    def distance_to(self, item):

        distance = QLineF(QPointF(self.pos().x() + 25,
                                  self.pos().y() + 25), item.pos())
        line = QGraphicsLineItem(distance)
        line.setPen(QPen(Qt.red))
        #        self.scene().addItem(line)
        return distance.length()
Exemplo n.º 33
0
 def scaleLineFinishedHandler(mode, line: QLineF):
     global finished
     if (finished):
         return
     if not mode == 'scaleLine':
         return
     # show dialog for input the length of line
     # lineLength, ok = QInputDialog.getDouble(self, 'Input the length of line', 'Length of line(mm)')
     lineLength, ok = QInputDialog.getDouble(
         self, 'Input the length of line', 'Length of line(mm)')
     if not ok:
         return
     if not (lineLength and line.length()):
         QMessageBox.warning('Length of line must be positive number.')
         return
     self.realScale = lineLength / line.length()
     finished = True
     print('Real Scale: %s' % self.realScale)
Exemplo n.º 34
0
    def joystickDirection(self):
        if not self.grabCenter:
            return 0
        normVector = QLineF(self._center(), self.movingOffset)
        currentDistance = normVector.length()
        angle = int(normVector.angle())

        distance = int(currentDistance / self.__maxDistance * 0)
        setPID(angle, distance)
        return (Direction.Right, distance)
 def updatePosition(self, force=False):
     #if self.toNode() is None and self.fromNode() is None:
     #if not force:
     #self.updateArrowHead()
     #self.updateTextPosition()
     #return
     if self.dest() and self.source():
         self._updatingPos = True
         #self.saveTextPosition()
         self.prepareGeometryChange()
         if len(self._points) == 2:
             a = self.source().closestBoundaryPosToItem(self.dest())
             b = self.dest().closestBoundaryPosToItem(self.source())
             a = self.mapFromItem(self.source(), a)
             b = self.mapFromItem(self.dest(), b)
         else:
             a = self.source().closestBoundaryPosToItem(self._points[1])
             b = self.dest().closestBoundaryPosToItem(self._points[-2])
             a = self.mapFromItem(self.source(), a)
             b = self.mapFromItem(self.dest(), b)
         line = QLineF(a, b)
         length = line.length()
         # BUGFIX
         if abs(length) == 0:
             line = QLineF(a, QPointF(a.x() + 1, a.y()))
             length = 1
         dx = line.dx()
         dx /= length
         if dx > 1:
             dx = 1
         elif dx < -1:
             dx = -1
         angle = acos(dx)
         size = self.arrowHeadSize()
         head = self._arrowHead
         if line.dy() >= 0:
             angle = pi * 2 - angle
         p2 = line.p2()
         u = p2 + QPointF(
             sin(angle + pi + pi / 3) * size,
             cos(angle + pi + pi / 3) * size)
         v = p2 + QPointF(
             sin(angle - pi / 3) * size,
             cos(angle - pi / 3) * size)
         if self.dest() != self.toPoint():
             self.toPoint().setPos(line.p2())
         if self.source() != self.fromPoint():
             self.fromPoint().setPos(line.p1())
         self.updateArrowHead()
         #self.updateTextPosition()
         self._updatingPos = False
     else:
         self.updateArrowHead()
         self.updateTextPosition()
Exemplo n.º 36
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()

        self.sourcePoint = line.p1()
        self.destPoint = line.p2()
Exemplo n.º 37
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()

        min_len = self._source.radius() + self._dest.radius(
        ) + self._source.pen().widthF() + self._dest.pen().widthF()
        if length > min_len:
            offset = QPointF(
                (line.dx() *
                 (self._source.radius() + self._source.pen().widthF() + 1)) /
                length,
                (line.dy() *
                 (self._source.radius() + self._source.pen().widthF() + 1)) /
                length)
            self.source_point = line.p1() + offset
            offset = QPointF(
                (line.dx() *
                 (self._dest.radius() + self._dest.pen().widthF() + 1)) /
                length,
                (line.dy() *
                 (self._dest.radius() + self._dest.pen().widthF() + 1)) /
                length)
            self.dest_point = line.p2() - offset
        else:
            self.source_point = self.dest_point = line.p1()

        path = QPainterPath()
        if self.sourceNode() == self.destNode():  # Draw self-loops
            self.__is_self_loop = True
            radius = self._source.radius()
            path.moveTo(
                self.source_point.x() - radius -
                2 * self._source.pen().widthF(), self.source_point.y())
            path.cubicTo(
                QPointF(self.source_point.x() - 4 * radius,
                        self.source_point.y()),
                QPointF(self.source_point.x(),
                        self.source_point.y() - 4 * radius),
                QPointF(
                    self.dest_point.x(),
                    self.dest_point.y() - radius -
                    2 * self._source.pen().widthF()))
        else:
            self.__is_self_loop = False
            path.moveTo(self.source_point)
            path.lineTo(self.dest_point)
        self.setPath(path)
Exemplo n.º 38
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

        painter.setPen(
            QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        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)

        conditionPoint = self.sourcePoint + QPointF(
            math.sin(angle + Edge.Pi / 3) * self.arrowSize * 2,
            math.cos(angle + Edge.Pi / 3) * self.arrowSize * 2)
        textToPrint = self.condition
        for path in self.source.edges():
            if path.destNode(
            ).name == self.dest.name and path.condition != self.condition:
                textToPrint += ", %c" % (path.condition)
                if path.condition > self.condition:
                    return

        painter.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
        painter.drawText(conditionPoint, textToPrint)
Exemplo n.º 39
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

        painter.setPen(
            QPen(Qt.green, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
Exemplo n.º 40
0
    def move_forward(self):

        distance_line = QLineF(self.pos(), self.currentDestination)
        if (distance_line.length() < 5):
            self.point_index += 1
            if (self.point_index >= len(self.directionPoints)):
                return
            self.currentDestination = self.directionPoints[self.point_index]
            self.rotateToPoint(self.currentDestination)

        theta = self.rotation()
        dy = Alien.STEP_SIZE * np.sin(np.radians(theta))
        dx = Alien.STEP_SIZE * np.cos(np.radians(theta))
        self.setPos(self.x() + dx, self.y() + dy)
Exemplo n.º 41
0
 def mouseMoveEvent(self, event):
     path, text = self._rulerObject
     baseElem = path.elementAt(0)
     canvasPos = event.localPos()
     if event.modifiers() & Qt.ShiftModifier:
         basePos = QPointF(baseElem.x, baseElem.y)
         canvasPos = self.clampToOrigin(canvasPos, basePos)
     canvasPos = self.magnetPos(canvasPos)
     x, y = canvasPos.x(), canvasPos.y()
     path.setElementPositionAt(1, x, baseElem.y)
     path.setElementPositionAt(2, x, y)
     path.setElementPositionAt(3, baseElem.x, baseElem.y)
     line = QLineF(baseElem.x, baseElem.y, x, y)
     l = line.length()
     # angle() doesnt go by trigonometric direction. Weird.
     # TODO: maybe split in positive/negative 180s (ff)
     a = 360 - line.angle()
     line.setP2(QPointF(x, baseElem.y))
     h = line.length()
     line.setP1(QPointF(x, y))
     v = line.length()
     text = "%d\n↔ %d\n↕ %d\nα %dº" % (l, h, v, a)
     self._rulerObject = (path, text)
     self.parent().update()
Exemplo n.º 42
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()
Exemplo n.º 43
0
 def angle_arrow(self, path, origin='head'):
     ''' Compute the two points of the arrow head with the right angle '''
     if origin == 'tail':
         path = path.toReversed()
     length = path.length()
     percent = path.percentAtLength(length - 10.0)
     src = path.pointAtPercent(percent)
     #path.moveTo(path.pointAtPercent(1))
     end_point = path.pointAtPercent(1)
     #end_point = path.currentPosition()
     line = QLineF(src, end_point)
     angle = math.acos(line.dx() / (line.length() or 1))
     if line.dy() >= 0:
         angle = math.pi * 2 - angle
     arrow_size = 10.0
     arrow_p1 = end_point + QPointF(
             math.sin(angle - math.pi / 3) * arrow_size,
             math.cos(angle - math.pi / 3) * arrow_size)
     arrow_p2 = end_point + QPointF(
             math.sin(angle - math.pi + math.pi / 3) * arrow_size,
             math.cos(angle - math.pi + math.pi / 3) * arrow_size)
     return (arrow_p1, arrow_p2)
Exemplo n.º 44
0
class KnifeTool(BaseTool):
    name = "Knife"
    iconPath = ":/resources/cutter.svg"

    def __init__(self, parent=None):
        super().__init__(parent)
        self._cachedIntersections = None
        self._knifeLine = None
        self._knifeDots = None

    def _appendIntersection(self, contour, index, pt, dotHalf, dotWidth):
        dotHeight = dotWidth
        x = pt[0] - dotHalf
        y = pt[1] - dotHalf
        self._knifeDots.addEllipse(x, y, dotWidth, dotHeight)
        if (contour, index) in self._cachedIntersections:
            self._cachedIntersections[(contour, index)].append(
                pt[2])
        else:
            self._cachedIntersections[(contour, index)] = [pt[2]]

    # events

    def mousePressEvent(self, event):
        canvasPos = event.localPos()
        self._knifeLine = QLineF(canvasPos, canvasPos)

    def mouseMoveEvent(self, event):
        line = self._knifeLine
        pos = event.localPos()
        widget = self.parent()
        if event.modifiers() & Qt.ShiftModifier:
            pos = self.clampToOrigin(pos, line.p1())
        line.setP2(pos)
        self._cachedIntersections = OrderedDict()
        scale = widget.inverseScale()
        dotWidth = 5 * scale
        dotHalf = dotWidth / 2.0
        self._knifeDots = QPainterPath()
        for contour in self._glyph:
            segments = contour.segments
            for index, seg in enumerate(segments):
                if seg[-1].segmentType == "move":
                    continue
                prev = segments[index - 1][-1]
                if len(seg) == 3:
                    i = bezierMath.curveIntersections(
                        prev, seg[0], seg[1], seg[2],
                        line.x1(), line.y1(), pos.x(), pos.y())
                    for pt in i:
                        self._appendIntersection(
                            contour, index, pt, dotHalf, dotWidth)
                else:
                    pt = bezierMath.lineIntersection(
                        prev.x, prev.y, seg[0].x, seg[0].y,
                        line.x1(), line.y1(), pos.x(), pos.y())
                    if pt is not None:
                        self._appendIntersection(
                            contour, index, pt, dotHalf, dotWidth)
        widget.update()

    def mouseReleaseEvent(self, event):
        self._knifeLine = None
        self._knifeDots = None
        # no-move clicks
        if self._cachedIntersections is None:
            return
        self._glyph.prepareUndo()
        # reverse so as to not invalidate our cached segment indexes
        for loc, ts in reversed(list(self._cachedIntersections.items())):
            contour, index = loc
            prev = 1
            # reverse so as to cut from higher to lower value and compensate
            for t in sorted(ts, reverse=True):
                contour.splitAndInsertPointAtSegmentAndT(index, t / prev)
                prev = t
        self._cachedIntersections = None
        self.parent().update()

    # custom painting

    def paint(self, painter):
        if self._knifeLine is not None and self._knifeLine.length():
            painter.drawLine(self._knifeLine)
            if self._knifeDots is not None:
                painter.drawPath(self._knifeDots)
Exemplo n.º 45
0
 def getNeighbors(self):
     items = filter(lambda x: type(x) is VirtualHelixItem, self.collidingItems())
     name = self._virtual_helix.getName()
     pos = self.scenePos()
     print("\n%s (%d, %d)" % (name, pos.x(), pos.y()))
     for nvhi in items:
         npos = nvhi.scenePos()
         line = QLineF(pos, npos)
         print("\t%s (%d, %d) %d" % (nvhi.virtualHelix().getName(), npos.x(), npos.y(), line.length()))