Java多边形重心计算

多边形重心计算

三角形重心

  • 顶点为a,b,c的三角形重心为x = (xa + xb + xc) / 3,y = (ya + yb + yc) / 3

多边形重心

  • x = (x1w1 + x2w2 + … + xnwn)/W
  • y = (y1w1 + y2w2 + … + ynwn)/W
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>Title : PolygonNodeTriangle </p>
 * <p>Description : 多边形自身节点组成三角形</p>
 * @author huifer
 * @date 2018/10/15
 */
public class PolygonNodeTriangle {
  private int NUM = 3;
  private Set result_p = new HashSet();
  public static void main(String[] args) {
    //0
    double[] point1 = new double[]{0, 0};
    //1
    double[] point2 = new double[]{10, 0};
    //2
    double[] point3 = new double[]{20, 0};
    //3
    double[] point4 = new double[]{10, 10};
    List<double[]> allPoint = new ArrayList();
    allPoint.add(point1);
    allPoint.add(point3);
    allPoint.add(point4);
    PolygonNodeTriangle polygonCenterPoint = new PolygonNodeTriangle();
    // 外围
    Polygon waiwei = polygonCenterPoint.waiwei(point1, point3, point4);
    // 节点三角形
    List<Polygon> sanjiaoxing = polygonCenterPoint.triangleMothed(allPoint);
    // 外围内所有三角形
    List<Polygon> rangeTriangle = polygonCenterPoint.getRangeTriangle(waiwei, sanjiaoxing);
    // 重心xy
    double[] gravityCenterXY = polygonCenterPoint.getGravityCenterXY(rangeTriangle);
    System.out.println(rangeTriangle.size());
    System.out.println("================================================");
    double[] doubles = polygonCenterPoint. polygonGravityPoint("POLYGON((0 0, 20 0, 10 10, 0 0))");
  }
  /***
   * polygon wkt 计算重心
   * @param wkt
   * @return
   */
  private double[] polygonGravityPoint(String wkt) {

    if (!wkt.startsWith("POLYGON")) {
      return null;
    }
    Operation operation = new Operation();
    // 外围数据转 list<double[]>
    Polygon waiwei = null;
    try {
      waiwei = operation.createPolygonByWKT(wkt);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    Coordinate[] coordinates = waiwei.getCoordinates();
    List<double[]> allP = new ArrayList<>();
    Arrays.stream(coordinates).forEach(
        s -> {
          double nowX = s.x;
          double nowY = s.y;
          allP.add(new double[]{nowX, nowY});
        }
    );
    List<Polygon> polygons = triangleMothed(allP);
    List<Polygon> rangeTriangle1 = getRangeTriangle(waiwei, polygons);
    double area = waiwei.getArea();
    double[] gravityCenterXY1 = getGravityCenterXY(rangeTriangle1);
    return gravityCenterXY1;
  }
  /***
   * 重心值
   * @param rangeTriangle
   * @return [x, y]
   */
  private double[] getGravityCenterXY(List<Polygon> rangeTriangle) {
    double xArea = 0.0;
    double yArea = 0.0;
    double aArea = 0.0;
    for (Polygon triangle : rangeTriangle) {
      Coordinate[] coordinates = triangle.getCoordinates();
      double area = triangle.getArea();
      double[] oneGR = triangleCenterOfGravity(coordinates[0], coordinates[1], coordinates[2]);
      xArea += oneGR[0] * area;
      yArea += oneGR[1] * area;
      aArea += area;
    }
    System.out.println("重心X " + xArea / aArea);
    System.out.println("重心Y " + yArea / aArea);
    return new double[]{xArea / aArea, yArea / aArea};
  }
  /***
   * 范围内三角形
   * @param waiwei
   * @param sanjiaoxing
   * @return
   */
  private List<Polygon> getRangeTriangle(Polygon waiwei, List<Polygon> sanjiaoxing) {
    List<Polygon> triangle = new ArrayList<>();
    // 判断三角形是否在面内
    for (int i = 0; i < sanjiaoxing.size(); i++) {
      Polygon polygon = sanjiaoxing.get(i);
      boolean within = polygon.within(waiwei);
      if (within) {
        triangle.add(polygon);
      }
    }
    return triangle;
  }
  /***
   * 三角形重心计算
   * @param a
   * @param b
   * @param c
   * @return
   */
  private double[] triangleCenterOfGravity(Coordinate a, Coordinate b, Coordinate c) {
    double gravityX = (a.x + b.x + c.x) / 3;
    double gravityY = (a.y + b.y + c.y) / 3;
    double[] result = new double[]{gravityX, gravityY};
    return result;
  }
  /***
   * 测试用外包图形
   * @return
   */
  private Polygon waiwei(double[] point1, double[] point3, double[] point4) {
    List<double[]> ceshimian = new ArrayList();
    ceshimian.add(point1);
//    ceshimian.add(point2);
//    ceshimian.add(point7);
    ceshimian.add(point4);
//    ceshimian.add(point6);
//    ceshimian.add(point5);
    ceshimian.add(point3);
    String polygonForList = createPolygonForList(ceshimian);
    Operation op = new Operation();
    Polygon polygonByWKT = null;
    try {
      polygonByWKT = op.createPolygonByWKT(polygonForList);
      return polygonByWKT;
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return null;
  }
  /***
   * 生成所有三角形
   * @param allPoint
   * @return
   */
  private List<Polygon> triangleMothed(List<double[]> allPoint) {
    // 索引 -> 点坐标
    Map<String, double[]> indexOfPoint = new HashMap();
    for (int i = 0; i < allPoint.size(); i++) {
      indexOfPoint.put(String.valueOf(i), allPoint.get(i));
    }
    // 排序结果
    sort((List) indexOfPoint.keySet().stream().collect(Collectors.toList()), new HashSet());
    // 删除元素相同后的集合
    // 所有三角形
    List<Polygon> allTriangle = new ArrayList();
    for (Object oneDataObj : result_p) {
      //这一行数据
      Set oneDataList = (Set) oneDataObj;
      // 这一行数据的三角形数据
      List<double[]> trianglePoint = new ArrayList();
      oneDataList.forEach(
          s -> trianglePoint.add(indexOfPoint.get(s)
          ));
      Polygon triangle = createTriangle(trianglePoint);
      if (triangle != null) {
        allTriangle.add(triangle);
      }
    }
    // 所有三角形结束
    return allTriangle;
  }
  /***
   * 从点坐标集合中创建一个面
   * @param points
   * @return
   */
  private static String createPolygonForList(List<double[]> points) {
    String end = "))";
    String res = "POLYGON((";
    Operation op = new Operation();
    for (double[] point : points) {
      String x = Double.toString(point[0]);
      String y = Double.toString(point[1]);
      res += x + " " + y + ", ";
    }
    res += Double.toString(points.get(0)[0]) + " " + Double.toString(points.get(0)[1]);
    res += end;
    try {
      op.createPolygonByWKT(res);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return res;
  }
  /***
   * 创建三角形
   * @param trianglePoint
   * @return polygon
   */
  private static Polygon createTriangle(List<double[]> trianglePoint) {
    Operation op = new Operation();
    String triangleWkt;
    boolean isTri = isTriangle(trianglePoint);
    if (isTri) {
      triangleWkt = "POLYGON((" + trianglePoint.get(0)[0] + " " + trianglePoint.get(0)[1] + ", " + trianglePoint.get(1)[0] + " " + trianglePoint.get(1)[1] + ", " + trianglePoint.get(2)[0] + " " + trianglePoint.get(2)[1] + ", " + trianglePoint.get(0)[0] + " " + trianglePoint.get(0)[1] + "))";
      try {
        Polygon polygonByWKT = op.createPolygonByWKT(triangleWkt);
        return polygonByWKT;
//        return triangleWkt;
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return null;
  }
  /***
   * 判断三角形
   * @param trianglePoint
   * @return
   */
  private static boolean isTriangle(List<double[]> trianglePoint) {
    double[] doubles = trianglePoint.get(0);
    double[] doubles1 = trianglePoint.get(1);
    double[] doubles2 = trianglePoint.get(2);
    double len = Math.sqrt(Math.pow(doubles[0] - doubles1[0], 2) + Math.pow(doubles[1] - doubles1[1], 2));
    double len1 = Math.sqrt(Math.pow(doubles[0] - doubles2[0], 2) + Math.pow(doubles[1] - doubles2[1], 2));
    double len2 = Math.sqrt(Math.pow(doubles1[0] - doubles2[0], 2) + Math.pow(doubles1[1] - doubles2[1], 2));
    if ((len + len1 > len2) && (len + len2 > len1) && (len1 + len2 > len)) {
      return true;
    }
    return false;
  }
  /***
   * 不重复排列 (元素不相同)
   * @param datas
   * @param target
   */
  private void sort(List datas, Set target) {
    if (target.size() == this.NUM) {
      this.result_p.add(target);
      return;
    }
    for (int i = 0; i < datas.size(); i++) {
      List newDatas = new ArrayList(datas);
      Set newTarget = new HashSet(target);
      newTarget.add(newDatas.get(i));
      newDatas.remove(i);
      sort(newDatas, newTarget);
    }
  }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Java计算器核心算法代码实现

    在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现.(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢谢啦) 我将这部分分成三个方法完成功能,并在getResult方法调用(getResult方法被主方法调用) private String getResult(String str) { //分割 String[] Str

  • java实现多线程卖票功能

    java多线程卖票直接先看个例子: public class SelTicketsMainTest { public static void main(String[] args) { SaleTickets1 saleTickets = new SaleTickets1(); for(int t=1;t<=3;t++) { new Thread(saleTickets).start(); } } } class SaleTickets1 implements Runnable{ private

  • 基于java计算买卖股票的最佳时机

    这篇文章主要介绍了基于java计算买卖股票的最佳时机,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 问题: 可以将问题转化为如下图所示,即求多个累计的收入差 分析: 如果当前位置i的价格比i+1的价格高,则当前不是买入点,则继续判断下一个位置, 如果当前位置i的价格比i+1的价格低,并且i+1仍比i+1+1低,则在当前位置买入,知道i+n比i+n+1大时,卖出. 继续下一轮判断 package com.example.demo; public

  • java计算图两点之间的所有路径

    本文实例为大家分享了java计算图两点之间的所有路径的具体代码,供大家参考,具体内容如下 1.给定图如下: 2.求0到3之间可达的所有路径 这里问题就是关于搜索遍历的问题,但其中需要注意到不能产生回路或环. 算法描述如下: top_node:当前栈顶元素 adjvex_node;当前top_node已经访问的邻接点 next_node:即将访问的元素(top_node的第adjvex_node个邻接点所对应的元素) 找出所有路径采用的是遍历的方法,以"深度优先"算法为基础.从源点出发,

  • java外卖订餐系统小项目

    本文实例为大家分享了java外卖订餐系统的具体代码,供大家参考,具体内容如下 执行结果: 通过选择功能序号,执行响应的功能: 代码实现: package 外卖订餐系统; /* * 代码优点,使用 循环: * 显示菜单, * 根据用户选择的数字执行相应功能(功能实现:do..while循环.) */ import java.util.Scanner; public class OrderingMsg { public static void main(String[] args) { //数据主题

  • 逆波兰计算器(Java实现)

    之前的一篇博客中,讲的是用栈实现了中缀表达式的简易计算器,对于我们人来讲,中缀表达式是一种比较直观,而且非常好计算的一种形式,但对于计算器来讲,非常的难去看懂.所以,下面我讲下逆波兰计算器的Java实现. 逆波兰式(后缀表达式) 逆波兰表达式又叫做后缀表达式.逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法 [1]  .后来,人们就把用这种表示法写出的表达式称作"逆波兰表达式".逆波兰表达式把运算量写在前面,把算符写在后面

  • Java通过卖票理解多线程

    以卖票的例子来介绍多线程和资源共享,下面我们来看看为什么要用卖票作为例子. 卖票是包含一系列动作的过程,有各种操作,例如查询票.收钱.数钱.出票等,其中有一个操作是每次卖掉一张,就将总的票数减去1.有10张票,如果一个人卖票,先做查票.收钱.数钱等各种操作,再将总的票数减去1,效率很低.如果多个人卖票,每个人都是做同样的操作,数钱.检查钱,最后将总的票数减1,这样效率高.但是有一个问题,如果出现两个人同时将总的票数减掉了1,例如,A.B两个人同时读取到票的总数是10,A从中减去1,同时B也从中减

  • Java多边形重心计算

    多边形重心计算 三角形重心 顶点为a,b,c的三角形重心为x = (xa + xb + xc) / 3,y = (ya + yb + yc) / 3 多边形重心 x = (x1w1 + x2w2 + - + xnwn)/W y = (y1w1 + y2w2 + - + ynwn)/W import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Polygon; import org.locationt

  • 三行Java代码实现计算多边形的几何中心点

    目录 前言 示例代码 前言 因为工作设计到gis相关的内容,需要计算采煤机工作面的中心点.如果套用数学的计算公式,用java去实现,太多麻烦还费时比较久,于是我找到java几何计算的工具包,几行代码就能求出多变形的中心,简直yyds!!! 废话不多说直接上代码,然后再慢慢讲解 示例代码 首先再maven项目的pom文件中引入依赖 <properties> <java.version>1.8</java.version> <maven.plugin.version&

  • Java编程实现计算两个日期的月份差实例代码

    本文实例主要实现计算两个日期的月份差,具体如下: package com.forezp.util; import org.joda.time.DateTime; import org.joda.time.Months; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * 在JAVA中,如何计算两个日期的月份差?<br> * * * @author Adm

  • Java实现的计算最大下标距离算法示例

    本文实例讲述了Java实现的计算最大下标距离算法.分享给大家供大家参考,具体如下: 题目描述 给定一个整形数组,找出最大下标距离j−i, 当且A[i] < A[j] 和 i < j 解法 复杂度:三次扫描,每次的复杂度O(N) 算法:{5,3,4,0,1,4,1} 找出从第一个元素开始的下降序列{5,3,0} i=3,j=6, j从尾部扫描 初始化,i=3, j=6, A[i]=0 实现代码 public static int maxindexdistance(int A[]) { boole

  • Java实现的计算稀疏矩阵余弦相似度示例

    本文实例讲述了Java实现的计算稀疏矩阵余弦相似度功能.分享给大家供大家参考,具体如下: import java.util.HashMap; public class MyUDF{ /** * UDF Evaluate接口 * * UDF在记录层面上是一对一,字段上是一对一或多对一. Evaluate方法在每条记录上被调用一次,输入为一个或多个字段,输出为一个字段 */ public Double evaluate(String a, String b) { // TODO: 请按需要修改参数和

  • JAVA 根据身份证计算年龄的实现代码

    下面一段代码给大家分享java根据身份证计算年龄的方法,具体代码如下所示: birthDate = idCard.substring(6,10)+"-"+idCard.substring(10,12)+"-"+idCard.substring(12,14) public static int getAgefromBirthTime(String birthTimeString){ // 先截取到字符串中的年.月.日 String strs[] = birthTime

  • Java滚动数组计算编辑距离操作示例

    本文实例讲述了Java滚动数组计算编辑距离操作.分享给大家供大家参考,具体如下: 编辑距离(Edit Distance),也称Levenshtein距离,是指由一个字符串转换为另一个字符串所需的最少编辑次数. 下面的代码摘自org.apache.commons.lang.StringUtils 用法示例: StringUtils.getLevenshteinDistance(null, *) = IllegalArgumentException StringUtils.getLevenshtei

  • Java介绍多线程计算阶乘实现方法

    代码运行结果如下: 输入n的值之后,就可以点击开始计算,计算过程中可以暂停计算,也可以停止计算 这是几种线程的操作: 1.sleep方法,线程按时间睡眠,到时间恢复. 2.suspend/resume,暂停/继续方法.Java多线程废弃方法.资源独占,容易发生死锁,脏数据. 3.stop,停止方法,Java多线程废弃方法,线程不安全. 4.wait方法,使得当前线程立刻停止运行,处于等待状态(WAIT),并将当前线程置入锁对象的等待队列中,直到被通知(notify)或被中断为止. 5.notif

  • 利用Java中Calendar计算两个日期之间的天数和周数

    前言 究竟什么是一个 Calendar 呢?中文的翻译就是日历,那我们立刻可以想到我们生活中有阳(公)历.阴(农)历之分.它们的区别在哪呢? 比如有: 月份的定义 - 阳`(公)历 一年12 个月,每个月的天数各不同:阴(农)历,每个月固定28天 每周的第一天 - 阳(公)历星期日是第一天:阴(农)历,星期一是第一天 实际上,在历史上有着许多种纪元的方法.它们的差异实在太大了,比如说一个人的生日是"八月八日" 那么一种可能是阳(公)历的八月八日,但也可以是阴(农)历的日期.所以为了计时

  • Java小程序计算圆周率代码

    下面我们来介绍两种Java编程中实现计算圆周率的方法. 方法一:割圆法 计算公式为: π≈3*2^n*y_n 其中,n代表割圆次数,y_n代表圆中内嵌正6*n边形的边长 package 计算π的近似值; import java.util.Scanner; public class Example { public static void main(String[] args) { Scanner scan=new Scanner(System.in); System.out.println("请

随机推荐