Example #1
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.
Example #2
0
    def drawSolution(
        self,
        func: str,
        args: Sequence[str],
        target: str,
        pos: Union[Tuple[VPoint, ...], Dict[int, Tuple[float, float]]]
    ):
        """Draw the solution triangle."""
        points, color = self.solutionPolygon(func, args, target, pos)

        color.setAlpha(150)
        pen = QPen(color)
        pen.setWidth(self.joint_size)
        self.painter.setPen(pen)

        def draw_arrow(index: int, text: str):
            """Draw arrow."""
            self.__draw_arrow(
                points[-1].x(),
                points[-1].y(),
                points[index].x(),
                points[index].y(),
                text=text
            )

        draw_arrow(0, args[1])
        if func == 'PLLP':
            draw_arrow(1, args[2])
        color.setAlpha(30)
        self.painter.setBrush(QBrush(color))
        self.painter.drawPolygon(QPolygonF(points))
        self.painter.setBrush(Qt.NoBrush)
Example #3
0
    def draw_point(self, i: int, cx, cy, fix: bool, color: Tuple[int, int,
                                                                 int]):
        """Draw a joint."""
        pen = QPen(Qt.black if self.monochrome else QColor(*color))
        pen.setWidth(2)
        self.painter.setPen(pen)
        x = cx * self.zoom
        y = cy * -self.zoom
        if fix:
            bottom = y + 20
            width = 10
            # Draw a triangle below.
            self.painter.drawPolygon(QPointF(x, y), QPointF(x - width, bottom),
                                     QPointF(x + width, bottom))
            r = self.joint_size * 2
        else:
            r = self.joint_size
        self.painter.drawEllipse(QPointF(x, y), r, r)

        if not self.show_point_mark:
            return
        pen.setColor(Qt.darkGray)
        pen.setWidth(2)
        self.painter.setPen(pen)
        text = f"[{i}]" if type(i) is str else f"[Point{i}]"
        if self.show_dimension:
            text += f":({cx:.02f}, {cy:.02f})"
        self.painter.drawText(QPointF(x, y) + QPointF(6, -6), text)
Example #4
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)
Example #5
0
 def drawPoint(self,
     i: int,
     cx,
     cy,
     fix: bool,
     color: QColor
 ):
     """Draw a joint."""
     pen = QPen(color)
     pen.setWidth(2)
     self.painter.setPen(pen)
     x = cx*self.zoom
     y = cy*-self.zoom
     if fix:
         bottom = y + 20
         width = 10
         #Draw a triangle below.
         self.painter.drawPolygon(
             QPointF(x, y),
             QPointF(x - width, bottom),
             QPointF(x + width, bottom)
         )
         self.painter.drawEllipse(QPointF(x, y), width, width)
     else:
         self.painter.drawEllipse(QPointF(x, y), 5, 5)
     if not self.showPointMark:
         return
     pen.setColor(Qt.darkGray)
     pen.setWidth(2)
     self.painter.setPen(pen)
     self.painter.setFont(QFont("Arial", self.fontSize))
     text = "[{}]".format(i) if type(i)==str else "[Point{}]".format(i)
     if self.showDimension:
         text += ":({:.02f}, {:.02f})".format(cx, cy)
     self.painter.drawText(QPointF(x+6, y-6), text)
Example #6
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))
Example #7
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)
Example #8
0
 def __drawPath(self):
     """Draw paths. Recording first."""
     pen = QPen()
     if self.autoPathShow and self.rightInput():
         """Replace to auto preview path."""
         exprs = self.getTriangle(self.Points)
         self.Path.path = expr_path(
             exprs, {n: 'P{}'.format(n)
                     for n in range(len(self.Points))}, self.Points,
             self.pathInterval())
         if self.solutionShow:
             for expr in exprs:
                 self._BaseCanvas__drawSolution(expr[0], expr[1:-1],
                                                expr[-1], self.Points)
     if hasattr(self, 'path_record'):
         paths = self.path_record
     else:
         paths = self.Path.path
     for i, path in enumerate(paths):
         if ((self.Path.show != i) and (self.Path.show != -1)
                 or (len(path) <= 1)):
             continue
         try:
             color = self.Points[i].color
         except:
             color = colorQt('Green')
         pen.setColor(color)
         pen.setWidth(self.pathWidth)
         self.painter.setPen(pen)
         if self.Path.curve:
             self._BaseCanvas__drawCurve(path)
         else:
             self._BaseCanvas__drawDot(path)
