QPolygons边的交集/获取Qpolygon边上的所有点

2024-03-22

我有两个闭合的 QPolygonF,我需要找出它们的边缘(即它们的轮廓)是否相交。由于这些多边形可能相互包含在一起,因此仅查看多边形的交集是行不通的。

PyQt5 有一个内置函数来检查一个点是否在多边形的轮廓线上,包含(QPointF(x,y))。因此,对 QPolygonF 中的每个点使用此方法似乎是显而易见的:

def check_if_two_polygons_share_contour(polygon1,polygon2):
        for i in range(polygon1.size()):
            if polygon2.contains(QPointF(polygon1[i].x(),polygon1[i].y()))
                print("polygon contours touch!")
                return 1
        return 0

然而,由于我的 QPolygons 仅由角点组成,因此这不起作用。

看起来合乎逻辑的下一步是获取构成 QPolygonF 轮廓的所有点,并在其上运行相同的函数(iso Polygon1.size())。

应该怎样做呢?

为了更好地说明这个概念,该函数应为下图中的第 1 个、第 4 个和第 5 个插图返回 1。


编辑:在此处添加了一些代码以表明某些建议的答案不起作用。

Input:

@alec 建议的功能:

def check_if_two_polygons_share_contour(polygon1,polygon2):
    polygon = polygon1.intersected(polygon2)
    return polygon and polygon not in (polygon1, polygon2)

@Yves Daoust 建议的逻辑:

def line_intersection(line1, line2):
    xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
    ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])

    def det(a, b):
        return a[0] * b[1] - a[1] * b[0]

    div = det(xdiff, ydiff)
    if div == 0:
        # print("Weak Exception 67892: Lines do not interact (function line_intersection). Return 9999999,9999999")
        return 9999999, 9999999
        # raise Exception('lines do not intersect')

    d = (det(*line1), det(*line2))
    x = det(d, xdiff) / div
    y = det(d, ydiff) / div
    return x, y


def check_if_two_polygons_share_contour(polygon1,polygon2):
    for i in range(polygon1.size()):
        if i != polygon1.size() - 1:
            j = i + 1
            point1 = [polygon1[i].x(), polygon1[i].y()]
            point2 = [polygon1[j].x(), polygon1[j].y()]
            for k in range(polygon2.size()):
                if k != polygon2.size() - 1:
                    l = k + 1
                    point3 = [polygon2[k].x(), polygon2[k].y()]
                    point4 = [polygon2[l].x(), polygon2[l].y()]
                    value_ = line_intersection([point1, point2], [point3, point4])
                    if value_ != (9999999, 9999999):
                        return 1

UI

import PyQt5
from PyQt5 import QtCore
import cv2
import numpy as np
import math
from scipy.ndimage.interpolation import rotate
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
import math


