Java多邊形重心計(jì)算
多邊形重心計(jì)算
三角形重心
- 頂點(diǎn)為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 : 多邊形自身節(jié)點(diǎn)組成三角形</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);
// 節(jié)點(diǎn)三角形
List<Polygon> sanjiaoxing = polygonCenterPoint.triangleMothed(allPoint);
// 外圍內(nèi)所有三角形
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 計(jì)算重心
* @param wkt
* @return
*/
private double[] polygonGravityPoint(String wkt) {
if (!wkt.startsWith("POLYGON")) {
return null;
}
Operation operation = new Operation();
// 外圍數(shù)據(jù)轉(zhuǎn) 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};
}
/***
* 范圍內(nèi)三角形
* @param waiwei
* @param sanjiaoxing
* @return
*/
private List<Polygon> getRangeTriangle(Polygon waiwei, List<Polygon> sanjiaoxing) {
List<Polygon> triangle = new ArrayList<>();
// 判斷三角形是否在面內(nèi)
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;
}
/***
* 三角形重心計(jì)算
* @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;
}
/***
* 測(cè)試用外包圖形
* @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) {
// 索引 -> 點(diǎn)坐標(biāo)
Map<String, double[]> indexOfPoint = new HashMap();
for (int i = 0; i < allPoint.size(); i++) {
indexOfPoint.put(String.valueOf(i), allPoint.get(i));
}
// 排序結(jié)果
sort((List) indexOfPoint.keySet().stream().collect(Collectors.toList()), new HashSet());
// 刪除元素相同后的集合
// 所有三角形
List<Polygon> allTriangle = new ArrayList();
for (Object oneDataObj : result_p) {
//這一行數(shù)據(jù)
Set oneDataList = (Set) oneDataObj;
// 這一行數(shù)據(jù)的三角形數(shù)據(jù)
List<double[]> trianglePoint = new ArrayList();
oneDataList.forEach(
s -> trianglePoint.add(indexOfPoint.get(s)
));
Polygon triangle = createTriangle(trianglePoint);
if (triangle != null) {
allTriangle.add(triangle);
}
}
// 所有三角形結(jié)束
return allTriangle;
}
/***
* 從點(diǎn)坐標(biāo)集合中創(chuàng)建一個(gè)面
* @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;
}
/***
* 創(chuàng)建三角形
* @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;
}
/***
* 不重復(fù)排列 (元素不相同)
* @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);
}
}
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
基于SpringBoot和Vue3的博客平臺(tái)的用戶注冊(cè)與登錄功能實(shí)現(xiàn)
本教程將指導(dǎo)您如何使用Spring?Boot和Vue3實(shí)現(xiàn)用戶注冊(cè)與登錄功能。我們將使用Spring?Boot作為后端框架,Vue3作為前端框架,同時(shí)使用MySQL作為數(shù)據(jù)庫(kù),感興趣的朋友可以參考一下2023-04-04
JAVA中調(diào)用C語(yǔ)言函數(shù)的實(shí)現(xiàn)方式
這篇文章主要介紹了JAVA中調(diào)用C語(yǔ)言函數(shù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
如何理解Java中基類子對(duì)象的構(gòu)建過(guò)程從"基類向外"進(jìn)行擴(kuò)散的?
今天小編就為大家分享一篇關(guān)于如何理解Java中基類子對(duì)象的構(gòu)建過(guò)程從"基類向外"進(jìn)行擴(kuò)散的?,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04
Java多線程中wait?notify等待喚醒機(jī)制詳解
這篇文章主要介紹了Java多線程中wait?notify等待喚醒機(jī)制,由于線程之間是搶占式執(zhí)行的,因此線程的執(zhí)行順序難以預(yù)知,但是實(shí)際開發(fā)中有時(shí)候我們希望合理的協(xié)調(diào)多個(gè)線程之間的執(zhí)行先后順序,所以這里我們來(lái)介紹下等待喚醒機(jī)制,需要的朋友可以參考下2024-10-10
解決Idea項(xiàng)目結(jié)構(gòu)顯示不全問(wèn)題
文章描述了在使用IntelliJ IDEA時(shí)遇到的問(wèn)題,并提出了解決方法:關(guān)閉IDEA、刪除項(xiàng)目中的.idea文件夾,然后重新打開IDEA導(dǎo)入項(xiàng)目2024-11-11

