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]