polycoords1_main_object=[PyQt5.QtCore.QPointF(1162.12, 302.37), PyQt5.QtCore.QPointF(1141.65, 304.13), PyQt5.QtCore.QPointF(1133.45, 307.05), PyQt5.QtCore.QPointF(1124.1, 315.83), PyQt5.QtCore.QPointF(1116.5, 332.2), PyQt5.QtCore.QPointF(1109.48, 365.54), PyQt5.QtCore.QPointF(1099.53, 396.53), PyQt5.QtCore.QPointF(1096.02, 419.93), PyQt5.QtCore.QPointF(1096.62, 457.94), PyQt5.QtCore.QPointF(1100.7, 464.96), PyQt5.QtCore.QPointF(1110.06, 471.98), PyQt5.QtCore.QPointF(1123.51, 471.4), PyQt5.QtCore.QPointF(1129.36, 467.3), PyQt5.QtCore.QPointF(1137.55, 466.13), PyQt5.QtCore.QPointF(1146.91, 466.72), PyQt5.QtCore.QPointF(1155.1, 470.23), PyQt5.QtCore.QPointF(1163.88, 464.38), PyQt5.QtCore.QPointF(1170.3, 450.93), PyQt5.QtCore.QPointF(1170.89, 431.62), PyQt5.QtCore.QPointF(1165.63, 414.07), PyQt5.QtCore.QPointF(1215.0, 448.0), PyQt5.QtCore.QPointF(1227.0, 443.0), PyQt5.QtCore.QPointF(1249.0, 388.0), PyQt5.QtCore.QPointF(1249.0, 362.0), PyQt5.QtCore.QPointF(1240.0, 336.0), PyQt5.QtCore.QPointF(1234.0, 310.0), PyQt5.QtCore.QPointF(1226.0, 288.0), PyQt5.QtCore.QPointF(1227.0, 275.0), PyQt5.QtCore.QPointF(1220.0, 257.0), PyQt5.QtCore.QPointF(1197.0, 247.0), PyQt5.QtCore.QPointF(1174.0, 249.0), PyQt5.QtCore.QPointF(1168.0, 260.0), PyQt5.QtCore.QPointF(1162.0, 278.0), PyQt5.QtCore.QPointF(1179.0, 273.0), PyQt5.QtCore.QPointF(1161.0, 287.0), PyQt5.QtCore.QPointF(1159.0, 291.0)]
polycoords2_secondary_not_touching=[PyQt5.QtCore.QPointF(1234.0, 395.0), PyQt5.QtCore.QPointF(1228.0, 411.0), PyQt5.QtCore.QPointF(1229.0, 417.0), PyQt5.QtCore.QPointF(1209.0, 408.0), PyQt5.QtCore.QPointF(1212.0, 392.0), PyQt5.QtCore.QPointF(1214.0, 390.0)]
polycoords3_secondary_touching = [PyQt5.QtCore.QPointF(1179.0, 401.0), PyQt5.QtCore.QPointF(1169.0, 407.0), PyQt5.QtCore.QPointF(1157.0, 424.0), PyQt5.QtCore.QPointF(1170.0, 448.0), PyQt5.QtCore.QPointF(1178.0, 446.0), PyQt5.QtCore.QPointF(1184.0, 442.0), PyQt5.QtCore.QPointF(1193.0, 434.0), PyQt5.QtCore.QPointF(1193.0, 421.0), PyQt5.QtCore.QPointF(1189.0, 412.0)]
polycoords4_secondary_touching_barely = [PyQt5.QtCore.QPointF(1116.0, 335.0), PyQt5.QtCore.QPointF(1115.0, 346.0), PyQt5.QtCore.QPointF(1111.0, 355.0), PyQt5.QtCore.QPointF(1107.0, 378.0), PyQt5.QtCore.QPointF(1129.0, 381.0), PyQt5.QtCore.QPointF(1130.0, 375.0), PyQt5.QtCore.QPointF(1139.0, 358.0), PyQt5.QtCore.QPointF(1139.0, 347.0), PyQt5.QtCore.QPointF(1141.0, 341.0), PyQt5.QtCore.QPointF(1141.0, 341.0)]

polygon1_main_object= QPolygonF(polycoords1_main_object)
polygon2_secondary_not_touching=QPolygonF(polycoords2_secondary_not_touching)
polygon3_secondary_touching = QPolygonF(polycoords3_secondary_touching)
polygon4_secondary_touching_barely = QPolygonF(polycoords4_secondary_touching_barely)


def main():
    app = QApplication(sys.argv)



    scene = QGraphicsScene()
    view = QGraphicsView(scene)

    a = check_if_two_polygons_share_contour(polygon1_main_object,polygon2_secondary_not_touching)
    if a == 1:
        print("polygon1_main_object and polygon2 touch")
    else:
        print("polygon1_main_object and polygon2 do not touch")

    a = check_if_two_polygons_share_contour(polygon1_main_object, polygon3_secondary_touching)
    if a == 1:
        print("polygon1_main_object and polygon3 touch")
    else:
        print("polygon1_main_object and polygon3do not touch")

    a = check_if_two_polygons_share_contour(polygon1_main_object, polygon4_secondary_touching_barely)
    if a == 1:
        print("polygon1_main_object and polygon4 touch")
    else:
        print("polygon1_main_object and polygon4  do not touch")



    scene.addPolygon(polygon1_main_object,QPen(QColor(0, 20, 0)))

    scene.addPolygon(polygon2_secondary_not_touching, QPen(QColor(240, 20, 0)))

    scene.addPolygon(polygon3_secondary_touching, QPen(QColor(0, 20, 250)))

    scene.addPolygon(polygon4_secondary_touching_barely, QPen(QColor(0, 250, 8)))





    view.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

