Ejemplo n.º 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.
        /// Note 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.
        /// <para>
        /// To satisfy the requirements of the Graham Scan algorithm, 
        /// the returned array has at least 3 entries.
        /// </para>
        /// </summary>
        /// <param name="pts">The coordinates to reduce</param>
        /// <returns>The reduced array of coordinates</returns>
        private static Coordinate[] Reduce(Coordinate[] pts)
        {
            var polyPts = ComputeOctRing(pts/*_inputPts*/);
            
            // unable to compute interior polygon for some reason
            if(polyPts == null)
                return pts;
            
            // add points defining polygon
            var reducedSet = new HashSet<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 (var i = 0; i < pts.Length; i++)
                if (!CGAlgorithms.IsPointInRing(pts[i], polyPts))                
                    reducedSet.Add(pts[i]);

            var reducedPts = CoordinateArrays.ToCoordinateArray((ICollection<Coordinate>)reducedSet);// new Coordinate[reducedSet.Count];
            Array.Sort(reducedPts);

            // ensure that computed array has at least 3 points (not necessarily unique)  
            if (reducedPts.Length < 3)
                return PadArray3(reducedPts);

            return reducedPts;
        }
Ejemplo n.º 2
0
 ///<summary>
 /// Determines whether a point lies in a LinearRing, using the ring envelope to short-circuit if possible.
 ///</summary>
 /// <param name="p">The point to test</param>
 /// <param name="ring">A linear ring</param>
 /// <returns>true if the point lies inside the ring</returns>
 private static bool IsPointInRing(ICoordinate p, ILinearRing ring)
 {
     // short-circuit if point is not in ring envelope
     if (!ring.EnvelopeInternal.Intersects(p))
     {
         return(false);
     }
     return(CGAlgorithms.IsPointInRing(p, ring.Coordinates));
 }
Ejemplo n.º 3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public bool IsInside(Coordinate pt)
 {
     return(CGAlgorithms.IsPointInRing(pt, pts));
 }