/**
*
*/
package math.geom2d.polygon;
import java.util.ArrayList;
import java.util.Collection;
import math.geom2d.Point2D;
import math.geom2d.Shape2D;
import math.geom2d.line.LineSegment2D;
import math.geom2d.point.PointSets2D;
/**
* Some utility functions for manipulating Polyline2D.
*
* @author dlegland
* @since 0.6.3
*/
public abstract class Polylines2D {
static ArrayList simplifyPolyline(ArrayList vertices,
double distMax) {
// index of last vertex
int last = vertices.size() - 1;
int[] inds = recurseSimplify(vertices, 0, last, distMax);
ArrayList newVerts = new ArrayList(inds.length + 2);
newVerts.add(vertices.get(0));
for (int i : inds)
newVerts.add(vertices.get(i));
newVerts.add(vertices.get(last));
return newVerts;
}
static ArrayList simplifyClosedPolyline(ArrayList vertices,
double distMax) {
// index of last vertex
int nv = vertices.size();
// first find index of farthest vertex from origin
int indMax = 0;
double maxDist = 0;
Point2D p0 = vertices.get(0);
for (int i = 1; i < vertices.size(); i++) {
double dist = vertices.get(i).distance(p0);
if (dist > maxDist) {
maxDist = dist;
indMax = i;
}
}
int[] inds1 = recurseSimplify(vertices, 0, indMax, distMax);
int[] inds2 = recurseSimplify(vertices, indMax, nv, distMax);
int[] inds = concatInds(inds1, indMax, inds2);
ArrayList newVerts = new ArrayList(inds.length + 2);
newVerts.add(vertices.get(0));
for (int i : inds)
newVerts.add(vertices.get(i));
return newVerts;
}
/**
* Used for constructing simplified polylines.
*/
private static int[] recurseSimplify(ArrayList vertices, int first,
int last, double distMax) {
if (last - first < 2) {
return new int[0];
}
int nv = vertices.size();
Point2D p0 = vertices.get(first);
Point2D p1 = vertices.get(last % nv);
LineSegment2D line = new LineSegment2D(p0, p1);
double dist;
double midDist = 0;
int indMid = 0;
for (int ind = first; ind < last; ind++) {
dist = line.distance(vertices.get(ind));
if (dist > midDist) {
midDist = dist;
indMid = ind;
}
}
if (midDist < distMax) {
return new int[]{};
}
// Recursively subdivide each of the resulting pieces
int[] inds1 = recurseSimplify(vertices, first, indMid, distMax);
int[] inds2 = recurseSimplify(vertices, indMid, last, distMax);
int[] res = concatInds(inds1, indMid, inds2);
// return concatenated indices
return res;
}
private static int[] concatInds(int[] inds1, int indMid, int[] inds2) {
int n = inds1.length + inds2.length + 1;
int[] res = new int[n];
for (int i = 0; i < inds1.length; i++)
res[i] = inds1[i];
res[inds1.length] = indMid;
for (int i = inds1.length + 1; i < n; i++)
res[i] = inds2[i - (inds1.length + 1)];
return res;
}
/**
* Checks if the open polyline has multiple vertices. Polyline extremities
* are not tested for equality.
*/
public final static boolean hasMultipleVertices(LinearCurve2D polyline) {
return hasMultipleVertices(polyline, false);
}
/**
* Checks if the input polyline has multiple vertices. Extremities are
* tested if the polyline is closed (second argument is true).
*/
public final static boolean hasMultipleVertices(LinearCurve2D polyline,
boolean closed) {
// Test vertices within polyline
if(PointSets2D.hasMultipleVertices(polyline.vertices))
return true;
// Eventually tests extremities
if (closed) {
Point2D p1 = polyline.firstPoint();
Point2D p2 = polyline.lastPoint();
if (p1.distance(p2) < Shape2D.ACCURACY)
return true;
}
return false;
}
/**
* Return all intersection points between the 2 polylines.
* This method implements a naive algorithm, that tests all possible edge
* couples.
* It is supposed that only one point is returned by intersection.
* @param poly1 a first polyline
* @param poly2 a second polyline
* @return the set of intersection points
*/
public static Collection intersect(
LinearCurve2D poly1, LinearCurve2D poly2) {
// array for storing intersections
ArrayList points = new ArrayList();
// iterate on edge couples
Point2D point;
for (LineSegment2D edge1 : poly1.edges()) {
for (LineSegment2D edge2 : poly2.edges()) {
// if the intersection is not empty, add it to the set
point = edge1.intersection(edge2);
if (point != null) {
// we keep only one intersection by couple
if (!points.contains(point))
points.add(point);
}
}
}
return points;
}
}
Ads help maintain this website.