[几何]计算不规则多边形的面积、中心、重心

最近项目用到:在不规则多边形的中心点加一个图标。(e.g: xx地区发生暴雪,暴雪区域是多边形,给多边形中心加一个暴雪的图标)

之前的设计是,计算不规则多边形范围矩形bounds的中心点。这个比较简单,对于一些圆,矩形,凸多边形都比较适合。但是遇到凹多边形就会出现问题,比如一个月牙型的不规则多边形,bounds的中心点,就落到月牙外了。就有点难以接受了。

经过讨论,决定将中心改为重心。


下面上代码,

计算不规则多边形的中心:

[java] view plain copy
  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
  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
  1. public final double latitude;  
  2. public final double longitude;  

通过这张图,就可以发现中心和重心的区别了

     

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值