/// <summary> /// Returns the index of the direction of the point q /// relative to a /// vector specified by p1-p2. /// /// </summary> /// <param name="p1">the origin point of the vector /// </param> /// <param name="p2">the final point of the vector /// </param> /// <param name="q">the point to compute the direction to /// /// </param> /// <returns> 1 if q is counter-clockwise (left) from p1-p2 /// </returns> /// <returns> -1 if q is clockwise (right) from p1-p2 /// </returns> /// <returns> 0 if q is collinear with p1-p2 /// </returns> public static int OrientationIndex(Coordinate p1, Coordinate p2, Coordinate q) { if (p1 == null) { throw new ArgumentNullException("p1"); } if (p2 == null) { throw new ArgumentNullException("p2"); } if (q == null) { throw new ArgumentNullException("q"); } // travelling along p1->p2, turn counter clockwise to get to q return 1, // travelling along p1->p2, turn clockwise to get to q return -1, // p1, p2 and q are colinear return 0. double dx1 = p2.X - p1.X; double dy1 = p2.Y - p1.Y; double dx2 = q.X - p2.X; double dy2 = q.Y - p2.Y; return(RobustDeterminant.SignOfDeterminant(dx1, dy1, dx2, dy2)); }
private void TestLineSegment(Coordinate p, LineSegment seg) { double xInt; // x intersection of segment with ray double x1; // translated coordinates double y1; double x2; double y2; // Test if segment Crosses ray from test point in positive x direction. Coordinate p1 = seg.p0; Coordinate p2 = seg.p1; x1 = p1.X - p.X; y1 = p1.Y - p.Y; x2 = p2.X - p.X; y2 = p2.Y - p.Y; if (((y1 > 0) && (y2 <= 0)) || ((y2 > 0) && (y1 <= 0))) { // segment straddles x axis, so compute intersection. xInt = RobustDeterminant.SignOfDeterminant(x1, y1, x2, y2) / (y2 - y1); //xsave = xInt; // Crosses ray if strictly positive intersection. if (0.0 < xInt) { crossings++; } } }
/// <summary> /// This algorithm does not attempt to first check the point against the envelope /// of the ring. /// /// </summary> /// <param name="ring">assumed to have first point identical to last point /// </param> public bool IsPointInRing(Coordinate p, ICoordinateList ring) { if (p == null) { throw new ArgumentNullException("p"); } if (ring == null) { throw new ArgumentNullException("ring"); } /* * For each segment l = (i-1, i), see if it crosses ray from test point in positive x direction. */ int crossings = 0; // number of segment/ray crossings int nCount = ring.Count; for (int i = 1; i < nCount; i++) { int i1 = i - 1; Coordinate p1 = ring[i]; Coordinate p2 = ring[i1]; if (((p1.Y > p.Y) && (p2.Y <= p.Y)) || ((p2.Y > p.Y) && (p1.Y <= p.Y))) { double x1 = p1.X - p.X; double y1 = p1.Y - p.Y; double x2 = p2.X - p.X; double y2 = p2.Y - p.Y; /* * segment straddles x axis, so compute intersection with x-axis. */ double xInt = RobustDeterminant.SignOfDeterminant(x1, y1, x2, y2) / (y2 - y1); //xsave = xInt; /* * crosses ray if strictly positive intersection. */ if (xInt > 0.0) { crossings++; } } } /* * p is inside if number of crossings is odd. */ if ((crossings % 2) == 1) { return(true); } else { return(false); } }