All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.mihosoft.vrl.v3d.ext.org.poly2tri.PolygonUtil Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * PolygonUtil.java
 *
 * Copyright 2014-2014 Michael Hoffer [email protected]. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY Michael Hoffer [email protected] "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Michael Hoffer [email protected] OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of Michael Hoffer
 * [email protected].
 */
package eu.mihosoft.vrl.v3d.ext.org.poly2tri;

import eu.mihosoft.vrl.v3d.Debug3dProvider;
import eu.mihosoft.vrl.v3d.Extrude;
import eu.mihosoft.vrl.v3d.Plane;
import eu.mihosoft.vrl.v3d.Polygon;
import eu.mihosoft.vrl.v3d.Transform;
import eu.mihosoft.vrl.v3d.Vector3d;
import eu.mihosoft.vrl.v3d.Vertex;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.triangulate.polygon.ConstrainedDelaunayTriangulator;

/**
 * The Class PolygonUtil.
 *
 * @author Michael Hoffer <[email protected]>
 */
public class PolygonUtil {

	/**
	 * Instantiates a new polygon util.
	 */
	private PolygonUtil() {
		throw new AssertionError("Don't instantiate me!", null);
	}

//	/**
//	 * Converts a CSG polygon to a poly2tri polygon (including holes).
//	 *
//	 * @param polygon the polygon to convert
//	 * @return a CSG polygon to a poly2tri polygon (including holes)
//	 */
//	public static eu.mihosoft.vrl.v3d.ext.org.poly2tri.Polygon fromCSGPolygon(eu.mihosoft.vrl.v3d.Polygon polygon) {
//
//		// convert polygon
//		List points = new ArrayList<>();
//		for (Vertex v : polygon.vertices) {
//			PolygonPoint vp = new PolygonPoint(v.pos.x, v.pos.y, v.pos.z);
//			points.add(vp);
//		}
//
//		eu.mihosoft.vrl.v3d.ext.org.poly2tri.Polygon result = new eu.mihosoft.vrl.v3d.ext.org.poly2tri.Polygon(points);
//
//		// convert holes
//		Optional> holesOfPresult = polygon.getStorage()
//				.getValue(eu.mihosoft.vrl.v3d.Edge.KEY_POLYGON_HOLES);
//		if (holesOfPresult.isPresent()) {
//			List holesOfP = holesOfPresult.get();
//
//			holesOfP.stream().forEach((hP) -> {
//				result.addHole(fromCSGPolygon(hP));
//			});
//		}
//
//		return result;
//	}

	/**
	 * Concave to convex.
	 *
	 * @param incoming the concave
	 * @return the list
	 */
	public static List concaveToConvex(Polygon incoming) {
		List result = new ArrayList<>();

		if (incoming == null)
			return result;
		if (incoming.vertices.size() < 3)
			return result;
		Polygon concave = incoming;
		Vector3d normalOfPlane = incoming.plane.normal;
		boolean reorent = normalOfPlane.z < 1.0-Plane.EPSILON;
		Transform orentationInv = null;
		boolean debug = false;
		if (reorent) {
			double degreesToRotate = Math.toDegrees(Math.atan2(normalOfPlane.x,normalOfPlane.z));
			Transform orentation = new Transform().roty(degreesToRotate);

			Polygon tmp = incoming.transformed(orentation);
			
			Vector3d normal = tmp.plane.normal;
			double degreesToRotate2 =90+Math.toDegrees(Math.atan2(normal.z,normal.y));
			Transform orentation2 = orentation.rotx(degreesToRotate2);// th triangulation function needs
			// the polygon on the xy plane
			if (debug) {
				Debug3dProvider.clearScreen();
				Debug3dProvider.addObject(incoming);
			}
			concave = incoming.transformed(orentation2);
			orentationInv = orentation2.inverse();
			if(concave.plane.normal.z <0) {
				Transform orentation3 = orentation2.rotx(180);
				concave = incoming.transformed(orentation3);
				orentationInv = orentation3.inverse();
			}
		}


		Vector3d normal = concave.plane.normal.clone();

		boolean cw = !Extrude.isCCW(concave);
		//concave = Extrude.toCCW(concave);
		if (debug) {
			Debug3dProvider.clearScreen();
			Debug3dProvider.addObject(concave);
			//Debug3dProvider.clearScreen();
		}
		
		Coordinate[] coordinates = new Coordinate[concave.vertices.size()+1];
		double zplane =concave.vertices.get(0).pos.z;
		for(int i=0;i triPoints = new ArrayList<>();

		for (int i=0;i();
				} else {
					counter++;
				}
			}
		}

