[幾何]計算不規則多邊形的面積、中心、重心(Android,轉)


轉自:[幾何]計算不規則多邊形的面積、中心、重心

最近項目用到:在不規則多邊形的中心點加一個圖標。(e.g: xx地區發生暴雪,暴雪區域是多邊形,給多邊形中心加一個暴雪的圖標)

之前的設計是,計算不規則多邊形范圍矩形bounds的中心點。這個比較簡單,對於一些圓,矩形,凸多邊形都比較適合。但是遇到凹多邊形就會出現問題,比如一個月牙型的不規則多邊形,bounds的中心點,就落到月牙外了。就有點難以接受了。

經過討論,決定將中心改為重心。

 

下面上代碼,

計算不規則多邊形的中心:

 

[java]  view plain  copy
 
 print?
  1. public static final double MIN_LAT = -90;  
  2. public static final double MAX_LAT = 90;  
  3. public static final double MIN_LNG = -180;  
  4. public static final double MAX_LNG = 180;  
  5.   
  6. /** 
  7.  * 獲取不規則多邊形幾何中心點 
  8.  * 
  9.  * @param mPoints 
  10.  * @return 
  11.  */  
  12. public static LatLng getCenterPoint(List<LatLng> mPoints) {  
  13.     // 1 自己計算  
  14.     // double latitude = (getMinLatitude(mPoints) + getMaxLatitude(mPoints)) / 2;  
  15.     // double longitude = (getMinLongitude(mPoints) + getMaxLongitude(mPoints)) / 2;  
  16.     // return new LatLng(latitude, longitude);  
  17.     // 2 使用Google map API提供的方法(推薦)  
  18.     LatLngBounds.Builder boundsBuilder = LatLngBounds.builder();  
  19.     for (LatLng ll : mPoints)  
  20.         boundsBuilder.include(ll);  
  21.     return boundsBuilder.build().getCenter();  
  22. }  
  23.   
  24. // 經度最小值  
  25. public static double getMinLongitude(List<LatLng> mPoints) {  
  26.     double minLongitude = MAX_LNG;  
  27.     if (mPoints.size() > 0) {  
  28.         minLongitude = mPoints.get(0).longitude;  
  29.         for (LatLng latlng : mPoints) {  
  30.             // 經度最小值  
  31.             if (latlng.longitude < minLongitude)  
  32.                 minLongitude = latlng.longitude;  
  33.         }  
  34.     }  
  35.     return minLongitude;  
  36. }  
  37.   
  38. // 經度最大值  
  39. public static double getMaxLongitude(List<LatLng> mPoints) {  
  40.     double maxLongitude = MIN_LNG;  
  41.     if (mPoints.size() > 0) {  
  42.         maxLongitude = mPoints.get(0).longitude;  
  43.         for (LatLng latlng : mPoints) {  
  44.             // 經度最大值  
  45.             if (latlng.longitude > maxLongitude)  
  46.                 maxLongitude = latlng.longitude;  
  47.         }  
  48.     }  
  49.     return maxLongitude;  
  50. }  
  51.   
  52. // 緯度最小值  
  53. public static double getMinLatitude(List<LatLng> mPoints) {  
  54.     double minLatitude = MAX_LAT;  
  55.     if (mPoints.size() > 0) {  
  56.         minLatitude = mPoints.get(0).latitude;  
  57.         for (LatLng latlng : mPoints) {  
  58.             // 緯度最小值  
  59.             if (latlng.latitude < minLatitude)  
  60.                 minLatitude = latlng.latitude;  
  61.         }  
  62.     }  
  63.     return minLatitude;  
  64. }  
  65.   
  66. // 緯度最大值  
  67. public static double getMaxLatitude(List<LatLng> mPoints) {  
  68.     double maxLatitude = MIN_LAT;  
  69.     if (mPoints.size() > 0) {  
  70.         maxLatitude = mPoints.get(0).latitude;  
  71.         for (LatLng latlng : mPoints) {  
  72.             // 緯度最大值  
  73.             if (latlng.latitude > maxLatitude)  
  74.                 maxLatitude = latlng.latitude;  
  75.         }  
  76.     }  
  77.     return maxLatitude;  
  78. }  

 

計算不規則多邊形的重心:

 

[java]  view plain  copy
 
 print?
  1. /** 
  2.  * 獲取不規則多邊形重心點 
  3.  * 
  4.  * @param mPoints 
  5.  * @return 
  6.  */  
  7. public static LatLng getCenterOfGravityPoint(List<LatLng> mPoints) {  
  8.     double area = 0.0;//多邊形面積  
  9.     double Gx = 0.0, Gy = 0.0;// 重心的x、y  
  10.     for (int i = 1; i <= mPoints.size(); i++) {  
  11.         double iLat = mPoints.get(i % mPoints.size()).latitude;  
  12.         double iLng = mPoints.get(i % mPoints.size()).longitude;  
  13.         double nextLat = mPoints.get(i - 1).latitude;  
  14.         double nextLng = mPoints.get(i - 1).longitude;  
  15.         double temp = (iLat * nextLng - iLng * nextLat) / 2.0;  
  16.         area += temp;  
  17.         Gx += temp * (iLat + nextLat) / 3.0;  
  18.         Gy += temp * (iLng + nextLng) / 3.0;  
  19.     }  
  20.     Gx = Gx / area;  
  21.     Gy = Gy / area;  
  22.     return new LatLng(Gx, Gy);  
  23. }  

 

其中LatLng類就是一個包含經緯度點的簡單類。可以自己創建一個包含 x ,y 的類代替。

 

[java]  view plain  copy
 
 print?
  1. public final double latitude;  
  2. public final double longitude;  

 

通過這張圖,就可以發現中心和重心的區別了

 

 

     


免責聲明!

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



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