예제 #1
0
 def addChart(self, title, data, fftchose):
     axisX = QValueAxis()
     axisY = QValueAxis()
     chart = DataChart(title, axisX, axisY)
     chart.setTheme(QChart.ChartThemeBlueNcs)
     ffttmp = []
     for col in data:
         line = QSplineSeries()
         line.setName(col[0])
         for row, value in enumerate(col[1:]):
             if fftchose:
                 ffttmp.append(value)
             else:
                 line.append(QPointF(self.sampletime * row, value))
         if fftchose:
             sp = np.fft.fft(ffttmp)
             Ayf = np.abs(sp)
             freq = np.fft.fftfreq(len(ffttmp), d=self.sampletime)
             for i in range(len(Ayf) - 1):
                 line.append(QPointF(freq[i], Ayf[i]))
         chart.addSeries(line)
         line.attachAxis(axisX)
         line.attachAxis(axisY)
     self.view = QView()
     self.view.combinedata(data)
     self.view.addQchart(chart)
     self.tabWidget.addTab(self.view, title)
     self.tabcount.append([title, self.view])
예제 #2
0
    def __draw_point(self, i: int, vpoint: VPoint):
        """Draw a point."""
        if vpoint.type in {VJoint.P, VJoint.RP}:
            pen = QPen(QColor(*vpoint.color))
            pen.setWidth(2)

            # Draw slot point and pin point.
            for j, (cx, cy) in enumerate(vpoint.c):
                if not vpoint.links:
                    grounded = False
                else:
                    grounded = vpoint.links[j] == 'ground'
                # Slot point.
                if j == 0 or vpoint.type == VJoint.P:
                    pen.setColor(Qt.black if self.monochrome else QColor(
                        *vpoint.color))
                    self.painter.setPen(pen)
                    cp = QPointF(cx, -cy) * self.zoom
                    jr = self.joint_size * (2 if j == 0 else 1)
                    rp = QPointF(jr, -jr)
                    self.painter.drawRect(QRectF(cp + rp, cp - rp))
                    if self.show_point_mark:
                        pen.setColor(Qt.darkGray)
                        self.painter.setPen(pen)
                        text = f"[Point{i}]"
                        if self.show_dimension:
                            text += f":({cx:.02f}, {cy:.02f})"
                        self.painter.drawText(cp + rp, text)
                else:
                    self.draw_point(i, cx, cy, grounded, vpoint.color)

            # Slider line
            pen.setColor(QColor(*vpoint.color).darker())
            self.painter.setPen(pen)
            qline_m = QLineF(
                QPointF(vpoint.c[1][0], -vpoint.c[1][1]) * self.zoom,
                QPointF(vpoint.c[0][0], -vpoint.c[0][1]) * self.zoom)
            nv = qline_m.normalVector()
            nv.setLength(self.joint_size)
            nv.setPoints(nv.p2(), nv.p1())
            qline_1 = nv.normalVector()
            qline_1.setLength(qline_m.length())
            self.painter.drawLine(qline_1)
            nv.setLength(nv.length() * 2)
            nv.setPoints(nv.p2(), nv.p1())
            qline_2 = nv.normalVector()
            qline_2.setLength(qline_m.length())
            qline_2.setAngle(qline_2.angle() + 180)
            self.painter.drawLine(qline_2)
        else:
            self.draw_point(i, vpoint.cx, vpoint.cy, vpoint.grounded(),
                            vpoint.color)

        # For selects function.
        if self.select_mode == SelectMode.Joint and (i in self.selections):
            pen = QPen(QColor(161, 16, 239))
            pen.setWidth(3)
            self.painter.setPen(pen)
            self.painter.drawRect(vpoint.cx * self.zoom - 12,
                                  vpoint.cy * -self.zoom - 12, 24, 24)
예제 #3
0
 def __drawSlvsRanges(self):
     """Draw solving range."""
     pen = QPen()
     self.painter.setFont(QFont("Arial", self.fontSize + 5))
     pen.setWidth(5)
     for i, (tag, rect) in enumerate(self.ranges.items()):
         range_color = QColor(colorNum(i + 1))
         range_color.setAlpha(30)
         self.painter.setBrush(range_color)
         range_color.setAlpha(255)
         pen.setColor(range_color)
         self.painter.setPen(pen)
         cx = rect.x() * self.zoom
         cy = rect.y() * -self.zoom
         if rect.width():
             self.painter.drawRect(
                 QRectF(cx, cy,
                        rect.width() * self.zoom,
                        rect.height() * self.zoom))
         else:
             self.painter.drawEllipse(QPointF(cx, cy), 3, 3)
         range_color.setAlpha(255)
         pen.setColor(range_color)
         self.painter.setPen(pen)
         self.painter.drawText(QPointF(cx + 6, cy - 6), tag)
         self.painter.setBrush(Qt.NoBrush)
