/// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Remember the initial end of segment
            PointGeometry initEnd = new PointGeometry(e);

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X - s.X);

            if (!hseg.IsValid)
            {
                status = 1;
                return(false);
            }

            IPointGeometry[] data = this.Data;

            // Get relative position code for the start of the line. If it's
            // somewhere on the horizontal segment, cut the line back.
            byte scode = Geom.GetPositionCode(data[0], s, e);

            if (scode == 0)
            {
                e = new PointGeometry(Start);
            }

            // Loop through each line segment, testing the end of each segment
            // against the horizontal segment.
            byte ecode;

            for (int i = 1; i < data.Length; scode = ecode, i++)
            {
                // Get the position code for the end of the line segment
                ecode = Geom.GetPositionCode(data[i], s, e);

                // If it's coincident with the horizontal segment, cut the
                // line back. Otherwise see whether there is any potential
                // intersection to cut back to.

                if (ecode == 0)
                {
                    e = new PointGeometry(data[i]);
                }
                else if ((scode & ecode) == 0)
                {
                    IPosition x = null;
                    if (hseg.Intersect(data[i - 1], data[i], ref x))
                    {
                        e = new PointGeometry(x);
                    }
                }
            }

            // Return flag to indicate whether we got closer or not.
            return(!e.IsCoincident(initEnd));
        }
        /// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Remember the initial end of segment
            PointGeometry initEnd = new PointGeometry(e);

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X - s.X);

            if (!hseg.IsValid)
            {
                status = 1;
                return(false);
            }

            // Get relative position code for the start of the line. If it's
            // somewhere on the horizontal segment, cut the line back.
            byte scode = Geom.GetPositionCode(Start, s, e);

            if (scode == 0)
            {
                e = new PointGeometry(Start);
            }

            // Get the position code for the end of the line segment
            byte ecode = Geom.GetPositionCode(End, s, e);

            // If it's coincident with the horizontal segment, cut the
            // line back. Otherwise see whether there is any potential
            // intersection to cut back to.

            if (ecode == 0)
            {
                e = new PointGeometry(End);
            }
            else if ((scode & ecode) == 0)
            {
                IPosition x = null;
                if (hseg.Intersect(Start, End, ref x))
                {
                    e = new PointGeometry(x);
                }
            }

            // Return flag to indicate whether we got closer or not.
            return(!e.IsCoincident(initEnd));
        }
