Package org.osm2world.core.math.algorithms

Source Code of org.osm2world.core.math.algorithms.Poly2TriTriangulationUtil

package org.osm2world.core.math.algorithms;

import static java.util.Collections.disjoint;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.osm2world.core.math.LineSegmentXZ;
import org.osm2world.core.math.SimplePolygonXZ;
import org.osm2world.core.math.TriangleXZ;
import org.osm2world.core.math.VectorXZ;
import org.osm2world.core.util.exception.TriangulationException;
import org.poly2tri.Poly2Tri;
import org.poly2tri.geometry.polygon.Polygon;
import org.poly2tri.geometry.polygon.PolygonPoint;
import org.poly2tri.triangulation.TriangulationPoint;
import org.poly2tri.triangulation.delaunay.DelaunayTriangle;
import org.poly2tri.triangulation.point.TPoint;

/**
* uses the poly2tri library for triangulation.
* Creates a Constrained Delaunay Triangulation, not true Delaunay!
*/
public final class Poly2TriTriangulationUtil {

  private Poly2TriTriangulationUtil() { }
   
  /**
   * triangulates of a polygon with holes.
   *
   * Accepts some unconnected points within the polygon area
   * and will create triangle vertices at these points.
   * It will also accept line segments as edges that must be integrated
   * into the resulting triangulation.
   * @throws TriangulationException if triangulation fails
   */
  public static final List<TriangleXZ> triangulate(
      SimplePolygonXZ outerPolygon,
      Collection<SimplePolygonXZ> holes,
      Collection<LineSegmentXZ> segments,
      Collection<VectorXZ> points) throws TriangulationException {
   
    /* remove any problematic data (duplicate points) from the input */
   
    Set<VectorXZ> knownVectors =
        new HashSet<VectorXZ>(outerPolygon.getVertexCollection());
   
    List<SimplePolygonXZ> filteredHoles = new ArrayList<SimplePolygonXZ>();
   
    for (SimplePolygonXZ hole : holes) {
     
      if (disjoint(hole.getVertexCollection(), knownVectors)) {
        filteredHoles.add(hole);
        knownVectors.addAll(hole.getVertices());
      }
     
    }
   
    //TODO filter segments
   
    Set<VectorXZ> filteredPoints = new HashSet<VectorXZ>(points);
    filteredPoints.removeAll(knownVectors);
   
    // remove points that are *almost* the same as a known vector
    Iterator<VectorXZ> filteredPointsIterator = filteredPoints.iterator();
    while (filteredPointsIterator.hasNext()) {
      VectorXZ filteredPoint = filteredPointsIterator.next();
      for (VectorXZ knownVector : knownVectors) {
        if (knownVector.distanceTo(filteredPoint) < 0.2) {
          filteredPointsIterator.remove();
        }
      }
    }
   
    /* run the actual triangulation */
   
    return triangulateFast(outerPolygon, filteredHoles, segments, filteredPoints);
   
  }

  /**
   * variant of {@link #triangulate(SimplePolygonXZ, Collection, Collection, Collection)}
   * that does not validate the input. This is obviously faster,
   * but the caller needs to make sure that there are no problems.
   * @throws TriangulationException if triangulation fails
   */
  public static final List<TriangleXZ> triangulateFast(
      SimplePolygonXZ outerPolygon,
      Collection<SimplePolygonXZ> holes,
      Collection<LineSegmentXZ> segments,
      Collection<VectorXZ> points) throws TriangulationException {
   
    /* prepare data for triangulation */
   
    Polygon triangulationPolygon = toPolygon(outerPolygon);
   
    for (SimplePolygonXZ hole : holes) {
      triangulationPolygon.addHole(toPolygon(hole));
    }
   
    //TODO collect points and constraints from segments
   
    for (VectorXZ p : points) {
      triangulationPolygon.addSteinerPoint(toTPoint(p));
    }
   
    try {
     
      /* run triangulation */
     
      Poly2Tri.triangulate(triangulationPolygon);
     
      /* convert the result to the desired format */
     
      List<DelaunayTriangle> triangles = triangulationPolygon.getTriangles();
     
      List<TriangleXZ> result = new ArrayList<TriangleXZ>(triangles.size());
     
      for (DelaunayTriangle triangle : triangles) {
        result.add(toTriangleXZ(triangle));
      }
       
      return result;
     
    } catch (Exception e) {
      throw new TriangulationException(e);
    } catch (StackOverflowError e) {
      throw new TriangulationException(e);
    }
   
  }
 
  private static final TPoint toTPoint(VectorXZ v) {
    return new TPoint(v.x, v.z);
  }

  private static final VectorXZ toVectorXZ(TriangulationPoint points) {
    return new VectorXZ(points.getX(), points.getY());
  }

  private static final Polygon toPolygon(SimplePolygonXZ polygon) {
       
    List<PolygonPoint> points = new ArrayList<PolygonPoint>(polygon.size());
   
    for (VectorXZ v : polygon.getVertices()) {
      points.add(new PolygonPoint(v.x, v.z));
    }
   
    return new Polygon(points);
   
  }

  private static final TriangleXZ toTriangleXZ(DelaunayTriangle triangle) {
   
    return new TriangleXZ(
        toVectorXZ(triangle.points[0]),
        toVectorXZ(triangle.points[1]),
        toVectorXZ(triangle.points[2]));
   
  }
 
}
TOP

Related Classes of org.osm2world.core.math.algorithms.Poly2TriTriangulationUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.