Package org.osm2world.core.math

Source Code of org.osm2world.core.math.Poly2TriUtil$CDTSet

package org.osm2world.core.math;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import org.osm2world.core.util.exception.TriangulationException;
import org.poly2tri.Poly2Tri;
import org.poly2tri.triangulation.Triangulatable;
import org.poly2tri.triangulation.TriangulationAlgorithm;
import org.poly2tri.triangulation.TriangulationContext;
import org.poly2tri.triangulation.TriangulationMode;
import org.poly2tri.triangulation.TriangulationPoint;
import org.poly2tri.triangulation.delaunay.DelaunayTriangle;
import org.poly2tri.triangulation.point.TPoint;
/**
* @author Hannes Janetzek
* */

public class Poly2TriUtil {
  static class CDTSet implements Triangulatable {
    List<TriangulationPoint> points = new ArrayList<TriangulationPoint>(20);
    List<DelaunayTriangle> triangles = new ArrayList<DelaunayTriangle>(20);
    ArrayList<LineSegmentXZ> segmentSet = new ArrayList<LineSegmentXZ>();

    // it seems poly2tri requires points to be unique objects
    HashMap<VectorXZ, TriangulationPoint> pointSet
      = new HashMap<VectorXZ, TriangulationPoint>();
   
    public CDTSet(SimplePolygonXZ polygon,
        Collection<SimplePolygonXZ> holes,
        Collection<LineSegmentXZ> cSegments,
        Collection<VectorXZ> cPoints) {

      List<VectorXZ> vertices = polygon.getVertexLoop();

      segmentSet.addAll(cSegments);
     
      for (VectorXZ p : cPoints) {
        if (!pointSet.containsKey(p)) {
          TPoint tp = new TPoint(p.x, p.z);
          pointSet.put(p, tp);
          points.add(tp);
        }
      }
     
      for (int i = 0, n = vertices.size() - 1; i < n; i++)
        segmentSet.add(new LineSegmentXZ(vertices.get(i),
            vertices.get(i + 1)));

      for (SimplePolygonXZ hole : holes) {
        vertices = hole.getVertexLoop();
        for (int i = 0, n = vertices.size() - 1; i < n; i++)
          segmentSet.add(new LineSegmentXZ(vertices.get(i),
              vertices.get(i + 1)));
      }

      removeDuplicateSegments();

      boolean foundIntersections = false;

      // split at intersections
      for (int i = 0, size = segmentSet.size(); i < size - 1; i++) {
        LineSegmentXZ l1 = segmentSet.get(i);

        for (int j = i + 1; j < size; j++) {
          LineSegmentXZ l2 = segmentSet.get(j);

          VectorXZ crossing;

          if ((crossing = l1.getIntersection(l2.p1, l2.p2)) != null) {
            System.out.println("split " + l1 + " " + l2 + " at "
                + crossing);
            foundIntersections = true;

            segmentSet.remove(l1);
            segmentSet.remove(l2);

            segmentSet.add(new LineSegmentXZ(crossing, l1.p1));
            segmentSet.add(new LineSegmentXZ(crossing, l1.p2));
            segmentSet.add(new LineSegmentXZ(crossing, l2.p1));
            segmentSet.add(new LineSegmentXZ(crossing, l2.p2));

            size += 2;

            // first segment was removed
            i--;
            break;
          }
        }
      }

      if (foundIntersections)
        removeDuplicateSegments();
    }

    private void removeDuplicateSegments() {
      for (int i = 0, size = segmentSet.size(); i < size - 1; i++) {
        LineSegmentXZ l1 = segmentSet.get(i);

        for (int j = i + 1; j < size; j++) {
          LineSegmentXZ l2 = segmentSet.get(j);

          if ((l1.p1.equals(l2.p1) && l1.p2.equals(l2.p2))
              || (l1.p1.equals(l2.p2) && l1.p2.equals(l2.p1))) {
            //System.out.println("remove dup " + l1 + " " + l2);
            segmentSet.remove(j);
            size--;
          }
        }
      }
    }

    public TriangulationMode getTriangulationMode() {
      return TriangulationMode.CONSTRAINED;
    }

    public List<TriangulationPoint> getPoints() {
      return points;
    }

    public List<DelaunayTriangle> getTriangles() {
      return triangles;
    }

    public void addTriangle(DelaunayTriangle t) {
      triangles.add(t);
    }

    public void addTriangles(List<DelaunayTriangle> list) {
      triangles.addAll(list);
    }

    public void clearTriangulation() {
      triangles.clear();
    }

    public void prepareTriangulation(TriangulationContext<?> tcx) {
      triangles.clear();


      for (LineSegmentXZ l : segmentSet) {
        TriangulationPoint tp1, tp2;
       
        if (!pointSet.containsKey(l.p1)){
          tp1 = new TPoint(l.p1.x, l.p1.z);
          pointSet.put(l.p1, tp1);
          points.add(tp1);
        } else {
          tp1 = pointSet.get(l.p1);
        }
        if (!pointSet.containsKey(l.p2)){
          tp2 = new TPoint(l.p2.x, l.p2.z);
          pointSet.put(l.p2, tp2);
          points.add(tp2);
        } else {
          tp2 = pointSet.get(l.p2);
        }

        tcx.newConstraint(tp1, tp2);
      }

      segmentSet.clear();
      pointSet.clear();
 
      tcx.addPoints(points);
    }
  }

  public static final List<TriangleXZ> triangulate(SimplePolygonXZ polygon,
      Collection<SimplePolygonXZ> holes,
      Collection<LineSegmentXZ> segments, Collection<VectorXZ> points) throws TriangulationException {

    CDTSet cdt = new CDTSet(polygon, holes, segments, points);
    TriangulationContext<?> tcx = Poly2Tri
        .createContext(TriangulationAlgorithm.DTSweep);
    tcx.prepareTriangulation(cdt);

    try {
   
      Poly2Tri.triangulate(tcx);
         
    } catch (Exception e) {
      throw new TriangulationException(e);
    } catch (StackOverflowError e) {
      throw new TriangulationException(e);
    }

    List<TriangleXZ> triangles = new ArrayList<TriangleXZ>();

    List<DelaunayTriangle> result = cdt.getTriangles();

    if (result == null)
      return triangles;

    for (DelaunayTriangle t : result) {

      TriangulationPoint tCenter = t.centroid();
      VectorXZ center = new VectorXZ(tCenter.getX(), tCenter.getY());

      boolean triangleInHole = false;
      for (SimplePolygonXZ hole : holes) {
        if (hole.contains(center)) {
          triangleInHole = true;
          break;
        }
      }

      if (triangleInHole || !polygon.contains(center))
        continue;

      triangles.add(new TriangleXZ(new VectorXZ(t.points[0].getX(),
          t.points[0].getY()), new VectorXZ(t.points[1].getX(),
          t.points[1].getY()), new VectorXZ(t.points[2].getX(),
          t.points[2].getY())));
    }

    return triangles;

  }
}
TOP

Related Classes of org.osm2world.core.math.Poly2TriUtil$CDTSet

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.