
pythagoras.f.CrossingHelper Maven / Gradle / Ivy
//
// Pythagoras - a collection of geometry classes
// http://github.com/samskivert/pythagoras
package pythagoras.f;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* An internal class used to compute crossings.
*/
class CrossingHelper
{
private float[][] coords;
private int[] sizes;
private List isectPoints = new ArrayList();
public CrossingHelper (float[][] coords, int[] sizes) {
this.coords = coords;
this.sizes = sizes;
}
public IntersectPoint[] findCrossing () {
int pointCount1 = sizes[0] / 2;
int pointCount2 = sizes[1] / 2;
int[] indices = new int[pointCount1 + pointCount2];
for (int i = 0; i < pointCount1 + pointCount2; i++) {
indices[i] = i;
}
sort(coords[0], pointCount1, coords[1], pointCount2, indices);
// the set for the shapes edges storing
List edges = new ArrayList();
Edge edge;
int begIndex, endIndex;
int areaNumber;
for (int i = 0; i < indices.length; i++) {
if (indices[i] < pointCount1) {
begIndex = indices[i];
endIndex = indices[i] - 1;
if (endIndex < 0) {
endIndex = pointCount1 - 1;
}
areaNumber = 0;
} else if (indices[i] < pointCount1 + pointCount2) {
begIndex = indices[i] - pointCount1;
endIndex = indices[i] - 1 - pointCount1;
if (endIndex < 0) {
endIndex = pointCount2 - 1;
}
areaNumber = 1;
} else {
throw new IndexOutOfBoundsException();
}
if (!removeEdge(edges, begIndex, endIndex)) {
edge = new Edge(begIndex, endIndex, areaNumber);
intersectShape(edges, coords[0], pointCount1, coords[1], pointCount2, edge);
edges.add(edge);
}
begIndex = indices[i];
endIndex = indices[i] + 1;
if ((begIndex < pointCount1) && (endIndex == pointCount1)) {
endIndex = 0;
} else if ((begIndex >= pointCount1) && (endIndex == (pointCount2 + pointCount1))) {
endIndex = pointCount1;
}
if (endIndex < pointCount1) {
areaNumber = 0;
} else {
areaNumber = 1;
endIndex -= pointCount1;
begIndex -= pointCount1;
}
if (!removeEdge(edges, begIndex, endIndex)) {
edge = new Edge(begIndex, endIndex, areaNumber);
intersectShape(edges, coords[0], pointCount1, coords[1], pointCount2, edge);
edges.add(edge);
}
}
return isectPoints.toArray(new IntersectPoint[isectPoints.size()]);
}
private boolean removeEdge (List edges, int begIndex, int endIndex) {
for (Edge edge : edges) {
if (edge.reverseCompare(begIndex, endIndex)) {
edges.remove(edge);
return true;
}
}
return false;
}
// return the quantity of intersect points
private void intersectShape (List edges, float[] coords1, int length1,
float[] coords2, int length2, Edge initEdge) {
int areaOfEdge1, areaOfEdge2;
int initBegin, initEnd;
int addBegin, addEnd;
float x1, y1, x2, y2, x3, y3, x4, y4;
float[] point = new float[2];
Edge edge;
if (initEdge.areaNumber == 0) {
x1 = coords1[2 * initEdge.begIndex];
y1 = coords1[2 * initEdge.begIndex + 1];
x2 = coords1[2 * initEdge.endIndex];
y2 = coords1[2 * initEdge.endIndex + 1];
areaOfEdge1 = 0;
} else {
x1 = coords2[2 * initEdge.begIndex];
y1 = coords2[2 * initEdge.begIndex + 1];
x2 = coords2[2 * initEdge.endIndex];
y2 = coords2[2 * initEdge.endIndex + 1];
areaOfEdge1 = 1;
}
for (Iterator iter = edges.iterator(); iter.hasNext();) {
edge = iter.next();
if (edge.areaNumber == 0) {
x3 = coords1[2 * edge.begIndex];
y3 = coords1[2 * edge.begIndex + 1];
x4 = coords1[2 * edge.endIndex];
y4 = coords1[2 * edge.endIndex + 1];
areaOfEdge2 = 0;
} else {
x3 = coords2[2 * edge.begIndex];
y3 = coords2[2 * edge.begIndex + 1];
x4 = coords2[2 * edge.endIndex];
y4 = coords2[2 * edge.endIndex + 1];
areaOfEdge2 = 1;
}
if ((areaOfEdge1 != areaOfEdge2) &&
(GeometryUtil.intersectLines(x1, y1, x2, y2, x3, y3, x4, y4, point) == 1) &&
(!containsPoint(point))) {
if (initEdge.areaNumber == 0) {
initBegin = initEdge.begIndex;
initEnd = initEdge.endIndex;
addBegin = edge.begIndex;
addEnd = edge.endIndex;
} else {
initBegin = edge.begIndex;
initEnd = edge.endIndex;
addBegin = initEdge.begIndex;
addEnd = initEdge.endIndex;
}
if (((initEnd == length1 - 1) && (initBegin == 0 && initEnd > initBegin)) ||
(((initEnd != length1 - 1) || (initBegin != 0)) &&
((initBegin != length1 - 1) || (initEnd != 0)) && (initBegin > initEnd))) {
int temp = initBegin;
initBegin = initEnd;
initEnd = temp;
}
if (((addEnd == length2 - 1) && (addBegin == 0) && (addEnd > addBegin)) ||
(((addEnd != length2 - 1) || (addBegin != 0)) &&
((addBegin != length2 - 1) || (addEnd != 0)) && (addBegin > addEnd))) {
int temp = addBegin;
addBegin = addEnd;
addEnd = temp;
}
IntersectPoint ip;
for (Iterator i = isectPoints.iterator(); i.hasNext();) {
ip = i.next();
if ((initBegin == ip.begIndex(true)) && (initEnd == ip.endIndex(true))) {
if (compare(ip.x(), ip.y(), point[0], point[1]) > 0) {
initEnd = -(isectPoints.indexOf(ip) + 1);
ip.setBegIndex1(-(isectPoints.size() + 1));
} else {
initBegin = -(isectPoints.indexOf(ip) + 1);
ip.setEndIndex1(-(isectPoints.size() + 1));
}
}
if ((addBegin == ip.begIndex(false)) && (addEnd == ip.endIndex(false))) {
if (compare(ip.x(), ip.y(), point[0], point[1]) > 0) {
addEnd = -(isectPoints.indexOf(ip) + 1);
ip.setBegIndex2(-(isectPoints.size() + 1));
} else {
addBegin = -(isectPoints.indexOf(ip) + 1);
ip.setEndIndex2(-(isectPoints.size() + 1));
}
}
}
isectPoints.add(new IntersectPoint(initBegin, initEnd, addBegin, addEnd,
point[0], point[1]));
}
}
}
// the array sorting
private static void sort (float[] coords1, int length1,
float[] coords2, int length2, int[] array) {
int temp;
int length = length1 + length2;
float x1, y1, x2, y2;
for (int i = 1; i < length; i++) {
if (array[i - 1] < length1) {
x1 = coords1[2 * array[i - 1]];
y1 = coords1[2 * array[i - 1] + 1];
} else {
x1 = coords2[2 * (array[i - 1] - length1)];
y1 = coords2[2 * (array[i - 1] - length1) + 1];
}
if (array[i] < length1) {
x2 = coords1[2 * array[i]];
y2 = coords1[2 * array[i] + 1];
} else {
x2 = coords2[2 * (array[i] - length1)];
y2 = coords2[2 * (array[i] - length1) + 1];
}
int j = i;
while (j > 0 && compare(x1, y1, x2, y2) <= 0) {
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
j--;
if (j > 0) {
if (array[j - 1] < length1) {
x1 = coords1[2 * array[j - 1]];
y1 = coords1[2 * array[j - 1] + 1];
} else {
x1 = coords2[2 * (array[j - 1] - length1)];
y1 = coords2[2 * (array[j - 1] - length1) + 1];
}
if (array[j] < length1) {
x2 = coords1[2 * array[j]];
y2 = coords1[2 * array[j] + 1];
} else {
x2 = coords2[2 * (array[j] - length1)];
y2 = coords2[2 * (array[j] - length1) + 1];
}
}
}
}
}
public boolean containsPoint (float[] point) {
IntersectPoint ipoint;
for (Iterator i = isectPoints.iterator(); i.hasNext();) {
ipoint = i.next();
if (ipoint.x() == point[0] && ipoint.y() == point[1]) {
return true;
}
}
return false;
}
public static int compare (float x1, float y1, float x2, float y2) {
if ((x1 < x2) || (x1 == x2 && y1 < y2)) {
return 1;
} else if (x1 == x2 && y1 == y2) {
return 0;
}
return -1;
}
private static final class Edge
{
final int begIndex;
final int endIndex;
final int areaNumber;
Edge (int begIndex, int endIndex, int areaNumber) {
this.begIndex = begIndex;
this.endIndex = endIndex;
this.areaNumber = areaNumber;
}
boolean reverseCompare (int begIndex, int endIndex) {
return this.begIndex == endIndex && this.endIndex == begIndex;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy