def catch(exprs: Sequence[str]) -> bool: """Detection function for solution polygons.""" points, _ = self.solution_polygon(exprs[0], exprs[1:-1], exprs[-1], self.vpoints) polygon = QPolygonF(points) if rect: return polygon.intersects( QPolygonF(self.selector.to_rect(self.zoom))) else: return polygon.containsPoint( QPointF(self.selector.x, self.selector.y), Qt.WindingFill)
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)
def catch(link: VLink) -> bool: """Detection function for links. + Is polygon: Using Qt polygon geometry. + If just a line: Create a range for mouse detection. """ points = self.__points_pos(link) if len(points) > 2: polygon = QPolygonF(convex_hull(points, as_qpoint=True)) else: polygon = QPolygonF( convex_hull([(x + self.sr, y + self.sr) for x, y in points] + [(x - self.sr, y - self.sr) for x, y in points], as_qpoint=True)) if rect: return polygon.intersects( QPolygonF(self.selector.to_rect(self.zoom))) else: return polygon.containsPoint( QPointF(self.selector.x, -self.selector.y) * self.zoom, Qt.WindingFill)
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