Exemple #1
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)
            )
 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)
Exemple #3
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}]')
Exemple #4
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)
 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)
Exemple #6
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()
 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
Exemple #8
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
Exemple #9
0
    def __init__(self, mechanism: Dict[str, Any],
                 path: Sequence[Sequence[Tuple[float, float]]],
                 vpoints: List[VPoint], vlinks: List[VLink], parent: QWidget):
        """Input link and path data."""
        super(_DynamicCanvas, self).__init__(parent)
        self.mechanism = mechanism
        self.path.path = path
        self.vpoints = vpoints
        self.vlinks = vlinks
        ranges: Dict[int, Tuple[float, float,
                                float]] = self.mechanism['Placement']
        self.ranges.update({
            f"P{i}":
            QRectF(QPointF(values[0] - values[2], values[1] + values[2]),
                   QSizeF(values[2] * 2, values[2] * 2))
            for i, values in ranges.items()
        })
        same: Dict[int, int] = self.mechanism['same']
        target_path: Dict[int, List[Tuple[float,
                                          float]]] = self.mechanism['Target']
        for i, path in target_path.items():
            for j in range(i):
                if j in same:
                    i -= 1
            self.target_path[f"P{i}"] = path
        self.__index = 0
        self.__interval = 1
        self.__path_count = max(len(path) for path in self.path.path) - 1
        self.pos: List[Tuple[float, float]] = []

        # Error
        self.error = False
        self.__no_error = 0

        # Timer start.
        self.__timer = QTimer()
        self.__timer.timeout.connect(self.__change_index)
        self.__timer.start(18)
Exemple #10
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)
Exemple #11
0
 def to_rect(self, zoom: float) -> QRectF:
     """Return limit as QRectF type."""
     return QRectF(QPointF(self.x * zoom, -self.y * zoom),
                   QPointF(self.sx * zoom, -self.sy * zoom))