Example #9
0
 def __draw_path(self):
     """Draw paths. Recording first."""
     paths = self.path_record or self.path.path or self.path_preview
     if len(self.vpoints) != len(paths):
         return
     if paths is self.path_preview:
         o_path = chain(enumerate(self.path_preview),
                        self.slider_path_preview.items())
     else:
         o_path = enumerate(paths)
     pen = QPen()
     for i, path in o_path:
         if self.path.show != i and self.path.show != -1:
             continue
         if self.monochrome:
             color = Qt.gray
         elif self.vpoints[i].color is None:
             color = color_qt('Green')
         else:
             color = QColor(*self.vpoints[i].color)
         pen.setColor(color)
         pen.setWidth(self.path_width)
         self.painter.setPen(pen)
         if self.path.curve:
             self.draw_curve(path)
         else:
             self.draw_dot(path)
Example #10
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)
Example #11
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)
 def __draw_path(self):
     """Draw paths. Recording first."""
     paths = self.path_record or self.Path.path or self.pathpreview
     if len(self.vpoints) != len(paths):
         return
     if paths == self.pathpreview:
         o_path = chain(enumerate(self.pathpreview),
                        self.sliderpathpreview.items())
     else:
         o_path = enumerate(paths)
     pen = QPen()
     for i, path in o_path:
         if (self.Path.show != i) and (self.Path.show != -1):
             continue
         if self.vpoints[i].color:
             color = self.vpoints[i].color
         else:
             color = color_qt('Green')
         pen.setColor(color)
         pen.setWidth(self.path_width)
         self.painter.setPen(pen)
         if self.Path.curve:
             self.drawCurve(path)
         else:
             self.drawDot(path)
Example #13
0
 def drawTargetPath(self):
     """Draw solving path."""
     pen = QPen()
     pen.setWidth(self.pathWidth)
     for i, name in enumerate(sorted(self.targetPath)):
         path = self.targetPath[name]
         Pen, Dot, Brush = colorPath(i)
         pen.setColor(Pen)
         self.painter.setPen(pen)
         self.painter.setBrush(Brush)
         if len(path)>1:
             pointPath = QPainterPath()
             for i, (x, y) in enumerate(path):
                 x *= self.zoom
                 y *= -self.zoom
                 self.painter.drawEllipse(QPointF(x, y), 4, 4)
                 if i==0:
                     self.painter.drawText(QPointF(x+6, y-6), name)
                     pointPath.moveTo(x, y)
                 else:
                     x2, y2 = path[i-1]
                     self.drawArrow(x, y, x2*self.zoom, y2*-self.zoom)
                     pointPath.lineTo(QPointF(x, y))
             self.painter.drawPath(pointPath)
             for x, y in path:
                 pen.setColor(Dot)
                 self.painter.setPen(pen)
                 self.painter.drawEllipse(
                     QPointF(x*self.zoom, y*-self.zoom), 3, 3
                 )
         elif len(path)==1:
             x = path[0][0]*self.zoom
             y = path[0][1]*-self.zoom
             self.painter.drawText(QPointF(x+6, y-6), name)
             pen.setColor(Dot)
             self.painter.setPen(pen)
             self.painter.drawEllipse(QPointF(x, y), 3, 3)
     self.painter.setBrush(Qt.NoBrush)
Example #14
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
Example #15
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)
            )
Example #16
0
    def __draw_path(self):
        """Draw a path.

        A simple function than main canvas.
        """
        pen = QPen()
        for i, path in enumerate(self.path.path):
            color = color_qt('Green')
            if f"P{i}" in self.target_path:
                color = color_qt('Dark-Orange')
            pen.setColor(color)
            pen.setWidth(self.path_width)
            self.painter.setPen(pen)
            self.draw_curve(path)