예제 #4
0
    def __draw_link(self, name: str, points: List[int]):
        """Draw link function.

        The link color will be the default color.
        """
        color = color_qt('Blue')
        pen = QPen(color)
        pen.setWidth(self.link_width)
        self.painter.setPen(pen)
        brush = QColor(226, 219, 190)
        brush.setAlphaF(0.70)
        self.painter.setBrush(brush)
        qpoints = tuple(
            QPointF(self.pos[i][0], -self.pos[i][1]) * self.zoom
            for i in points if self.pos[i] and (not isnan(self.pos[i][0]))
        )
        if len(qpoints) == len(points):
            self.painter.drawPolygon(*qpoints)
        self.painter.setBrush(Qt.NoBrush)
        if self.show_point_mark and (name != 'ground') and qpoints:
            pen.setColor(Qt.darkGray)
            self.painter.setPen(pen)
            self.painter.setFont(QFont('Arial', self.font_size))
            text = f"[{name}]"
            cen_x = sum(self.pos[i][0] for i in points if self.pos[i])
            cen_y = sum(self.pos[i][1] for i in points if self.pos[i])
            self.painter.drawText(QPointF(cen_x, -cen_y) * self.zoom / len(points), text)
예제 #5
0
 def drawLink(self, name: str, points: Tuple[int]):
     """Draw linkage function.
     
     The link color will be the default color.
     """
     color = colorQt('Blue')
     pen = QPen(color)
     pen.setWidth(self.linkWidth)
     self.painter.setPen(pen)
     brush = QColor(226, 219, 190)
     brush.setAlphaF(0.70)
     self.painter.setBrush(brush)
     qpoints = tuple(
         QPointF(self.Point[i][0] * self.zoom, self.Point[i][1] *
                 -self.zoom) for i in points
         if self.Point[i] and not isnan(self.Point[i][0]))
     if len(qpoints) == len(points):
         self.painter.drawPolygon(*qpoints)
     self.painter.setBrush(Qt.NoBrush)
     if self.showPointMark and name != 'ground' and qpoints:
         pen.setColor(Qt.darkGray)
         self.painter.setPen(pen)
         self.painter.setFont(QFont('Arial', self.fontSize))
         text = "[{}]".format(name)
         cenX = sum(self.Point[i][0] for i in points if self.Point[i])
         cenY = sum(self.Point[i][1] for i in points if self.Point[i])
         cenX *= self.zoom / len(points)
         cenY *= -self.zoom / len(points)
         self.painter.drawText(QPointF(cenX, cenY), text)
예제 #6
0
 def __drawPoint(self, i: int, vpoint: VPoint):
     """Draw a point."""
     if vpoint.type == 1 or vpoint.type == 2:
         #Draw slider
         silder_points = vpoint.c
         for j, (cx, cy) in enumerate(silder_points):
             if vpoint.type == 1:
                 if j == 0:
                     self._BaseCanvas__drawPoint(
                         i, cx, cy, vpoint.links[j] == 'ground',
                         vpoint.color)
                 else:
                     pen = QPen(vpoint.color)
                     pen.setWidth(2)
                     self.painter.setPen(pen)
                     r = 5
                     self.painter.drawRect(
                         QRectF(
                             QPointF(cx * self.zoom + r,
                                     cy * -self.zoom + r),
                             QPointF(cx * self.zoom - r,
                                     cy * -self.zoom - r)))
             elif vpoint.type == 2:
                 if j == 0:
                     self._BaseCanvas__drawPoint(
                         i, cx, cy, vpoint.links[j] == 'ground',
                         vpoint.color)
                 else:
                     #Turn off point mark.
                     showPointMark = self.showPointMark
                     self.showPointMark = False
                     self._BaseCanvas__drawPoint(
                         i, cx, cy, vpoint.links[j] == 'ground',
                         vpoint.color)
                     self.showPointMark = showPointMark
         pen = QPen(vpoint.color.darker())
         pen.setWidth(2)
         self.painter.setPen(pen)
         x_all = tuple(cx for cx, cy in silder_points)
         if x_all:
             p_left = silder_points[x_all.index(min(x_all))]
             p_right = silder_points[x_all.index(max(x_all))]
             if p_left == p_right:
                 y_all = tuple(cy for cx, cy in silder_points)
                 p_left = silder_points[y_all.index(min(y_all))]
                 p_right = silder_points[y_all.index(max(y_all))]
             self.painter.drawLine(
                 QPointF(p_left[0] * self.zoom, p_left[1] * -self.zoom),
                 QPointF(p_right[0] * self.zoom, p_right[1] * -self.zoom))
     else:
         self._BaseCanvas__drawPoint(i, vpoint.cx, vpoint.cy,
                                     vpoint.grounded(), vpoint.color)
     #For selects function.
     if i in self.pointsSelection:
         pen = QPen(QColor(161, 16, 239))
         pen.setWidth(3)
         self.painter.setPen(pen)
         self.painter.drawRect(vpoint.cx * self.zoom - 12,
                               vpoint.cy * -self.zoom - 12, 24, 24)
