如何确定某个点是否在Python中的某个平行四边形内?

时间:2017-11-26 03:13:45

标签: python math geometry

我想知道如何确定两个点d1(920,52.1),d2(920,52)是否在这个橙色平行四边形内部,它由p1~p4组成。

enter image description here

正如您所看到的,平行四边形的基础不是x轴的平行。

是否有任何模块可以解决这类问题?或者我想在这个问题上得到一些数学帮助。

3 个答案:

答案 0 :(得分:2)

对于平行四边形,有一种比一般多边形更简单的方法。以c,a,b的顺序获取三个相邻顶点的坐标,并基于APAB向量表示AC向量 - 系数应在范围0..1中。

请注意,Delphi和Python函数使用不同的参数顺序。在Delphi中,基点(a)先行,然后是邻居(b,c),而Python列表依次包含c,a,b(或b,a,c)点。

德尔福代码:

function PtInPlgm(ax, ay, bx, by, cx, cy, px, py: Integer): Boolean;
var
  xb, yb, xc, yc, xp, yp, d: Integer;
  bb, cc, oned: Double;
begin
  Result := False;
  xb := bx - ax;
  yb := by - ay;
  xc := cx - ax;
  yc := cy - ay;
  xp := px - ax;
  yp := py - ay;
  d := xb * yc - yb * xc;
  if d <> 0 then begin
    oned := 1 / d;
    bb := (xp * yc - xc * yp) * oned;
    cc := (xb * yp - xp * yb) * oned;
    Result := (bb >= 0) and (cc >= 0) and (bb <= 1) and (cc <= 1);
  end;
end;

Literal Python translation

def point_inside_prlgm(x,y,poly):
    inside = False
    xb = poly[0][0] - poly[1][0]
    yb = poly[0][1] - poly[1][1]
    xc = poly[2][0] - poly[1][0]
    yc = poly[2][1] - poly[1][1]
    xp = x - poly[1][0]
    yp = y - poly[1][1]
    d = xb * yc - yb * xc;
    if (d <> 0):
        oned = 1.0 / d;
        bb = (xp * yc - xc * yp) * oned
        cc = (xb * yp - xp * yb) * oned
        inside = (bb >= 0) & (cc >= 0) & (bb <= 1) & (cc <= 1)
    return inside

    print(point_inside_prlgm(1, 1, [[1, 2], [0, 0], [2, 0]]))
    print(point_inside_prlgm(-1, 1, [[2, 1], [0, 0], [2, 0]])) 

答案 1 :(得分:1)

以下解决方案使用针对平行四边形优化的象限步行算法。它是绕组数算法的衍生物。

该算法将测试点P放置在坐标系的中心,并按顺序遍历多边形的顶点,检查“正轴和负轴交叉”。如果轴交叉的数量是4的乘数(但不是0),则P在多边形内。直观地,P在多边形内,如果行走顶点“跨越所有四个半轴”。因此4的乘数。

该算法可以高度优化(特别适合汇编程序实现)和快速运行

这是在Delphi中,使用与MBo的答案中给出的函数 PtInPlgm 相同的参数顺序

function PtInPlgm2( bx, by, ax, ay, cx, cy, px, py: double ): boolean;
var
  Sum    : integer;
  dx, dy : double;

begin
  Sum := 0;
  dx := cx - bx + ax;
  dy := cy - by + ay;
  if ( px < ax ) <> ( px < bx ) then inc( Sum );
  if ( py < ay ) <> ( py < by ) then inc( Sum );
  if ( px < bx ) <> ( px < cx ) then inc( Sum );
  if ( py < by ) <> ( py < cy ) then inc( Sum );
  if ( px < cx ) <> ( px < dx ) then inc( Sum );
  if ( py < cy ) <> ( py < dy ) then inc( Sum );
  if ( px < dx ) <> ( px < ax ) then inc( Sum );
  if ( py < dy ) <> ( py < ay ) then inc( Sum );
  Result := (Sum mod 4 = 0) AND (Sum <> 0);
end;

我相信没关系,我没有提供Python实现

答案 2 :(得分:0)

我尝试使用Shapely,但我读到它的速度很慢。我的程序需要每分钟至少使用100次逻辑,因此我在互联网上查找关键字并找到此页面:http://www.ariel.com.au/a/python-point-int-poly.html

# determine if a point is inside a given polygon or not
# Polygon is a list of (x,y) pairs.

def point_inside_polygon(x,y,poly):

    n = len(poly)
    inside =False

    p1x,p1y = poly[0]
    for i in range(n+1):
        p2x,p2y = poly[i % n]
        if y > min(p1y,p2y):
            if y <= max(p1y,p2y):
                if x <= max(p1x,p2x):
                    if p1y != p2y:
                        xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
                    if p1x == p2x or x <= xinters:
                        inside = not inside
        p1x,p1y = p2x,p2y

    return inside

它工作得足够快,不需要额外的模块。我认为用C语言编写代码并在Python中使用它可能是一个好主意。