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

com.massisframework.massis.util.geom.KPolygonUtils Maven / Gradle / Ivy

package com.massisframework.massis.util.geom;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import com.badlogic.gdx.math.EarClippingTriangulator;
import com.seisw.util.geom.Poly;
import com.seisw.util.geom.PolyDefault;

import straightedge.geom.KPoint;
import straightedge.geom.KPolygon;
import straightedge.geom.PolygonHolder;

public final class KPolygonUtils {

	public static KPolygon intersection(KPolygon kpolygon1, KPolygon kpolygon2)
	{
		Poly m_Poly1 = new PolyDefault();
		Poly m_Poly2 = new PolyDefault();

		for (KPoint p : kpolygon1.getPoints())
		{
			m_Poly1.add(p.x, p.y);
		}
		for (KPoint p : kpolygon2.getPoints())
		{
			m_Poly2.add(p.x, p.y);
		}

		PolyDefault intersection = (PolyDefault) m_Poly1.intersection(m_Poly2);
		if (intersection.isEmpty())
		{
			return null;
		}
		ArrayList points = new ArrayList<>();
		for (int i = 0; i < intersection.getNumPoints(); i++)
		{
			points.add(new KPoint(intersection.getX(i), intersection.getY(i)));
		}
		return new KPolygon(points);
	}

	public static PolyDefault create(KPolygon kpoly)
	{
		PolyDefault poly = new PolyDefault();
		for (KPoint p : kpoly.getPoints())
		{
			poly.add(p.x, p.y);
		}
		return poly;
	}

	public static KPolygon create(Poly poly)
	{
		ArrayList points = new ArrayList<>();
		for (int i = 0; i < poly.getNumPoints(); i++)
		{
			points.add(new KPoint(poly.getX(i), poly.getY(i)));
		}
		return new KPolygon(points);

	}

	public static boolean intersects(PolygonHolder p1, PolygonHolder p2)
	{
		return p1.getPolygon().intersectionPossible(p2.getPolygon())
				&& p1.getPolygon().intersects(p2.getPolygon());
	}

	public static ArrayList union(List list)
	{
		// inicializacion
		ArrayList res = new ArrayList<>();
		LinkedList kpolygons = new LinkedList();
		for (PolygonHolder ph : list)
		{
			kpolygons.add(ph.getPolygon());
		}
		// KPolygon currentKPoly = kpolygons.remove(0);
		// Poly currentPoly = create(currentKPoly);
		while (!kpolygons.isEmpty())
		{
			LinkedList candidates = new LinkedList<>();
			Queue queue = new LinkedList();
			queue.add(kpolygons.remove(0));
			while (!queue.isEmpty())
			{
				KPolygon currentKPoly = queue.poll();
				Iterator it = kpolygons.iterator();
				while (it.hasNext())
				{
					KPolygon next = it.next();
					if (intersects(next, currentKPoly))
					{
						queue.add(next);
						it.remove();
					}
				}
				candidates.add(currentKPoly);
			}
			// unimos los candidatos
			if (!candidates.isEmpty())
			{
				Poly current = create(candidates.remove(0));
				for (KPolygon candidate : candidates)
				{
					Poly union = current.union(create(candidate));
					if (union.getNumInnerPoly() > 1)
					{
						// no funciona. De vuelta a la lista ppal.
						kpolygons.add(candidate);
					} else
					{
						current = union;
					}
				}
				res.add(create(current));
			}

		}
		return res;
	}

	public static ArrayList getLines(KPolygon poly)
	{
		ArrayList lines = new ArrayList<>();

		ArrayList points = poly.getPoints();
		for (int i = 0; i < points.size() - 1; i++)
		{
			lines.add(new KLine(points.get(i), points.get(i + 1)));
		}
		lines.add(new KLine(points.get(points.size() - 1), points.get(0)));

		return lines;
	}

	public static KPoint[] getBoundaryPointsClosestTo(KPolygon poly, double x,
			double y, int npoints)
	{
		npoints = Math.min(npoints, poly.getPoints().size());
		// double closestDistanceSq = Double.MAX_VALUE;

		int[] closestIndex = new int[npoints];
		int[] closestNextIndex = new int[npoints];
		double[] closestDistanceSq = new double[npoints];
		Arrays.fill(closestIndex, -1);
		Arrays.fill(closestNextIndex, -1);
		Arrays.fill(closestDistanceSq, Double.MAX_VALUE);

		ArrayList points = poly.getPoints();
		int nextI;
		for (int i = 0; i < points.size(); i++)
		{
			nextI = (i + 1 == points.size() ? 0 : i + 1);
			KPoint p = points.get(i);
			KPoint pNext = points.get(nextI);
			double ptSegDistSq = KPoint.ptSegDistSq(p.x, p.y, pNext.x, pNext.y,
					x, y);
			for (int j = 0; j < closestDistanceSq.length; j++)
			{
				if (ptSegDistSq < closestDistanceSq[j])
				{
					shiftRight(closestDistanceSq, j);
					shiftRight(closestIndex, j);
					shiftRight(closestNextIndex, j);
					closestDistanceSq[j] = ptSegDistSq;
					closestIndex[j] = i;
					closestNextIndex[j] = nextI;
					break;
				}
			}

		}
		KPoint[] res = new KPoint[npoints];
		for (int i = 0; i < npoints; i++)
		{
			KPoint p = points.get(closestIndex[i]);
			KPoint pNext = points.get(closestNextIndex[i]);
			res[i] = KPoint.getClosestPointOnSegment(p.x, p.y, pNext.x, pNext.y,
					x, y);
		}
		return res;
	}

	private static void shiftRight(int[] array, int position)
	{
		for (int i = position + 1; i < array.length; i++)
		{
			array[i] = array[i - 1];
		}
	}

	private static void shiftRight(double[] array, int position)
	{

		for (int i = position + 1; i < array.length; i++)
		{
			array[i] = array[i - 1];
		}
	}

	public static KPolygon[] triangulate(KPolygon polygon)
	{

		ArrayList polyPoints = polygon.getPoints();
		EarClippingTriangulator ect = new EarClippingTriangulator();
		float[] points = new float[polyPoints.size() * 2];
		int index = 0;
		for (KPoint point : polyPoints)
		{
			points[index++] = (float) point.x;
			points[index++] = (float) point.y;
		}
		short[] triangles = ect.computeTriangles(points).toArray();
		KPolygon[] trianglePolys = new KPolygon[triangles.length / 3];
		int tIndex = 0;
		for (int i = 0; i < trianglePolys.length; i++)
		{
			final int p1_index = triangles[tIndex++];
			final int p2_index = triangles[tIndex++];
			final int p3_index = triangles[tIndex++];
			// ya tenemos los 3 indices
			final KPoint p1 = polyPoints.get(p1_index);
			final KPoint p2 = polyPoints.get(p2_index);
			final KPoint p3 = polyPoints.get(p3_index);
			trianglePolys[i] = new KPolygon(p1, p2, p3);

		}
		return trianglePolys;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy