コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        private static Location Locate(Coordinate p, ILineString l)
        {
            // bounding-box check
            if (!l.EnvelopeInternal.Intersects(p))
            {
                return(Location.Exterior);
            }


            Coordinate[] pt = l.Coordinates;
            if (!l.IsClosed)
            {
                if (p.Equals(pt[0]) || p.Equals(pt[pt.Length - 1]))
                {
                    return(Location.Boundary);
                }
            }
            if (CGAlgorithms.IsOnLine(p, pt))
            {
                return(Location.Interior);
            }
            return(Location.Exterior);
        }
コード例 #2
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.CounterClockwise)
                    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;
            }
コード例 #3
0
        /// <summary>
        /// Computes the distance from a line segment AB to a line segment CD.
        /// Note: NON-ROBUST!
        /// </summary>
        /// <param name="A">A point of one line.</param>
        /// <param name="B">The second point of the line (must be different to A).</param>
        /// <param name="C">One point of the line.</param>
        /// <param name="D">Another point of the line (must be different to A).</param>
        /// <returns>The distance from line segment AB to line segment CD.</returns>
        public static double DistanceLineLine(Coordinate A, Coordinate B,
                                              Coordinate C, Coordinate D)
        {
            // check for zero-length segments
            if (A.Equals(B))
            {
                return(CGAlgorithms.DistancePointLine(A, C, D));
            }
            if (C.Equals(D))
            {
                return(CGAlgorithms.DistancePointLine(D, A, B));
            }

            // AB and CD are line segments

            /*
             * from comp.graphics.algo
             *
             * Solving the above for r and s yields
             *     (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
             * r = ----------------------------- (eqn 1)
             *     (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
             *
             *     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
             * s = ----------------------------- (eqn 2)
             *     (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
             *
             * Let P be the position vector of the
             * intersection point, then
             * P=A+r(B-A) or
             * Px=Ax+r(Bx-Ax)
             * Py=Ay+r(By-Ay)
             * By examining the values of r & s, you can also determine some other limiting
             * conditions:
             * If 0<=r<=1 & 0<=s<=1, intersection exists
             *    r<0 or r>1 or s<0 or s>1 line segments do not intersect
             * If the denominator in eqn 1 is zero, AB & CD are parallel
             * If the numerator in eqn 1 is also zero, AB & CD are collinear.
             */

            double r_top = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y);
            double r_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X);

            double s_top = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y);
            double s_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X);

            if ((r_bot == 0) || (s_bot == 0))
            {
                return(Math
                       .Min(
                           CGAlgorithms.DistancePointLine(A, C, D),
                           Math.Min(
                               CGAlgorithms.DistancePointLine(B, C, D),
                               Math.Min(CGAlgorithms.DistancePointLine(C, A, B),
                                        CGAlgorithms.DistancePointLine(D, A, B)))));
            }
            double s = s_top / s_bot;
            double r = r_top / r_bot;

            if ((r < 0) || (r > 1) || (s < 0) || (s > 1))
            {
                // no intersection
                return(Math
                       .Min(
                           CGAlgorithms.DistancePointLine(A, C, D),
                           Math.Min(
                               CGAlgorithms.DistancePointLine(B, C, D),
                               Math.Min(CGAlgorithms.DistancePointLine(C, A, B),
                                        CGAlgorithms.DistancePointLine(D, A, B)))));
            }
            return(0.0); // intersection exists
        }
コード例 #4
0
        public override int 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(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(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(NoIntersection);
            }

            bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0;

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

            /*
             * At this point we know that there is a single intersection point
             * (since the lines are not collinear).
             */

            /*
             *  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;

                /*
                 * Check for two equal endpoints.
                 * This is done explicitly rather than by the orientation tests
                 * below in order to improve robustness.
                 *
                 * [An example where the orientation tests fail to be consistent is
                 * the following (where the true intersection is at the shared endpoint
                 * POINT (19.850257749638203 46.29709338043669)
                 *
                 * LINESTRING ( 19.850257749638203 46.29709338043669, 20.31970698357233 46.76654261437082 )
                 * and
                 * LINESTRING ( -48.51001596420236 -22.063180333403878, 19.850257749638203 46.29709338043669 )
                 *
                 * which used to produce the INCORRECT result: (20.31970698357233, 46.76654261437082, NaN)
                 *
                 */
                if (p1.Equals2D(q1) || p1.Equals2D(q2))
                {
                    IntersectionPoint[0] = p1;
                }
                else if (p2.Equals2D(q1) || p2.Equals2D(q2))
                {
                    IntersectionPoint[0] = p2;
                }
                else if (Pq1 == 0)
                {
                    IntersectionPoint[0] = new Coordinate(q1);
                }
                else if (Pq2 == 0)
                {
                    IntersectionPoint[0] = new Coordinate(q2);
                }
                else if (Qp1 == 0)
                {
                    IntersectionPoint[0] = new Coordinate(p1);
                }
                else if (Qp2 == 0)
                {
                    IntersectionPoint[0] = new Coordinate(p2);
                }
            }
            else
            {
                IsProper             = true;
                IntersectionPoint[0] = Intersection(p1, p2, q1, q2);
            }
            return(PointIntersection);
        }
コード例 #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="pt"></param>
 /// <returns></returns>
 public bool IsInside(Coordinate pt)
 {
     return(CGAlgorithms.IsPointInRing(pt, pts));
 }