• [几何]计算不规则多边形的面积、中心、重心(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;  
    通过这张图,就可以发现中心和重心的区别了

         

  • 相关阅读:
    熟悉常用的HBase操作,编写MapReduce作业
    爬虫大作业
    熟悉常用的HDFS操作
    数据结构化与保存
    获取全部校园新闻
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    leetcode
    归并排序
    选择排序法
  • 原文地址:https://www.cnblogs.com/weizhxa/p/8029752.html
Copyright © 2020-2023  润新知