首页 > 解决方案 > 在具有一定间隙的主要多边形内绘制第二个相同的多边形

问题描述

下面的代码在图像上绘制了一个多边形。我想在主要的内部绘制第二个相同的形状,间隙为 0.3m。我尝试了几个解决方案,但没有一个适用于所有用例。

请参阅随附的屏幕截图。

图片

上下文:通过使用 QPolygon 类组合一组选定的点来绘制形状。

import sys
from sympy import Polygon
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import QLine, Qt, QPoint, QRect
from PyQt5.QtGui import QPixmap, QPainter,QColor,QPolygon
from PyQt5 import QtCore, QtGui, QtWidgets, uic





class MyApp(QWidget):
    
    def __init__(self):
        super().__init__()
        self.window_width, self.window_height =1200,800
        self.setMinimumSize(self.window_width,self.window_height)
        layout= QVBoxLayout()
        self.setLayout(layout)

        self.pix  = QPixmap('image.jpg')
        self.resize(self.pix.width(),self.pix.height())
        # self.pix.fill(Qt.white)
        # tableau
        self.point = QPoint()
        self.tab =[]

   

    def paintEvent(self,event):
        painter = QPainter(self)
        pen = QtGui.QPen()
        pen.setColor(QtGui.QColor('red'))
        pen.setWidth(3)
        painter.setPen(pen)
        painter.drawPixmap(QPoint(),self.pix)
      
        if not self.point.isNull():
            # rect = QRect(self.begin,self.destination)
            # painter.drawRect(rect.normalized())
            line = QPoint(self.point)
            painter.drawPoint(line)
            

    def mousePressEvent(self,event):
        if event.buttons() & Qt.LeftButton:
            self.point = event.pos()
            # self.destination = self.begin
            

            
            self.update()
        

    # def mouseMoveEvent(self,event):
    #     if event.buttons() & Qt.LeftButton:
    #         self.point = event.pos()
    #         self.update()

    def mouseReleaseEvent(self,event):
        pen = QtGui.QPen()
        painter = QPainter(self.pix)
        if event.button() == Qt.LeftButton:
            # rect = QRect(self.begin,self.destination)
            line = QPoint(self.point)
            pen.setColor(QtGui.QColor('red'))
            pen.setWidth(3)
            painter.setPen(pen)
            painter.drawPoint(line)
            painter.setPen(QColor(168, 34, 3))
            
            self.tab.append(self.point)
            print(self.point.x,self.point.y)
            
            self.point = QPoint()
            # w = (rect.width()*12.5)/1056
            # h = (rect.height()*12.5/1056)
            # a=w*h
            # print(w, h,a)
            self.update()
        if event.button() == Qt.RightButton:
            points = QPolygon(self.tab)
            pen.setColor(QtGui.QColor('red'))
            painter.setPen(pen)
            painter.drawPolygon(points)
            #print(self.tab[0])
            polytab=[]
            for i in self.tab:
                polytab.append((i.x(),i.y()))   
            print(Polygon(*polytab).area*(12.5/1056)*(12.5/1056))
            print((self.tab[0].x()-self.tab[1].x())*(12.5/1056))
            self.tab=[]
            self.update()




if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    app.setStyleSheet('''QWidget{font-size:30px}''')
    myAPP = MyApp()
    myAPP.show()

    try:
        sys.exit(app.exec_())
    except SystemExit:
        print('Closing Window...')

标签: pythonpyqtpyqt5

解决方案


该算法给出了一个顶点,因此相关的边必须以平行的方式平移,并且这些线的交点是所需多边形的一个点。

import sys

from PyQt5.QtCore import QLineF
from PyQt5.QtGui import QColor, QPainter, QPen, QPolygonF
from PyQt5.QtWidgets import QApplication, QWidget


def calculate_inner_polygon(polygon, offset):
    if polygon.count() < 3:
        return QPolygonF()
    points = []
    for i in range(polygon.count()):
        pp = polygon[(i - 1 + polygon.count()) % polygon.count()]
        pc = polygon[i]
        pn = polygon[(i + 1 + polygon.count()) % polygon.count()]

        line_0 = QLineF(pp, pc)
        normal_0 = line_0.normalVector()
        normal_0.setLength(offset)
        line_0.translate(normal_0.dx(), normal_0.dy())

        line_1 = QLineF(pc, pn)
        normal_1 = line_1.normalVector()
        normal_1.setLength(offset)
        line_1.translate(normal_1.dx(), normal_1.dy())

        t, point = line_0.intersects(line_1)

        if t != QLineF.NoIntersection:
            points.append(point)
    return QPolygonF(points)


class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setMinimumSize(1200, 800)
        self._points = list()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), QColor("white"))

        if not self._points:
            return

        pen_width = 3
        offset = -8

        pen = QPen(QColor("red"))

        outer_polygon = QPolygonF(self._points)
        inner_polygon = calculate_inner_polygon(outer_polygon, offset)

        for polygon in (outer_polygon, inner_polygon):
            pen.setWidth(pen_width)
            painter.setPen(pen)
            painter.drawPolygon(polygon)
            pen.setWidth(2 * pen_width)
            painter.setPen(pen)
            for point in polygon:
                painter.drawPoint(point)

    def mouseReleaseEvent(self, event):
        self._points.append(event.pos())
        self.update()


if __name__ == "__main__":

    app = QApplication(sys.argv)

    w = MyApp()
    w.show()

    sys.exit(app.exec_())

在此处输入图像描述


推荐阅读