如何在Java中对某些形状进行三角测量/镶嵌?

时间:2014-05-11 20:15:52

标签: java mesh geotools tessellation jts

我想从GeoTools镶嵌国家形状,在地球表面上以3D显示。 GeoTools使用内部功能丰富的JTS拓扑套件。

是否包含镶嵌某些形状的实用程序?我看到有三角测量包,但无法弄清楚,如何将它用于带孔的形状。

此外,我不仅可以像现在这样连接现有的顶点

enter image description here

它应该填充内部有多个顶点的形状。

更新

我发现,JTS包含类ConformingDelaunayTriangulationBuilder,它允许以某种方式制作希望的镶嵌,但它的工作很糟糕。首先,它只允许约束,这意味着需要额外的代码来从凹陷区域中删除三角形。并且它还试图保留细分的Delaunay性质,这导致创建许多其他部分。

最后,它导致ConstraintEnforcementException复杂的形状,如国家和无法使用。

我还找到"triangle" package,用C语言编写并实现Chew's second algorithm并且效果很好

enter image description here

现在我想知道,它是移植到Java还是包含在其中?

2 个答案:

答案 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 的一种快速而肮脏的方法:

首先:

  • 使用 JTS DelaunayTriangulationBuilder 对几何进行三角测量
  • 准备一组网站,sites;从初始三角剖分复制顶点位置

循环:

  • 迭代三角剖分的三角形几何,将三角形质心**添加到 sites
  • 使用 sites 重新三角化(现在由原始站点和新质心站点组成)

最后:

  • 将三角剖分与原始几何体相交以恢复其凹形外壳和任何孔

**对于这种肮脏的技术,我发现使用三角形质心比三角形圆心产生更好的结果,尽管后者往往用于更多正式的改进(ChewRuppert 等等......))。

代码

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() > Ntriangle.getArea() > N 跳过细化已经很小的三角形。

示例

原始形状

enter image description here

JTS 三角剖分

enter image description here

带交点的 JTS 三角剖分

enter image description here

1 次改进

enter image description here

3 项改进

enter image description here