微信地圖多邊形算法及判斷點位是否在多邊形中

最新一個小項目,需要用到地圖定義自由區域,並判斷選點是否落在此區域內,思路是通過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 就說明選點在多邊形區域內, 否則就是在之外

 

 

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