pythongeometrypyqt5intersectionqpolygon

How calculate QPolygon area


I'm trying to get the intersection of a blue and green QPolygons, and the % that this makes up of the blue QPolygon (see image below).

enter image description here

I've created the polygons as follows:

import PyQt5
from PyQt5 import QtWidgets,QtGui,QtCore

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

import sys, math


class MyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.pen1 = QtGui.QPen(QtGui.QColor(20,0,250))                      # set lineColor
        self.pen = QtGui.QPen(QtGui.QColor(0,0,0))                      # set lineColor
        self.pen2 = QtGui.QPen(QtGui.QColor(0,250,0))                      # set lineColor

        self.pen.setWidth(3)                                            # set lineWidth
        self.brush = QtGui.QBrush(QtGui.QColor(255,255,255,10))        # set fillColor
        
        coords = [PyQt5.QtCore.QPointF(640.0, 334.0), PyQt5.QtCore.QPointF(626.0, 462.0), PyQt5.QtCore.QPointF(782.0, 509.0), PyQt5.QtCore.QPointF(807.0, 373.0), PyQt5.QtCore.QPointF(807.0, 333.0)]
        greenpolygoncoords = [PyQt5.QtCore.QPointF(698.0, 373.0), PyQt5.QtCore.QPointF(690.0, 433.0), PyQt5.QtCore.QPointF(757.0, 376.0), PyQt5.QtCore.QPointF(713.0, 351.0), PyQt5.QtCore.QPointF(713.0, 351.0), PyQt5.QtCore.QPointF(698.0, 373.0)]
        self.bluepolygon = QPolygonF(coords)
        self.greenpolygon =QPolygonF(greenpolygoncoords)
        self.intersection = self.bluepolygon.intersected(self.greenpolygon)


        print("overlap = "+str(self.intersection.size()/self.bluepolygon.size()))


    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.setPen(self.pen1)
        painter.setBrush(self.brush)
        painter.drawPolygon(self.bluepolygon) #bluepolygon = Blue
        painter.setPen(self.pen)
        painter.drawPolygon(self.intersection) #Intersection = black
        painter.setPen(self.pen2)
        painter.drawPolygon(self.greenpolygon) # greenpolygon = Green
app = QtWidgets.QApplication(sys.argv)

widget = MyWidget()
widget.show()

sys.exit(app.exec_())

However, when I try to calculate the overlap between the two polygons, as a percentage of the blue polygon, I get a wrong answer (it says that the overlap is equal to 1, however, the green polygon definately does not make up 100% of the blue polygon).

overlap = self.intersection.size()/self.bluepolygon.size()

When looking at the sizes calculated by QPolygon.size(), it becomes apparent that the QPolygon.size() returns an incorrect size of the polygon.

    print("size of blue polygon = "+str(self.bluepolygon.size()))
    print("size of greenpolygon = "+str(self.greenpolygon.size()))
    print("size of intersection = "+str(self.intersection.size()))

returns:

size of blue polygon = 5
size of greenpolygon = 6
size of intersection = 5

Apparently for some reason for PyQt5, the blue polygon is smaller than the green polygon. How come?

What am I doing wrong?


Solution

  • The size() method does not return the area of the polygon but the number of sides or vertices. If you want to calculate the area then you must implement it using the standard method:

    def calculate_area(qpolygon):
        area = 0
        for i in range(qpolygon.size()):
            p1 = qpolygon[i]
            p2 = qpolygon[(i + 1) % qpolygon.size()]
            d = p1.x() * p2.y() - p2.x() * p1.y()
            area += d
        return abs(area) / 2
    

    And then you evaluate what you want:

    print(
        "overlap = "
        + str(calculate_area(self.intersection) / calculate_area(self.bluepolygon))
    )
    

    Output:

    overlap = 0.0962288941619438