/// <summary> /// Test whether a point lies inside a ring. /// The ring may be oriented in either direction. /// If the point lies on the ring boundary the result of this method is unspecified. /// This algorithm does not attempt to first check the point against the envelope /// of the ring. /// </summary> /// <param name="p">Point to check for ring inclusion.</param> /// <param name="ring">Assumed to have first point identical to last point.</param> /// <returns><c>true</c> if p is inside ring.</returns> public static bool IsPointInRing(ICoordinate p, ICoordinate[] ring) { if (p == null) { return(false); } int i; int i1; // point index; i1 = i-1 double xInt; // x intersection of segment with ray int crossings = 0; // number of segment/ray crossings double x1; // translated coordinates double y1; double x2; double y2; int nPts = ring.Length; /* * For each segment l = (i-1, i), see if it crosses ray from test point in positive x direction. */ for (i = 1; i < nPts; i++) { i1 = i - 1; ICoordinate p1 = ring[i]; ICoordinate p2 = ring[i1]; 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.SignOfDet2x2(x1, y1, x2, y2) / (y2 - y1); /* * crosses ray if strictly positive intersection. */ if (0.0 < xInt) { crossings++; } } } /* * p is inside if number of crossings is odd. */ if ((crossings % 2) == 1) { return(true); } else { return(false); } }
/// <summary> /// Returns the index of the direction of the point <c>q</c> /// relative to a vector specified by <c>p1-p2</c>. /// </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, /// -1 if q is clockwise (right) from p1-p2, /// 0 if q is collinear with p1-p2. /// </returns> public static int OrientationIndex(ICoordinate p1, ICoordinate p2, ICoordinate 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.SignOfDet2x2(dx1, dy1, dx2, dy2)); }