countSegment method
Counts a segment
@param p1 an endpoint of the segment @param p2 another endpoint of the segment
Implementation
void countSegment(Coordinate p1, Coordinate p2) {
/**
* For each segment, check if it crosses
* a horizontal ray running from the test point in the positive x direction.
*/
// check if the segment is strictly to the left of the test point
if (p1.x < p.x && p2.x < p.x) return;
// check if the point is equal to the current ring vertex
if (p.x == p2.x && p.y == p2.y) {
isPointOnSegment = true;
return;
}
/**
* For horizontal segments, check if the point is on the segment.
* Otherwise, horizontal segments are not counted.
*/
if (p1.y == p.y && p2.y == p.y) {
double minx = p1.x;
double maxx = p2.x;
if (minx > maxx) {
minx = p2.x;
maxx = p1.x;
}
if (p.x >= minx && p.x <= maxx) {
isPointOnSegment = true;
}
return;
}
/**
* Evaluate all non-horizontal segments which cross a horizontal ray to the
* right of the test pt. To avoid double-counting shared vertices, we use the
* convention that
* <ul>
* <li>an upward edge includes its starting endpoint, and excludes its
* final endpoint
* <li>a downward edge excludes its starting endpoint, and includes its
* final endpoint
* </ul>
*/
if (((p1.y > p.y) && (p2.y <= p.y)) || ((p2.y > p.y) && (p1.y <= p.y))) {
int orient = Orientation.index(p1, p2, p);
if (orient == Orientation.COLLINEAR) {
isPointOnSegment = true;
return;
}
// Re-orient the result if needed to ensure effective segment direction is upwards
if (p2.y < p1.y) {
orient = -orient;
}
// The upward segment crosses the ray if the test point lies to the left (CCW) of the segment.
if (orient == Orientation.LEFT) {
crossingCount++;
}
}
}