예제 #7
0
 def setZoom(self, zoom: int):
     """Update zoom factor."""
     zoom_old = self.zoom
     self.zoom = zoom / 100 * self.rate
     dz = zoom_old - self.zoom
     if self.zoomby == 0:
         pos = self.mapFromGlobal(QCursor.pos())
     else:
         pos = QPointF(self.width() / 2, self.height() / 2)
     self.ox += (pos.x() - self.ox) / self.zoom * dz
     self.oy += (pos.y() - self.oy) / self.zoom * dz
     self.update()
예제 #8
0
def graph(G: Graph,
          width: int,
          engine: [str, Dict[int, Tuple[float, float]]],
          node_mode: bool = False,
          except_node: int = None) -> QIcon:
    """Draw a linkage graph."""
    try:
        pos = engine_picker(G, engine, node_mode)
    except EngineError as e:
        raise e
    width_ = -inf
    for x, y in pos.values():
        if abs(x) > width_:
            width_ = x
        if abs(y) > width_:
            width_ = y
    width_ *= 2 * 1.2
    image = QImage(QSize(width_, width_), QImage.Format_ARGB32_Premultiplied)
    image.fill(Qt.transparent)
    painter = QPainter(image)
    painter.translate(image.width() / 2, image.height() / 2)
    pen = QPen()
    r = width_ / 50
    pen.setWidth(r)
    painter.setPen(pen)
    if node_mode:
        for l1, l2 in G.edges:
            painter.drawLine(QPointF(pos[l1][0], -pos[l1][1]),
                             QPointF(pos[l2][0], -pos[l2][1]))
    else:
        painter.setBrush(QBrush(QColor(226, 219, 190, 150)))
        for link in G.nodes:
            if link == except_node:
                continue
            #Distance sorted function from canvas
            painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1])
                                              for n, edge in edges_view(G)
                                              if link in edge]))
    for k, (x, y) in pos.items():
        if node_mode:
            color = colorNum(len(list(G.neighbors(k))) - 1)
        else:
            if except_node in tuple(G.edges)[k]:
                color = colorQt('Green')
            else:
                color = colorQt('Blue')
        pen.setColor(color)
        painter.setPen(pen)
        painter.setBrush(QBrush(color))
        painter.drawEllipse(QPointF(x, -y), r, r)
    painter.end()
    icon = QIcon(QPixmap.fromImage(image).scaledToWidth(width))
    return icon
예제 #9
0
 def drawArrow(self, x1: float, y1: float, x2: float, y2: float):
     """Front point -> Back point"""
     a = atan2(y2 - y1, x2 - x1)
     x1 = (x1 + x2) / 2 - 7.5*cos(a)
     y1 = (y1 + y2) / 2 - 7.5*sin(a)
     self.painter.drawLine(
         QPointF(x1, y1),
         QPointF(x1 + 15*cos(a + radians(20)), y1 + 15*sin(a + radians(20)))
     )
     self.painter.drawLine(
         QPointF(x1, y1),
         QPointF(x1 + 15*cos(a - radians(20)), y1 + 15*sin(a - radians(20)))
     )