Example #17
0
    def __draw_path(self):
        """Draw a path.

        A simple function than main canvas.
        """
        pen = QPen()
        for i, path in enumerate(self.Path.path):
            color = color_qt('Green')
            if self.exp_symbol[i] in self.mechanism['Target']:
                color = color_qt('Dark-Orange')
            pen.setColor(color)
            pen.setWidth(self.path_width)
            self.painter.setPen(pen)
            self.drawCurve(path)
Example #18
0
 def draw_slvs_ranges(self):
     """Draw solving range."""
     pen = QPen()
     pen.setWidth(5)
     for i, (tag, rect) in enumerate(self.ranges.items()):
         range_color = QColor(color_num(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(QPointF(cx, cy),
                        QSizeF(rect.width(), 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, cy) + QPointF(6, -6), tag)
         self.painter.setBrush(Qt.NoBrush)
Example #19
0
    def __drawSolution(self, func: str, args: Tuple[str], target: str,
                       pos: TypeVar('Coords', Tuple[VPoint],
                                    Dict[int, Tuple[float, float]])):
        """Draw the solution triangle."""
        if func == 'PLLP':
            color = QColor(121, 171, 252)
            params = [args[0], args[-1]]
        elif func == 'PLAP':
            color = QColor(249, 84, 216)
            params = [args[0]]
        elif func == 'PLPP':
            color = QColor(94, 255, 185)
            params = [args[0]]
        params.append(target)
        pen = QPen()
        pen.setColor(color)
        pen.setWidth(RADIUS)
        self.painter.setPen(pen)

        def drawArrow(n: int) -> bool:
            """Draw arrow and return True if done."""
            try:
                x, y = pos[int(params[-1].replace('P', ''))]
                x2, y2 = pos[int(params[n].replace('P', ''))]
            except ValueError:
                return False
            else:
                self.__drawArrow(x * self.zoom, y * -self.zoom, x2 * self.zoom,
                                 y2 * -self.zoom)
                return True

        if not drawArrow(0):
            return
        if func == 'PLLP':
            if not drawArrow(1):
                return
        color.setAlpha(30)
        self.painter.setBrush(QBrush(color))
        qpoints = []
        for name in params:
            x, y = pos[int(name.replace('P', ''))]
            qpoints.append(QPointF(x * self.zoom, y * -self.zoom))
        self.painter.drawPolygon(*qpoints)
        self.painter.setBrush(Qt.NoBrush)
Example #20
0
 def drawPath(self):
     """Draw paths. Recording first."""
     pen = QPen()
     if hasattr(self, 'PathRecord'):
         Path = self.PathRecord
     else:
         Path = self.Path.path
     for i, path in enumerate(Path):
         if self.Path.show != i and self.Path.show != -1:
             continue
         if len(set(path)) > 1:
             try:
                 color = self.Point[i].color
             except:
                 color = colorQt('Green')
             pen.setColor(color)
             pen.setWidth(self.pathWidth)
             self.painter.setPen(pen)
             if self.Path.curve:
                 self.drawCurve(path)
             else:
                 self.drawDot(path)
Example #21
0
def to_graph(graph: Graph,
             width: int,
             engine: Union[str, Dict[int, Tuple[float, float]]],
             node_mode: bool = False,
             except_node: int = None) -> QIcon:
    """Draw a generalized chain graph."""
    pos: Pos = engine_picker(graph, engine, node_mode)
    width_bound = -float('inf')
    for x, y in pos.values():
        if abs(x) > width_bound:
            width_bound = x
        if abs(y) > width_bound:
            width_bound = y
    width_bound *= 2.2
    image = QImage(QSize(int(width_bound), int(width_bound)),
                   QImage.Format_ARGB32_Premultiplied)
    image.fill(Qt.transparent)
    painter = QPainter(image)
    painter.translate(image.width() / 2, image.height() / 2)
    pen = QPen()
    r = width_bound / 50
    pen.setWidth(int(r))
    painter.setPen(pen)

    # Draw edges.
    if node_mode:
        for l1, l2 in graph.edges:
            if except_node in {l1, l2}:
                pen.setColor(color_qt('Gray'))
            else:
                pen.setColor(color_qt('Black'))
            painter.setPen(pen)

            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 graph.nodes:
            if link == except_node:
                pen.setColor(color_qt('Gray'))
            else:
                pen.setColor(color_qt('Black'))
            painter.setPen(pen)

            painter.drawPolygon(*convex_hull([(pos[n][0], -pos[n][1])
                                              for n, edge in edges_view(graph)
                                              if link in edge],
                                             as_qpoint=True))

    # Draw nodes.
    for k, (x, y) in pos.items():
        if node_mode:
            color = color_num(len(list(graph.neighbors(k))) - 1)
            if k == except_node:
                color.setAlpha(150)
        else:
            if except_node in dict(edges_view(graph))[k]:
                color = color_qt('Green')
            else:
                color = color_qt('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
Example #22
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)
Example #23
0
 def __draw_link(self, vlink: VLink):
     """Draw a link."""
     if vlink.name == 'ground' or (not vlink.points):
         return
     points = self.__points_pos(vlink)
     pen = QPen()
     # Rearrange: Put the nearest point to the next position.
     qpoints = convex_hull(points, as_qpoint=True)
     if (self.select_mode == SelectMode.Link
             and self.vlinks.index(vlink) in self.selections):
         pen.setWidth(self.link_width + 6)
         pen.setColor(Qt.black if self.monochrome else QColor(161, 16, 239))
         self.painter.setPen(pen)
         self.painter.drawPolygon(*qpoints)
     pen.setWidth(self.link_width)
     pen.setColor(Qt.black if self.monochrome else QColor(*vlink.color))
     self.painter.setPen(pen)
     brush = QColor(Qt.darkGray) if self.monochrome else QColor(
         226, 219, 190)
     brush.setAlphaF(self.transparency)
     self.painter.setBrush(brush)
     self.painter.drawPolygon(*qpoints)
     self.painter.setBrush(Qt.NoBrush)
     if not self.show_point_mark:
         return
     pen.setColor(Qt.darkGray)
     self.painter.setPen(pen)
     p_count = len(points)
     cen_x = sum(p[0] for p in points) / p_count
     cen_y = sum(p[1] for p in points) / p_count
     self.painter.drawText(QRectF(cen_x - 50, cen_y - 50, 100, 100),
                           Qt.AlignCenter, f'[{vlink.name}]')
Example #24
0
    def paintEvent(self, event):
        """Drawing functions."""
        width = self.width()
        height = self.height()
        if self.width_old is None:
            self.width_old = width
        if self.height_old is None:
            self.height_old = 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

        # 'self' is the instance of 'DynamicCanvas'.
        BaseCanvas.paintEvent(self, event)

        # Draw links except ground.
        for vlink in self.vlinks[1:]:
            self.__draw_link(vlink)

        # Draw path.
        if self.path.show != -2:
            self.__draw_path()

        # Draw solving path.
        if self.show_target_path:
            self.painter.setFont(QFont("Arial", self.font_size + 5))
            self.draw_slvs_ranges()
            self.draw_target_path()
            self.painter.setFont(QFont("Arial", self.font_size))

        # Draw points.
        for i, vpoint in enumerate(self.vpoints):
            self.__draw_point(i, vpoint)

        # Draw solutions.
        if self.select_mode == SelectMode.Solution:
            for i, expr in enumerate(self.exprs):
                func = expr[0]
                params = expr[1:-1]
                target = expr[-1]
                self.draw_solution(func, params, target, self.vpoints)
                if i in self.selections:
                    pos, _ = self.solution_polygon(func, params, target,
                                                   self.vpoints)
                    pen = QPen()
                    pen.setWidth(self.link_width + 3)
                    pen.setColor(QColor(161, 16, 239))
                    self.painter.setPen(pen)
                    self.painter.drawPolygon(QPolygonF(pos))

        # Draw a colored frame for free move mode.
        if self.free_move != FreeMode.NoFreeMove:
            pen = QPen()
            if self.free_move == FreeMode.Translate:
                pen.setColor(QColor(161, 16, 229))
            elif self.free_move == FreeMode.Rotate:
                pen.setColor(QColor(219, 162, 6))
            elif self.free_move == FreeMode.Reflect:
                pen.setColor(QColor(79, 249, 193))
            pen.setWidth(8)
            self.painter.setPen(pen)
            self.__draw_frame()

        # Rectangular selection
        if self.selector.picking:
            pen = QPen(Qt.gray)
            pen.setWidth(1)
            self.painter.setPen(pen)
            self.painter.drawRect(self.selector.to_rect(self.zoom))

        # Show FPS
        self.fps_updated.emit()
        self.painter.end()

        # Record the widget size.
        self.width_old = width
        self.height_old = height
Example #25
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)
Example #26
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
Example #27
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
Example #28
0
 def paintEvent(self, event):
     """Draw the structure."""
     width = self.width()
     height = self.height()
     if self.pos:
         x_right, x_left, y_top, y_bottom = self.__zoom_to_fit_limit()
         x_diff = x_left - x_right
         y_diff = y_top - y_bottom
         x_diff = x_diff if x_diff else 1
         y_diff = y_diff if y_diff else 1
         if width / x_diff < height / y_diff:
             factor = width / x_diff
         else:
             factor = height / y_diff
         self.zoom = factor * 0.95
         self.ox = width / 2 - (x_left + x_right) / 2 * self.zoom
         self.oy = height / 2 + (y_top + y_bottom) / 2 * self.zoom
     else:
         sq_w = 240
         self.zoom = (width / sq_w) if (width <= height) else (height / sq_w)
         self.ox = width / 2
         self.oy = height / 2
     super(PreviewCanvas, self).paintEvent(event)
     pen = QPen()
     pen.setWidth(self.joint_size)
     self.painter.setPen(pen)
     self.painter.setBrush(QBrush(QColor(226, 219, 190, 150)))
     # Links
     for link in self.G.nodes:
         if link == self.grounded:
             continue
         points = []
         # Points that is belong with the link.
         for num, edge in edges_view(self.G):
             if link in edge:
                 if num in self.same:
                     num = self.same[num]
                 x, y = self.pos[num]
                 points.append((x * self.zoom, y * -self.zoom))
         # Customize points.
         for name, link_ in self.cus.items():
             if link == link_:
                 x, y = self.pos[int(name.replace('P', ''))]
                 points.append((x * self.zoom, y * -self.zoom))
         self.painter.drawPolygon(*convex_hull(points, as_qpoint=True))
     # Nodes
     for node, (x, y) in self.pos.items():
         if node in self.same:
             continue
         x *= self.zoom
         y *= -self.zoom
         if node in (self.Driver, self.Target):
             if node == self.Driver:
                 pen.setColor(color_qt('Red'))
             elif node == self.Target:
                 pen.setColor(color_qt('Yellow'))
             self.painter.setPen(pen)
             self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size)
         if self.getStatus(node):
             color = color_qt('Dark-Magenta')
         else:
             color = color_qt('Green')
         pen.setColor(color)
         self.painter.setPen(pen)
         self.painter.setBrush(QBrush(color))
         self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size)
         pen.setColor(color_qt('Black'))
         self.painter.setPen(pen)
     # Solutions
     if self.showSolutions:
         solutions = self.get_solutions()
         if solutions:
             for expr in solutions.split(';'):
                 self.drawSolution(
                     io.str_before(expr, '['),
                     io.str_between(expr, '[', ']').split(','),
                     io.str_between(expr, '(', ')'),
                     self.pos
                 )
     # Text of node.
     pen.setColor(Qt.black)
     self.painter.setPen(pen)
     for node, (x, y) in self.pos.items():
         if node in self.same:
             continue
         x *= self.zoom
         x += 2 * self.joint_size
         y *= -self.zoom
         y -= 2 * self.joint_size
         self.painter.drawText(QPointF(x, y), f'P{node}')
     self.painter.end()