Exemple #3
0
        /// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Get the window of the circle that this curve lies on.
            IWindow cwin = m_Circle.Extent;

            // Get a window for the horizontal segment.
            IWindow segwin = new Window(s, e);

            // Return if the windows don't overlap.
            if (!cwin.IsOverlap(segwin))
            {
                return(false);
            }

            // Return if the the segment is to the west of the circle's window.
            if (segwin.Max.X < cwin.Min.X)
            {
                return(false);
            }

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X - s.X);

            if (!hseg.IsValid)
            {
                status = 1;
                return(false);
            }

            // Locate up to two intersections of the horizontal segment with the circle.
            IPosition x1 = null;
            IPosition x2 = null;
            uint      nx = hseg.Intersect(m_Circle, ref x1, ref x2);

            // Return if no intersections
            if (nx == 0)
            {
                return(false);
            }

            // Return if this arc curve is a complete circle.
            if (this.IsCircle)
            {
                return(false);
            }

            // Check whether the first intersection lies on this arc. If
            // so, update the end of segment, and return.
            if (CircularArcGeometry.IsInSector(this, x1, 0.0))
            {
                e = new PointGeometry(x1);
                return(true);
            }

            // If we got two intersections with the circle, check the
            // second intersection as well.
            if (nx == 2 && CircularArcGeometry.IsInSector(this, x2, 0.0))
            {
                e = new PointGeometry(x2);
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Remember the initial end of segment
            PointGeometry initEnd = new PointGeometry(e);

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X-s.X);
            if (!hseg.IsValid)
            {
                status = 1;
                return false;
            }

            // Get relative position code for the start of the line. If it's
            // somewhere on the horizontal segment, cut the line back.
            byte scode = Geom.GetPositionCode(Start, s, e);
            if (scode==0)
                e = new PointGeometry(Start);

            // Get the position code for the end of the line segment
            byte ecode = Geom.GetPositionCode(End, s, e);

            // If it's coincident with the horizontal segment, cut the
            // line back. Otherwise see whether there is any potential
            // intersection to cut back to.

            if (ecode==0)
                e = new PointGeometry(End);
            else if ((scode & ecode)==0)
            {
                IPosition x = null;
                if (hseg.Intersect(Start, End, ref x))
                    e = new PointGeometry(x);
            }

            // Return flag to indicate whether we got closer or not.
            return (!e.IsCoincident(initEnd));
        }
        /// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Remember the initial end of segment
            PointGeometry initEnd = new PointGeometry(e);

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X-s.X);
            if (!hseg.IsValid)
            {
                status = 1;
                return false;
            }

            IPointGeometry[] data = this.Data;

            // Get relative position code for the start of the line. If it's
            // somewhere on the horizontal segment, cut the line back.
            byte scode = Geom.GetPositionCode(data[0], s, e);
            if (scode==0)
                e = new PointGeometry(Start);

            // Loop through each line segment, testing the end of each segment
            // against the horizontal segment.
            byte ecode;
            for (int i=1; i<data.Length; scode=ecode, i++)
            {
                // Get the position code for the end of the line segment
                ecode = Geom.GetPositionCode(data[i], s, e);

                // If it's coincident with the horizontal segment, cut the
                // line back. Otherwise see whether there is any potential
                // intersection to cut back to.

                if (ecode==0)
                    e = new PointGeometry(data[i]);
                else if ((scode & ecode)==0)
                {
                    IPosition x=null;
                    if (hseg.Intersect(data[i-1], data[i], ref x))
                        e = new PointGeometry(x);
                }
            }

            // Return flag to indicate whether we got closer or not.
            return (!e.IsCoincident(initEnd));
        }
        /// <summary>
        /// Cuts back a horizontal line segment to the closest intersection with this line.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="s">Start of horizontal segment.</param>
        /// <param name="e">End of segment (will be modified if segment intersects this line)</param>
        /// <param name="status">Return code indicating whether an error has arisen (returned
        /// as 0 if no error).</param>
        /// <returns>True if the horizontal line was cut back.</returns>
        internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status)
        {
            status = 0;

            // Get the window of the circle that this curve lies on.
            IWindow cwin = m_Circle.Extent;

            // Get a window for the horizontal segment.
            IWindow segwin = new Window(s, e);

            // Return if the windows don't overlap.
            if (!cwin.IsOverlap(segwin))
                return false;

            // Return if the the segment is to the west of the circle's window.
            if (segwin.Max.X < cwin.Min.X)
                return false;

            // Represent the horizontal segment in a class of its own
            HorizontalRay hseg = new HorizontalRay(s, e.X-s.X);
            if (!hseg.IsValid)
            {
                status = 1;
                return false;
            }

            // Locate up to two intersections of the horizontal segment with the circle.
            IPosition x1=null;
            IPosition x2=null;
            uint nx = hseg.Intersect(m_Circle, ref x1, ref x2);

            // Return if no intersections
            if (nx==0)
                return false;

            // Return if this arc curve is a complete circle.
            if (this.IsCircle)
                return false;

            // Check whether the first intersection lies on this arc. If
            // so, update the end of segment, and return.
            if (CircularArcGeometry.IsInSector(this, x1, 0.0))
            {
                e = new PointGeometry(x1);
                return true;
            }

            // If we got two intersections with the circle, check the
            // second intersection as well.
            if (nx==2 && CircularArcGeometry.IsInSector(this, x2, 0.0))
            {
                e = new PointGeometry(x2);
                return true;
            }

            return false;
        }