		return result;
	}

//	/**
//	 * Concave to convex.
//	 *
//	 * @param concave the concave
//	 * @return the list
//	 */
//	public static List concaveToConvex(eu.mihosoft.vrl.v3d.Polygon incoming) {
//		//incoming = pruneDuplicatePoints(incoming);
//		if (incoming == null)
//			return new ArrayList<>();
//		if (incoming.vertices.size() < 3)
//			return new ArrayList<>();
//		eu.mihosoft.vrl.v3d.Polygon concave;
//		Vector3d normalOfPlane = incoming.plane.normal;
//		boolean reorent = Math.abs(normalOfPlane.z) < 1.0-Plane.EPSILON;
//		Transform orentationInv = null;
//		boolean debug = false;
//		Vector3d normal2;
//		if (reorent) {
//			//debug = true;
//			double degreesToRotate = Math.toDegrees(Math.atan2(normalOfPlane.x,normalOfPlane.z));
//			Transform orentation = new Transform().roty(degreesToRotate);
//
//			eu.mihosoft.vrl.v3d.Polygon tmp = incoming.transformed(orentation);
//			
//			Vector3d normal = tmp.plane.normal;
//			double degreesToRotate2 =90+Math.toDegrees(Math.atan2(normal.z,normal.y));
//			Transform orentation2 = orentation.rotx(degreesToRotate2);// th triangulation function needs
//			// the polygon on the xy plane
//			orentationInv = orentation2.inverse();
//
//			if (debug) {
//				Debug3dProvider.clearScreen();
//				Debug3dProvider.addObject(incoming);
//			}
//			concave = incoming.transformed(orentation2);
//			normal2 = concave.plane.normal;
//			//System.out.println("New vectors "+normal2+" "+normal);
//		} else
//			concave = incoming;
//		if(Math.abs(concave.plane.normal.z) < 1.0-Plane.EPSILON) {
//			throw new RuntimeException("Orentaion of plane misaligned for triangulation");
//		}
//
//		List result = new ArrayList<>();
//
//		Vector3d normal = concave.vertices.get(0).normal.clone();
//
//		boolean cw = !Extrude.isCCW(concave);
//		concave = Extrude.toCCW(concave);
//		if (reorent) {
//			// Debug3dProvider.addObject(concave);
//		}
//
//		eu.mihosoft.vrl.v3d.ext.org.poly2tri.Polygon p = fromCSGPolygon(concave);
//
//		eu.mihosoft.vrl.v3d.ext.org.poly2tri.Poly2Tri.triangulate(p);
//
//		List triangles = p.getTriangles();
//
//		List triPoints = new ArrayList<>();
//
//		for (DelaunayTriangle t : triangles) {
//
//			int counter = 0;
//			for (TriangulationPoint tp : t.points) {
//
//				triPoints.add(new Vertex(new Vector3d(tp.getX(), tp.getY(), tp.getZ()), normal));
//
//				if (counter == 2) {
//					if (!cw) {
//						Collections.reverse(triPoints);
//					}
//					eu.mihosoft.vrl.v3d.Polygon poly = new eu.mihosoft.vrl.v3d.Polygon(triPoints, concave.getStorage(),true);
//
//					poly.plane.normal = concave.plane.normal;
//					// Debug3dProvider.addObject(poly);
//					if (reorent) {
//						poly = poly.transform(orentationInv);
//						if (reorent) {
//							// Debug3dProvider.addObject(poly);
//						}
//					}
//					Vector3d clone = normalOfPlane.clone();
//
//					// System.out.println("Updating the normal to " + clone);
//					poly.plane.normal = clone;
//					// Debug3dProvider.addObject(poly);
//					result.add(poly);
//					counter = 0;
//					triPoints = new ArrayList<>();
//
//				} else {
//					counter++;
//				}
//			}
//		}
//
//		return result;
//	}

	public static Polygon pruneDuplicatePoints(Polygon incoming) {
		ArrayList newPoints = new ArrayList();
		for (int i = 0; i < incoming.vertices.size(); i++) {
			Vertex v = incoming.vertices.get(i);
			boolean duplicate = false;
			for (Vertex vx : newPoints) {
				if (vx.pos.test(v.pos,	Plane.EPSILON_duplicate)) {
					duplicate = true;
				}
			}
			if (!duplicate) {
				newPoints.add(v);
			}

		}
		if(newPoints.size()<3)
			return null;
	
		return new Polygon(newPoints);

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy