Итак, я пытаюсь создать фальшивый эффект 3D / изометрического экструзии, создав QpainterPath, дублировать и смещать его, преобразовая оба в полигоны, извлекая их точки и, наконец, соединяя эти точки с прямыми линиями. Это результат:
Я не могу понять Выход способ заполнить внутренние линии цветом, любая помощь?from PyQt6.QtGui import QPainter, QPainterPath, QFont, QPen, QBrush, QColor
from PyQt6.QtCore import QPointF, Qt
from PyQt6.QtWidgets import QApplication, QWidget, QSlider, QVBoxLayout
import sys
import math
class TextPathPoints(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 300)
# Create a QPainterPath with text
self.font = QFont("Super Dessert", 120) # Use a valid font
self.path = QPainterPath()
self.path.addText(100, 200, self.font, "HELLO!")
# Control variables for extrusion
self.extrusion_length = 25 # Length of extrusion
self.extrusion_angle = 45 # Angle in degrees (measured counterclockwise from the positive x-axis)
layout = QVBoxLayout()
# Create slider for extrusion length (range 0-100, step 1)
self.length_slider = QSlider()
self.length_slider.setRange(0, 100)
self.length_slider.setValue(self.extrusion_length)
self.length_slider.setTickInterval(1)
self.length_slider.valueChanged.connect(self.update_extrusion_length)
layout.addWidget(self.length_slider)
# Create slider for extrusion angle (range 0-360, step 1)
self.angle_slider = QSlider()
self.angle_slider.setRange(0, 360)
self.angle_slider.setValue(self.extrusion_angle)
self.angle_slider.setTickInterval(1)
self.angle_slider.valueChanged.connect(self.update_extrusion_angle)
layout.addWidget(self.angle_slider)
self.setLayout(layout)
def update_extrusion_length(self, value):
self.extrusion_length = value
self.update() # Trigger repaint to update the path
def update_extrusion_angle(self, value):
self.extrusion_angle = value
self.update() # Trigger repaint to update the path
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
# Convert angle to radians
angle_rad = math.radians(self.extrusion_angle)
# Calculate x and y offsets based on extrusion length and angle
self.offset_x = self.extrusion_length * math.cos(angle_rad)
self.offset_y = self.extrusion_length * math.sin(angle_rad)
# Duplicate the path
self.duplicated_path = QPainterPath(self.path) # Duplicate the original path
self.duplicated_path.translate(self.offset_x, self.offset_y) # Offset using calculated values
# Convert paths to polygons
original_polygon = self.path.toFillPolygon()
duplicated_polygon = self.duplicated_path.toFillPolygon()
# Extract points from polygons
self.original_points = [(p.x(), p.y()) for p in original_polygon]
self.duplicated_points = [(p.x(), p.y()) for p in duplicated_polygon]
# Set brush for filling the path
brush = QBrush(QColor("#ebd086")) # Front and back fill
painter.setBrush(brush)
# Fill the original path
painter.fillPath(self.path, brush)
# Set pen for drawing lines between points
pen = QPen()
pen.setColor(QColor("black")) # Color of the lines
pen.setWidthF(1.4)
painter.setPen(pen)
pen.setJoinStyle(Qt.PenJoinStyle.RoundJoin)
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
# Draw duplicated path
painter.drawPath(self.duplicated_path)
# Connect corresponding points between the original and duplicated paths
num_points = min(len(self.original_points), len(self.duplicated_points))
for i in range(num_points):
original_x, original_y = self.original_points
duplicated_x, duplicated_y = self.duplicated_points
painter.drawLine(QPointF(original_x, original_y), QPointF(duplicated_x, duplicated_y))
# Draw the original path
painter.drawPath(self.path)
app = QApplication(sys.argv)
window = TextPathPoints()
window.show()
sys.exit(app.exec())
< /code>
*Обновлено.from PyQt6.QtGui import QPainter, QPainterPath, QPen, QBrush, QColor
from PyQt6.QtCore import QPointF, Qt
from PyQt6.QtWidgets import QApplication, QWidget, QSlider, QVBoxLayout
import sys
import math
class ExtrudeWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 300)
# Create a QPainterPath with rect
self.path = QPainterPath()
self.path.addRect(200, 100, 200, 50)
# Control variables for extrusion
self.extrusion_length = 15 # Length of extrusion
self.extrusion_angle = 135 # Angle in degrees (measured counterclockwise from the positive x-axis)
layout = QVBoxLayout()
# Create slider for extrusion length (range 0-100, step 1)
self.length_slider = QSlider()
self.length_slider.setRange(0, 100)
self.length_slider.setValue(self.extrusion_length)
self.length_slider.setTickInterval(1)
self.length_slider.valueChanged.connect(self.update_extrusion_length)
layout.addWidget(self.length_slider)
# Create slider for extrusion angle (range 0-360, step 1)
self.angle_slider = QSlider()
self.angle_slider.setRange(0, 360)
self.angle_slider.setValue(self.extrusion_angle)
self.angle_slider.setTickInterval(1)
self.angle_slider.valueChanged.connect(self.update_extrusion_angle)
layout.addWidget(self.angle_slider)
self.setLayout(layout)
def update_extrusion_length(self, value):
self.extrusion_length = value
self.update() # Trigger repaint to update the path
def update_extrusion_angle(self, value):
self.extrusion_angle = value
self.update() # Trigger repaint to update the path
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
# Convert angle to radians
angle_rad = math.radians(self.extrusion_angle)
# Calculate x and y offsets based on extrusion length and angle
offset_x = self.extrusion_length * math.cos(angle_rad)
offset_y = self.extrusion_length * math.sin(angle_rad)
# Duplicate the path
duplicated_path = QPainterPath(self.path) # Duplicate the original path
duplicated_path.translate(offset_x, offset_y) # Offset using calculated values
# Convert paths to polygons
original_polygon = self.path.toFillPolygon()
duplicated_polygon = duplicated_path.toFillPolygon()
# Extract points from polygons
original_points = [(p.x(), p.y()) for p in original_polygon]
duplicated_points = [(p.x(), p.y()) for p in duplicated_polygon]
# Create brushes
main_brush = QBrush(QColor("#ebd086"))
side_brush = QBrush(QColor("#c4a56a"))
# Define a list of colors to cycle through for debugging
debug_colors = [
QColor("#ff0000"), # Red
QColor("#00ff00"), # Green
QColor("#0000ff"), # Blue
QColor("#ffff00"), # Yellow
QColor("#ff00ff"), # Magenta
QColor("#00ffff"), # Cyan
QColor("#ff7f00") # Orange
]
# Fill the original path
painter.fillPath(self.path, main_brush)
# Set pen for drawing lines
pen = QPen()
pen.setColor(QColor("black")) # Color of the lines
pen.setWidthF(1)
painter.setPen(pen)
pen.setJoinStyle(Qt.PenJoinStyle.RoundJoin)
pen.setCapStyle(Qt.PenCapStyle.RoundCap)
# Draw duplicated path
painter.drawPath(duplicated_path)
# Create and connect side polygons
num_points = min(len(original_points), len(duplicated_points))
for i in range(num_points - 1): # Iterate over pairs of points
orig_p1 = QPointF(*original_points)
orig_p2 = QPointF(*original_points[i + 1])
dup_p1 = QPointF(*duplicated_points)
dup_p2 = QPointF(*duplicated_points[i + 1])
# Create a side polygon
side_face = QPainterPath()
side_face.moveTo(orig_p1)
side_face.lineTo(orig_p2)
side_face.lineTo(dup_p2)
side_face.lineTo(dup_p1)
side_face.closeSubpath()
# Choose a color from the debug_colors list based on the index
side_color = debug_colors[i % len(debug_colors)] # Cycle through the colors
side_brush = QBrush(side_color) # Use the color for filling
# Fill the side with the chosen color
painter.fillPath(side_face, side_brush)
# Draw the outlines
painter.drawPath(side_face)
# Draw the original path
painter.setBrush(main_brush)
painter.drawPath(self.path)
app = QApplication(sys.argv)
window = ExtrudeWidget()
window.show()
sys.exit(app.exec())
Подробнее здесь: https://stackoverflow.com/questions/794 ... responding
С Qpainter я создал путь, дублировал его и подключил их соответствующие точки прямыми линиями, как мне заполнить новые ф ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как заполнить закрытую полинии линии равноудаленными горизонтальными линиями?
Anonymous » » в форуме C++ - 0 Ответы
- 2 Просмотры
-
Последнее сообщение Anonymous
-