Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何知道点是否在QPolygon(PyQt4)的周长上_Python_Pyqt4_Qpolygon - Fatal编程技术网

Python 如何知道点是否在QPolygon(PyQt4)的周长上

Python 如何知道点是否在QPolygon(PyQt4)的周长上,python,pyqt4,qpolygon,Python,Pyqt4,Qpolygon,PyQt4中是否有任何函数可以帮助我确定点是否位于多边形的周长上?例如: from PyQt4 import QtGui from PyQt4.QtCore import Qt, QPoint as QP polygon = QtGui.QPolygon([QP(0, 1), QP(3,7), QP(4, 6), QP(4,3), QP(2,1), QP(0,1]) 如果我将QP(1,3)、QP(4,5)、QP(3,2)或QP(1,1)传递给该函数,则该函数应返回true。这确实是一个困难

PyQt4中是否有任何函数可以帮助我确定点是否位于多边形的周长上?例如:

from PyQt4 import QtGui
from PyQt4.QtCore import Qt, QPoint as QP

polygon = QtGui.QPolygon([QP(0, 1),  QP(3,7), QP(4, 6), QP(4,3), QP(2,1), QP(0,1])

如果我将QP(1,3)、QP(4,5)、QP(3,2)或QP(1,1)传递给该函数,则该函数应返回true。

这确实是一个困难的问题。我用了很多种方法,比如交叉法、联合法、减法法,但都没有成功

例如,我认为这可能有效:复制多边形,将点添加到副本中,然后检查结果是否为空。如果点位于多边形的周长上,则原始和副本应具有相同的形状,因此结果应为空

def on_perimeter(poly, point):
    poly2 = poly + QtGui.QPolygon()  # copy the polygon
    poly2.add(point)
    return poly.subtracted(poly2).isEmpty()
然而,多边形似乎是按照给定的点的顺序“绘制”的,因此,如果只添加点,这将导致其他形状。例如,考虑点<代码>(0,0)(0,2)(2.2)(2,0)< /代码>,它构成正方形,并且要检查<代码>(0,1)< /C>。然后,如果您只在末尾添加点,这将“连接”
(2,0)
(0,1)
(0,1)
(0,0)
因为多边形必须是闭合形式。这会提供一些其他形状。因此,您必须在正确的位置插入点才能获得相同的形状。例如,它将位于
(0,0)
之后。因此我想,好吧,让我们尝试上述所有可能的排列,并且只有一种配置(以及由旋转和反转产生的变换)使减法结果为空

import itertools

def on_perimeter(poly, point):
    points = [point]  # the points of the new polygon
    for ii in range(0, poly.size()):
        points += [poly.point(ii)]

    permuts = list(itertools.permutations(points))  # all possible permutations

    checks = 0
    for permut in permuts:
        checks += int(poly.subtracted(QtGui.QPolygon(list(permut))).isEmpty())

    return checks
但不知何故,这也不起作用。试一下你的例子,我得到了
QP(4,5)
QP(3,2)
checks=10
对于
QP(1,1)
检查=20和
QP(1,3)
检查=0。我所期望的是所有分数都得到
checks=12
(因为它们都位于外围).
12
因为
poly2
6个
点组成,所以你可以旋转
6次
并在你颠倒顺序后做同样的事情因此
12
排列中包含的不同配置导致相同的形状s以另一种方式执行(即
QtGui.QPolygon(list(permut)).subtracted(poly).isEmpty()
)对于每个点,甚至对于不在多边形内但在多边形外的点,我都得到
True

在上述函数中,我使用
united
intersected
而不是
isEmpty
尝试了类似的方法:

tmp = QtGui.QPolygon(list(permut))
checks += int(poly.intersected(tmp) == poly.united(tmp))
同样,如果该点实际位于周界上,则其应仅计算为
True
。但这将返回
False
,几乎我在上述示例中检查的每个点

我没有看一看
QPolygon
方法的源代码(如果有的话),但似乎发生了一些奇怪的事情

因此,我建议您编写一个自己的方法,如果点位于多边形中的一条线上,该方法将计算多边形中的所有直线

def on_perimeter(poly, point):
    lines = []
    for ii in range(1, poly.size()):
        p1 = poly.point(ii-1)
        p2 = poly.point(ii)
        lines += [ ( (p1.x(), p1.y()), (p2.x(), p2.y()) ) ]
    lines += [ ( (poly.last.x(), poly.last.y()), (poly.first.x(), poly.first.y()) ) ]

    for line in lines:
        dx = line[1][0] - line[0][0]
        dy = line[1][1] - line[0][1]

        if abs(dx) > abs(dy) and dx*dy != 0 or dx == 0 and dy == 0:  # abs(slope) < 1 and != 0 thus no point with integer coordinates can lie on this line
            continue

        if dx == 0:
            if point.x() == line[0][0] and (point.y()-line[[0][1])*abs(dy)/dy > 0 and (line[1][1]-point.y())*abs(dy)/dy > 0:
                return True

        if dy == 0:
            if point.y() == line[0][1] and (point.x()-line[[0][0])*abs(dx)/dx > 0 and (line[1][0]-point.x())*abs(dx)/dx > 0:
                return True

        dx2 = point.x() - line[0][0]
        dy2 = point.y() - line[0][1]

        if dx*dx2 < 0 or dy*dy2 < 0:
            continue

        if abs(dx) % abs(dx2) == 0 and abs(dy) % abs(dy2) == 0:
            return True

    return False
def在_周长上(多边形,点):
行=[]
对于范围(1,poly.size())内的ii:
p1=多边形点(ii-1)
p2=多边形点(ii)
行+=[((p1.x(),p1.y()),(p2.x(),p2.y())]
线条+=[((poly.last.x(),poly.last.y()),(poly.first.x(),poly.first.y())]
对于行中的行:
dx=第[1][0]行-第[0][0]行
dy=第[1][1]行-第[0][1]行
如果abs(dx)>abs(dy)和dx*dy!=0或dx==0和dy==0:#abs(slope)<1和!=0,则具有整数坐标的点不能位于这条线上
持续
如果dx==0:
如果点x()==line[0][0]和(point.y()-line[[0][1])*abs(dy)/dy>0和(line[1][1]-point.y())*abs(dy)/dy>0:
返回真值
如果dy==0:
如果点.y()==line[0][1]和(point.x()-line[[0][0])*abs(dx)/dx>0和(line[1][0]-point.x())*abs(dx)/dx>0:
返回真值
dx2=点.x()-线[0][0]
dy2=点.y()-线[0][1]
如果dx*dx2<0或dy*dy2<0:
持续
如果abs(dx)%abs(dx2)==0且abs(dy)%abs(dy2)==0:
返回真值
返回错误

这似乎有点繁重,但必须仅使用整数执行所有计算,因为由于浮点精度的原因,可能会得到错误的结果(
QPolygon
无论如何只接受整数)。虽然还没有测试,但它应该可以工作。

谢谢你的长篇大论。我确实根据绘制绘图时使用的一些缩放比例找到了解决方法。我曾经检查过像你在这里显示的每个点,但是我的绘图细节非常复杂,花费了太长时间。