如何判断一个点是否在多边形内部?

简介: 如何判断一个点是否在多边形内部?

如何判断一个点是否在多边形内部?

(1)面积和判别法:判断目标点与多边形的每条边组成的三角形面积和是否等于该多边形,相等则在多边形内部。--采纳

(2)夹角和判别法:判断目标点与所有边的夹角和是否为360度,为360度则在多边形内部。

(3)引射线法:从目标点出发引一条射线,看这条射线和多边形所有边的交点数目。如果有奇数个交点,则说明在内部,如果有偶数个交点,则说明在外部。


(4)转角法:按照多边形顶点逆时针顺序,根据顶点和判断点连线的方向正负(设定角度逆时针为正)求和判断;



射线法的实现(转载文章:https://www.jianshu.com/p/ba03c600a557


射线法就是以判断点开始,向右(或向左)的水平方向作一射线,计算该射线与多边形每条边的交点个数,如果交点个数为奇数,则点位于多边形内,偶数则在多边形外。该算法对于复合多边形也能正确判断。




复合多边形的情况



射线法的关键是正确计算射线与每条边是否相交。并且规定线段与射线重叠或者射线经过线段下端点属于不相交。首先排除掉不相交的情况,下图的情况都是需要排除掉的:




求交之前可排除的情况



排除掉这些情况的函数如下:



def isRayIntersectsSegment(poi,s_poi,e_poi): #[x,y] [lng,lat]
    #输入:判断点,边起点,边终点,都是[lng,lat]格式数组
    if s_poi[1]==e_poi[1]: #排除与射线平行、重合,线段首尾端点重合的情况
        return False
    if s_poi[1]>poi[1] and e_poi[1]>poi[1]: #线段在射线上边
        return False
    if s_poi[1]<poi[1] and e_poi[1]<poi[1]: #线段在射线下边
        return False
    if s_poi[1]==poi[1] and e_poi[1]>poi[1]: #交点为下端点,对应spoint
        return False
    if e_poi[1]==poi[1] and s_poi[1]>poi[1]: #交点为下端点,对应epoint
        return False
    if s_poi[0]<poi[0] and e_poi[1]<poi[1]: #线段在射线左边
        return False
    xseg=e_poi[0]-(e_poi[0]-s_poi[0])*(e_poi[1]-poi[1])/(e_poi[1]-s_poi[1]) #求交
    if xseg<poi[0]: #交点在射线起点的左侧
        return False
    return True  #排除上述情况之后

排除掉上述情况真正需要求交点来判断的情况只有两种:





需要求交的两种情况


函数isRayIntersectsSegment()里求交的部分就是利用两个三角形的比例关系求出交点在起点的左边还是右边;用图去理解如下:





求交的具体过程


最后判断的代码如下:


def isPoiWithinPoly(poi,poly):

   #输入:点,多边形三维数组

   #poly=[[[x1,y1],[x2,y2],……,[xn,yn],[x1,y1]],[[w1,t1],……[wk,tk]]] 三维数组

   #可以先判断点是否在外包矩形内

   #if not isPoiWithinBox(poi,mbr=[[0,0],[180,90]]): return False

   #但算最小外包矩形本身需要循环边,会造成开销,本处略去

   sinsc=0 #交点个数

   for epoly in poly: #循环每条边的曲线->each polygon 是二维数组[[x1,y1],…[xn,yn]]

       for i in range(len(epoly)-1): #[0,len-1]

           s_poi=epoly[i]

           e_poi=epoly[i+1]

           if isRayIntersectsSegment(poi,s_poi,e_poi):

               sinsc+=1 #有交点就加1

   return True if sinsc%2==1 else  False

 


相关文章
|
编解码 索引 Python
python--根据任意非网格经纬度坐标,找到均匀网格点上最接近的经纬度坐标
需求:根据非规则经纬度坐标,查找均匀网格点上最接近的经纬度坐标,并提取该点上的变量。
python--根据任意非网格经纬度坐标,找到均匀网格点上最接近的经纬度坐标
|
3月前
|
存储 算法 Java
给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
给定一组棋子的坐标,判断是否可以互相攻击。如果两个棋子的横纵坐标任意一个相同,则认为它们可以互相攻击。(提示:使用哈希表)
19 0
|
3月前
根据经纬度计算两点距离的方法
根据经纬度计算两点距离的方法
|
23天前
|
C++
[C++/PTA] 判断一个点是否在一个圆的内部
[C++/PTA] 判断一个点是否在一个圆的内部
35 0
|
10月前
判断点是否在线段上
判断点是否在线段上
77 0
|
10月前
给定三个顶点的坐标使用程序计算三角形
给定三个顶点的坐标使用程序计算三角形
32 0
|
10月前
射线法——判断一个点是否在多边形内部(适用于凸多边形和凹多边形)【关键原理解释+文字伪代码】
射线法——判断一个点是否在多边形内部(适用于凸多边形和凹多边形)【关键原理解释+文字伪代码】
259 0
|
10月前
|
Java
判断顶点凹凸性、判断多边形的凹凸性、填充凹坑将凹多边形处理为凸多边形【java实现+原理讲解】
判断顶点凹凸性、判断多边形的凹凸性、填充凹坑将凹多边形处理为凸多边形【java实现+原理讲解】
158 0
判断顶点凹凸性、判断多边形的凹凸性、填充凹坑将凹多边形处理为凸多边形【java实现+原理讲解】
|
10月前
|
Java 索引
给定一个多边形的点集——判断所给点集的方向为顺时针方向还是逆时针方向【java实现+原理讲解】
给定一个多边形的点集——判断所给点集的方向为顺时针方向还是逆时针方向【java实现+原理讲解】
151 0
|
C++ 计算机视觉
C++使用opencv判断一个点是否在多边形之内
C++使用opencv判断一个点是否在多边形之内
158 0