Class S2Predicates
- java.lang.Object
-
- com.google.common.geometry.S2Predicates
-
@GwtCompatible public final class S2Predicates extends Object
A collection of geometric predicates core to the robustness of the S2 library. In particular,sign(A, B, C): Compute the orientation of a triple of points as clockwise (-1), colinear (0), or counter-clockwise (1).
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classS2Predicates.ExcludedGiven two sites A and B that form the center of caps of radius 'r', this indicates which sites are irrelevant to the Voronoi diagram relative to an edge PQ.static classS2Predicates.SignTests of whether three points represent a left turn (+1), right turn (-1), or neither (0).
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static intcompareDistances(S2Point x, S2Point a, S2Point b)Returns -1, 0, or +1 according to whether AX < BX, A == B, or AX > BX respectively.static intcompareEdgeDistance(S2Point x, S2Point a, S2Point b, double r2)Returns -1, 0, or +1 according to whether the distance from the point X to the edge AB is less than, equal to, or greater than the squared chord distance "r2" respectively.static intedgeCircumcenterSign(S2Point p, S2Point q, S2Point a, S2Point b, S2Point c)Returns sign(P, Q, Z) where Z is the circumcenter of triangle ABC.static S2Predicates.ExcludedgetVoronoiSiteExclusion(S2Point a, S2Point b, S2Point p, S2Point q, double r2)This is a specialized method that is used to compute the intersection of an edge PQ with the Voronoi diagram of a set of points, where each Voronoi region is intersected with a disc of fixed radius "r".static booleanorderedCCW(S2Point a, S2Point b, S2Point c, S2Point o)Return true if the edges OA, OB, and OC are encountered in that order while sweeping CCW around the point O.static intsign(S2Point a, S2Point b, S2Point c)Returns +1 if the points A, B, C are counterclockwise, -1 if the points are clockwise, and 0 if any two points are the same.
-
-
-
Method Detail
-
sign
public static int sign(S2Point a, S2Point b, S2Point c)
Returns +1 if the points A, B, C are counterclockwise, -1 if the points are clockwise, and 0 if any two points are the same. This function is essentially like taking the sign of the determinant of ABC, except that it has additional logic to make sure that the above properties hold even when the three points are coplanar, and to deal with the limitations of floating-point arithmetic.Sign satisfies the following conditions:
sign(a,b,c) == 0iffa.equals(b) || b.equals(c) || c.equals(a)sign(b,c,a) == sign(a,b,c), for all a,b,csign(c,b,a) == -sign(a,b,c), for all a,b,c
In other words:
- The result is zero if and only if two points are the same.
- Rotating the order of the arguments does not affect the result.
- Exchanging any two arguments inverts the result.
On the other hand, note that it is not true in general that
sign(-a,b,c) == -sign(a,b,c), or any similar identities involving antipodal points.
-
orderedCCW
public static boolean orderedCCW(S2Point a, S2Point b, S2Point c, S2Point o)
Return true if the edges OA, OB, and OC are encountered in that order while sweeping CCW around the point O. You can think of this as testing whether A <= B <= C with respect to a continuous CCW ordering around O.Properties:
- If orderedCCW(a,b,c,o) && orderedCCW(b,a,c,o), then a == b
- If orderedCCW(a,b,c,o) && orderedCCW(a,c,b,o), then b == c
- If orderedCCW(a,b,c,o) && orderedCCW(c,b,a,o), then a == b == c
- If a == b or b == c, then orderedCCW(a,b,c,o) is true
- Otherwise if a == c, then orderedCCW(a,b,c,o) is false
-
compareDistances
public static int compareDistances(S2Point x, S2Point a, S2Point b)
Returns -1, 0, or +1 according to whether AX < BX, A == B, or AX > BX respectively. Distances are measured with respect to the positions of X, A, and B as though they were reprojected to lie exactly on the surface of the unit sphere. Furthermore, this method uses symbolic perturbations to ensure that the result is non-zero whenever A != B, even when AX == BX exactly, or even when A and B project to the same point on the sphere. Such results are guaranteed to be self-consistent, i.e. if AB < BC and BC < AC, then AB < AC.
-
compareEdgeDistance
public static int compareEdgeDistance(S2Point x, S2Point a, S2Point b, double r2)
Returns -1, 0, or +1 according to whether the distance from the point X to the edge AB is less than, equal to, or greater than the squared chord distance "r2" respectively.Distances are measured with respect to the positions of all points as though they were projected to lie exactly on the surface of the unit sphere.
Requires that A and B do not project to antipodal points (e.g., A != -B). This can occur if for example A == S * B, for some constant S < 0.
Note all of the predicates defined here could be extended to handle edges consisting of antipodal points by implementing additional symbolic perturbation logic (similar to
sign(com.google.common.geometry.S2Point, com.google.common.geometry.S2Point, com.google.common.geometry.S2Point)) in order to rigorously define the direction of such edges.
-
edgeCircumcenterSign
public static int edgeCircumcenterSign(S2Point p, S2Point q, S2Point a, S2Point b, S2Point c)
Returns sign(P, Q, Z) where Z is the circumcenter of triangle ABC. The return value is -1 if Z is to the left of edge PQ, and +1 if Z is to the right of edge PQ. The return value is zero if A == B, B == C, or C == A (exactly), and also if P and Q project to identical points on the sphere (e.g., P == Q).The result is determined with respect to the positions of all points as though they were projected to lie exactly on the surface of the unit sphere. Furthermore this method uses symbolic perturbations to compute a consistent non-zero result even when Z lies exactly on edge PQ.
Requires that P and Q do not project to antipodal points (e.g., P == -Q) (see comments in compareEdgeDistance).
-
getVoronoiSiteExclusion
public static S2Predicates.Excluded getVoronoiSiteExclusion(S2Point a, S2Point b, S2Point p, S2Point q, double r2)
This is a specialized method that is used to compute the intersection of an edge PQ with the Voronoi diagram of a set of points, where each Voronoi region is intersected with a disc of fixed radius "r".Given two sites A and B and an edge (P, Q) such that
d(A,P) < d(B,P), and both sites are within the given distance "r" of edge PQ, this method intersects the Voronoi region of each site with a disc of radius r and determines whether either region has an empty intersection with edge PQ. It returns FIRST if site A has an empty intersection, SECOND if site B has an empty intersection, NEITHER if neither site has an empty intersection, or UNCERTAIN if A == B exactly. Note that it is not possible for both intersections to be empty because of the requirement that both sites are within distance r of edge PQ. (For example, the only reason that Voronoi region A can have an empty intersection with PQ is that site B is closer to all points on PQ that are within radius r of site A.)The result is determined with respect to the positions of all points as though they were projected to lie exactly on the surface of the unit sphere. Furthermore this method uses symbolic perturbations to compute a consistent non-zero result even when A and B lie on opposite sides of PQ such that the Voronoi edge between them exactly coincides with edge PQ, or when A and B are distinct but project to the same point on the sphere (i.e., they are linearly dependent).
Requires that
r < S1ChordAngle.RIGHT(90 degrees)compareDistances(p, a, b) < 0compareEdgeDistance(a, p, q, r) <= 0compareEdgeDistance(b, p, q, r) <= 0- P and Q do not project to antipodal points (e.g., P != -Q), see
S2Predicates.CompareEdgeDistancefor details.
-
-