countSegment method

void countSegment(
  1. Coordinate p1,
  2. Coordinate p2
)

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++;
    }
  }
}