python - 在具有一定间隙的主要多边形内绘制第二个相同的多边形
问题描述
下面的代码在图像上绘制了一个多边形。我想在主要的内部绘制第二个相同的形状,间隙为 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...')
解决方案
该算法给出了一个顶点,因此相关的边必须以平行的方式平移,并且这些线的交点是所需多边形的一个点。
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_())
推荐阅读
- c++ - OpenGL绘制一个矩形填充窗口
- sql-server - Insert In 语句卡在循环中
- python - 我收到一个错误:“UnboundLocalError:分配前引用了局部变量'text_to_print'”
- c++ - 模板类是否可以基于参数包从多个父级继承?
- python - pandas 使用 UTC 索引获取列值
- javascript - 在 Laravel + Vue 上 @click 事件时获取旧数据
- javascript - Javascript/Python - 单击网站上的按钮并在 python 中运行函数
- python - 选择列时的Python panda keyerror
- c++ - 如何使用arm64程序集进行浮点运算?
- linux - 在 Linux 上调试 Webkitgtk