예제 #10
0
 def paintEvent(self, event):
     """Using a QPainter under 'self',
     so just change QPen or QBrush before painting.
     """
     self.painter = QPainter()
     self.painter.begin(self)
     self.painter.fillRect(event.rect(), QBrush(Qt.white))
     self.painter.translate(self.ox, self.oy)
     #Draw origin lines.
     pen = QPen(Qt.gray)
     pen.setWidth(1)
     self.painter.setPen(pen)
     x_l = -self.ox
     x_r = self.width()-self.ox
     self.painter.drawLine(QPointF(x_l, 0), QPointF(x_r, 0))
     y_t = self.height()-self.oy
     y_b = -self.oy
     self.painter.drawLine(QPointF(0, y_b), QPointF(0, y_t))
     #Draw tick.
     Indexing = lambda v: int(v/self.zoom - (v/self.zoom)%5)
     for x in range(Indexing(x_l), Indexing(x_r)+1, 5):
         self.painter.drawLine(
             QPointF(x*self.zoom, 0),
             QPointF(x*self.zoom, -10 if x%10==0 else -5)
         )
     for y in range(Indexing(y_b), Indexing(y_t)+1, 5):
         self.painter.drawLine(
             QPointF(0, y*self.zoom),
             QPointF(10 if y%10==0 else 5, y*self.zoom)
         )
     """Please to call the "end" method when ending paint event.
예제 #11
0
 def drawLimit(self, sq_w: int):
     """Center square."""
     limit = sq_w / 2 * self.zoom
     self.painter.drawLine(QPointF(-limit, limit), QPointF(limit, limit))
     self.painter.drawLine(QPointF(-limit, limit), QPointF(-limit, -limit))
     self.painter.drawLine(QPointF(-limit, -limit), QPointF(limit, -limit))
     self.painter.drawLine(QPointF(limit, -limit), QPointF(limit, limit))
예제 #12
0
 def solutionPolygon(
     self,
     func: str,
     args: Sequence[str],
     target: str,
     pos: Union[Tuple[VPoint, ...], Dict[int, Tuple[float, float]]]
 ) -> Tuple[List[QPointF], QColor]:
     """Get solution polygon."""
     if func == 'PLLP':
         color = QColor(121, 171, 252)
         params = [args[0], args[-1]]
     elif func == 'PLAP':
         color = QColor(249, 84, 216)
         params = [args[0]]
     else:
         if func == 'PLPP':
             color = QColor(94, 255, 185)
         else:
             # PXY
             color = QColor(249, 175, 27)
         params = [args[0]]
     params.append(target)
     tmp_list = []
     for name in params:
         try:
             index = int(name.replace('P', ''))
         except ValueError:
             continue
         else:
             x, y = pos[index]
             tmp_list.append(QPointF(x, -y) * self.zoom)
     return tmp_list, color
예제 #13
0
 def on_save_atlas_clicked(self):
     """Save function as same as type synthesis widget."""
     count = self.collection_list.count()
     if not count:
         return
     lateral, ok = QInputDialog.getInt(self, "Atlas",
                                       "The number of lateral:", 5, 1, 10)
     if not ok:
         return
     fileName = self.outputTo("Atlas image", Qt_images)
     if not fileName:
         return
     icon_size = self.collection_list.iconSize()
     width = icon_size.width()
     image_main = QImage(
         QSize(lateral * width if count > lateral else count * width,
               ((count // lateral) + bool(count % lateral)) * width),
         self.collection_list.item(0).icon().pixmap(
             icon_size).toImage().format())
     image_main.fill(QColor(Qt.white).rgb())
     painter = QPainter(image_main)
     for row in range(count):
         image = self.collection_list.item(row).icon().pixmap(
             icon_size).toImage()
         painter.drawImage(
             QPointF(row % lateral * width, row // lateral * width), image)
     painter.end()
     pixmap = QPixmap()
     pixmap.convertFromImage(image_main)
     pixmap.save(fileName, format=QFileInfo(fileName).suffix())
     self.saveReplyBox("Atlas", fileName)
예제 #14
0
    def __init__(self, parent: QWidget):
        """Set the parameters for drawing."""
        super(BaseCanvas, self).__init__(parent)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.setFocusPolicy(Qt.StrongFocus)
        self.painter = QPainter()

        # Origin coordinate.
        self.ox = self.width() / 2
        self.oy = self.height() / 2
        # Canvas zoom rate.
        self.rate = 2.
        self.zoom = 2. * self.rate
        # Joint size.
        self.joint_size = 3
        # Canvas line width.
        self.link_width = 3
        self.path_width = 3
        # Font size.
        self.font_size = 15
        # Show point mark or dimension.
        self.show_point_mark = True
        self.show_dimension = True
        # Path track.
        self.Path = _Path()
        # Path solving.
        self.target_path = {}
        self.show_target_path = False
        # Background
        self.background = QImage()
        self.background_opacity = 1.
        self.background_scale = 1
        self.background_offset = QPointF(0, 0)
예제 #15
0
def convex_hull(points: List[_Coord],
                *,
                as_qpoint: bool = False) -> Union[List[_Coord], List[QPointF]]:
    """Returns points on convex hull in counterclockwise order
    according to Graham's scan algorithm.
    """
    def cmp(a: float, b: float) -> int:
        return (a > b) - (a < b)

    def turn(p: _Coord, q: _Coord, r: _Coord) -> int:
        px, py = p
        qx, qy = q
        rx, ry = r
        return cmp((qx - px) * (ry - py) - (rx - px) * (qy - py), 0)

    def keep_left(hull: List[_Coord], r: _Coord) -> List[_Coord]:
        while len(hull) > 1 and turn(hull[-2], hull[-1], r) != 1:
            hull.pop()
        if not hull or hull[-1] != r:
            hull.append(r)
        return hull

    points.sort()
    lower = reduce(keep_left, points, [])
    upper = reduce(keep_left, reversed(points), [])
    lower.extend(upper[i] for i in range(1, len(upper) - 1))

    result = []
    for x, y in lower:
        if as_qpoint:
            result.append(QPointF(x, y))
        else:
            result.append((x, y))
    return result
예제 #16
0
 def draw_curve(self, path: Sequence[_Coord]):
     """Draw path as curve."""
     if len(set(path)) <= 2:
         return
     painter_path = QPainterPath()
     error = False
     for i, (x, y) in enumerate(path):
         if isnan(x):
             error = True
             self.painter.drawPath(painter_path)
             painter_path = QPainterPath()
         else:
             x *= self.zoom
             y *= -self.zoom
             if i == 0:
                 painter_path.moveTo(x, y)
                 self.painter.drawEllipse(QPointF(x, y), self.joint_size,
                                          self.joint_size)
                 continue
             if error:
                 painter_path.moveTo(x, y)
                 error = False
             else:
                 painter_path.lineTo(x, y)
     self.painter.drawPath(painter_path)
예제 #17
0
 def drawSolution(self, func: str, args: Tuple[str], target: str):
     """Draw the solution triangle."""
     params = [args[0], args[-1]]
     params.append(target)
     if func == 'PLLP':
         color = QColor(121, 171, 252)
     else:
         color = QColor(249, 84, 216)
     color.setAlpha(255)
     pen = QPen()
     pen.setColor(color)
     pen.setWidth(self.r)
     self.painter.setPen(pen)
     for n in (0, 1):
         x, y = self.pos[int(params[-1].replace('P', ''))]
         x2, y2 = self.pos[int(params[n].replace('P', ''))]
         self.drawArrow(
             x*self.zoom, y*-self.zoom, x2*self.zoom, y2*-self.zoom
         )
     color.setAlpha(30)
     self.painter.setBrush(QBrush(color))
     qpoints = []
     for name in params:
         x, y = self.pos[int(name.replace('P', ''))]
         qpoints.append(QPointF(x*self.zoom, y*-self.zoom))
     self.painter.drawPolygon(*qpoints)
예제 #18
0
def convex_hull(
    points: List[Tuple[float, float]],
    *,
    as_qpoint: bool = False
) -> Union[List[Tuple[float, float]], List[QPointF]]:
    """Returns points on convex hull in counterclockwise order
    according to Graham's scan algorithm.
    """
    coordinate: type = Tuple[float, float]

    def cmp(a: float, b: float) -> int:
        return (a > b) - (a < b)

    def turn(p: coordinate, q: coordinate, r: coordinate) -> int:
        return cmp((q[0] - p[0])*(r[1] - p[1]) - (r[0] - p[0])*(q[1] - p[1]), 0)

    def keep_left(hull: List[coordinate], r: coordinate) -> List[coordinate]:
        while (len(hull) > 1) and (turn(hull[-2], hull[-1], r) != 1):
            hull.pop()
        if not len(hull) or hull[-1] != r:
            hull.append(r)
        return hull

    points.sort()
    lower = reduce(keep_left, points, [])
    upper = reduce(keep_left, reversed(points), [])
    lower.extend(upper[i] for i in range(1, len(upper) - 1))

    result = []
    for x, y in lower:
        if as_qpoint:
            result.append(QPointF(x, y))
        else:
            result.append((x, y))
    return result
예제 #19
0
    def __save_atlas(self):
        """Save function as same as type synthesis widget."""
        count = self.collection_list.count()
        if not count:
            return

        lateral, ok = QInputDialog.getInt(self, "Atlas",
                                          "The number of lateral:", 5, 1)
        if not ok:
            return

        file_name = self.output_to("Atlas image", qt_image_format)
        if not file_name:
            return

        icon_size = self.collection_list.iconSize()
        width = icon_size.width()
        image_main = QImage(
            QSize(lateral * width if count > lateral else count * width,
                  ((count // lateral) + bool(count % lateral)) * width),
            self.collection_list.item(0).icon().pixmap(
                icon_size).toImage().format())
        image_main.fill(Qt.transparent)
        painter = QPainter(image_main)
        for row in range(count):
            image = self.collection_list.item(row).icon().pixmap(
                icon_size).toImage()
            painter.drawImage(
                QPointF(row % lateral * width, row // lateral * width), image)
        painter.end()
        pixmap = QPixmap()
        pixmap.convertFromImage(image_main)
        pixmap.save(file_name)
        self.save_reply_box("Atlas", file_name)
예제 #20
0
def convex_hull(points: Sequence[Tuple[float, float]]):
    """Returns points on convex hull in CCW order
    according to Graham's scan algorithm.
    """
    def cmp(a: float, b: float) -> int:
        return (a > b) - (a < b)

    def turn(p: Tuple[float, float], q: Tuple[float, float], r: Tuple[float,
                                                                      float]):
        return cmp(
            (q[0] - p[0]) * (r[1] - p[1]) - (r[0] - p[0]) * (q[1] - p[1]), 0)

    def keep_left(hull: Sequence[Tuple[float, float]], r: Tuple[float, float]):
        while (len(hull) > 1) and (turn(hull[-2], hull[-1], r) != 1):
            hull.pop()
        if not len(hull) or hull[-1] != r:
            hull.append(r)
        return hull

    points = sorted(points)
    l = reduce(keep_left, points, [])
    u = reduce(keep_left, reversed(points), [])
    return [
        QPointF(x, y) for x, y in (l.extend(u[i]
                                            for i in range(1,
                                                           len(u) - 1)) or l)
    ]
예제 #21
0
 def __drawLink(self, vlink: VLink):
     """Draw a link."""
     points = []
     for i in vlink.points:
         vpoint = self.Points[i]
         if vpoint.type == 1 or vpoint.type == 2:
             coordinate = vpoint.c[0 if
                                   (vlink.name == vpoint.links[0]) else 1]
             x = coordinate[0] * self.zoom
             y = coordinate[1] * -self.zoom
         else:
             x = vpoint.cx * self.zoom
             y = vpoint.cy * -self.zoom
         points.append((x, y))
     pen = QPen(vlink.color)
     pen.setWidth(self.linkWidth)
     self.painter.setPen(pen)
     brush = QColor(226, 219, 190)
     brush.setAlphaF(self.transparency)
     self.painter.setBrush(brush)
     #Rearrange: Put the nearest point to the next position.
     qpoints = convex_hull(points)
     if qpoints:
         self.painter.drawPolygon(*qpoints)
     self.painter.setBrush(Qt.NoBrush)
     if ((not self.showPointMark) or (vlink.name == 'ground')
             or (not qpoints)):
         return
     pen.setColor(Qt.darkGray)
     self.painter.setPen(pen)
     cenX = sum(p[0] for p in points) / len(points)
     cenY = sum(p[1] for p in points) / len(points)
     self.painter.drawText(QPointF(cenX, cenY), '[{}]'.format(vlink.name))
예제 #22
0
 def Topologic_result_context_menu(self, point):
     """Context menu for the type synthesis results."""
     index = self.Topologic_result.currentIndex().row()
     self.add_collection.setEnabled(index>-1)
     self.copy_edges.setEnabled(index>-1)
     self.copy_image.setEnabled(index>-1)
     action = self.popMenu_topo.exec_(self.Topologic_result.mapToGlobal(point))
     if not action:
         return
     clipboard = QApplication.clipboard()
     if action==self.add_collection:
         self.addCollection(self.answer[index].edges)
     elif action==self.copy_edges:
         clipboard.setText(str(self.answer[index].edges))
     elif action==self.copy_image:
         #Turn the transparent background to white.
         image1 = self.atlas_image()
         image2 = QImage(image1.size(), image1.format())
         image2.fill(QColor(Qt.white).rgb())
         painter = QPainter(image2)
         painter.drawImage(QPointF(0, 0), image1)
         painter.end()
         pixmap = QPixmap()
         pixmap.convertFromImage(image2)
         clipboard.setPixmap(pixmap)
예제 #23
0
 def paintEvent(self, event):
     """Drawing functions."""
     width = self.width()
     height = self.height()
     if ((self.width_old is not None) and ((self.width_old != width) or
                                           (self.height_old != height))):
         self.ox += (width - self.width_old) / 2
         self.oy += (height - self.height_old) / 2
     super(DynamicCanvas, self).paintEvent(event)
     self.painter.setFont(QFont('Arial', self.fontSize))
     if self.freemove != FreeMode.NoFreeMove:
         #Draw a colored frame for free move mode.
         pen = QPen()
         if self.freemove == FreeMode.Translate:
             pen.setColor(QColor(161, 105, 229))
         elif self.freemove == FreeMode.Rotate:
             pen.setColor(QColor(219, 162, 6))
         elif self.freemove == FreeMode.Reflect:
             pen.setColor(QColor(79, 249, 193))
         pen.setWidth(8)
         self.painter.setPen(pen)
         self.__drawFrame()
     #Draw links except ground.
     for vlink in self.Links[1:]:
         self.__drawLink(vlink)
     #Draw path.
     if self.Path.show != -2:
         self.__drawPath()
     #Draw solving path.
     if self.showTargetPath:
         self.__drawSlvsRanges()
         self._BaseCanvas__drawTargetPath()
     #Draw points.
     for i, vpoint in enumerate(self.Points):
         self.__drawPoint(i, vpoint)
     #Rectangular selection
     if self.Selector.RectangularSelection:
         pen = QPen(Qt.gray)
         pen.setWidth(1)
         self.painter.setPen(pen)
         self.painter.drawRect(
             QRectF(QPointF(self.Selector.x, self.Selector.y),
                    QPointF(self.Selector.sx, self.Selector.sy)))
     self.painter.end()
     #Record the widget size.
     self.width_old = width
     self.height_old = height
예제 #24
0
 def updateRanges(self, ranges: Dict[str, Tuple[float, float, float]]):
     """Update the ranges of dimensional synthesis."""
     self.ranges.clear()
     self.ranges.update({tag: QRectF(
         QPointF(values[0] - values[2]/2, values[1] + values[2]/2),
         QSizeF(values[2], values[2])
     ) for tag, values in ranges.items()})
     self.update()
예제 #25
0
 def drawDot(self, path: Sequence[Tuple[float, float]]):
     """Draw path as dots."""
     if len(set(path)) <= 2:
         return
     for x, y in path:
         if isnan(x):
             continue
         self.painter.drawPoint(QPointF(x, -y) * self.zoom)
예제 #26
0
 def __draw_frame(self):
     """Draw a external frame."""
     pos_x = self.width() - self.ox
     pos_y = -self.oy
     neg_x = -self.ox
     neg_y = self.height() - self.oy
     self.painter.drawLine(QPointF(neg_x, pos_y), QPointF(pos_x, pos_y))
     self.painter.drawLine(QPointF(neg_x, neg_y), QPointF(pos_x, neg_y))
     self.painter.drawLine(QPointF(neg_x, pos_y), QPointF(neg_x, neg_y))
     self.painter.drawLine(QPointF(pos_x, pos_y), QPointF(pos_x, neg_y))
예제 #27
0
 def __draw_arrow(
     self,
     x1: float,
     y1: float,
     x2: float,
     y2: float,
     *,
     zoom: bool = False,
     text: str = ''
 ):
     """Front point -> Back point"""
     if zoom:
         x1 *= self.zoom
         y1 *= self.zoom
         x2 *= self.zoom
         y2 *= self.zoom
     a = atan2(y2 - y1, x2 - x1)
     x1 = (x1 + x2) / 2 - 7.5 * cos(a)
     y1 = (y1 + y2) / 2 - 7.5 * sin(a)
     first_point = QPointF(x1, y1)
     self.painter.drawLine(first_point, QPointF(
         x1 + 15 * cos(a + radians(20)),
         y1 + 15 * sin(a + radians(20))
     ))
     self.painter.drawLine(first_point, QPointF(
         x1 + 15 * cos(a - radians(20)),
         y1 + 15 * sin(a - radians(20))
     ))
     if not text:
         return
     # Font
     font = self.painter.font()
     font_copy = QFont(font)
     font.setBold(True)
     font.setPointSize(font.pointSize() + 8)
     self.painter.setFont(font)
     # Color
     pen = self.painter.pen()
     color = pen.color()
     pen.setColor(color.darker())
     self.painter.setPen(pen)
     self.painter.drawText(first_point, text)
     pen.setColor(color)
     self.painter.setPen(pen)
     self.painter.setFont(font_copy)
예제 #28
0
 def paintEvent(self, event):
     """Drawing functions."""
     width = self.width()
     height = self.height()
     if self.width_old != width or self.height_old != height:
         self.ox += (width - self.width_old) / 2
         self.oy += (height - self.height_old) / 2
     super(DynamicCanvas, self).paintEvent(event)
     self.painter.setFont(QFont('Arial', self.fontSize))
     if self.freemove:
         #Draw a colored frame for free move mode.
         pen = QPen()
         if self.freemove == 1:
             pen.setColor(QColor(161, 105, 229))
         elif self.freemove == 2:
             pen.setColor(QColor(219, 162, 6))
         elif self.freemove == 3:
             pen.setColor(QColor(79, 249, 193))
         pen.setWidth(8)
         self.painter.setPen(pen)
         self.drawFrame()
     if self.Selector.RectangularSelection:
         pen = QPen(Qt.gray)
         pen.setWidth(1)
         self.painter.setPen(pen)
         self.painter.drawRect(
             QRectF(QPointF(self.Selector.x, self.Selector.y),
                    QPointF(self.Selector.sx, self.Selector.sy)))
     #Draw links.
     for vlink in self.Link[1:]:
         self.drawLink(vlink)
     #Draw path.
     if self.Path.show > -2:
         self.drawPath()
     #Draw solving path.
     if self.showTargetPath:
         self.drawSlvsRanges()
         self.drawTargetPath()
     #Draw points.
     for i, vpoint in enumerate(self.Point):
         self.drawPoint(i, vpoint)
     self.painter.end()
     self.width_old = width
     self.height_old = height
예제 #29
0
 def drawCurve(self, path):
     pointPath = QPainterPath()
     for i, (x, y) in enumerate(path):
         if isnan(x):
             continue
         else:
             if i==0:
                 pointPath.moveTo(x*self.zoom, y*-self.zoom)
             else:
                 pointPath.lineTo(QPointF(x*self.zoom, y*-self.zoom))
     self.painter.drawPath(pointPath)
예제 #30
0
    def paintEvent(self, event):
        """Using a QPainter under 'self',
        so just change QPen or QBrush before painting.
        """
        self.painter.begin(self)
        self.painter.fillRect(event.rect(), QBrush(Qt.white))
        # Translation
        self.painter.translate(self.ox, self.oy)
        # Background
        if not self.background.isNull():
            rect = self.background.rect()
            self.painter.setOpacity(self.background_opacity)
            img_origin: QPointF = self.background_offset * self.zoom
            self.painter.drawImage(
                QRectF(img_origin, QSizeF(
                    rect.width() * self.background_scale * self.zoom,
                    rect.height() * self.background_scale * self.zoom
                )),
                self.background,
                QRectF(rect)
            )
            self.painter.setOpacity(1)
        # Show frame.
        pen = QPen(Qt.blue)
        pen.setWidth(1)
        self.painter.setPen(pen)
        self.painter.setFont(QFont("Arial", self.font_size))
        # Draw origin lines.
        pen.setColor(Qt.gray)
        self.painter.setPen(pen)
        x_l = -self.ox
        x_r = self.width() - self.ox
        self.painter.drawLine(QPointF(x_l, 0), QPointF(x_r, 0))
        y_t = self.height() - self.oy
        y_b = -self.oy
        self.painter.drawLine(QPointF(0, y_b), QPointF(0, y_t))

        def indexing(v):
            """Draw tick."""
            return int(v / self.zoom - v / self.zoom % 5)

        for x in range(indexing(x_l), indexing(x_r) + 1, 5):
            self.painter.drawLine(
                QPointF(x, 0) * self.zoom,
                QPointF(x * self.zoom, -10 if x % 10 == 0 else -5)
            )
        for y in range(indexing(y_b), indexing(y_t) + 1, 5):
            self.painter.drawLine(
                QPointF(0, y) * self.zoom,
                QPointF(10 if y % 10 == 0 else 5, y * self.zoom)
            )