예제 #1
0
        /// <summary>
        /// Uses a heuristic to reduce the number of points scanned to compute the hull.
        /// The heuristic is to find a polygon guaranteed to
        /// be in (or on) the hull, and eliminate all points inside it.
        /// A quadrilateral defined by the extremal points
        /// in the four orthogonal directions
        /// can be used, but even more inclusive is
        /// to use an octilateral defined by the points in the 8 cardinal directions.
        /// Notice that even if the method used to determine the polygon vertices
        /// is not 100% robust, this does not affect the robustness of the convex hull.
        /// </summary>
        /// <param name="pts"></param>
        /// <returns></returns>
        private static Coordinate[] Reduce(Coordinate[] pts)
        {
            Coordinate[] polyPts = ComputeOctRing(pts);

            // unable to compute interior polygon for some reason
            if (polyPts == null)
            {
                return(pts);
            }

            // add points defining polygon
            Iesi.Collections.Generic.SortedSet <Coordinate> reducedSet = new Iesi.Collections.Generic.SortedSet <Coordinate>();
            for (int i = 0; i < polyPts.Length; i++)
            {
                reducedSet.Add(polyPts[i]);
            }

            /*
             * Add all unique points not in the interior poly.
             * CgAlgorithms.IsPointInRing is not defined for points actually on the ring,
             * but this doesn't matter since the points of the interior polygon
             * are forced to be in the reduced set.
             */
            for (int i = 0; i < pts.Length; i++)
            {
                if (!CgAlgorithms.IsPointInRing(pts[i], polyPts))
                {
                    reducedSet.Add(pts[i]);
                }
            }

            Coordinate[] arr = new Coordinate[reducedSet.Count];
            reducedSet.CopyTo(arr, 0);
            return(arr);
        }
예제 #2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="p"></param>
 /// <param name="ring"></param>
 /// <returns></returns>
 private static LocationType LocateInPolygonRing(Coordinate p, IBasicGeometry ring)
 {
     // can this test be folded into IsPointInRing?
     if (CgAlgorithms.IsOnLine(p, ring.Coordinates))
     {
         return(LocationType.Boundary);
     }
     if (CgAlgorithms.IsPointInRing(p, ring.Coordinates))
     {
         return(LocationType.Interior);
     }
     return(LocationType.Exterior);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="poly"></param>
        /// <returns></returns>
        public static bool ContainsPointInPolygon(Coordinate p, IPolygon poly)
        {
            if (poly.IsEmpty)
            {
                return(false);
            }
            LinearRing shell = (LinearRing)poly.Shell;

            if (!CgAlgorithms.IsPointInRing(p, shell.Coordinates))
            {
                return(false);
            }
            // now test if the point lies in or on the holes
            for (int i = 0; i < poly.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)poly.GetInteriorRingN(i);
                if (CgAlgorithms.IsPointInRing(p, hole.Coordinates))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public virtual bool IsInside(Coordinate pt)
 {
     return(CgAlgorithms.IsPointInRing(pt, _pts));
 }