Esempio n. 1
0
        /// <summary>
        /// Gets the point on this line that is closest to a specified position.
        /// </summary>
        /// <param name="p">The position to search from.</param>
        /// <param name="tol">Maximum distance from line to the search position</param>
        /// <returns>The closest position (null if the line is further away than the specified
        /// max distance)</returns>
        internal override IPosition GetClosest(IPointGeometry p, ILength tol)
        {
            // Get the distance from the centre of the circle to the search point.
            IPointGeometry center = m_Circle.Center;
            double         dist   = Geom.Distance(center, p);

            // Return if the search point is beyond tolerance.
            double radius = m_Circle.Radius;
            double diff   = Math.Abs(dist - radius);

            if (diff > tol.Meters)
            {
                return(null);
            }

            // If the vertex lies in the curve sector, the closest position
            // is along the bearing from the centre through the search
            // position. Otherwise the closest position is the end of
            // the curve that's closest (given that it's within tolerance).

            if (CircularArcGeometry.IsInSector(this, p, 0.0))
            {
                double bearing = Geom.BearingInRadians(center, p);
                return(Geom.Polar(center, bearing, radius));
            }

            double d1 = Geom.DistanceSquared(p, BC);
            double d2 = Geom.DistanceSquared(p, EC);

            double t = tol.Meters;

            if (Math.Min(d1, d2) < (t * t))
            {
                if (d1 < d2)
                {
                    return(BC);
                }
                else
                {
                    return(EC);
                }
            }

            return(null);
        }
Esempio n. 2
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);
        }