Example #29
0
    def paintEvent(self, event):
        """Draw the structure."""
        width = self.width()
        height = self.height()
        if self.pos:
            x_right, x_left, y_top, y_bottom = self.__zoom_to_fit_limit()
            x_diff = x_left - x_right
            y_diff = y_top - y_bottom
            x_diff = x_diff if x_diff else 1
            y_diff = y_diff if y_diff else 1
            if width / x_diff < height / y_diff:
                factor = width / x_diff
            else:
                factor = height / y_diff
            self.zoom = factor * 0.75
            self.ox = width / 2 - (x_left + x_right) / 2 * self.zoom
            self.oy = height / 2 + (y_top + y_bottom) / 2 * self.zoom
        else:
            if width <= height:
                self.zoom = width / PreviewCanvas.view_size
            else:
                self.zoom = height / PreviewCanvas.view_size
            self.ox = width / 2
            self.oy = height / 2

        super(PreviewCanvas, self).paintEvent(event)

        pen = QPen()
        pen.setWidth(self.joint_size)
        self.painter.setPen(pen)
        if self.monochrome:
            color = QColor(Qt.darkGray)
        else:
            color = QColor(226, 219, 190)
        color.setAlpha(150)
        self.painter.setBrush(QBrush(color))

        # Links
        for link in self.G.nodes:
            if link == self.grounded:
                continue
            points = []
            # Points that is belong with the link.
            for num, edge in edges_view(self.G):
                if link in edge:
                    if num in self.same:
                        num = self.same[num]
                    x, y = self.pos[num]
                    points.append((x * self.zoom, y * -self.zoom))
            # Customize points.
            for name, link_ in self.cus.items():
                if link == link_:
                    x, y = self.pos[name]
                    points.append((x * self.zoom, y * -self.zoom))
            self.painter.drawPolygon(*convex_hull(points, as_qpoint=True))

        # Nodes
        for node, (x, y) in self.pos.items():
            if node in self.same:
                continue
            x *= self.zoom
            y *= -self.zoom
            if self.monochrome:
                color = Qt.black
            elif node in self.driver:
                color = color_qt('Red')
            elif node in self.target:
                color = color_qt('Orange')
            elif self.get_status(node):
                color = color_qt('Green')
            else:
                color = color_qt('Blue')
            pen.setColor(color)
            self.painter.setPen(pen)
            self.painter.setBrush(QBrush(color))
            self.painter.drawEllipse(QPointF(x, y), self.joint_size,
                                     self.joint_size)
            pen.setColor(Qt.black)
            self.painter.setPen(pen)

        # Text of node.
        pen.setColor(Qt.black)
        self.painter.setPen(pen)
        for node, (x, y) in self.pos.items():
            if node in self.same:
                continue
            x *= self.zoom
            x += 2 * self.joint_size
            y *= -self.zoom
            y -= 2 * self.joint_size
            self.painter.drawText(QPointF(x, y), f'P{node}')

        self.painter.end()
