///<summary> /// Counts a segment ///</summary> /// <param name="p1">An endpoint of the segment</param> /// <param name="p2">Another endpoint of the segment</param> public 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))) { // translate the segment so that the test point lies on the origin double x1 = p1.X - _p.X; double y1 = p1.Y - _p.Y; double x2 = p2.X - _p.X; double y2 = p2.Y - _p.Y; /* * The translated segment straddles the x-axis. Compute the sign of the * ordinate of intersection with the x-axis. (y2 != y1, so denominator * will never be 0.0) */ // double xIntSign = RobustDeterminant.signOfDet2x2(x1, y1, x2, y2) / (y2 // - y1); // MD - faster & more robust computation? double xIntSign = RobustDeterminant.SignOfDet2x2(x1, y1, x2, y2); if (xIntSign == 0.0) { _isPointOnSegment = true; return; } if (y2 < y1) { xIntSign = -xIntSign; } // xsave = xInt; // The segment crosses the ray if the sign is strictly positive. if (xIntSign > 0.0) { _crossingCount++; } } }