PyQt5:填充 QPolygon 中的孔 // 增加 qpolygon 的大小(高度)
PyQt5: Filling in the holes in QPolygon // Increasing the size (height) of a qpolygon
我有以下 QPolygon:
我需要增加它的高度来获得以下 QPolygon:
而qpolygon的下边界保持在相同位置,即第一张图像中的x1,y1,第二张图像中仍然是x1,y1,上面添加的黑色区域应该是一半qpolygon 本身的高度(最好是一条直线,但不太重要)
为此,我采用了 QPolygon 的边界框
poly1_bounding_rect=QPolygonF(poly_1_coords).boundingRect()
和X0,Y0坐标,还有宽高,然后把多边形加法和原来的多边形统一起来
max_y, min_x, height_, width_ = poly1_bounding_rect.y(), poly1_bounding_rect.x(), poly1_bounding_rect.height(), poly1_bounding_rect.width()
poly1_addition = QPolygonF(
[QPointF(min_x, max_y), QPointF(min_x, max_y - height_ * .5),
QPointF(min_x + width_, max_y - height_ * .5),
QPointF(min_x + width_, max_y)])
然而,这个解决方案使 QPolygon 有漏洞,我不确定我应该如何填充它们,或者首先创建一个没有这些整体的 QPolygon。
非常感谢任何指导,谢谢!
这是一个最小的可重现示例:
import PyQt5
from PyQt5 import QtCore
import sys
import PyQt5
from PyQt5.QtCore import *#QPointF, QRectF
from PyQt5.QtGui import *#QPainterPath, QPolygonF, QBrush,QPen,QFont,QColor, QTransform
from PyQt5.QtWidgets import *#QApplication, QGraphicsScene, QGraphicsView, QGraphicsSimpleTextItem
poly_1_coords= [PyQt5.QtCore.QPointF(412.01, 257.98), PyQt5.QtCore.QPointF(372.24, 197.66), PyQt5.QtCore.QPointF(358.88, 230.95), PyQt5.QtCore.QPointF(371.46, 278.4), PyQt5.QtCore.QPointF(381.16, 291.77), PyQt5.QtCore.QPointF(428.34, 308.81), PyQt5.QtCore.QPointF(483.66, 341.84), PyQt5.QtCore.QPointF(648.02, 373.29), PyQt5.QtCore.QPointF(945.05, 386.61), PyQt5.QtCore.QPointF(1087.66, 374.02), PyQt5.QtCore.QPointF(1285.26, 331.05), PyQt5.QtCore.QPointF(1317.34, 304.71), PyQt5.QtCore.QPointF(1345.85, 265.03), PyQt5.QtCore.QPointF(1340.6, 214.96), PyQt5.QtCore.QPointF(1326.19, 197.39), PyQt5.QtCore.QPointF(1303.38, 243.79), PyQt5.QtCore.QPointF(1134.3, 290.19), PyQt5.QtCore.QPointF(1091.57, 306.71), PyQt5.QtCore.QPointF(1067.45, 295.44), PyQt5.QtCore.QPointF(1017.38, 250.09), PyQt5.QtCore.QPointF(993.53, 218.63), PyQt5.QtCore.QPointF(925.89, 219.41), PyQt5.QtCore.QPointF(852.23, 233.31), PyQt5.QtCore.QPointF(723.52, 219.41), PyQt5.QtCore.QPointF(671.51, 309.58), PyQt5.QtCore.QPointF(638.88, 313.37), PyQt5.QtCore.QPointF(583.5, 299.71), PyQt5.QtCore.QPointF(485.61, 240.53), PyQt5.QtCore.QPointF(451.47, 270.88)]
def main():
app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
pen_ = QPen(QColor(0, 20, 255))
brush_ = QBrush(QColor(0,0,0))
poly_1 = QPolygonF(poly_1_coords)
#scene.addPolygon(poly_1,pen_,brush_)
poly1_bounding_rect = poly_1.boundingRect()
max_y, min_x, height_, width_ = poly1_bounding_rect.y(), poly1_bounding_rect.x(), poly1_bounding_rect.height(), poly1_bounding_rect.width()
poly1_addition = QPolygonF(
[QPointF(min_x, max_y), QPointF(min_x, max_y - height_ * .5),
QPointF(min_x + width_, max_y - height_ * .5),
QPointF(min_x + width_, max_y)])
complete_poly1 = poly_1.united(poly1_addition)
scene.addPolygon(complete_poly1,pen_,brush_)
view.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
不是最优的也不是优雅的答案,但解决了问题。
我遍历初始多边形轮廓点,减少 y 坐标并将其与初始多边形结合,从而有效地创建或多或少所需的结果。
如果有人提出更优的方案,将被采纳!
changed_polygon = QPolygonF()
for adjust in range(1,200):
temp_polygon= QPolygonF()
temp_coords_list = []
for item in poly_1_coords:
temp_coords_list.append(QPointF(item.x(),item.y()-adjust))
changed_polygon = changed_polygon.united(QPolygonF(temp_coords_list))
假设多边形始终是一个简单的多边形,没有任何交集,您可以执行以下操作:
- 找到最小和最大 x(左和右)和最大 y(下)的点;
- 从上面两点开始,建立两条独立的路径,分别是顶部和底部;
- 找出哪一个包括底点,这将意味着它是“底面”;
- 将边界矩形平移其高度的一半,并将其角用作多边形的附加点;
poly_1 = QPolygonF(poly_1_coords)
poly_1_bounding_rect = poly_1.boundingRect()
# translate the bounding rect by half its height to get the top corners
poly_1_bounding_rect.translate(
QPointF(0, -poly_1_bounding_rect.height() * .5))
# find the left/right/bottom-most points
left = right = bottom = None
for point in poly_1_coords:
if not left or left.x() > point.x():
left = point
if not right or right.x() < point.x():
right = point
if not bottom or bottom.y() < point.y():
bottom = point
# assuming points are in correct order and there is no intersection between
# lines, get the indexes of the left and right points to build two separate
# paths, one from the top side, one for the bottom
leftIndex = poly_1_coords.index(left)
rightIndex = poly_1_coords.index(right)
if leftIndex < rightIndex:
side_a = poly_1_coords[leftIndex:rightIndex + 1]
side_b = poly_1_coords[rightIndex:] + poly_1_coords[:leftIndex + 1]
else:
side_a = poly_1_coords[rightIndex:leftIndex + 1]
side_b = poly_1_coords[leftIndex:] + poly_1_coords[:rightIndex + 1]
# look for the bottom point to get the bottom side
if bottom in side_a:
final = side_a
else:
final = side_b
# if the first point is also the left, the coordinates are counter clockwise
# so we add the top corners accordingly, and vice versa
if final[0] == left:
final += [poly_1_bounding_rect.topRight(), poly_1_bounding_rect.topLeft()]
else:
final += [poly_1_bounding_rect.topLeft(), poly_1_bounding_rect.topRight()]
item = scene.addPolygon(QPolygonF(final))
item.setPen(pen_)
item.setBrush(brush_)
或者,您可以根据需要通过翻译来添加顶部:
# look for the bottom point to get the bottom side and add the other
# by translating by half the bounding rect height
delta = QPointF(0, -poly_1_bounding_rect.height() * .5)
if bottom in side_a:
final = side_a + [p + delta for p in side_b]
else:
final = side_b + [p + delta for p in side_a]
我有以下 QPolygon:
我需要增加它的高度来获得以下 QPolygon:
而qpolygon的下边界保持在相同位置,即第一张图像中的x1,y1,第二张图像中仍然是x1,y1,上面添加的黑色区域应该是一半qpolygon 本身的高度(最好是一条直线,但不太重要)
为此,我采用了 QPolygon 的边界框
poly1_bounding_rect=QPolygonF(poly_1_coords).boundingRect()
和X0,Y0坐标,还有宽高,然后把多边形加法和原来的多边形统一起来
max_y, min_x, height_, width_ = poly1_bounding_rect.y(), poly1_bounding_rect.x(), poly1_bounding_rect.height(), poly1_bounding_rect.width()
poly1_addition = QPolygonF(
[QPointF(min_x, max_y), QPointF(min_x, max_y - height_ * .5),
QPointF(min_x + width_, max_y - height_ * .5),
QPointF(min_x + width_, max_y)])
然而,这个解决方案使 QPolygon 有漏洞,我不确定我应该如何填充它们,或者首先创建一个没有这些整体的 QPolygon。
非常感谢任何指导,谢谢!
这是一个最小的可重现示例:
import PyQt5
from PyQt5 import QtCore
import sys
import PyQt5
from PyQt5.QtCore import *#QPointF, QRectF
from PyQt5.QtGui import *#QPainterPath, QPolygonF, QBrush,QPen,QFont,QColor, QTransform
from PyQt5.QtWidgets import *#QApplication, QGraphicsScene, QGraphicsView, QGraphicsSimpleTextItem
poly_1_coords= [PyQt5.QtCore.QPointF(412.01, 257.98), PyQt5.QtCore.QPointF(372.24, 197.66), PyQt5.QtCore.QPointF(358.88, 230.95), PyQt5.QtCore.QPointF(371.46, 278.4), PyQt5.QtCore.QPointF(381.16, 291.77), PyQt5.QtCore.QPointF(428.34, 308.81), PyQt5.QtCore.QPointF(483.66, 341.84), PyQt5.QtCore.QPointF(648.02, 373.29), PyQt5.QtCore.QPointF(945.05, 386.61), PyQt5.QtCore.QPointF(1087.66, 374.02), PyQt5.QtCore.QPointF(1285.26, 331.05), PyQt5.QtCore.QPointF(1317.34, 304.71), PyQt5.QtCore.QPointF(1345.85, 265.03), PyQt5.QtCore.QPointF(1340.6, 214.96), PyQt5.QtCore.QPointF(1326.19, 197.39), PyQt5.QtCore.QPointF(1303.38, 243.79), PyQt5.QtCore.QPointF(1134.3, 290.19), PyQt5.QtCore.QPointF(1091.57, 306.71), PyQt5.QtCore.QPointF(1067.45, 295.44), PyQt5.QtCore.QPointF(1017.38, 250.09), PyQt5.QtCore.QPointF(993.53, 218.63), PyQt5.QtCore.QPointF(925.89, 219.41), PyQt5.QtCore.QPointF(852.23, 233.31), PyQt5.QtCore.QPointF(723.52, 219.41), PyQt5.QtCore.QPointF(671.51, 309.58), PyQt5.QtCore.QPointF(638.88, 313.37), PyQt5.QtCore.QPointF(583.5, 299.71), PyQt5.QtCore.QPointF(485.61, 240.53), PyQt5.QtCore.QPointF(451.47, 270.88)]
def main():
app = QApplication(sys.argv)
scene = QGraphicsScene()
view = QGraphicsView(scene)
pen_ = QPen(QColor(0, 20, 255))
brush_ = QBrush(QColor(0,0,0))
poly_1 = QPolygonF(poly_1_coords)
#scene.addPolygon(poly_1,pen_,brush_)
poly1_bounding_rect = poly_1.boundingRect()
max_y, min_x, height_, width_ = poly1_bounding_rect.y(), poly1_bounding_rect.x(), poly1_bounding_rect.height(), poly1_bounding_rect.width()
poly1_addition = QPolygonF(
[QPointF(min_x, max_y), QPointF(min_x, max_y - height_ * .5),
QPointF(min_x + width_, max_y - height_ * .5),
QPointF(min_x + width_, max_y)])
complete_poly1 = poly_1.united(poly1_addition)
scene.addPolygon(complete_poly1,pen_,brush_)
view.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
不是最优的也不是优雅的答案,但解决了问题。 我遍历初始多边形轮廓点,减少 y 坐标并将其与初始多边形结合,从而有效地创建或多或少所需的结果。
如果有人提出更优的方案,将被采纳!
changed_polygon = QPolygonF()
for adjust in range(1,200):
temp_polygon= QPolygonF()
temp_coords_list = []
for item in poly_1_coords:
temp_coords_list.append(QPointF(item.x(),item.y()-adjust))
changed_polygon = changed_polygon.united(QPolygonF(temp_coords_list))
假设多边形始终是一个简单的多边形,没有任何交集,您可以执行以下操作:
- 找到最小和最大 x(左和右)和最大 y(下)的点;
- 从上面两点开始,建立两条独立的路径,分别是顶部和底部;
- 找出哪一个包括底点,这将意味着它是“底面”;
- 将边界矩形平移其高度的一半,并将其角用作多边形的附加点;
poly_1 = QPolygonF(poly_1_coords)
poly_1_bounding_rect = poly_1.boundingRect()
# translate the bounding rect by half its height to get the top corners
poly_1_bounding_rect.translate(
QPointF(0, -poly_1_bounding_rect.height() * .5))
# find the left/right/bottom-most points
left = right = bottom = None
for point in poly_1_coords:
if not left or left.x() > point.x():
left = point
if not right or right.x() < point.x():
right = point
if not bottom or bottom.y() < point.y():
bottom = point
# assuming points are in correct order and there is no intersection between
# lines, get the indexes of the left and right points to build two separate
# paths, one from the top side, one for the bottom
leftIndex = poly_1_coords.index(left)
rightIndex = poly_1_coords.index(right)
if leftIndex < rightIndex:
side_a = poly_1_coords[leftIndex:rightIndex + 1]
side_b = poly_1_coords[rightIndex:] + poly_1_coords[:leftIndex + 1]
else:
side_a = poly_1_coords[rightIndex:leftIndex + 1]
side_b = poly_1_coords[leftIndex:] + poly_1_coords[:rightIndex + 1]
# look for the bottom point to get the bottom side
if bottom in side_a:
final = side_a
else:
final = side_b
# if the first point is also the left, the coordinates are counter clockwise
# so we add the top corners accordingly, and vice versa
if final[0] == left:
final += [poly_1_bounding_rect.topRight(), poly_1_bounding_rect.topLeft()]
else:
final += [poly_1_bounding_rect.topLeft(), poly_1_bounding_rect.topRight()]
item = scene.addPolygon(QPolygonF(final))
item.setPen(pen_)
item.setBrush(brush_)
或者,您可以根据需要通过翻译来添加顶部:
# look for the bottom point to get the bottom side and add the other
# by translating by half the bounding rect height
delta = QPointF(0, -poly_1_bounding_rect.height() * .5)
if bottom in side_a:
final = side_a + [p + delta for p in side_b]
else:
final = side_b + [p + delta for p in side_a]