Example #30
0
 def drawTargetPath(self):
     """Draw solving path."""
     pen = QPen()
     pen.setWidth(self.path_width)
     for i, name in enumerate(sorted(self.target_path)):
         path = self.target_path[name]
         road, dot, brush = target_path_style(i)
         pen.setColor(road)
         self.painter.setPen(pen)
         self.painter.setBrush(brush)
         if len(path) == 1:
             x, y = path[0]
             p = QPointF(x, -y) * self.zoom
             self.painter.drawText(p + QPointF(6, -6), name)
             pen.setColor(dot)
             self.painter.setPen(pen)
             self.painter.drawEllipse(p, self.joint_size, self.joint_size)
         else:
             painter_path = QPainterPath()
             for j, (x, y) in enumerate(path):
                 p = QPointF(x, -y) * self.zoom
                 self.painter.drawEllipse(p, self.joint_size, self.joint_size)
                 if j == 0:
                     self.painter.drawText(p + QPointF(6, -6), name)
                     painter_path.moveTo(p)
                 else:
                     x2, y2 = path[j - 1]
                     self.__draw_arrow(x, -y, x2, -y2, zoom=True)
                     painter_path.lineTo(p)
             pen.setColor(road)
             self.painter.setPen(pen)
             self.painter.drawPath(painter_path)
             for x, y in path:
                 pen.setColor(dot)
                 self.painter.setPen(pen)
                 p = QPointF(x, -y) * self.zoom
                 self.painter.drawEllipse(p, self.joint_size, self.joint_size)
     self.painter.setBrush(Qt.NoBrush)