Exemplo n.º 1
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="o"></param>
            /// <param name="p"></param>
            /// <param name="q"></param>
            /// <returns></returns>
            private static int PolarCompare(Coordinate o, Coordinate p, Coordinate q)
            {
                double dxp = p.X - o.X;
                double dyp = p.Y - o.Y;
                double dxq = q.X - o.X;
                double dyq = q.Y - o.Y;

                int orient = CgAlgorithms.ComputeOrientation(o, p, q);

                if (orient == CgAlgorithms.COUNTER_CLOCKWISE)
                {
                    return(1);
                }
                if (orient == CgAlgorithms.CLOCKWISE)
                {
                    return(-1);
                }

                // points are collinear - check distance
                double op = dxp * dxp + dyp * dyp;
                double oq = dxq * dxq + dyq * dyq;

                if (op < oq)
                {
                    return(-1);
                }
                if (op > oq)
                {
                    return(1);
                }
                return(0);
            }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="c1"></param>
 /// <param name="c2"></param>
 /// <param name="c3"></param>
 /// <returns>
 /// Whether the three coordinates are collinear
 /// and c2 lies between c1 and c3 inclusive.
 /// </returns>
 private static bool IsBetween(Coordinate c1, Coordinate c2, Coordinate c3)
 {
     if (CgAlgorithms.ComputeOrientation(c1, c2, c3) != 0)
     {
         return(false);
     }
     if (c1.X != c3.X)
     {
         if (c1.X <= c2.X && c2.X <= c3.X)
         {
             return(true);
         }
         if (c3.X <= c2.X && c2.X <= c1.X)
         {
             return(true);
         }
     }
     if (c1.Y != c3.Y)
     {
         if (c1.Y <= c2.Y && c2.Y <= c3.Y)
         {
             return(true);
         }
         if (c3.Y <= c2.Y && c2.Y <= c1.Y)
         {
             return(true);
         }
     }
     return(false);
 }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pts"></param>
        private void AddHole(IList <Coordinate> pts)
        {
            bool isPositiveArea = CgAlgorithms.IsCounterClockwise(pts);

            for (int i = 0; i < pts.Count - 1; i++)
            {
                AddTriangle(_basePt, pts[i], pts[i + 1], isPositiveArea);
            }
        }
Exemplo n.º 5
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);
 }
Exemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        private static LocationType LocateInLineString(Coordinate p, ILineString l)
        {
            IList <Coordinate> pt = l.Coordinates;

            if (!l.IsClosed)
            {
                if (p.Equals(pt[0]) || p.Equals(pt[pt.Count - 1]))
                {
                    return(LocationType.Boundary);
                }
            }
            if (CgAlgorithms.IsOnLine(p, pt))
            {
                return(LocationType.Interior);
            }
            return(LocationType.Exterior);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="p"></param>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 public override void ComputeIntersection(Coordinate p, Coordinate p1, Coordinate p2)
 {
     IsProper = false;
     // do between check first, since it is faster than the orientation test
     if (Envelope.Intersects(p1, p2, p))
     {
         if ((CgAlgorithms.OrientationIndex(p1, p2, p) == 0) && (CgAlgorithms.OrientationIndex(p2, p1, p) == 0))
         {
             IsProper = true;
             if (p.Equals(p1) || p.Equals(p2))
             {
                 IsProper = false;
             }
             Result = IntersectionType.PointIntersection;
             return;
         }
     }
     Result = IntersectionType.NoIntersection;
 }
Exemplo n.º 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private static Stack <Coordinate> GrahamScan(Coordinate[] c)
        {
            Stack <Coordinate> ps = new Stack <Coordinate>(c.Length);

            ps.Push(c[0]);
            ps.Push(c[1]);
            ps.Push(c[2]);
            for (int i = 3; i < c.Length; i++)
            {
                Coordinate p = ps.Pop();
                while (CgAlgorithms.ComputeOrientation(ps.Peek(), p, c[i]) > 0)
                {
                    p = ps.Pop();
                }
                ps.Push(p);
                ps.Push(c[i]);
            }
            ps.Push(c[0]);
            return(ps);
        }
        /// <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);
        }
Exemplo n.º 10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="q1"></param>
        /// <param name="q2"></param>
        /// <returns></returns>
        public override IntersectionType ComputeIntersect(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
        {
            IsProper = false;

            // first try a fast test to see if the envelopes of the lines intersect
            if (!Envelope.Intersects(p1, p2, q1, q2))
            {
                return(IntersectionType.NoIntersection);
            }

            // for each endpoint, compute which side of the other segment it lies
            // if both endpoints lie on the same side of the other segment,
            // the segments do not intersect
            int pq1 = CgAlgorithms.OrientationIndex(p1, p2, q1);
            int pq2 = CgAlgorithms.OrientationIndex(p1, p2, q2);

            if ((pq1 > 0 && pq2 > 0) || (pq1 < 0 && pq2 < 0))
            {
                return(IntersectionType.NoIntersection);
            }

            int qp1 = CgAlgorithms.OrientationIndex(q1, q2, p1);
            int qp2 = CgAlgorithms.OrientationIndex(q1, q2, p2);

            if ((qp1 > 0 && qp2 > 0) || (qp1 < 0 && qp2 < 0))
            {
                return(IntersectionType.NoIntersection);
            }

            bool collinear = (pq1 == 0 && pq2 == 0 && qp1 == 0 && qp2 == 0);

            if (collinear)
            {
                return(ComputeCollinearIntersection(p1, p2, q1, q2));
            }

            /*
             *  Check if the intersection is an endpoint. If it is, copy the endpoint as
             *  the intersection point. Copying the point rather than computing it
             *  ensures the point has the exact value, which is important for
             *  robustness. It is sufficient to simply check for an endpoint which is on
             *  the other line, since at this point we know that the inputLines must
             *  intersect.
             */
            if (pq1 == 0 || pq2 == 0 || qp1 == 0 || qp2 == 0)
            {
                IsProper = false;
                if (pq1 == 0)
                {
                    IntersectionPoints[0] = new Coordinate(q1);
                }
                if (pq2 == 0)
                {
                    IntersectionPoints[0] = new Coordinate(q2);
                }
                if (qp1 == 0)
                {
                    IntersectionPoints[0] = new Coordinate(p1);
                }
                if (qp2 == 0)
                {
                    IntersectionPoints[0] = new Coordinate(p2);
                }
            }
            else
            {
                IsProper = true;
                IntersectionPoints[0] = Intersection(p1, p2, q1, q2);
            }
            return(IntersectionType.PointIntersection);
        }
Exemplo n.º 11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public virtual bool IsInside(Coordinate pt)
 {
     return(CgAlgorithms.IsPointInRing(pt, _pts));
 }