musicamante建议的解决方案:

def return_path_from_points(poly_coords_in):
    path = QPainterPath()

    path.moveTo(poly_coords_in[0])
    for points in poly_coords_in:
        path.lineTo(points)
    path.lineTo(poly_coords_in[0])

    return path


def check_if_two_polygons_share_contour(polygon_coords_a,polygon_coords_b):
    path_a = return_path_from_points(polygon_coords_a)
    path_b = return_path_from_points(polygon_coords_b)

    if path_a.intersects(path_b):
        return 1
    else:
        return 0

当然,需要在 UI 文件中编辑 check_if_two_polygons_share_contour 以包含多坐标 iso 多边形check_if_two_polygons_share_contour(polygon1_main_object,polygon2_secondary_not_touching) ---> check_if_two_polygons_share_contour(polycoords1_main_object, polycoords2_secondary_not_touching)

所有情况的输出:

polygon1_main_object and polygon2 touch
polygon1_main_object and polygon3 touch
polygon1_main_object and polygon4 touch

正确的输出:

polygon1_main_object and polygon2 do not touch
polygon1_main_object and polygon3 touch
polygon1_main_object and polygon4 touch

如果您需要验证拦截但not遏制,你必须检查两者;以下内容就足够了:

def check_if_two_polygons_share_contour(p1, p2):
    path1 = QPainterPath()
    path1.addPolygon(p1)
    path2 = QPainterPath()
    path2.addPolygon(p2)
    return path1.intersects(path2) and not (
        path1.contains(path2) or path2.contains(path1))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QPolygons边的交集/获取Qpolygon边上的所有点 的相关文章

  • Python中的三角波形状数组

    生成 100 个数字组成的数组 形成下面三角波的形状 最大 最小幅度为 0 5 的最有效方法是什么 记住三角波形 生成三角波的最简单方法是使用 signal sawtooth 请注意 signal sawtooth phi width 接受
  • WPF 3D 旋转球体 GUI

    我一直在尝试在 WPF 中为我的课堂作业制作 3D 用户界面 但遇到了一个问题 现在 2 3 天都无法解决 我尝试用谷歌搜索答案 我查看了一些 stackoverflow 帖子 但还没有一个可以帮助我解决问题 情况是这样的 我有一个 3D
  • 球体表面上测地线(最短距离路径)之间的交点

    我进行了广泛的搜索 但尚未找到该问题的合适答案 给定球体上的两条线 每条线由起点和终点定义 确定它们是否相交以及相交的位置 我找到了这个网站 http mathforum org library drmath view 62205 html
  • pyqt5不显示窗口[重复]

    这个问题在这里已经有答案了 我真的希望有人能帮助我解决这个问题 我正在尝试开始使用pyqt5 并且几乎从我正在学习的课程中复制了这段代码 代码似乎执行没有任何问题 但我应该看到的窗口根本没有出现 我做错了什么 我正在尝试ubuntu 18顺
  • 基于正方形瓷砖直角三角形象限的坐标系中的边界框

    我正在为游戏创建一个基于图块的 2D 地形系统 然而 我还使用游戏中的坐标 需要能够将边界框映射到 图块坐标 中 并点击边界框接触的每个图块 不用担心 有一个 kd 树和所有工作 美好的 使用定点 真实世界 坐标 我可以将每个图块计为 2
  • 如何在M1 arm64架构上安装PyQt5?

    我有一台 M1 mac 但我注意到 每当本机 python 运行任何自动化脚本 如 PyAutoGui 时 它都会逐渐变得越来越慢 几乎就像受到了限制一样 我用 Miniforge3 创建了一个能够利用 Apple 芯片的环境 使脚本运行得
  • 使用圆点填充圆,使用圆边缘的偏置

    这就是我想要实现的目标 到目前为止 我对我拥有的代码感到满意 这是从 Wolfram 和另一个数学来源借来的 但我不知道如何整合一些偏差计算 或者只是一种分配随机但有组织的内容的方法 有人能指出我正确的方向吗 这是我的代码 它将使用 P5
  • 不均匀圆盘的最佳覆盖

    What kind of algorithm can I use to search for an optimal minimum area covering of a limited region of the XY plane with
  • 如何在QTextEdit中自动滚动文本(动画效果)?

    我想问一下如何让QTextEdit中的文字滚动 达到动画效果 动画效果应该类似于视频中所示的效果 https www youtube com watch v MyeuGdXv4XM https www youtube com watch v
  • 在iOS开发中,使用Core Graphics和/或Quartz 2D,如何绘制一个充满渐变的圆,使其看起来像一个球体?

    到目前为止 我已经研究过使用 CGContextDrawLinearGradient 和 CGContextDrawRadialGradient 但是 对于前者 我无法弄清楚如何使渐变看起来像球体 对于后者 我无法弄清楚如何使渐变成球体形状
  • 查找椭圆或贝塞尔曲线上的等距点

    目前我正在编写 JavaScript 代码 将对象放置在屏幕上的椭圆上 我试图找到能够解决这个问题之一的算法 椭圆将是完美的 但如果它太昂贵 贝塞尔曲线也可以 抱歉 但不幸的是我的数学不允许我使用我找到的答案 https mathoverf
  • 查找二维空间中圆内的所有点

    我表示我的 2D 空间 考虑一个窗口 其中每个像素显示为 2D 数组中的一个单元格 即 100x100 的窗口由相同维度的数组表示 现在给定窗口中的一个点 如果我画一个半径的圆r 我想找到该圆圈中的所有点 我想我应该检查半径周围方形区域中的
  • 在二维空间中从 A 点前往 B 点?

    我正在开发一个项目 需要我计算从可变点 A 到可变点 B 的 0 360 度航向 以使 A 点的物体面向 B 点 现在 我不确定如何实现这一目标 我用谷歌搜索但没有找到任何好的解决方案 在任何情况下 如何计算二维空间中从 A 点到 B 点的
  • 使用 boost 几何检查两条线是否有交点

    是否可以使用 boost geometry 检查两条线段 每条线段由二维中的两个点给出 是否彼此相交 如果可能的话 boost geometry 是否还允许检查特殊情况 例如另一条线上只有一个点 数字上 或者两条线相等 如果你具体谈论Boo
  • 找到两个移动物体的更好交点

    我想极大地优化我的算法之一 我将尽力以最好的方式解释它 主题 我们当时处于二维欧几里德系统中t 0 在这个系统中有两个对象 O1 and O2 O1 and O2分别位于点PA and PC O1移动于常数和已知点方向的速度PB 当物体到达
  • 将坐标插入 MySQL - PolyFromText SQL 语法错误/返回 null

    我正在尝试将多边形的地理坐标插入到我的 MySQL 数据库中 我有一个名为 POLYGON 类型的 Polygon 字段 并且我已尝试运行所有这些查询 但仍然出现 SQL 语法错误 SET g POLYGON 74 135913848876
  • 如何在iphone中画同心圆?

    我想画一个戒指 环应填充在外圆中 我参考了一个文档http developer apple com library mac documentation GraphicsImaging Conceptual drawingwithquartz
  • Postgis安装:类型“几何”不存在

    我正在尝试使用 Postgis 创建表 我按这个做page http postgis refractions net documentation manual 1 5 ch02 html id2619431 但是当我导入 postgis s
  • 如何为 Windows 和 macOS 更新 PyQT5 应用程序?

    我有一个使用 PyQT5 为 Windows 和 macOS 构建的应用程序 目前 用户通过单击按钮检查更新 当有可用的新更新时 我将它们重定向到浏览器到我的服务器以下载最新的 exe Windows 或 pkg macOS 问题在于 如果
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做

随机推荐