百度地圖判斷點是否在多邊形內


jsapi里有如何判斷點是否在多邊形內的例子,但是這個項目根據實際需要,需要在后台來判斷,點是否在多邊形中,但是在百度地圖web服務api中沒有相關的方法,

只有百度其他的了:主要看來數學要不錯才行啊。親測可用。我用的第二種方法:

具體解法:

要判斷點是否在多邊形的內部,適用於任意多邊形的方法最常用的就是射線法,即以要判斷的點向左或者向右作水平射線,與多邊形交點的個數為奇數個時則在多邊形的內部,若為偶數個交點時則在多邊形的外部,其中0個交點也為偶數個交點。

依據該原理,於是有了第一種實現:

/// <summary>  
       /// 判斷點是否在多邊形內.  
       /// ----------原理----------  
       /// 注意到如果從P作水平向左的射線的話,如果P在多邊形內部,那么這條射線與多邊形的交點必為奇數,  
       /// 如果P在多邊形外部,則交點個數必為偶數(0也在內)。  
       /// 所以,我們可以順序考慮多邊形的每條邊,求出交點的總個數。還有一些特殊情況要考慮。假如考慮邊(P1,P2),  
       /// 1)如果射線正好穿過P1或者P2,那么這個交點會被算作2次,處理辦法是如果P的從坐標與P1,P2中較小的縱坐標相同,則直接忽略這種情況  
       /// 2)如果射線水平,則射線要么與其無交點,要么有無數個,這種情況也直接忽略。  
       /// 3)如果射線豎直,而P0的橫坐標小於P1,P2的橫坐標,則必然相交。  
       /// 4)再判斷相交之前,先判斷P是否在邊(P1,P2)的上面,如果在,則直接得出結論:P再多邊形內部。  
       /// </summary>  
       /// <param name="checkPoint">要判斷的點</param>  
       /// <param name="polygonPoints">多邊形的頂點</param>  
       /// <returns></returns>  
       public static bool IsInPolygon2(PointF checkPoint, List<PointF> polygonPoints)  
       {  
           int counter = 0;  
           int i;  
           double xinters;  
           PointF p1, p2;  
           int pointCount = polygonPoints.Count;  
           p1 = polygonPoints[0];  
           for (i = 1; i <= pointCount; i++)  
           {  
               p2 = polygonPoints[i % pointCount];  
               if (checkPoint.Y > Math.Min(p1.Y, p2.Y)//校驗點的Y大於線段端點的最小Y  
                   && checkPoint.Y <= Math.Max(p1.Y, p2.Y))//校驗點的Y小於線段端點的最大Y  
               {  
                   if (checkPoint.X <= Math.Max(p1.X, p2.X))//校驗點的X小於等線段端點的最大X(使用校驗點的左射線判斷).  
                   {  
                       if (p1.Y != p2.Y)//線段不平行於X軸  
                       {  
                           xinters = (checkPoint.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;  
                           if (p1.X == p2.X || checkPoint.X <= xinters)  
                           {  
                               counter++;  
                           }  
                       }  
                   }  
  
               }  
               p1 = p2;  
           }  
  
           if (counter % 2 == 0)  
           {  
               return false;  
           }  
           else  
           {  
               return true;  
           }  
       }  

  由於上述的方法中關鍵的判斷在於xinters = (checkPoint.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X,這里使用了除法,一般而言除法的速度會低於乘法,特別是當除法是浮點數的時候,那能否改用乘法來實現呢?答案是可以的,只要進行一定的變換就可以實現。下面是第二種實現方法。

/// <summary>  
       /// 判斷點是否在多邊形內.  
       /// ----------原理----------  
       /// 注意到如果從P作水平向左的射線的話,如果P在多邊形內部,那么這條射線與多邊形的交點必為奇數,  
       /// 如果P在多邊形外部,則交點個數必為偶數(0也在內)。  
       /// </summary>  
       /// <param name="checkPoint">要判斷的點</param>  
       /// <param name="polygonPoints">多邊形的頂點</param>  
       /// <returns></returns>  
       public static bool IsInPolygon(PointF checkPoint, List<PointF> polygonPoints)  
       {  
           bool inside = false;  
           int pointCount = polygonPoints.Count;  
           PointF p1, p2;  
           for (int i = 0, j = pointCount - 1; i < pointCount; j = i, i++)//第一個點和最后一個點作為第一條線,之后是第一個點和第二個點作為第二條線,之后是第二個點與第三個點,第三個點與第四個點...  
           {  
               p1 = polygonPoints[i];  
               p2 = polygonPoints[j];  
               if (checkPoint.Y < p2.Y)  
               {//p2在射線之上  
                   if (p1.Y <= checkPoint.Y)  
                   {//p1正好在射線中或者射線下方  
                       if ((checkPoint.Y - p1.Y) * (p2.X - p1.X) > (checkPoint.X - p1.X) * (p2.Y - p1.Y))//斜率判斷,在P1和P2之間且在P1P2右側  
                       {  
                           //射線與多邊形交點為奇數時則在多邊形之內,若為偶數個交點時則在多邊形之外。  
                           //由於inside初始值為false,即交點數為零。所以當有第一個交點時,則必為奇數,則在內部,此時為inside=(!inside)  
                           //所以當有第二個交點時,則必為偶數,則在外部,此時為inside=(!inside)  
                           inside = (!inside);  
                       }  
                   }  
               }  
               else if (checkPoint.Y < p1.Y)  
               {  
                   //p2正好在射線中或者在射線下方,p1在射線上  
                   if ((checkPoint.Y - p1.Y) * (p2.X - p1.X) < (checkPoint.X - p1.X) * (p2.Y - p1.Y))//斜率判斷,在P1和P2之間且在P1P2右側  
                   {  
                       inside = (!inside);  
                   }  
               }  
           }  
           return inside;  
       }  

  這里還使用一個隱含的知識,即頂點在射線之上。該方法摘自於《計算機圖形學幾何工具算法詳解》。運行結果如下圖:

摘自:https://blog.csdn.net/xxdddail/article/details/49093635

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM