我想从GeoTools镶嵌国家形状,在地球表面上以3D显示。 GeoTools使用内部功能丰富的JTS拓扑套件。
是否包含镶嵌某些形状的实用程序?我看到有三角测量包,但无法弄清楚,如何将它用于带孔的形状。
此外,我不仅可以像现在这样连接现有的顶点
它应该填充内部有多个顶点的形状。
更新
我发现,JTS包含类ConformingDelaunayTriangulationBuilder
,它允许以某种方式制作希望的镶嵌,但它的工作很糟糕。首先,它只允许约束,这意味着需要额外的代码来从凹陷区域中删除三角形。并且它还试图保留细分的Delaunay性质,这导致创建许多其他部分。
最后,它导致ConstraintEnforcementException
复杂的形状,如国家和无法使用。
我还找到"triangle" package,用C语言编写并实现Chew's second algorithm并且效果很好
现在我想知道,它是移植到Java还是包含在其中?
答案 0 :(得分:1)
我知道这篇文章相对较旧,但我最近遇到了同样的情况,需要一些Java库或类似的工具来对一些复杂的多边形进行三角测量(因为我想在OpenGL上显示它们,它只能将三角形绘制为基本操作)
经过一番搜索和测试后,适合我的图书馆来自Orbgis的 Poly2Tri 。您可以从Maven here * 获取该库。
这个库有许多功能,包括带孔的多边形,用于优化三角测量的Steiner点以及其他功能。基本用法示例如下(基于链接仓库的示例):
//Create the polygon passing a List of PolygonPoints
Polygon polygon = new Polygon(
Arrays.asList(
new PolygonPoint(0, 0, 0),
new PolygonPoint(10, 0, 1),
new PolygonPoint(10, 10, 2),
new PolygonPoint(0, 10, 3)));
//Here you could add holes as needed, passing them as Polygons
polygon.addHole(someHoleYouCreated);
//Next, proceed to calculate the triangulation of the polygon
Poly2Tri.triangulate(polygon);
//Finally, obtain the resulting triangles
List<DelaunayTriangle> triangles = polygon.getTriangles();
编辑:不知道您是否已经尝试过,但JTS拓扑套件还有一个DelaunayTriangulationBuilder
类(没有符合部分)。它可以在org.locationtech.jts.triangulate.DelaunayTriangulationBuilder
找到,也许它比你尝试过的但是效果更好。
* 注意:小心不要使用this one,就像我最初做的那样,发现它不是正确的依赖项(不是-core版本)
答案 1 :(得分:0)
这是使用 JTS 的一种快速而肮脏的方法:
首先:
DelaunayTriangulationBuilder
对几何进行三角测量sites
;从初始三角剖分复制顶点位置循环:
sites
sites
重新三角化(现在由原始站点和新质心站点组成)最后:
**对于这种肮脏的技术,我发现使用三角形质心比三角形圆心产生更好的结果,尽管后者往往用于更多正式的改进(Chew、Ruppert 等等......))。
static Geometry refinedTriangulation(Geometry g, int nRefinements, double tolerance) {
DelaunayTriangulationBuilder builder = new DelaunayTriangulationBuilder();
builder.setSites(g); // set vertex sites
builder.setTolerance(tolerance); // set tolerance for initial triangulation only
Geometry triangulation = builder.getTriangles(geometryFactory); // initial triangulation
HashSet<Coordinate> sites = new HashSet<>();
for (int i = 0; i < triangulation.getCoordinates().length; i++) {
sites.add(triangulation.getCoordinates()[i]);
}
for (int refinement = 0; refinement < nRefinements; refinement++) {
for (int i = 0; i < triangulation.getNumGeometries(); i++) {
Polygon triangle = (Polygon) triangulation.getGeometryN(i);
if (triangle.getArea() > 50) { // skip small triangles
sites.add(new Coordinate(triangle.getCentroid().getX(), triangle.getCentroid().getY()));
}
}
builder = new DelaunayTriangulationBuilder();
builder.setSites(sites);
triangulation = builder.getTriangles(geometryFactory); // re-triangulate using new centroid sites
}
triangulation = triangulation.intersection(g); // restore concave hull and any holes
return triangulation;
}
您可以使用 triangle.getExteriorRing().getLength() > N
或 triangle.getArea() > N
跳过细化已经很小的三角形。