微信地图多边形算法及判断点位是否在多边形中

最新一个小项目,需要用到地图定义自由区域,并判断选点是否落在此区域内,思路是通过map的polygons中的points来定义多边形边界,通过polygons的fillColor 、 strokeColor、strokeWidth来进行选区颜色的渲染。 然后再通过地图中心点位的移动来确定需要判断的选点(因为小程序地图目前不支持直接点击地图选点获取座标,只能是触发一个chooseLocation,而我又不想这么麻烦用chooseLocation)

最重要的来了,就是这个点位如何判断是在多边形里面或者外面。。。。。其实这就是一个数学问题,经过我多方参考,判断的数学原理就是:

1、选取目标区域每2个点的y座标y1及y2,如果满足 y1<y <y2 则记为有效边

2、以选取的点为中心做一条直线, 与上述的有效边相交,求交点的x值,如果交点的x值大于选取点的x值 ,则记1, 否则记0, 计数全部加起来 ,如果最终得到的计数是单数,则选取点在区域内,如果是双数,则在区域外

这么说可能不直观,我画几个图:

这个属于所有的点的y值都大于选点的y值,则在区域外,

这个是所有的点的y值都小于选点的y值,也在区域外

这里满足y1<y<y2的 有4条边, 但是满足多边形y值大于选点y值的只有3个, 是奇数,所以选点在多边形区域内

这里满足y1<y<y2的 有4条边,但是满足多边形y值大于选点y值的有4个,是偶数,所以选点在多边形区域外

 

判断的函数代码:

//我这里用的 x 来判断 x1<x<x2  用y来判断相交的点位数  实际上效果一样
//point为选取的点座标, polygon为多边形的点座标数组
function isPointInPolygon (point, polygon) {
	var nCross = 0;
	var n = polygon.length
	
    //遍历多边形每一条线
	for(let i  =0 ;i< n;i++){
			var p1=polygon[i] //定义第一个点的座标
			var p2=polygon[(i+1)%n] //定义下一个点的座标,%n的作用在于让最后一个点的座标与第一个点座标重合
            //如果两点之间与y轴平行,则进行下一轮循环
			if(Number(p1.longitude) == Number(p2.longitude))			
			continue;
            //如果两点之间的x值都大于选取点的x值 ,则进行下一轮循环
			if(Number(point[0]) < Math.min(Number(p1.longitude),Number(p2.longitude)))
			continue;
            //如果两点之间的x值都小于或等于选取点的x值 ,则进行下一轮循环
			if(Number(point[0]) >=Math.max(Number(p1.longitude),Number(p2.longitude)))
      continue;

            //如果x1<x<x2  ,且已知x,则通过两点间直线公式, 算出交点y
            var  y = (Number(point[0]) - Number(p1.longitude)) *(Number(p2.latitude)-Number(p1.latitude)) / (Number(p2.longitude)-Number(p1.longitude))  + (Number(p1.latitude))
              
            //交点y值大于选点y值 则计数
            if (y > Number(point[1]))
			   nCross ++;

	       }
	 
    //遍历完了之后求交点y值大于选点y值的数量奇偶,奇数返回true ,偶数返回false 
	return (nCross%2 === 1)
	
}


接下来调用此函数, 返回true 就说明选点在多边形区域内, 否则就是在之外

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章