1. 程式人生 > 實用技巧 >判斷一點是否在多邊形內/判斷是否在圍欄內

判斷一點是否在多邊形內/判斷是否在圍欄內

引射線法:從目標點出發引一條射線,看這條射線和多邊形所有邊的交點數射線法
時間複雜度:O(n) 適用範圍:任意多邊形
個人認為是非常不錯的演算法(不需考慮精度誤差和多邊形點給出的順序),可以作為第一選擇。

演算法思想:
以被測點Q為端點,向任意方向作射線(一般水平向右作射線),統計該射線與多邊形的交點數。如果為奇數,Q在多邊形內;如果為偶數,Q在多邊形外。計數的時候會有一些特殊情況,如圖

封裝一個PointUtil裡面用 boolean判斷

/**
  * 判斷一點是否在多邊形內
  *
  * @param target
  * @param points
  * @return
  */
 public
static boolean isPointInPolygon(LatLonPoint target, LatLonPoint[] points) { int iSum, iCount, iIndex; double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon; if (points.length < 3) { return false; } iSum = 0; iCount = points.length; for (iIndex = 0; iIndex<iCount;iIndex++) {
if (iIndex == iCount - 1) { dLon1 = points[iIndex].getLongitude(); dLat1 = points[iIndex].getLatitude(); dLon2 = points[0].getLongitude(); dLat2 = points[0].getLatitude(); } else { dLon1 = points[iIndex].getLongitude(); dLat1
= points[iIndex].getLatitude(); dLon2 = points[iIndex + 1].getLongitude(); dLat2 = points[iIndex + 1].getLatitude(); } double ALat = target.getLatitude(); double ALon = target.getLongitude(); // 以下語句判斷A點是否在邊的兩端點的水平平行線之間,在則可能有交點,開始判斷交點是否在左射線上 if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) { if (Math.abs(dLat1 - dLat2) > 0) { //得到 A點向左射線與邊的交點的x座標: dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat) ) / (dLat1 - dLat2); // 如果交點在A點左側(說明是做射線與 邊的交點),則射線與邊的全部交點數加一: if (dLon < ALon) { iSum++; } } } } return (iSum % 2) != 0; }