Skip to content

Commit e3151c7

Browse files
eengleMichael Bolin
authored andcommitted
The checkEdgeCrossings() method now uses the edge index of the context loop, instead of iterating over the product of all edges against all other edges filtered only by bounding volume. This method is integral to the performance of intersects(), contains(), containsOrCrosses(), etc. This matches the c++ algorithm in the corresponding method S2Loop::AreBoundariesCrossing.
------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=24938116
1 parent b898242 commit e3151c7

1 file changed

Lines changed: 14 additions & 51 deletions

File tree

src/com/google/common/geometry/S2Loop.java

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -894,66 +894,29 @@ private int findVertex(S2Point p) {
894894
* intersection tests. It is used in three slightly different variations to
895895
* implement contains(), intersects(), and containsOrCrosses().
896896
*
897-
* In a nutshell, this method checks all the edges of this polygon (A) for
897+
* In a nutshell, this method checks all the edges of this loop (A) for
898898
* intersection with all the edges of B. It returns -1 immediately if any edge
899899
* intersections are found. Otherwise, if there are any shared vertices, it
900900
* returns the minimum value of the given WedgeRelation for all such vertices
901901
* (returning immediately if any wedge returns -1). Returns +1 if there are no
902902
* intersections and no shared vertices.
903903
*/
904904
private int checkEdgeCrossings(S2Loop b, S2EdgeUtil.WedgeRelation relation) {
905-
if (b.numVertices() <= 6) {
906-
int result = 1;
907-
// For small loops (such as S2Cell boundaries), it is not worth computing
908-
// longitude bounds to avoid edge tests, and it is more efficient to
909-
// reverse the loop nesting.
910-
for (int j = 0; j < b.numVertices(); ++j) {
911-
S2EdgeUtil.EdgeCrosser crosser =
912-
new S2EdgeUtil.EdgeCrosser(b.vertex(j), b.vertex(j + 1), vertex(0));
913-
for (int i = 0; i < numVertices(); ++i) {
914-
int crossing = crosser.robustCrossing(vertex(i + 1));
915-
if (crossing < 0) {
916-
continue;
917-
}
918-
if (crossing > 0) {
919-
return -1; // There is a proper edge crossing.
920-
}
921-
// We only need to check each shared vertex once, so we only
922-
// consider the case where vertex(i+1) == b->vertex(j+1).
923-
if (vertex(i + 1).equals(b.vertex(j + 1))) {
924-
result = Math.min(result, relation.test(
925-
vertex(i), vertex(i + 1), vertex(i + 2), b.vertex(j), b.vertex(j + 2)));
926-
927-
if (result < 0) {
928-
return result;
929-
}
930-
}
931-
}
932-
}
933-
return result;
934-
}
935-
936-
// For larger loops, we can save a lot of edge tests by first checking
937-
// whether each edge of the outer loop intersects the xyz bounding
938-
// box of the inner loop. To that end we now accumulate a bounding box
939-
// in XYZ space for the inner loop.
940-
S2EdgeUtil.XYZPruner pruner = new S2EdgeUtil.XYZPruner();
941-
for (int i = 1; i < b.numVertices(); i++) {
942-
pruner.addEdgeToBounds(b.vertex(i - 1), b.vertex(i));
943-
}
944-
pruner.addEdgeToBounds(b.vertex(b.numVertices() - 1), b.vertex(0));
945-
946-
pruner.setFirstIntersectPoint(vertex(0));
947-
905+
DataEdgeIterator it = getEdgeIterator(b.numVertices);
948906
int result = 1;
949-
for (int i = 0; i < numVertices(); ++i) {
950-
if (!pruner.intersects(vertex(i + 1))) {
951-
continue;
952-
}
907+
// since 'this' usually has many more vertices than 'b', use the index on
908+
// 'this' and loop over 'b'
909+
for (int j = 0; j < b.numVertices(); ++j) {
953910
S2EdgeUtil.EdgeCrosser crosser =
954-
new S2EdgeUtil.EdgeCrosser(vertex(i), vertex(i + 1), b.vertex(0));
955-
for (int j = 0; j < b.numVertices(); ++j) {
956-
int crossing = crosser.robustCrossing(b.vertex(j + 1));
911+
new S2EdgeUtil.EdgeCrosser(b.vertex(j), b.vertex(j + 1), vertex(0));
912+
int previousIndex = -2;
913+
for (it.getCandidates(b.vertex(j), b.vertex(j + 1)); it.hasNext(); it.next()) {
914+
int i = it.index();
915+
if (previousIndex != i - 1) {
916+
crosser.restartAt(vertex(i));
917+
}
918+
previousIndex = i;
919+
int crossing = crosser.robustCrossing(vertex(i + 1));
957920
if (crossing < 0) {
958921
continue;
959922
}

0 commit comments

Comments
 (0)